diff --git "a/ort/ort.webgl.mjs" "b/ort/ort.webgl.mjs" new file mode 100644--- /dev/null +++ "b/ort/ort.webgl.mjs" @@ -0,0 +1,25754 @@ +/*! + * ONNX Runtime Web v1.30.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 __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a, b) => (typeof require !== "undefined" ? require : a)[b] +}) : x)(function(x) { + if (typeof require !== "undefined") return require.apply(this, arguments); + throw Error('Dynamic require of "' + x + '" is not supported'); +}); +var __esm = (fn, res, err) => function __init() { + if (err) throw err[0]; + try { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; + } catch (e) { + throw err = [e], e; + } +}; +var __commonJS = (cb, mod) => function __require2() { + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } +}; +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 = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __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 || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// common/dist/esm/backend-impl.js +var backends, backendsSortedByPriority, registerBackend, tryResolveAndInitializeBackend, resolveBackendAndExecutionProviders; +var init_backend_impl = __esm({ + "common/dist/esm/backend-impl.js"() { + "use strict"; + backends = /* @__PURE__ */ new Map(); + backendsSortedByPriority = []; + registerBackend = (name2, backend2, priority) => { + if (backend2 && typeof backend2.init === "function" && typeof backend2.createInferenceSessionHandler === "function") { + const currentBackend = backends.get(name2); + if (currentBackend === void 0) { + backends.set(name2, { backend: backend2, priority }); + } else if (currentBackend.priority > priority) { + return; + } else if (currentBackend.priority === priority) { + if (currentBackend.backend !== backend2) { + throw new Error(`cannot register backend "${name2}" using priority ${priority}`); + } + } + if (priority >= 0) { + const i = backendsSortedByPriority.indexOf(name2); + if (i !== -1) { + backendsSortedByPriority.splice(i, 1); + } + for (let i2 = 0; i2 < backendsSortedByPriority.length; i2++) { + if (backends.get(backendsSortedByPriority[i2]).priority <= priority) { + backendsSortedByPriority.splice(i2, 0, name2); + return; + } + } + backendsSortedByPriority.push(name2); + } + return; + } + throw new TypeError("not a valid backend"); + }; + tryResolveAndInitializeBackend = async (backendName) => { + const backendInfo = backends.get(backendName); + if (!backendInfo) { + return "backend not found."; + } + if (backendInfo.initialized) { + return backendInfo.backend; + } else if (backendInfo.aborted) { + return backendInfo.error; + } else { + const isInitializing = !!backendInfo.initPromise; + try { + if (!isInitializing) { + backendInfo.initPromise = backendInfo.backend.init(backendName); + } + await backendInfo.initPromise; + backendInfo.initialized = true; + return backendInfo.backend; + } catch (e) { + if (!isInitializing) { + backendInfo.error = `${e}`; + backendInfo.aborted = true; + } + return backendInfo.error; + } finally { + delete backendInfo.initPromise; + } + } + }; + resolveBackendAndExecutionProviders = async (options) => { + const eps = options.executionProviders || []; + const backendHints = eps.map((i) => typeof i === "string" ? i : i.name); + const backendNames = backendHints.length === 0 ? backendsSortedByPriority : backendHints; + let backend2; + const errors = []; + const availableBackendNames = /* @__PURE__ */ new Set(); + for (const backendName of backendNames) { + const resolveResult = await tryResolveAndInitializeBackend(backendName); + if (typeof resolveResult === "string") { + errors.push({ name: backendName, err: resolveResult }); + } else { + if (!backend2) { + backend2 = resolveResult; + } + if (backend2 === resolveResult) { + availableBackendNames.add(backendName); + } + } + } + if (!backend2) { + throw new Error(`no available backend found. ERR: ${errors.map((e) => `[${e.name}] ${e.err}`).join(", ")}`); + } + for (const { name: name2, err } of errors) { + if (backendHints.includes(name2)) { + console.warn(`removing requested execution provider "${name2}" from session options because it is not available: ${err}`); + } + } + const filteredEps = eps.filter((i) => availableBackendNames.has(typeof i === "string" ? i : i.name)); + return [ + backend2, + new Proxy(options, { + get: (target, prop) => { + if (prop === "executionProviders") { + return filteredEps; + } + return Reflect.get(target, prop); + } + }) + ]; + }; + } +}); + +// common/dist/esm/backend.js +var init_backend = __esm({ + "common/dist/esm/backend.js"() { + "use strict"; + init_backend_impl(); + } +}); + +// common/dist/esm/version.js +var version; +var init_version = __esm({ + "common/dist/esm/version.js"() { + "use strict"; + version = "1.30.0"; + } +}); + +// common/dist/esm/env-impl.js +var logLevelValue, env; +var init_env_impl = __esm({ + "common/dist/esm/env-impl.js"() { + "use strict"; + init_version(); + logLevelValue = "warning"; + env = { + wasm: {}, + webgl: {}, + webgpu: {}, + versions: { common: version }, + set logLevel(value) { + if (value === void 0) { + return; + } + if (typeof value !== "string" || ["verbose", "info", "warning", "error", "fatal"].indexOf(value) === -1) { + throw new Error(`Unsupported logging level: ${value}`); + } + logLevelValue = value; + }, + get logLevel() { + return logLevelValue; + } + }; + Object.defineProperty(env, "logLevel", { enumerable: true }); + } +}); + +// common/dist/esm/env.js +var env2; +var init_env = __esm({ + "common/dist/esm/env.js"() { + "use strict"; + init_env_impl(); + env2 = env; + } +}); + +// common/dist/esm/tensor-conversion-impl.js +var tensorToDataURL, tensorToImageData; +var init_tensor_conversion_impl = __esm({ + "common/dist/esm/tensor-conversion-impl.js"() { + "use strict"; + tensorToDataURL = (tensor, options) => { + const canvas = typeof document !== "undefined" ? document.createElement("canvas") : new OffscreenCanvas(1, 1); + canvas.width = tensor.dims[3]; + canvas.height = tensor.dims[2]; + const pixels2DContext = canvas.getContext("2d"); + if (pixels2DContext != null) { + let width; + let height; + if (options?.tensorLayout !== void 0 && options.tensorLayout === "NHWC") { + width = tensor.dims[2]; + height = tensor.dims[3]; + } else { + width = tensor.dims[3]; + height = tensor.dims[2]; + } + const inputformat = options?.format !== void 0 ? options.format : "RGB"; + const norm = options?.norm; + let normMean; + let normBias; + if (norm === void 0 || norm.mean === void 0) { + normMean = [255, 255, 255, 255]; + } else { + if (typeof norm.mean === "number") { + normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; + } else { + normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 0]; + if (norm.mean[3] !== void 0) { + normMean[3] = norm.mean[3]; + } + } + } + if (norm === void 0 || norm.bias === void 0) { + normBias = [0, 0, 0, 0]; + } else { + if (typeof norm.bias === "number") { + normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; + } else { + normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0]; + if (norm.bias[3] !== void 0) { + normBias[3] = norm.bias[3]; + } + } + } + const stride = height * width; + let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; + if (inputformat === "RGBA") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + aTensorPointer = stride * 3; + } else if (inputformat === "RGB") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + } else if (inputformat === "RBG") { + rTensorPointer = 0; + bTensorPointer = stride; + gTensorPointer = stride * 2; + } + for (let i = 0; i < height; i++) { + for (let j = 0; j < width; j++) { + const R = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; + const G = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; + const B = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; + const A = aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; + pixels2DContext.fillStyle = "rgba(" + R + "," + G + "," + B + "," + A + ")"; + pixels2DContext.fillRect(j, i, 1, 1); + } + } + if ("toDataURL" in canvas) { + return canvas.toDataURL(); + } else { + throw new Error("toDataURL is not supported"); + } + } else { + throw new Error("Can not access image data"); + } + }; + tensorToImageData = (tensor, options) => { + const pixels2DContext = typeof document !== "undefined" ? document.createElement("canvas").getContext("2d") : new OffscreenCanvas(1, 1).getContext("2d"); + let image; + if (pixels2DContext != null) { + let width; + let height; + let channels; + if (options?.tensorLayout !== void 0 && options.tensorLayout === "NHWC") { + width = tensor.dims[2]; + height = tensor.dims[1]; + channels = tensor.dims[3]; + } else { + width = tensor.dims[3]; + height = tensor.dims[2]; + channels = tensor.dims[1]; + } + const inputformat = options !== void 0 ? options.format !== void 0 ? options.format : "RGB" : "RGB"; + const norm = options?.norm; + let normMean; + let normBias; + if (norm === void 0 || norm.mean === void 0) { + normMean = [255, 255, 255, 255]; + } else { + if (typeof norm.mean === "number") { + normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; + } else { + normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 255]; + if (norm.mean[3] !== void 0) { + normMean[3] = norm.mean[3]; + } + } + } + if (norm === void 0 || norm.bias === void 0) { + normBias = [0, 0, 0, 0]; + } else { + if (typeof norm.bias === "number") { + normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; + } else { + normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0]; + if (norm.bias[3] !== void 0) { + normBias[3] = norm.bias[3]; + } + } + } + const stride = height * width; + if (options !== void 0) { + if (options.format !== void 0 && channels === 4 && options.format !== "RGBA" || channels === 3 && options.format !== "RGB" && options.format !== "BGR") { + throw new Error("Tensor format doesn't match input tensor dims"); + } + } + const step = 4; + let rImagePointer = 0, gImagePointer = 1, bImagePointer = 2, aImagePointer = 3; + let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; + if (inputformat === "RGBA") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + aTensorPointer = stride * 3; + } else if (inputformat === "RGB") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + } else if (inputformat === "RBG") { + rTensorPointer = 0; + bTensorPointer = stride; + gTensorPointer = stride * 2; + } + image = pixels2DContext.createImageData(width, height); + for (let i = 0; i < height * width; rImagePointer += step, gImagePointer += step, bImagePointer += step, aImagePointer += step, i++) { + image.data[rImagePointer] = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; + image.data[gImagePointer] = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; + image.data[bImagePointer] = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; + image.data[aImagePointer] = aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; + } + } else { + throw new Error("Can not access image data"); + } + return image; + }; + } +}); + +// common/dist/esm/tensor-factory-impl.js +var bufferToTensor, tensorFromImage, tensorFromTexture, tensorFromGpuBuffer, tensorFromMLTensor, tensorFromPinnedBuffer; +var init_tensor_factory_impl = __esm({ + "common/dist/esm/tensor-factory-impl.js"() { + "use strict"; + init_tensor_impl(); + bufferToTensor = (buffer, options) => { + if (buffer === void 0) { + throw new Error("Image buffer must be defined"); + } + if (options.height === void 0 || options.width === void 0) { + throw new Error("Image height and width must be defined"); + } + if (options.tensorLayout === "NHWC") { + throw new Error("NHWC Tensor layout is not supported yet"); + } + const { height, width } = options; + const norm = options.norm ?? { mean: 255, bias: 0 }; + let normMean; + let normBias; + if (typeof norm.mean === "number") { + normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; + } else { + normMean = [norm.mean[0], norm.mean[1], norm.mean[2], norm.mean[3] ?? 255]; + } + if (typeof norm.bias === "number") { + normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; + } else { + normBias = [norm.bias[0], norm.bias[1], norm.bias[2], norm.bias[3] ?? 0]; + } + const inputformat = options.format !== void 0 ? options.format : "RGBA"; + const outputformat = options.tensorFormat !== void 0 ? options.tensorFormat !== void 0 ? options.tensorFormat : "RGB" : "RGB"; + const stride = height * width; + const float32Data = outputformat === "RGBA" ? new Float32Array(stride * 4) : new Float32Array(stride * 3); + let step = 4, rImagePointer = 0, gImagePointer = 1, bImagePointer = 2, aImagePointer = 3; + let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; + if (inputformat === "RGB") { + step = 3; + rImagePointer = 0; + gImagePointer = 1; + bImagePointer = 2; + aImagePointer = -1; + } + if (outputformat === "RGBA") { + aTensorPointer = stride * 3; + } else if (outputformat === "RBG") { + rTensorPointer = 0; + bTensorPointer = stride; + gTensorPointer = stride * 2; + } else if (outputformat === "BGR") { + bTensorPointer = 0; + gTensorPointer = stride; + rTensorPointer = stride * 2; + } + for (let i = 0; i < stride; i++, rImagePointer += step, bImagePointer += step, gImagePointer += step, aImagePointer += step) { + float32Data[rTensorPointer++] = (buffer[rImagePointer] + normBias[0]) / normMean[0]; + float32Data[gTensorPointer++] = (buffer[gImagePointer] + normBias[1]) / normMean[1]; + float32Data[bTensorPointer++] = (buffer[bImagePointer] + normBias[2]) / normMean[2]; + if (aTensorPointer !== -1 && aImagePointer !== -1) { + float32Data[aTensorPointer++] = (buffer[aImagePointer] + normBias[3]) / normMean[3]; + } + } + const outputTensor = outputformat === "RGBA" ? new Tensor("float32", float32Data, [1, 4, height, width]) : new Tensor("float32", float32Data, [1, 3, height, width]); + return outputTensor; + }; + tensorFromImage = async (image, options) => { + const isHTMLImageEle = typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement; + const isImageDataEle = typeof ImageData !== "undefined" && image instanceof ImageData; + const isImageBitmap = typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap; + const isString = typeof image === "string"; + let data; + let bufferToTensorOptions = options ?? {}; + const createCanvas2 = () => { + if (typeof document !== "undefined") { + return document.createElement("canvas"); + } else if (typeof OffscreenCanvas !== "undefined") { + return new OffscreenCanvas(1, 1); + } else { + throw new Error("Canvas is not supported"); + } + }; + const createCanvasContext = (canvas) => { + if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) { + return canvas.getContext("2d"); + } else if (canvas instanceof OffscreenCanvas) { + return canvas.getContext("2d"); + } else { + return null; + } + }; + if (isHTMLImageEle) { + const canvas = createCanvas2(); + canvas.width = image.width; + canvas.height = image.height; + const pixels2DContext = createCanvasContext(canvas); + if (pixels2DContext != null) { + let height = image.height; + let width = image.width; + if (options !== void 0 && options.resizedHeight !== void 0 && options.resizedWidth !== void 0) { + height = options.resizedHeight; + width = options.resizedWidth; + } + if (options !== void 0) { + bufferToTensorOptions = options; + if (options.tensorFormat !== void 0) { + throw new Error("Image input config format must be RGBA for HTMLImageElement"); + } else { + bufferToTensorOptions.tensorFormat = "RGBA"; + } + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + } else { + bufferToTensorOptions.tensorFormat = "RGBA"; + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + } + pixels2DContext.drawImage(image, 0, 0); + data = pixels2DContext.getImageData(0, 0, width, height).data; + } else { + throw new Error("Can not access image data"); + } + } else if (isImageDataEle) { + let height; + let width; + if (options !== void 0 && options.resizedWidth !== void 0 && options.resizedHeight !== void 0) { + height = options.resizedHeight; + width = options.resizedWidth; + } else { + height = image.height; + width = image.width; + } + if (options !== void 0) { + bufferToTensorOptions = options; + } + bufferToTensorOptions.format = "RGBA"; + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + if (options !== void 0) { + const tempCanvas = createCanvas2(); + tempCanvas.width = width; + tempCanvas.height = height; + const pixels2DContext = createCanvasContext(tempCanvas); + if (pixels2DContext != null) { + pixels2DContext.putImageData(image, 0, 0); + data = pixels2DContext.getImageData(0, 0, width, height).data; + } else { + throw new Error("Can not access image data"); + } + } else { + data = image.data; + } + } else if (isImageBitmap) { + if (options === void 0) { + throw new Error("Please provide image config with format for Imagebitmap"); + } + const canvas = createCanvas2(); + canvas.width = image.width; + canvas.height = image.height; + const pixels2DContext = createCanvasContext(canvas); + if (pixels2DContext != null) { + const height = image.height; + const width = image.width; + pixels2DContext.drawImage(image, 0, 0, width, height); + data = pixels2DContext.getImageData(0, 0, width, height).data; + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + return bufferToTensor(data, bufferToTensorOptions); + } else { + throw new Error("Can not access image data"); + } + } else if (isString) { + return new Promise((resolve, reject) => { + const canvas = createCanvas2(); + const context = createCanvasContext(canvas); + if (!image || !context) { + return reject(); + } + const newImage = new Image(); + newImage.crossOrigin = "Anonymous"; + newImage.src = image; + newImage.onload = () => { + canvas.width = newImage.width; + canvas.height = newImage.height; + context.drawImage(newImage, 0, 0, canvas.width, canvas.height); + const img = context.getImageData(0, 0, canvas.width, canvas.height); + bufferToTensorOptions.height = canvas.height; + bufferToTensorOptions.width = canvas.width; + resolve(bufferToTensor(img.data, bufferToTensorOptions)); + }; + }); + } else { + throw new Error("Input data provided is not supported - aborted tensor creation"); + } + if (data !== void 0) { + return bufferToTensor(data, bufferToTensorOptions); + } else { + throw new Error("Input data provided is not supported - aborted tensor creation"); + } + }; + tensorFromTexture = (texture, options) => { + const { width, height, download, dispose } = options; + const dims = [1, height, width, 4]; + return new Tensor({ location: "texture", type: "float32", texture, dims, download, dispose }); + }; + tensorFromGpuBuffer = (gpuBuffer, options) => { + const { dataType, dims, download, dispose } = options; + return new Tensor({ location: "gpu-buffer", type: dataType ?? "float32", gpuBuffer, dims, download, dispose }); + }; + tensorFromMLTensor = (mlTensor, options) => { + const { dataType, dims, download, dispose } = options; + return new Tensor({ location: "ml-tensor", type: dataType ?? "float32", mlTensor, dims, download, dispose }); + }; + tensorFromPinnedBuffer = (type, buffer, dims) => new Tensor({ location: "cpu-pinned", type, data: buffer, dims: dims ?? [buffer.length] }); + } +}); + +// common/dist/esm/tensor-impl-type-mapping.js +var NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP, NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP, isTypedArrayChecked, checkTypedArray; +var init_tensor_impl_type_mapping = __esm({ + "common/dist/esm/tensor-impl-type-mapping.js"() { + "use strict"; + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP = /* @__PURE__ */ new Map([ + ["float32", Float32Array], + ["uint8", Uint8Array], + ["int8", Int8Array], + ["uint16", Uint16Array], + ["int16", Int16Array], + ["int32", Int32Array], + ["bool", Uint8Array], + ["float64", Float64Array], + ["uint32", Uint32Array], + ["int4", Uint8Array], + ["uint4", Uint8Array] + ]); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP = /* @__PURE__ */ new Map([ + [Float32Array, "float32"], + [Uint8Array, "uint8"], + [Int8Array, "int8"], + [Uint16Array, "uint16"], + [Int16Array, "int16"], + [Int32Array, "int32"], + [Float64Array, "float64"], + [Uint32Array, "uint32"] + ]); + isTypedArrayChecked = false; + checkTypedArray = () => { + if (!isTypedArrayChecked) { + isTypedArrayChecked = true; + const isBigInt64ArrayAvailable = typeof BigInt64Array !== "undefined" && BigInt64Array.from; + const isBigUint64ArrayAvailable = typeof BigUint64Array !== "undefined" && BigUint64Array.from; + const Float16Array = globalThis.Float16Array; + const isFloat16ArrayAvailable = typeof Float16Array !== "undefined" && Float16Array.from; + if (isBigInt64ArrayAvailable) { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("int64", BigInt64Array); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(BigInt64Array, "int64"); + } + if (isBigUint64ArrayAvailable) { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("uint64", BigUint64Array); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(BigUint64Array, "uint64"); + } + if (isFloat16ArrayAvailable) { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("float16", Float16Array); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(Float16Array, "float16"); + } else { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("float16", Uint16Array); + } + } + }; + } +}); + +// common/dist/esm/tensor-utils-impl.js +var calculateSize, tensorReshape; +var init_tensor_utils_impl = __esm({ + "common/dist/esm/tensor-utils-impl.js"() { + "use strict"; + init_tensor_impl(); + calculateSize = (dims) => { + let size = 1; + for (let i = 0; i < dims.length; i++) { + const dim = dims[i]; + if (typeof dim !== "number" || !Number.isSafeInteger(dim)) { + throw new TypeError(`dims[${i}] must be an integer, got: ${dim}`); + } + if (dim < 0) { + throw new RangeError(`dims[${i}] must be a non-negative integer, got: ${dim}`); + } + size *= dim; + } + return size; + }; + tensorReshape = (tensor, dims) => { + switch (tensor.location) { + case "cpu": + return new Tensor(tensor.type, tensor.data, dims); + case "cpu-pinned": + return new Tensor({ + location: "cpu-pinned", + data: tensor.data, + type: tensor.type, + dims + }); + case "texture": + return new Tensor({ + location: "texture", + texture: tensor.texture, + type: tensor.type, + dims + }); + case "gpu-buffer": + return new Tensor({ + location: "gpu-buffer", + gpuBuffer: tensor.gpuBuffer, + type: tensor.type, + dims + }); + case "ml-tensor": + return new Tensor({ + location: "ml-tensor", + mlTensor: tensor.mlTensor, + type: tensor.type, + dims + }); + default: + throw new Error(`tensorReshape: tensor location ${tensor.location} is not supported`); + } + }; + } +}); + +// common/dist/esm/tensor-impl.js +var Tensor; +var init_tensor_impl = __esm({ + "common/dist/esm/tensor-impl.js"() { + "use strict"; + init_tensor_conversion_impl(); + init_tensor_factory_impl(); + init_tensor_impl_type_mapping(); + init_tensor_utils_impl(); + Tensor = class { + /** + * implementation. + */ + constructor(arg0, arg1, arg2) { + checkTypedArray(); + let type; + let dims; + if (typeof arg0 === "object" && "location" in arg0) { + this.dataLocation = arg0.location; + type = arg0.type; + dims = arg0.dims; + switch (arg0.location) { + case "cpu-pinned": { + const expectedTypedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(type); + if (!expectedTypedArrayConstructor) { + throw new TypeError(`unsupported type "${type}" to create tensor from pinned buffer`); + } + if (!(arg0.data instanceof expectedTypedArrayConstructor)) { + throw new TypeError(`buffer should be of type ${expectedTypedArrayConstructor.name}`); + } + this.cpuData = arg0.data; + break; + } + case "texture": { + if (type !== "float32") { + throw new TypeError(`unsupported type "${type}" to create tensor from texture`); + } + this.gpuTextureData = arg0.texture; + this.downloader = arg0.download; + this.disposer = arg0.dispose; + break; + } + case "gpu-buffer": { + if (type !== "float32" && type !== "float16" && type !== "int32" && type !== "int64" && type !== "uint32" && type !== "uint8" && type !== "bool" && type !== "uint4" && type !== "int4") { + throw new TypeError(`unsupported type "${type}" to create tensor from gpu buffer`); + } + this.gpuBufferData = arg0.gpuBuffer; + this.downloader = arg0.download; + this.disposer = arg0.dispose; + break; + } + case "ml-tensor": { + if (type !== "float32" && type !== "float16" && type !== "int32" && type !== "int64" && type !== "uint32" && type !== "uint64" && type !== "int8" && type !== "uint8" && type !== "bool" && type !== "uint4" && type !== "int4") { + throw new TypeError(`unsupported type "${type}" to create tensor from MLTensor`); + } + this.mlTensorData = arg0.mlTensor; + this.downloader = arg0.download; + this.disposer = arg0.dispose; + break; + } + default: + throw new Error(`Tensor constructor: unsupported location '${this.dataLocation}'`); + } + } else { + let data; + let maybeDims; + if (typeof arg0 === "string") { + type = arg0; + maybeDims = arg2; + if (arg0 === "string") { + if (!Array.isArray(arg1)) { + throw new TypeError("A string tensor's data must be a string array."); + } + data = arg1; + } else { + const typedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(arg0); + if (typedArrayConstructor === void 0) { + throw new TypeError(`Unsupported tensor type: ${arg0}.`); + } + if (Array.isArray(arg1)) { + if (arg0 === "float16" && typedArrayConstructor === Uint16Array || arg0 === "uint4" || arg0 === "int4") { + throw new TypeError(`Creating a ${arg0} tensor from number array is not supported. Please use ${typedArrayConstructor.name} as data.`); + } else if (arg0 === "uint64" || arg0 === "int64") { + data = typedArrayConstructor.from(arg1, BigInt); + } else { + data = typedArrayConstructor.from(arg1); + } + } else if (arg1 instanceof typedArrayConstructor) { + data = arg1; + } else if (arg1 instanceof Uint8ClampedArray) { + if (arg0 === "uint8") { + data = Uint8Array.from(arg1); + } else { + throw new TypeError(`A Uint8ClampedArray tensor's data must be type of uint8`); + } + } else if (arg0 === "float16" && arg1 instanceof Uint16Array && typedArrayConstructor !== Uint16Array) { + data = new globalThis.Float16Array(arg1.buffer, arg1.byteOffset, arg1.length); + } else { + throw new TypeError(`A ${type} tensor's data must be type of ${typedArrayConstructor}`); + } + } + } else { + maybeDims = arg1; + if (Array.isArray(arg0)) { + if (arg0.length === 0) { + throw new TypeError("Tensor type cannot be inferred from an empty array."); + } + const firstElementType = typeof arg0[0]; + if (firstElementType === "string") { + type = "string"; + data = arg0; + } else if (firstElementType === "boolean") { + type = "bool"; + data = Uint8Array.from(arg0); + } else { + throw new TypeError(`Invalid element type of data array: ${firstElementType}.`); + } + } else if (arg0 instanceof Uint8ClampedArray) { + type = "uint8"; + data = Uint8Array.from(arg0); + } else { + const mappedType = NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.get(arg0.constructor); + if (mappedType === void 0) { + throw new TypeError(`Unsupported type for tensor data: ${arg0.constructor}.`); + } + type = mappedType; + data = arg0; + } + } + if (maybeDims === void 0) { + maybeDims = [data.length]; + } else if (!Array.isArray(maybeDims)) { + throw new TypeError("A tensor's dims must be a number array"); + } + dims = maybeDims; + this.cpuData = data; + this.dataLocation = "cpu"; + } + const size = calculateSize(dims); + if (this.cpuData && size !== this.cpuData.length) { + if ((type === "uint4" || type === "int4") && Math.ceil(size / 2) === this.cpuData.length) { + } else { + throw new Error(`Tensor's size(${size}) does not match data length(${this.cpuData.length}).`); + } + } + this.type = type; + this.dims = dims; + this.size = size; + } + // #endregion + // #region factory + static async fromImage(image, options) { + return tensorFromImage(image, options); + } + static fromTexture(texture, options) { + return tensorFromTexture(texture, options); + } + static fromGpuBuffer(gpuBuffer, options) { + return tensorFromGpuBuffer(gpuBuffer, options); + } + static fromMLTensor(mlTensor, options) { + return tensorFromMLTensor(mlTensor, options); + } + static fromPinnedBuffer(type, buffer, dims) { + return tensorFromPinnedBuffer(type, buffer, dims); + } + // #endregion + // #region conversions + toDataURL(options) { + return tensorToDataURL(this, options); + } + toImageData(options) { + return tensorToImageData(this, options); + } + // #endregion + // #region properties + get data() { + this.ensureValid(); + if (!this.cpuData) { + throw new Error("The data is not on CPU. Use `getData()` to download GPU data to CPU, or use `texture` or `gpuBuffer` property to access the GPU data directly."); + } + return this.cpuData; + } + get location() { + return this.dataLocation; + } + get texture() { + this.ensureValid(); + if (!this.gpuTextureData) { + throw new Error("The data is not stored as a WebGL texture."); + } + return this.gpuTextureData; + } + get gpuBuffer() { + this.ensureValid(); + if (!this.gpuBufferData) { + throw new Error("The data is not stored as a WebGPU buffer."); + } + return this.gpuBufferData; + } + get mlTensor() { + this.ensureValid(); + if (!this.mlTensorData) { + throw new Error("The data is not stored as a WebNN MLTensor."); + } + return this.mlTensorData; + } + // #endregion + // #region methods + async getData(releaseData) { + this.ensureValid(); + switch (this.dataLocation) { + case "cpu": + case "cpu-pinned": + return this.data; + case "texture": + case "gpu-buffer": + case "ml-tensor": { + if (!this.downloader) { + throw new Error("The current tensor is not created with a specified data downloader."); + } + if (this.isDownloading) { + throw new Error("The current tensor is being downloaded."); + } + try { + this.isDownloading = true; + const data = await this.downloader(); + this.downloader = void 0; + this.dataLocation = "cpu"; + this.cpuData = data; + if (releaseData && this.disposer) { + this.disposer(); + this.disposer = void 0; + } + return data; + } finally { + this.isDownloading = false; + } + } + default: + throw new Error(`cannot get data from location: ${this.dataLocation}`); + } + } + dispose() { + if (this.isDownloading) { + throw new Error("The current tensor is being downloaded."); + } + if (this.disposer) { + this.disposer(); + this.disposer = void 0; + } + this.cpuData = void 0; + this.gpuTextureData = void 0; + this.gpuBufferData = void 0; + this.mlTensorData = void 0; + this.downloader = void 0; + this.isDownloading = void 0; + this.dataLocation = "none"; + } + // #endregion + // #region tensor utilities + ensureValid() { + if (this.dataLocation === "none") { + throw new Error("The tensor is disposed."); + } + } + reshape(dims) { + this.ensureValid(); + if (this.downloader || this.disposer) { + throw new Error("Cannot reshape a tensor that owns GPU resource."); + } + return tensorReshape(this, dims); + } + }; + } +}); + +// common/dist/esm/tensor.js +var Tensor2; +var init_tensor = __esm({ + "common/dist/esm/tensor.js"() { + "use strict"; + init_tensor_impl(); + Tensor2 = Tensor; + } +}); + +// common/dist/esm/trace.js +var TRACE, TRACE_FUNC, TRACE_FUNC_BEGIN, TRACE_FUNC_END, TRACE_EVENT_BEGIN, TRACE_EVENT_END; +var init_trace = __esm({ + "common/dist/esm/trace.js"() { + "use strict"; + init_env_impl(); + TRACE = (deviceType, label) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + console.timeStamp(`${deviceType}::ORT::${label}`); + }; + TRACE_FUNC = (msg, extraMsg) => { + const stack = new Error().stack?.split(/\r\n|\r|\n/g) || []; + let hasTraceFunc = false; + for (let i = 0; i < stack.length; i++) { + if (hasTraceFunc && !stack[i].includes("TRACE_FUNC")) { + let label = `FUNC_${msg}::${stack[i].trim().split(" ")[1]}`; + if (extraMsg) { + label += `::${extraMsg}`; + } + TRACE("CPU", label); + return; + } + if (stack[i].includes("TRACE_FUNC")) { + hasTraceFunc = true; + } + } + }; + TRACE_FUNC_BEGIN = (extraMsg) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + TRACE_FUNC("BEGIN", extraMsg); + }; + TRACE_FUNC_END = (extraMsg) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + TRACE_FUNC("END", extraMsg); + }; + TRACE_EVENT_BEGIN = (extraMsg) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + console.time(`ORT::${extraMsg}`); + }; + TRACE_EVENT_END = (extraMsg) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + console.timeEnd(`ORT::${extraMsg}`); + }; + } +}); + +// common/dist/esm/inference-session-impl.js +var InferenceSession; +var init_inference_session_impl = __esm({ + "common/dist/esm/inference-session-impl.js"() { + "use strict"; + init_backend_impl(); + init_tensor(); + init_trace(); + InferenceSession = class _InferenceSession { + constructor(handler) { + this.handler = handler; + } + async run(feeds, arg1, arg2) { + TRACE_FUNC_BEGIN(); + TRACE_EVENT_BEGIN("InferenceSession.run"); + const fetches = {}; + let options = {}; + if (typeof feeds !== "object" || feeds === null || feeds instanceof Tensor2 || Array.isArray(feeds)) { + throw new TypeError("'feeds' must be an object that use input names as keys and OnnxValue as corresponding values."); + } + let isFetchesEmpty = true; + if (typeof arg1 === "object") { + if (arg1 === null) { + throw new TypeError("Unexpected argument[1]: cannot be null."); + } + if (arg1 instanceof Tensor2) { + throw new TypeError("'fetches' cannot be a Tensor"); + } + if (Array.isArray(arg1)) { + if (arg1.length === 0) { + throw new TypeError("'fetches' cannot be an empty array."); + } + isFetchesEmpty = false; + for (const name2 of arg1) { + if (typeof name2 !== "string") { + throw new TypeError("'fetches' must be a string array or an object."); + } + if (this.outputNames.indexOf(name2) === -1) { + throw new RangeError(`'fetches' contains invalid output name: ${name2}.`); + } + fetches[name2] = null; + } + if (typeof arg2 === "object" && arg2 !== null) { + options = arg2; + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else { + let isFetches = false; + const arg1Keys = Object.getOwnPropertyNames(arg1); + for (const name2 of this.outputNames) { + if (arg1Keys.indexOf(name2) !== -1) { + const v = arg1[name2]; + if (v === null || v instanceof Tensor2) { + isFetches = true; + isFetchesEmpty = false; + fetches[name2] = v; + } + } + } + if (isFetches) { + if (typeof arg2 === "object" && arg2 !== null) { + options = arg2; + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else { + options = arg1; + } + } + } else if (typeof arg1 !== "undefined") { + throw new TypeError("Unexpected argument[1]: must be 'fetches' or 'options'."); + } + for (const name2 of this.inputNames) { + if (typeof feeds[name2] === "undefined") { + throw new Error(`input '${name2}' is missing in 'feeds'.`); + } + } + if (isFetchesEmpty) { + for (const name2 of this.outputNames) { + fetches[name2] = null; + } + } + const results = await this.handler.run(feeds, fetches, options); + const returnValue = {}; + for (const key in results) { + if (Object.hasOwnProperty.call(results, key)) { + const result = results[key]; + if (result instanceof Tensor2) { + returnValue[key] = result; + } else { + returnValue[key] = new Tensor2(result.type, result.data, result.dims); + } + } + } + TRACE_EVENT_END("InferenceSession.run"); + TRACE_FUNC_END(); + return returnValue; + } + async release() { + return this.handler.dispose(); + } + static async create(arg0, arg1, arg2, arg3) { + TRACE_FUNC_BEGIN(); + TRACE_EVENT_BEGIN("InferenceSession.create"); + let filePathOrUint8Array; + let options = {}; + if (typeof arg0 === "string") { + filePathOrUint8Array = arg0; + if (typeof arg1 === "object" && arg1 !== null) { + options = arg1; + } else if (typeof arg1 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else if (arg0 instanceof Uint8Array) { + filePathOrUint8Array = arg0; + if (typeof arg1 === "object" && arg1 !== null) { + options = arg1; + } else if (typeof arg1 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else if (arg0 instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && arg0 instanceof SharedArrayBuffer) { + const buffer = arg0; + let byteOffset = 0; + let byteLength = arg0.byteLength; + if (typeof arg1 === "object" && arg1 !== null) { + options = arg1; + } else if (typeof arg1 === "number") { + byteOffset = arg1; + if (!Number.isSafeInteger(byteOffset)) { + throw new RangeError("'byteOffset' must be an integer."); + } + if (byteOffset < 0 || byteOffset >= buffer.byteLength) { + throw new RangeError(`'byteOffset' is out of range [0, ${buffer.byteLength}).`); + } + byteLength = arg0.byteLength - byteOffset; + if (typeof arg2 === "number") { + byteLength = arg2; + if (!Number.isSafeInteger(byteLength)) { + throw new RangeError("'byteLength' must be an integer."); + } + if (byteLength <= 0 || byteOffset + byteLength > buffer.byteLength) { + throw new RangeError(`'byteLength' is out of range (0, ${buffer.byteLength - byteOffset}].`); + } + if (typeof arg3 === "object" && arg3 !== null) { + options = arg3; + } else if (typeof arg3 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'byteLength' must be a number."); + } + } else if (typeof arg1 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + filePathOrUint8Array = new Uint8Array(buffer, byteOffset, byteLength); + } else { + throw new TypeError("Unexpected argument[0]: must be 'path' or 'buffer'."); + } + const [backend2, optionsWithValidatedEPs] = await resolveBackendAndExecutionProviders(options); + const handler = await backend2.createInferenceSessionHandler(filePathOrUint8Array, optionsWithValidatedEPs); + TRACE_EVENT_END("InferenceSession.create"); + TRACE_FUNC_END(); + return new _InferenceSession(handler); + } + startProfiling() { + this.handler.startProfiling(); + } + endProfiling() { + this.handler.endProfiling(); + } + get inputNames() { + return this.handler.inputNames; + } + get outputNames() { + return this.handler.outputNames; + } + get inputMetadata() { + return this.handler.inputMetadata; + } + get outputMetadata() { + return this.handler.outputMetadata; + } + }; + } +}); + +// common/dist/esm/inference-session.js +var InferenceSession2; +var init_inference_session = __esm({ + "common/dist/esm/inference-session.js"() { + "use strict"; + init_inference_session_impl(); + InferenceSession2 = InferenceSession; + } +}); + +// common/dist/esm/tensor-conversion.js +var init_tensor_conversion = __esm({ + "common/dist/esm/tensor-conversion.js"() { + "use strict"; + } +}); + +// common/dist/esm/tensor-factory.js +var init_tensor_factory = __esm({ + "common/dist/esm/tensor-factory.js"() { + "use strict"; + } +}); + +// common/dist/esm/onnx-model.js +var init_onnx_model = __esm({ + "common/dist/esm/onnx-model.js"() { + "use strict"; + } +}); + +// common/dist/esm/onnx-value.js +var init_onnx_value = __esm({ + "common/dist/esm/onnx-value.js"() { + "use strict"; + } +}); + +// common/dist/esm/index.js +var esm_exports = {}; +__export(esm_exports, { + InferenceSession: () => InferenceSession2, + TRACE: () => TRACE, + TRACE_EVENT_BEGIN: () => TRACE_EVENT_BEGIN, + TRACE_EVENT_END: () => TRACE_EVENT_END, + TRACE_FUNC_BEGIN: () => TRACE_FUNC_BEGIN, + TRACE_FUNC_END: () => TRACE_FUNC_END, + Tensor: () => Tensor2, + env: () => env2, + registerBackend: () => registerBackend +}); +var init_esm = __esm({ + "common/dist/esm/index.js"() { + "use strict"; + init_backend(); + init_env(); + init_inference_session(); + init_tensor(); + init_tensor_conversion(); + init_tensor_factory(); + init_trace(); + init_onnx_model(); + init_onnx_value(); + } +}); + +// web/lib/onnxjs/instrument.ts +function log(arg0, arg1, arg2, arg3) { + if (arg1 === void 0) { + return createCategorizedLogger(arg0); + } else if (arg2 === void 0) { + logInternal(arg0, arg1, 1); + } else if (typeof arg2 === "number" && arg3 === void 0) { + logInternal(arg0, arg1, arg2); + } else if (typeof arg2 === "string" && arg3 === void 0) { + logInternal(arg0, arg2, 1, arg1); + } else if (typeof arg2 === "string" && typeof arg3 === "number") { + logInternal(arg0, arg2, arg3, arg1); + } else { + throw new TypeError("input is valid"); + } +} +function createCategorizedLogger(category) { + return { + verbose: log.verbose.bind(null, category), + info: log.info.bind(null, category), + warning: log.warning.bind(null, category), + error: log.error.bind(null, category), + fatal: log.fatal.bind(null, category) + }; +} +function logInternal(severity, content, _stack, category) { + const config = LOGGER_CONFIG_MAP[category || ""] || LOGGER_CONFIG_MAP[""]; + if (SEVERITY_VALUE[severity] < SEVERITY_VALUE[config.minimalSeverity]) { + return; + } + if (config.logDateTime) { + content = `${(/* @__PURE__ */ new Date()).toISOString()}|${content}`; + } + if (config.logSourceLocation) { + } + LOGGER_PROVIDER_MAP[config.provider].log(severity, content, category); +} +var NoOpLoggerProvider, ConsoleLoggerProvider, SEVERITY_VALUE, LOGGER_PROVIDER_MAP, LOGGER_DEFAULT_CONFIG, LOGGER_CONFIG_MAP, Logger, Event, EventRecord, Profiler, now; +var init_instrument = __esm({ + "web/lib/onnxjs/instrument.ts"() { + "use strict"; + NoOpLoggerProvider = class { + log(_severity, _content, _category) { + } + }; + ConsoleLoggerProvider = class { + log(severity, content, category) { + console.log(`${this.color(severity)} ${category ? "\x1B[35m" + category + "\x1B[0m " : ""}${content}`); + } + color(severity) { + switch (severity) { + case "verbose": + return "\x1B[34;40mv\x1B[0m"; + case "info": + return "\x1B[32mi\x1B[0m"; + case "warning": + return "\x1B[30;43mw\x1B[0m"; + case "error": + return "\x1B[31;40me\x1B[0m"; + case "fatal": + return "\x1B[101mf\x1B[0m"; + default: + throw new Error(`unsupported severity: ${severity}`); + } + } + }; + SEVERITY_VALUE = { + verbose: 1e3, + info: 2e3, + warning: 4e3, + error: 5e3, + fatal: 6e3 + }; + LOGGER_PROVIDER_MAP = { + ["none"]: new NoOpLoggerProvider(), + ["console"]: new ConsoleLoggerProvider() + }; + LOGGER_DEFAULT_CONFIG = { + provider: "console", + minimalSeverity: "warning", + logDateTime: true, + logSourceLocation: false + }; + LOGGER_CONFIG_MAP = { + [""]: LOGGER_DEFAULT_CONFIG + }; + ((log3) => { + function verbose(arg0, arg1) { + log3("verbose", arg0, arg1); + } + log3.verbose = verbose; + function info(arg0, arg1) { + log3("info", arg0, arg1); + } + log3.info = info; + function warning(arg0, arg1) { + log3("warning", arg0, arg1); + } + log3.warning = warning; + function error(arg0, arg1) { + log3("error", arg0, arg1); + } + log3.error = error; + function fatal(arg0, arg1) { + log3("fatal", arg0, arg1); + } + log3.fatal = fatal; + function reset(config) { + LOGGER_CONFIG_MAP = {}; + set("", config || {}); + } + log3.reset = reset; + function set(category, config) { + if (category === "*") { + reset(config); + } else { + const previousConfig = LOGGER_CONFIG_MAP[category] || LOGGER_DEFAULT_CONFIG; + LOGGER_CONFIG_MAP[category] = { + provider: config.provider || previousConfig.provider, + minimalSeverity: config.minimalSeverity || previousConfig.minimalSeverity, + logDateTime: config.logDateTime === void 0 ? previousConfig.logDateTime : config.logDateTime, + logSourceLocation: config.logSourceLocation === void 0 ? previousConfig.logSourceLocation : config.logSourceLocation + }; + } + } + log3.set = set; + function setWithEnv(env3) { + const config = {}; + if (env3.logLevel) { + config.minimalSeverity = env3.logLevel; + } + set("", config); + } + log3.setWithEnv = setWithEnv; + })(log || (log = {})); + Logger = log; + Event = class { + constructor(category, name2, startTime, endCallback, timer, ctx) { + this.category = category; + this.name = name2; + this.startTime = startTime; + this.endCallback = endCallback; + this.timer = timer; + this.ctx = ctx; + } + async end() { + return this.endCallback(this); + } + async checkTimer() { + if (this.ctx === void 0 || this.timer === void 0) { + throw new Error("No webgl timer found"); + } else { + this.ctx.endTimer(); + return this.ctx.waitForQueryAndGetTime(this.timer); + } + } + }; + EventRecord = class { + constructor(category, name2, startTime, endTime) { + this.category = category; + this.name = name2; + this.startTime = startTime; + this.endTime = endTime; + } + }; + Profiler = class { + constructor(maxNumberEvents, flushBatchSize, flushIntervalInMilliseconds) { + this._started = false; + this._flushPointer = 0; + this._started = false; + this._maxNumberEvents = maxNumberEvents === void 0 ? 1e4 : maxNumberEvents; + this._flushBatchSize = flushBatchSize === void 0 ? 10 : flushBatchSize; + this._flushIntervalInMilliseconds = flushIntervalInMilliseconds === void 0 ? 5e3 : flushIntervalInMilliseconds; + } + static create(config) { + if (config === void 0) { + return new this(); + } + return new this(config.maxNumberEvents, config.flushBatchSize, config.flushIntervalInMilliseconds); + } + // start profiling + start() { + this._started = true; + this._timingEvents = []; + this._flushTime = now(); + this._flushPointer = 0; + } + // stop profiling + stop() { + this._started = false; + for (; this._flushPointer < this._timingEvents.length; this._flushPointer++) { + this.logOneEvent(this._timingEvents[this._flushPointer]); + } + } + event(category, name2, func, ctx) { + const event = this._started ? this.begin(category, name2, ctx) : void 0; + let isPromise = false; + const res = func(); + if (res && typeof res.then === "function") { + isPromise = true; + return new Promise((resolve, reject) => { + res.then( + async (value) => { + if (event) { + await event.end(); + } + resolve(value); + }, + async (reason) => { + if (event) { + await event.end(); + } + reject(reason); + } + ); + }); + } + if (!isPromise && event) { + const eventRes = event.end(); + if (eventRes && typeof eventRes.then === "function") { + return new Promise((resolve, reject) => { + eventRes.then( + () => { + resolve(res); + }, + (reason) => { + reject(reason); + } + ); + }); + } + } + return res; + } + // begin an event + begin(category, name2, ctx) { + if (!this._started) { + throw new Error("profiler is not started yet"); + } + if (ctx === void 0) { + const startTime = now(); + this.flush(startTime); + return new Event(category, name2, startTime, (e) => this.endSync(e)); + } else { + const timer = ctx.beginTimer(); + return new Event(category, name2, 0, async (e) => this.end(e), timer, ctx); + } + } + // end the specific event + async end(event) { + const endTime = await event.checkTimer(); + if (this._timingEvents.length < this._maxNumberEvents) { + this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime)); + this.flush(endTime); + } + } + endSync(event) { + const endTime = now(); + if (this._timingEvents.length < this._maxNumberEvents) { + this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime)); + this.flush(endTime); + } + } + logOneEvent(event) { + Logger.verbose( + `Profiler.${event.category}`, + `${(event.endTime - event.startTime).toFixed(2)}ms on event '${event.name}' at ${event.endTime.toFixed(2)}` + ); + } + flush(currentTime) { + if (this._timingEvents.length - this._flushPointer >= this._flushBatchSize || currentTime - this._flushTime >= this._flushIntervalInMilliseconds) { + for (const previousPointer = this._flushPointer; this._flushPointer < previousPointer + this._flushBatchSize && this._flushPointer < this._timingEvents.length; this._flushPointer++) { + this.logOneEvent(this._timingEvents[this._flushPointer]); + } + this._flushTime = now(); + } + } + get started() { + return this._started; + } + }; + now = typeof performance !== "undefined" && performance.now ? () => performance.now() : Date.now; + } +}); + +// web/lib/onnxjs/opset.ts +function resolveOperator(node, opsets, rules) { + for (const rule of rules) { + const opType = rule[0]; + const domain = rule[1]; + const versionSelector = rule[2]; + const opImpl = rule[3]; + const opInit = rule[4]; + if (node.opType === opType) { + for (const opset of opsets) { + if (opset.domain === domain || opset.domain === "ai.onnx" && domain === "") { + if (matchSelector(opset.version, versionSelector)) { + return { opImpl, opInit }; + } + } + } + } + } + throw new TypeError( + `cannot resolve operator '${node.opType}' with opsets: ${opsets.map((set) => `${set.domain || "ai.onnx"} v${set.version}`).join(", ")}` + ); +} +function matchSelector(version3, selector) { + if (selector.endsWith("+")) { + const rangeStart = Number.parseInt(selector.substring(0, selector.length - 1), 10); + return !isNaN(rangeStart) && rangeStart <= version3; + } else if (selector.split("-").length === 2) { + const pair = selector.split("-"); + const rangeStart = Number.parseInt(pair[0], 10); + const rangeEnd = Number.parseInt(pair[1], 10); + return !isNaN(rangeStart) && !isNaN(rangeEnd) && rangeStart <= version3 && version3 <= rangeEnd; + } else { + return Number.parseInt(selector, 10) === version3; + } +} +var init_opset = __esm({ + "web/lib/onnxjs/opset.ts"() { + "use strict"; + } +}); + +// web/node_modules/guid-typescript/dist/guid.js +var require_guid = __commonJS({ + "web/node_modules/guid-typescript/dist/guid.js"(exports) { + "use strict"; + exports.__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; + })() + ); + exports.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([ + // \0asm + 0, + 97, + 115, + 109, + // version 1 + 1, + 0, + 0, + 0, + // section "type" + 1, + 13, + 2, + // 0, () => i32 + 96, + 0, + 1, + 127, + // 1, (i32, i32, i32, i32) => i32 + 96, + 4, + 127, + 127, + 127, + 127, + 1, + 127, + // section "function" + 3, + 7, + 6, + // 0, type 0 + 0, + // 1, type 1 + 1, + // 2, type 1 + 1, + // 3, type 1 + 1, + // 4, type 1 + 1, + // 5, type 1 + 1, + // section "global" + 6, + 6, + 1, + // 0, "high", mutable i32 + 127, + 1, + 65, + 0, + 11, + // section "export" + 7, + 50, + 6, + // 0, "mul" + 3, + 109, + 117, + 108, + 0, + 1, + // 1, "div_s" + 5, + 100, + 105, + 118, + 95, + 115, + 0, + 2, + // 2, "div_u" + 5, + 100, + 105, + 118, + 95, + 117, + 0, + 3, + // 3, "rem_s" + 5, + 114, + 101, + 109, + 95, + 115, + 0, + 4, + // 4, "rem_u" + 5, + 114, + 101, + 109, + 95, + 117, + 0, + 5, + // 5, "get_high" + 8, + 103, + 101, + 116, + 95, + 104, + 105, + 103, + 104, + 0, + 0, + // section "code" + 10, + 191, + 1, + 6, + // 0, "get_high" + 4, + 0, + 35, + 0, + 11, + // 1, "mul" + 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, + // 2, "div_s" + 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, + // 3, "div_u" + 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, + // 4, "rem_s" + 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, + // 5, "rem_u" + 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 { + } + 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.isSafeInteger = function isSafeInteger() { + var top11Bits = this.high >> 21; + if (!top11Bits) return true; + if (this.unsigned) return false; + return top11Bits === -1 && !(this.low === 0 && this.high === -2097152); + }; + 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 + ); + }; + if (typeof BigInt === "function") { + Long.fromBigInt = function fromBigInt(value, unsigned) { + var lowBits = Number(BigInt.asIntN(32, value)); + var highBits = Number(BigInt.asIntN(32, value >> BigInt(32))); + return fromBits(lowBits, highBits, unsigned); + }; + Long.fromValue = function fromValueWithBigInt(value, unsigned) { + if (typeof value === "bigint") return Long.fromBigInt(value, unsigned); + return fromValue(value, unsigned); + }; + LongPrototype.toBigInt = function toBigInt() { + var lowBigInt = BigInt(this.low >>> 0); + var highBigInt = BigInt(this.unsigned ? this.high >>> 0 : this.high); + return highBigInt << BigInt(32) | lowBigInt; + }; + } + 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"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.ArgType = void 0; + var ArgType2; + (function(ArgType3) { + ArgType3[ArgType3["INPUT"] = 0] = "INPUT"; + ArgType3[ArgType3["OUTPUT"] = 1] = "OUTPUT"; + })(ArgType2 || (exports.ArgType = ArgType2 = {})); + } +}); + +// web/node_modules/flatbuffers/js/constants.js +var require_constants = __commonJS({ + "web/node_modules/flatbuffers/js/constants.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.SIZE_PREFIX_LENGTH = exports.FILE_IDENTIFIER_LENGTH = exports.SIZEOF_INT = exports.SIZEOF_SHORT = void 0; + exports.SIZEOF_SHORT = 2; + exports.SIZEOF_INT = 4; + exports.FILE_IDENTIFIER_LENGTH = 4; + exports.SIZE_PREFIX_LENGTH = 4; + } +}); + +// web/node_modules/flatbuffers/js/utils.js +var require_utils = __commonJS({ + "web/node_modules/flatbuffers/js/utils.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.isLittleEndian = exports.float64 = exports.float32 = exports.int32 = void 0; + exports.int32 = new Int32Array(2); + exports.float32 = new Float32Array(exports.int32.buffer); + exports.float64 = new Float64Array(exports.int32.buffer); + exports.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"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.Encoding = void 0; + var Encoding; + (function(Encoding2) { + Encoding2[Encoding2["UTF8_BYTES"] = 1] = "UTF8_BYTES"; + Encoding2[Encoding2["UTF16_STRING"] = 2] = "UTF16_STRING"; + })(Encoding || (exports.Encoding = Encoding = {})); + } +}); + +// web/node_modules/flatbuffers/js/byte-buffer.js +var require_byte_buffer = __commonJS({ + "web/node_modules/flatbuffers/js/byte-buffer.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.ByteBuffer = void 0; + var constants_js_1 = require_constants(); + var encoding_js_1 = require_encoding(); + var utils_js_1 = require_utils(); + 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; + } + }; + exports.ByteBuffer = ByteBuffer2; + } +}); + +// web/node_modules/flatbuffers/js/builder.js +var require_builder = __commonJS({ + "web/node_modules/flatbuffers/js/builder.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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(); + } + }; + exports.Builder = Builder; + } +}); + +// web/node_modules/flatbuffers/js/flatbuffers.js +var require_flatbuffers = __commonJS({ + "web/node_modules/flatbuffers/js/flatbuffers.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.Encoding = exports.ByteBuffer = exports.Builder = exports.isLittleEndian = exports.int32 = exports.float64 = exports.float32 = exports.SIZE_PREFIX_LENGTH = exports.SIZEOF_SHORT = exports.SIZEOF_INT = exports.FILE_IDENTIFIER_LENGTH = void 0; + var constants_js_1 = require_constants(); + Object.defineProperty(exports, "FILE_IDENTIFIER_LENGTH", { enumerable: true, get: function() { + return constants_js_1.FILE_IDENTIFIER_LENGTH; + } }); + Object.defineProperty(exports, "SIZEOF_INT", { enumerable: true, get: function() { + return constants_js_1.SIZEOF_INT; + } }); + Object.defineProperty(exports, "SIZEOF_SHORT", { enumerable: true, get: function() { + return constants_js_1.SIZEOF_SHORT; + } }); + Object.defineProperty(exports, "SIZE_PREFIX_LENGTH", { enumerable: true, get: function() { + return constants_js_1.SIZE_PREFIX_LENGTH; + } }); + var utils_js_1 = require_utils(); + Object.defineProperty(exports, "float32", { enumerable: true, get: function() { + return utils_js_1.float32; + } }); + Object.defineProperty(exports, "float64", { enumerable: true, get: function() { + return utils_js_1.float64; + } }); + Object.defineProperty(exports, "int32", { enumerable: true, get: function() { + return utils_js_1.int32; + } }); + Object.defineProperty(exports, "isLittleEndian", { enumerable: true, get: function() { + return utils_js_1.isLittleEndian; + } }); + var builder_js_1 = require_builder(); + Object.defineProperty(exports, "Builder", { enumerable: true, get: function() { + return builder_js_1.Builder; + } }); + var byte_buffer_js_1 = require_byte_buffer(); + Object.defineProperty(exports, "ByteBuffer", { enumerable: true, get: function() { + return byte_buffer_js_1.ByteBuffer; + } }); + var encoding_js_1 = require_encoding(); + Object.defineProperty(exports, "Encoding", { enumerable: true, get: function() { + return encoding_js_1.Encoding; + } }); + } +}); + +// 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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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 || (exports.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"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.NodeType = void 0; + var NodeType2; + (function(NodeType3) { + NodeType3[NodeType3["Primitive"] = 0] = "Primitive"; + NodeType3[NodeType3["Fused"] = 1] = "Fused"; + })(NodeType2 || (exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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(); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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; + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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 || (exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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; + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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; + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.DimensionValueType = void 0; + var DimensionValueType2; + (function(DimensionValueType3) { + DimensionValueType3[DimensionValueType3["UNKNOWN"] = 0] = "UNKNOWN"; + DimensionValueType3[DimensionValueType3["VALUE"] = 1] = "VALUE"; + DimensionValueType3[DimensionValueType3["PARAM"] = 2] = "PARAM"; + })(DimensionValueType2 || (exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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; + } + }; + exports.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"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.TypeInfoValue = void 0; + exports.unionToTypeInfoValue = unionToTypeInfoValue; + exports.unionListToTypeInfoValue = unionListToTypeInfoValue; + 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 || (exports.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; + } + } + 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; + } + } + } +}); + +// 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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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; + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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; + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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; + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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; + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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; + } + }; + exports.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"(exports) { + "use strict"; + var __createBinding = exports && exports.__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 = exports && exports.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function(o2) { + var ar = []; + for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) { + for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + } + __setModuleDefault(result, mod); + return result; + }; + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.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); + } + }; + exports.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"(exports, module) { + "use strict"; + module.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"(exports) { + "use strict"; + var base64 = exports; + 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"(exports, module) { + "use strict"; + module.exports = EventEmitter; + function EventEmitter() { + this._listeners = /* @__PURE__ */ Object.create(null); + } + 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 = /* @__PURE__ */ Object.create(null); + else { + if (fn === void 0) + this._listeners[evt] = []; + else { + var listeners = this._listeners[evt]; + if (!listeners) + return this; + 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"(exports, module) { + "use strict"; + module.exports = factory(factory); + function factory(exports2) { + 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]; + } + exports2.writeFloatLE = le ? writeFloat_f32_cpy : writeFloat_f32_rev; + exports2.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]; + } + exports2.readFloatLE = le ? readFloat_f32_cpy : readFloat_f32_rev; + exports2.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); + } + } + exports2.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE); + exports2.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); + } + exports2.readFloatLE = readFloat_ieee754.bind(null, readUintLE); + exports2.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]; + } + exports2.writeDoubleLE = le ? writeDouble_f64_cpy : writeDouble_f64_rev; + exports2.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]; + } + exports2.readDoubleLE = le ? readDouble_f64_cpy : readDouble_f64_rev; + exports2.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); + } + } + } + exports2.writeDoubleLE = writeDouble_ieee754.bind(null, writeUintLE, 0, 4); + exports2.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); + } + exports2.readDoubleLE = readDouble_ieee754.bind(null, readUintLE, 0, 4); + exports2.readDoubleBE = readDouble_ieee754.bind(null, readUintBE, 4, 0); + })(); + return exports2; + } + 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 { + if (typeof __require !== "function") { + return null; + } + var mod = __require(moduleName); + if (mod && (mod.length || Object.keys(mod).length)) return mod; + return null; + } catch (err) { + return null; + } + } + } +}); + +// web/node_modules/@protobufjs/utf8/index.js +var require_utf8 = __commonJS({ + "web/node_modules/@protobufjs/utf8/index.js"(exports) { + "use strict"; + var utf8 = exports; + var replacementChar = "\uFFFD"; + 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) { + if (end - start < 1) { + return ""; + } + var str = ""; + for (var i = start; i < end; ) { + var t = buffer[i++]; + if (t <= 127) { + str += String.fromCharCode(t); + } else if (t >= 192 && t < 224) { + var c2 = (t & 31) << 6 | buffer[i++] & 63; + str += c2 >= 128 ? String.fromCharCode(c2) : replacementChar; + } else if (t >= 224 && t < 240) { + var c3 = (t & 15) << 12 | (buffer[i++] & 63) << 6 | buffer[i++] & 63; + str += c3 >= 2048 ? String.fromCharCode(c3) : replacementChar; + } else if (t >= 240) { + var t2 = (t & 7) << 18 | (buffer[i++] & 63) << 12 | (buffer[i++] & 63) << 6 | buffer[i++] & 63; + if (t2 < 65536 || t2 > 1114111) + str += replacementChar; + else { + t2 -= 65536; + str += String.fromCharCode(55296 + (t2 >> 10)); + str += String.fromCharCode(56320 + (t2 & 1023)); + } + } + } + return str; + }; + 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"(exports, module) { + "use strict"; + module.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"(exports, module) { + "use strict"; + module.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/long/umd/index.js +var require_umd = __commonJS({ + "web/node_modules/long/umd/index.js"(exports, module) { + (function(global2, factory) { + function preferDefault(exports2) { + return exports2.default || exports2; + } + if (typeof define === "function" && define.amd) { + define([], function() { + var exports2 = {}; + factory(exports2); + return preferDefault(exports2); + }); + } else if (typeof exports === "object") { + factory(exports); + if (typeof module === "object") module.exports = preferDefault(exports); + } else { + (function() { + var exports2 = {}; + factory(exports2); + global2.Long = preferDefault(exports2); + })(); + } + })( + typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : exports, + function(_exports) { + "use strict"; + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.default = void 0; + var wasm2 = null; + try { + wasm2 = new WebAssembly.Instance( + new WebAssembly.Module( + new Uint8Array([ + // \0asm + 0, + 97, + 115, + 109, + // version 1 + 1, + 0, + 0, + 0, + // section "type" + 1, + 13, + 2, + // 0, () => i32 + 96, + 0, + 1, + 127, + // 1, (i32, i32, i32, i32) => i32 + 96, + 4, + 127, + 127, + 127, + 127, + 1, + 127, + // section "function" + 3, + 7, + 6, + // 0, type 0 + 0, + // 1, type 1 + 1, + // 2, type 1 + 1, + // 3, type 1 + 1, + // 4, type 1 + 1, + // 5, type 1 + 1, + // section "global" + 6, + 6, + 1, + // 0, "high", mutable i32 + 127, + 1, + 65, + 0, + 11, + // section "export" + 7, + 50, + 6, + // 0, "mul" + 3, + 109, + 117, + 108, + 0, + 1, + // 1, "div_s" + 5, + 100, + 105, + 118, + 95, + 115, + 0, + 2, + // 2, "div_u" + 5, + 100, + 105, + 118, + 95, + 117, + 0, + 3, + // 3, "rem_s" + 5, + 114, + 101, + 109, + 95, + 115, + 0, + 4, + // 4, "rem_u" + 5, + 114, + 101, + 109, + 95, + 117, + 0, + 5, + // 5, "get_high" + 8, + 103, + 101, + 116, + 95, + 104, + 105, + 103, + 104, + 0, + 0, + // section "code" + 10, + 191, + 1, + 6, + // 0, "get_high" + 4, + 0, + 35, + 0, + 11, + // 1, "mul" + 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, + // 2, "div_s" + 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, + // 3, "div_u" + 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, + // 4, "rem_s" + 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, + // 5, "rem_u" + 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 { + } + function Long2(low, high, unsigned) { + this.low = low | 0; + this.high = high | 0; + this.unsigned = !!unsigned; + } + Long2.prototype.__isLong__; + Object.defineProperty(Long2.prototype, "__isLong__", { + value: true + }); + function isLong2(obj) { + return (obj && obj["__isLong__"]) === true; + } + function ctz322(value) { + var c = Math.clz32(value & -value); + return value ? 31 - c : c; + } + Long2.isLong = isLong2; + var INT_CACHE2 = {}; + var UINT_CACHE2 = {}; + function fromInt2(value, unsigned) { + var obj, cachedObj, cache2; + if (unsigned) { + value >>>= 0; + if (cache2 = 0 <= value && value < 256) { + cachedObj = UINT_CACHE2[value]; + if (cachedObj) return cachedObj; + } + obj = fromBits2(value, 0, true); + if (cache2) UINT_CACHE2[value] = obj; + return obj; + } else { + value |= 0; + if (cache2 = -128 <= value && value < 128) { + cachedObj = INT_CACHE2[value]; + if (cachedObj) return cachedObj; + } + obj = fromBits2(value, value < 0 ? -1 : 0, false); + if (cache2) INT_CACHE2[value] = obj; + return obj; + } + } + Long2.fromInt = fromInt2; + function fromNumber2(value, unsigned) { + if (isNaN(value)) return unsigned ? UZERO2 : ZERO2; + if (unsigned) { + if (value < 0) return UZERO2; + if (value >= TWO_PWR_64_DBL2) return MAX_UNSIGNED_VALUE2; + } else { + if (value <= -TWO_PWR_63_DBL2) return MIN_VALUE2; + if (value + 1 >= TWO_PWR_63_DBL2) return MAX_VALUE2; + } + if (value < 0) return fromNumber2(-value, unsigned).neg(); + return fromBits2( + value % TWO_PWR_32_DBL2 | 0, + value / TWO_PWR_32_DBL2 | 0, + unsigned + ); + } + Long2.fromNumber = fromNumber2; + function fromBits2(lowBits, highBits, unsigned) { + return new Long2(lowBits, highBits, unsigned); + } + Long2.fromBits = fromBits2; + var pow_dbl2 = Math.pow; + function fromString2(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 ? UZERO2 : ZERO2; + 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 fromString2(str.substring(1), unsigned, radix).neg(); + } + var radixToPower = fromNumber2(pow_dbl2(radix, 8)); + var result = ZERO2; + 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 = fromNumber2(pow_dbl2(radix, size)); + result = result.mul(power).add(fromNumber2(value)); + } else { + result = result.mul(radixToPower); + result = result.add(fromNumber2(value)); + } + } + result.unsigned = unsigned; + return result; + } + Long2.fromString = fromString2; + function fromValue2(val, unsigned) { + if (typeof val === "number") return fromNumber2(val, unsigned); + if (typeof val === "string") return fromString2(val, unsigned); + return fromBits2( + val.low, + val.high, + typeof unsigned === "boolean" ? unsigned : val.unsigned + ); + } + Long2.fromValue = fromValue2; + var TWO_PWR_16_DBL2 = 1 << 16; + var TWO_PWR_24_DBL2 = 1 << 24; + var TWO_PWR_32_DBL2 = TWO_PWR_16_DBL2 * TWO_PWR_16_DBL2; + var TWO_PWR_64_DBL2 = TWO_PWR_32_DBL2 * TWO_PWR_32_DBL2; + var TWO_PWR_63_DBL2 = TWO_PWR_64_DBL2 / 2; + var TWO_PWR_242 = fromInt2(TWO_PWR_24_DBL2); + var ZERO2 = fromInt2(0); + Long2.ZERO = ZERO2; + var UZERO2 = fromInt2(0, true); + Long2.UZERO = UZERO2; + var ONE2 = fromInt2(1); + Long2.ONE = ONE2; + var UONE2 = fromInt2(1, true); + Long2.UONE = UONE2; + var NEG_ONE2 = fromInt2(-1); + Long2.NEG_ONE = NEG_ONE2; + var MAX_VALUE2 = fromBits2(4294967295 | 0, 2147483647 | 0, false); + Long2.MAX_VALUE = MAX_VALUE2; + var MAX_UNSIGNED_VALUE2 = fromBits2(4294967295 | 0, 4294967295 | 0, true); + Long2.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE2; + var MIN_VALUE2 = fromBits2(0, 2147483648 | 0, false); + Long2.MIN_VALUE = MIN_VALUE2; + var LongPrototype2 = Long2.prototype; + LongPrototype2.toInt = function toInt2() { + return this.unsigned ? this.low >>> 0 : this.low; + }; + LongPrototype2.toNumber = function toNumber2() { + if (this.unsigned) + return (this.high >>> 0) * TWO_PWR_32_DBL2 + (this.low >>> 0); + return this.high * TWO_PWR_32_DBL2 + (this.low >>> 0); + }; + LongPrototype2.toString = function toString2(radix) { + radix = radix || 10; + if (radix < 2 || 36 < radix) throw RangeError("radix"); + if (this.isZero()) return "0"; + if (this.isNegative()) { + if (this.eq(MIN_VALUE2)) { + var radixLong = fromNumber2(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 = fromNumber2(pow_dbl2(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; + } + } + }; + LongPrototype2.getHighBits = function getHighBits2() { + return this.high; + }; + LongPrototype2.getHighBitsUnsigned = function getHighBitsUnsigned2() { + return this.high >>> 0; + }; + LongPrototype2.getLowBits = function getLowBits2() { + return this.low; + }; + LongPrototype2.getLowBitsUnsigned = function getLowBitsUnsigned2() { + return this.low >>> 0; + }; + LongPrototype2.getNumBitsAbs = function getNumBitsAbs2() { + if (this.isNegative()) + return this.eq(MIN_VALUE2) ? 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; + }; + LongPrototype2.isSafeInteger = function isSafeInteger2() { + var top11Bits = this.high >> 21; + if (!top11Bits) return true; + if (this.unsigned) return false; + return top11Bits === -1 && !(this.low === 0 && this.high === -2097152); + }; + LongPrototype2.isZero = function isZero2() { + return this.high === 0 && this.low === 0; + }; + LongPrototype2.eqz = LongPrototype2.isZero; + LongPrototype2.isNegative = function isNegative2() { + return !this.unsigned && this.high < 0; + }; + LongPrototype2.isPositive = function isPositive2() { + return this.unsigned || this.high >= 0; + }; + LongPrototype2.isOdd = function isOdd2() { + return (this.low & 1) === 1; + }; + LongPrototype2.isEven = function isEven2() { + return (this.low & 1) === 0; + }; + LongPrototype2.equals = function equals2(other) { + if (!isLong2(other)) other = fromValue2(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; + }; + LongPrototype2.eq = LongPrototype2.equals; + LongPrototype2.notEquals = function notEquals2(other) { + return !this.eq( + /* validates */ + other + ); + }; + LongPrototype2.neq = LongPrototype2.notEquals; + LongPrototype2.ne = LongPrototype2.notEquals; + LongPrototype2.lessThan = function lessThan2(other) { + return this.comp( + /* validates */ + other + ) < 0; + }; + LongPrototype2.lt = LongPrototype2.lessThan; + LongPrototype2.lessThanOrEqual = function lessThanOrEqual2(other) { + return this.comp( + /* validates */ + other + ) <= 0; + }; + LongPrototype2.lte = LongPrototype2.lessThanOrEqual; + LongPrototype2.le = LongPrototype2.lessThanOrEqual; + LongPrototype2.greaterThan = function greaterThan2(other) { + return this.comp( + /* validates */ + other + ) > 0; + }; + LongPrototype2.gt = LongPrototype2.greaterThan; + LongPrototype2.greaterThanOrEqual = function greaterThanOrEqual2(other) { + return this.comp( + /* validates */ + other + ) >= 0; + }; + LongPrototype2.gte = LongPrototype2.greaterThanOrEqual; + LongPrototype2.ge = LongPrototype2.greaterThanOrEqual; + LongPrototype2.compare = function compare2(other) { + if (!isLong2(other)) other = fromValue2(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; + }; + LongPrototype2.comp = LongPrototype2.compare; + LongPrototype2.negate = function negate2() { + if (!this.unsigned && this.eq(MIN_VALUE2)) return MIN_VALUE2; + return this.not().add(ONE2); + }; + LongPrototype2.neg = LongPrototype2.negate; + LongPrototype2.add = function add3(addend) { + if (!isLong2(addend)) addend = fromValue2(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 fromBits2(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); + }; + LongPrototype2.subtract = function subtract2(subtrahend) { + if (!isLong2(subtrahend)) subtrahend = fromValue2(subtrahend); + return this.add(subtrahend.neg()); + }; + LongPrototype2.sub = LongPrototype2.subtract; + LongPrototype2.multiply = function multiply2(multiplier) { + if (this.isZero()) return this; + if (!isLong2(multiplier)) multiplier = fromValue2(multiplier); + if (wasm2) { + var low = wasm2["mul"]( + this.low, + this.high, + multiplier.low, + multiplier.high + ); + return fromBits2(low, wasm2["get_high"](), this.unsigned); + } + if (multiplier.isZero()) return this.unsigned ? UZERO2 : ZERO2; + if (this.eq(MIN_VALUE2)) return multiplier.isOdd() ? MIN_VALUE2 : ZERO2; + if (multiplier.eq(MIN_VALUE2)) return this.isOdd() ? MIN_VALUE2 : ZERO2; + 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_242) && multiplier.lt(TWO_PWR_242)) + return fromNumber2( + 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 fromBits2(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); + }; + LongPrototype2.mul = LongPrototype2.multiply; + LongPrototype2.divide = function divide2(divisor) { + if (!isLong2(divisor)) divisor = fromValue2(divisor); + if (divisor.isZero()) throw Error("division by zero"); + if (wasm2) { + if (!this.unsigned && this.high === -2147483648 && divisor.low === -1 && divisor.high === -1) { + return this; + } + var low = (this.unsigned ? wasm2["div_u"] : wasm2["div_s"])( + this.low, + this.high, + divisor.low, + divisor.high + ); + return fromBits2(low, wasm2["get_high"](), this.unsigned); + } + if (this.isZero()) return this.unsigned ? UZERO2 : ZERO2; + var approx, rem, res; + if (!this.unsigned) { + if (this.eq(MIN_VALUE2)) { + if (divisor.eq(ONE2) || divisor.eq(NEG_ONE2)) + return MIN_VALUE2; + else if (divisor.eq(MIN_VALUE2)) return ONE2; + else { + var halfThis = this.shr(1); + approx = halfThis.div(divisor).shl(1); + if (approx.eq(ZERO2)) { + return divisor.isNegative() ? ONE2 : NEG_ONE2; + } else { + rem = this.sub(divisor.mul(approx)); + res = approx.add(rem.div(divisor)); + return res; + } + } + } else if (divisor.eq(MIN_VALUE2)) return this.unsigned ? UZERO2 : ZERO2; + 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 = ZERO2; + } else { + if (!divisor.unsigned) divisor = divisor.toUnsigned(); + if (divisor.gt(this)) return UZERO2; + if (divisor.gt(this.shru(1))) + return UONE2; + res = UZERO2; + } + 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_dbl2(2, log22 - 48), approxRes = fromNumber2(approx), approxRem = approxRes.mul(divisor); + while (approxRem.isNegative() || approxRem.gt(rem)) { + approx -= delta; + approxRes = fromNumber2(approx, this.unsigned); + approxRem = approxRes.mul(divisor); + } + if (approxRes.isZero()) approxRes = ONE2; + res = res.add(approxRes); + rem = rem.sub(approxRem); + } + return res; + }; + LongPrototype2.div = LongPrototype2.divide; + LongPrototype2.modulo = function modulo2(divisor) { + if (!isLong2(divisor)) divisor = fromValue2(divisor); + if (wasm2) { + var low = (this.unsigned ? wasm2["rem_u"] : wasm2["rem_s"])( + this.low, + this.high, + divisor.low, + divisor.high + ); + return fromBits2(low, wasm2["get_high"](), this.unsigned); + } + return this.sub(this.div(divisor).mul(divisor)); + }; + LongPrototype2.mod = LongPrototype2.modulo; + LongPrototype2.rem = LongPrototype2.modulo; + LongPrototype2.not = function not3() { + return fromBits2(~this.low, ~this.high, this.unsigned); + }; + LongPrototype2.countLeadingZeros = function countLeadingZeros2() { + return this.high ? Math.clz32(this.high) : Math.clz32(this.low) + 32; + }; + LongPrototype2.clz = LongPrototype2.countLeadingZeros; + LongPrototype2.countTrailingZeros = function countTrailingZeros2() { + return this.low ? ctz322(this.low) : ctz322(this.high) + 32; + }; + LongPrototype2.ctz = LongPrototype2.countTrailingZeros; + LongPrototype2.and = function and3(other) { + if (!isLong2(other)) other = fromValue2(other); + return fromBits2( + this.low & other.low, + this.high & other.high, + this.unsigned + ); + }; + LongPrototype2.or = function or3(other) { + if (!isLong2(other)) other = fromValue2(other); + return fromBits2( + this.low | other.low, + this.high | other.high, + this.unsigned + ); + }; + LongPrototype2.xor = function xor3(other) { + if (!isLong2(other)) other = fromValue2(other); + return fromBits2( + this.low ^ other.low, + this.high ^ other.high, + this.unsigned + ); + }; + LongPrototype2.shiftLeft = function shiftLeft2(numBits) { + if (isLong2(numBits)) numBits = numBits.toInt(); + if ((numBits &= 63) === 0) return this; + else if (numBits < 32) + return fromBits2( + this.low << numBits, + this.high << numBits | this.low >>> 32 - numBits, + this.unsigned + ); + else return fromBits2(0, this.low << numBits - 32, this.unsigned); + }; + LongPrototype2.shl = LongPrototype2.shiftLeft; + LongPrototype2.shiftRight = function shiftRight2(numBits) { + if (isLong2(numBits)) numBits = numBits.toInt(); + if ((numBits &= 63) === 0) return this; + else if (numBits < 32) + return fromBits2( + this.low >>> numBits | this.high << 32 - numBits, + this.high >> numBits, + this.unsigned + ); + else + return fromBits2( + this.high >> numBits - 32, + this.high >= 0 ? 0 : -1, + this.unsigned + ); + }; + LongPrototype2.shr = LongPrototype2.shiftRight; + LongPrototype2.shiftRightUnsigned = function shiftRightUnsigned2(numBits) { + if (isLong2(numBits)) numBits = numBits.toInt(); + if ((numBits &= 63) === 0) return this; + if (numBits < 32) + return fromBits2( + this.low >>> numBits | this.high << 32 - numBits, + this.high >>> numBits, + this.unsigned + ); + if (numBits === 32) return fromBits2(this.high, 0, this.unsigned); + return fromBits2(this.high >>> numBits - 32, 0, this.unsigned); + }; + LongPrototype2.shru = LongPrototype2.shiftRightUnsigned; + LongPrototype2.shr_u = LongPrototype2.shiftRightUnsigned; + LongPrototype2.rotateLeft = function rotateLeft2(numBits) { + var b; + if (isLong2(numBits)) numBits = numBits.toInt(); + if ((numBits &= 63) === 0) return this; + if (numBits === 32) return fromBits2(this.high, this.low, this.unsigned); + if (numBits < 32) { + b = 32 - numBits; + return fromBits2( + this.low << numBits | this.high >>> b, + this.high << numBits | this.low >>> b, + this.unsigned + ); + } + numBits -= 32; + b = 32 - numBits; + return fromBits2( + this.high << numBits | this.low >>> b, + this.low << numBits | this.high >>> b, + this.unsigned + ); + }; + LongPrototype2.rotl = LongPrototype2.rotateLeft; + LongPrototype2.rotateRight = function rotateRight2(numBits) { + var b; + if (isLong2(numBits)) numBits = numBits.toInt(); + if ((numBits &= 63) === 0) return this; + if (numBits === 32) return fromBits2(this.high, this.low, this.unsigned); + if (numBits < 32) { + b = 32 - numBits; + return fromBits2( + this.high << b | this.low >>> numBits, + this.low << b | this.high >>> numBits, + this.unsigned + ); + } + numBits -= 32; + b = 32 - numBits; + return fromBits2( + this.low << b | this.high >>> numBits, + this.high << b | this.low >>> numBits, + this.unsigned + ); + }; + LongPrototype2.rotr = LongPrototype2.rotateRight; + LongPrototype2.toSigned = function toSigned2() { + if (!this.unsigned) return this; + return fromBits2(this.low, this.high, false); + }; + LongPrototype2.toUnsigned = function toUnsigned2() { + if (this.unsigned) return this; + return fromBits2(this.low, this.high, true); + }; + LongPrototype2.toBytes = function toBytes2(le) { + return le ? this.toBytesLE() : this.toBytesBE(); + }; + LongPrototype2.toBytesLE = function toBytesLE2() { + 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 + ]; + }; + LongPrototype2.toBytesBE = function toBytesBE2() { + 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 + ]; + }; + Long2.fromBytes = function fromBytes2(bytes, unsigned, le) { + return le ? Long2.fromBytesLE(bytes, unsigned) : Long2.fromBytesBE(bytes, unsigned); + }; + Long2.fromBytesLE = function fromBytesLE2(bytes, unsigned) { + return new Long2( + bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24, + bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24, + unsigned + ); + }; + Long2.fromBytesBE = function fromBytesBE2(bytes, unsigned) { + return new Long2( + bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7], + bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], + unsigned + ); + }; + if (typeof BigInt === "function") { + Long2.fromBigInt = function fromBigInt(value, unsigned) { + var lowBits = Number(BigInt.asIntN(32, value)); + var highBits = Number(BigInt.asIntN(32, value >> BigInt(32))); + return fromBits2(lowBits, highBits, unsigned); + }; + Long2.fromValue = function fromValueWithBigInt(value, unsigned) { + if (typeof value === "bigint") return Long2.fromBigInt(value, unsigned); + return fromValue2(value, unsigned); + }; + LongPrototype2.toBigInt = function toBigInt() { + var lowBigInt = BigInt(this.low >>> 0); + var highBigInt = BigInt(this.unsigned ? this.high >>> 0 : this.high); + return highBigInt << BigInt(32) | lowBigInt; + }; + } + var _default = _exports.default = Long2; + } + ); + } +}); + +// web/node_modules/protobufjs/src/util/minimal.js +var require_minimal = __commonJS({ + "web/node_modules/protobufjs/src/util/minimal.js"(exports) { + "use strict"; + var util = exports; + 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(); + function isUnsafeProperty(key) { + return key === "__proto__" || key === "prototype" || key === "constructor"; + } + util.isUnsafeProperty = isUnsafeProperty; + 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 || exports; + 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 && Object.hasOwnProperty.call(obj, prop)) + return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0; + return false; + }; + util.Buffer = (function() { + try { + var Buffer2 = util.global.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 || (function() { + try { + var Long2 = require_umd(); + return Long2 && Long2.isLong ? Long2 : null; + } catch (e) { + return null; + } + })(); + 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) { + var ifNotSet = typeof arguments[arguments.length - 1] === "boolean", limit = ifNotSet ? arguments.length - 1 : arguments.length; + ifNotSet = ifNotSet && arguments[arguments.length - 1]; + for (var a = 1; a < limit; ++a) { + var src = arguments[a]; + if (!src) + continue; + for (var keys = Object.keys(src), i = 0; i < keys.length; ++i) + if (!isUnsafeProperty(keys[i]) && (dst[keys[i]] === void 0 || !ifNotSet)) + dst[keys[i]] = src[keys[i]]; + } + return dst; + } + util.merge = merge; + util.nestingLimit = 32; + util.recursionLimit = 100; + util.makeProp = function makeProp(obj, key) { + Object.defineProperty(obj, key, { + enumerable: true, + configurable: true, + writable: true + }); + }; + 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"(exports, module) { + "use strict"; + module.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) < 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) { + var lo = val.lo, hi = val.hi; + while (hi) { + buf[pos++] = lo & 127 | 128; + lo = (lo >>> 7 | hi << 25) >>> 0; + hi >>>= 7; + } + while (lo > 127) { + buf[pos++] = lo & 127 | 128; + lo = lo >>> 7; + } + buf[pos++] = 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"(exports, module) { + "use strict"; + module.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"(exports, module) { + "use strict"; + module.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.recursionLimit = util.recursionLimit; + Reader.prototype.skipType = function(wireType, depth) { + if (depth === void 0) depth = 0; + if (depth > Reader.recursionLimit) + throw Error("maximum nesting depth exceeded"); + 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, depth + 1); + } + 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"(exports, module) { + "use strict"; + module.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"(exports, module) { + "use strict"; + module.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"(exports) { + "use strict"; + var rpc = exports; + rpc.Service = require_service(); + } +}); + +// web/node_modules/protobufjs/src/roots.js +var require_roots = __commonJS({ + "web/node_modules/protobufjs/src/roots.js"(exports, module) { + "use strict"; + module.exports = /* @__PURE__ */ Object.create(null); + } +}); + +// web/node_modules/protobufjs/src/index-minimal.js +var require_index_minimal = __commonJS({ + "web/node_modules/protobufjs/src/index-minimal.js"(exports) { + "use strict"; + var protobuf = exports; + 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"(exports, module) { + "use strict"; + module.exports = require_index_minimal(); + } +}); + +// web/lib/onnxjs/ort-schema/protobuf/onnx.js +var require_onnx = __commonJS({ + "web/lib/onnxjs/ort-schema/protobuf/onnx.js"(exports, module) { + "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; + })(); + module.exports = $root; + } +}); + +// web/lib/onnxjs/util.ts +function assert(expr, msg) { + if (!expr) { + throw new Error(typeof msg === "string" ? msg : msg()); + } +} +function decodeUtf8String(buffer) { + return new TextDecoder().decode(buffer); +} +var import_onnx, ArrayUtil, MatMulUtil, BroadcastUtil, GemmUtil, ProtoUtil, LongUtil, ShapeUtil, SplitUtil, PoolConvUtil, MIN_CLIP, MAX_CLIP; +var init_util = __esm({ + "web/lib/onnxjs/util.ts"() { + "use strict"; + init_long(); + import_onnx = __toESM(require_onnx()); + init_tensor2(); + ArrayUtil = class { + /** + * Verifies if 2 input arrays contain the same elements. + * @param n1 Array 1 + * @param n2 Array 2 + * @returns Whether these 2 are equal + */ + static arraysEqual(n1, n2) { + if (n1.length !== n2.length) { + return false; + } + for (let i = 0; i < n1.length; i++) { + if (n1[i] !== n2[i]) { + return false; + } + } + return true; + } + }; + MatMulUtil = class { + /** + * Fix the input shapes for MatMul operation if they need fixing + * @param dimsA The shape of tensor A. Should be an array of positive integers + * @param dimsB The shape of tensor B. Should be an array of positive integers + * @returns A tuple containing the preprocessed input shapes as required by ONNX specifications + */ + static preprocessInputShapes(dimsA, dimsB) { + const a = dimsA.length === 1 ? [1, dimsA[0]] : dimsA; + const b = dimsB.length === 1 ? [dimsB[0], 1] : dimsB; + return [a, b]; + } + /** + * Fix the output shape computed for MatMul operation if it needs fixing + * @param outputShape The computed outputShape. Should be an array (at least of length 2) of positive integers. + * This will be mutated. + * @param aRank The rank of tensor A. + * @param bRank The rank of tensor B. + */ + static postprocessOutputShape(outputShape, aRank, bRank) { + if (aRank === 1) { + outputShape.splice(outputShape.length - 2, 1); + } + if (bRank === 1) { + outputShape.pop(); + } + } + /** + * Calculate the expected shape when matrix multiplication + * @param a The shape of tensor A. Should be a tuple of 2 positive integers + * @param b The shape of tensor B. Should be a tuple of 2 positive integers + * @returns The expected shape of the result, or undefined if N/A + */ + static calcMatMulShape(a, b) { + return a[1] !== b[0] ? void 0 : [a[0], b[1]]; + } + }; + BroadcastUtil = class _BroadcastUtil { + /** + * Calculate the expected shape when broadcasting 2 tensors + * @param a The shape of tensor A. Should be an array of positive integers + * @param b The shape of tensor B. Should be an array of positive integers + * @param isMatMul Whether the operation is MatMul + * @returns The expected shape of the result, or undefined if N/A + */ + static calcShape(adims, bdims, isMatMul = false) { + const arank = adims.length; + const brank = bdims.length; + if (arank === 0) { + return bdims; + } + if (brank === 0) { + return adims; + } + const crank = Math.max(adims.length, bdims.length); + const cdims = new Array(crank); + if (isMatMul) { + if (arank < 2 || brank < 2) { + return void 0; + } + const cShapeMatMul = MatMulUtil.calcMatMulShape( + [adims[arank - 2], adims[arank - 1]], + [bdims[brank - 2], bdims[brank - 1]] + ); + if (cShapeMatMul === void 0) { + return void 0; + } + [cdims[crank - 2], cdims[crank - 1]] = cShapeMatMul; + } + for (let i = isMatMul ? 3 : 1; i <= crank; i++) { + const aLen = arank - i < 0 ? 1 : adims[arank - i]; + const bLen = brank - i < 0 ? 1 : bdims[brank - i]; + if (aLen !== bLen && aLen > 1 && bLen > 1) { + return void 0; + } + cdims[crank - i] = Math.max(aLen, bLen); + } + return cdims; + } + /** + * Given the indices of a broadcasted tensor, calculate the original indices + * @param broadcastedIndices The given indices of the broadcasted tensor. + * @param originalShape The original shape of the tensor before broadcast + * @returns The calculated indices that maps to the original tensor. + */ + static index(broadcastedIndices, originalShape) { + const originalIndices = new Array(originalShape.length); + _BroadcastUtil.fillIndex(broadcastedIndices, originalShape, originalIndices); + return originalIndices; + } + /** + * Given the indices of a broadcasted tensor, calculate the original indices + * @param broadcastedIndices The given indices of the broadcasted tensor. + * @param originalShape The original shape of the tensor before broadcast + * @param originalIndices The mapping of broadcastedIndices to the originalIndices (output parameter - will be + * mutated). + */ + static fillIndex(broadcastedIndices, originalShape, originalIndices) { + const dimOffset = broadcastedIndices.length - originalShape.length; + for (let i = 0; i < originalShape.length; i++) { + originalIndices[i] = broadcastedIndices[dimOffset + i] % originalShape[i]; + } + } + /** + * Perform the broadcasting operation on the specific operator + * @param a The input tensor A + * @param b The input tensor B + * @param op The operator lambda function + * @param inplace Whether to write the result back to A. + * @returns The result tensor, or undefined if input not broadcastable. + */ + static calc(a, b, op, inplace, resultType) { + const outputShape = _BroadcastUtil.calcShape(a.dims, b.dims); + if (outputShape) { + if (inplace && !ShapeUtil.areEqual(outputShape, a.dims)) { + return void 0; + } + const size = ShapeUtil.size(outputShape); + const c = inplace ? a : new Tensor4(outputShape, resultType || a.type); + if (outputShape.length === 0) { + c.set([], op(a.get([]), b.get([]))); + } else { + const outputIndices = new Array(outputShape.length); + const originalIndicesA = new Array(a.dims.length); + const originalIndicesB = new Array(b.dims.length); + let valA = 0; + let valB = 0; + let isAScalar = false; + let isBScalar = false; + if (a.dims.length === 0) { + valA = a.get([]); + isAScalar = true; + } + if (b.dims.length === 0) { + valB = b.get([]); + isBScalar = true; + } + let rest; + for (let i = 0; i < size; i++) { + rest = i; + for (let j = outputShape.length - 1; j >= 0; j--) { + outputIndices[j] = rest % outputShape[j]; + rest = Math.floor(rest / outputShape[j]); + } + if (!isAScalar) { + _BroadcastUtil.fillIndex(outputIndices, a.dims, originalIndicesA); + valA = a.get(originalIndicesA); + } + if (!isBScalar) { + _BroadcastUtil.fillIndex(outputIndices, b.dims, originalIndicesB); + valB = b.get(originalIndicesB); + } + c.set(outputIndices, op(valA, valB)); + } + } + return c; + } + return void 0; + } + /** + * Determine if a shape is unidirectional broadcastable to another shape + * @param shape The input shape + * @param finalShape The desired shape after broadcasting + */ + static isValidBroadcast(shape2, finalShape) { + const inputRank = shape2.length; + const finalRank = finalShape.length; + if (inputRank > finalRank) { + return false; + } + for (let i = 1; i <= inputRank; i++) { + if (shape2[inputRank - i] !== 1 && shape2[inputRank - i] !== finalShape[finalRank - i]) { + return false; + } + } + return true; + } + /** + * Determine the broadcasted dims in input shape based on the given output shape. + * Note that this function only returns the broadcasted dims. + * @param inputShape The input shape + * @param outputShape The output shape + * @returns The broadcasted dims in input shape. + */ + static getBroadcastDims(inputShape, outputShape) { + const inRank = inputShape.length; + const dims = []; + for (let i = 0; i < inRank; i++) { + const dim = inRank - 1 - i; + const a = inputShape[dim] || 1; + const b = outputShape[outputShape.length - 1 - i] || 1; + if (b > 1 && a === 1) { + dims.unshift(dim); + } + } + return dims; + } + }; + GemmUtil = class { + // will make sure input shapes are compatible for this op + // and return back the shape of the output in the form of a tuple + // will throw exception if the input shapes are not compatible + static getShapeOfGemmResult(leftShape, transLeft, rightShape, transRight, biasShape) { + if (leftShape.length !== 2 || rightShape.length !== 2) { + throw new Error("shape need to be of size 2"); + } + let M; + let K; + let N; + if (transLeft) { + M = leftShape[1]; + K = leftShape[0]; + } else { + M = leftShape[0]; + K = leftShape[1]; + } + let kDim = -1; + if (transRight) { + N = rightShape[0]; + kDim = 1; + } else { + N = rightShape[1]; + kDim = 0; + } + if (rightShape[kDim] !== K) { + throw new Error("dimension mismatch"); + } + if (M <= 0 || N <= 0 || K <= 0) { + throw new Error("invalid shape specified"); + } + if (biasShape && !BroadcastUtil.isValidBroadcast(biasShape, [M, N])) { + throw new Error("gemm: invalid bias shape for broadcast"); + } + return [M, N, K]; + } + }; + ProtoUtil = class _ProtoUtil { + static tensorDataTypeFromProto(typeProto) { + switch (typeProto) { + case import_onnx.onnx.TensorProto.DataType.INT8: + return "int8"; + case import_onnx.onnx.TensorProto.DataType.UINT8: + return "uint8"; + case import_onnx.onnx.TensorProto.DataType.BOOL: + return "bool"; + case import_onnx.onnx.TensorProto.DataType.INT16: + return "int16"; + case import_onnx.onnx.TensorProto.DataType.UINT16: + return "uint16"; + case import_onnx.onnx.TensorProto.DataType.INT32: + return "int32"; + case import_onnx.onnx.TensorProto.DataType.UINT32: + return "uint32"; + case import_onnx.onnx.TensorProto.DataType.FLOAT: + return "float32"; + case import_onnx.onnx.TensorProto.DataType.DOUBLE: + return "float64"; + case import_onnx.onnx.TensorProto.DataType.STRING: + return "string"; + // For INT64/UINT64, reduce their value to 32-bits. + // Should throw exception when overflow + case import_onnx.onnx.TensorProto.DataType.INT64: + return "int32"; + case import_onnx.onnx.TensorProto.DataType.UINT64: + return "uint32"; + default: + throw new Error(`unsupported data type: ${import_onnx.onnx.TensorProto.DataType[typeProto]}`); + } + } + static tensorDataTypeStringToEnum(type) { + switch (type) { + case "int8": + return import_onnx.onnx.TensorProto.DataType.INT8; + case "uint8": + return import_onnx.onnx.TensorProto.DataType.UINT8; + case "bool": + return import_onnx.onnx.TensorProto.DataType.BOOL; + case "int16": + return import_onnx.onnx.TensorProto.DataType.INT16; + case "uint16": + return import_onnx.onnx.TensorProto.DataType.UINT16; + case "int32": + return import_onnx.onnx.TensorProto.DataType.INT32; + case "uint32": + return import_onnx.onnx.TensorProto.DataType.UINT32; + case "float32": + return import_onnx.onnx.TensorProto.DataType.FLOAT; + case "float64": + return import_onnx.onnx.TensorProto.DataType.DOUBLE; + case "string": + return import_onnx.onnx.TensorProto.DataType.STRING; + case "int64": + return import_onnx.onnx.TensorProto.DataType.INT64; + case "uint64": + return import_onnx.onnx.TensorProto.DataType.UINT64; + default: + throw new Error(`unsupported data type: ${type}`); + } + } + static tensorDimsFromProto(dims) { + return dims.map((d) => long_default.isLong(d) ? d.toNumber() : d); + } + static tensorValueTypeFromProto(valueType) { + return { + tensorType: _ProtoUtil.tensorDataTypeFromProto(valueType.elemType), + shape: { dims: _ProtoUtil.tensorDimsFromProto(valueType.shape.dim.map((d) => d.dimValue)) } + }; + } + static tensorDimsFromORTFormat(tensor) { + const dims = []; + for (let i = 0; i < tensor.dimsLength(); i++) { + dims.push(LongUtil.longToNumber(tensor.dims(i))); + } + return dims; + } + static tensorAttributesFromORTFormat(node) { + const attributes = []; + for (let i = 0; i < node.attributesLength(); i++) { + attributes.push(node.attributes(i)); + } + return attributes; + } + }; + LongUtil = class { + // This function is called to get a number from long type of data for attribute, dim, and ir version, + // which values are signed integers. + // To make it more generic, add an optional parameter to convert to a unsigned number. + static longToNumber(n) { + if (long_default.isLong(n)) { + return n.toNumber(); + } else if (typeof n === "bigint") { + return Number(n); + } + return n; + } + static isLong(n) { + return long_default.isLong(n) || typeof n === "bigint"; + } + }; + ShapeUtil = class _ShapeUtil { + static size(dims) { + return _ShapeUtil.getSizeFromDimensionRange(dims, 0, dims.length); + } + // `axis` inclusive + static sizeFromDimension(dims, axis) { + if (axis < 0 || axis > dims.length) { + throw new Error(`invalid dimension of ${axis} for sizeFromDimension as Tensor has ${dims.length} dimensions.`); + } + return _ShapeUtil.getSizeFromDimensionRange(dims, axis, dims.length); + } + // `axis` exclusive + static sizeToDimension(dims, axis) { + if (axis < 0 || axis > dims.length) { + throw new Error(`invalid dimension of ${axis} for sizeToDimension as Tensor has ${dims.length} dimensions.`); + } + return _ShapeUtil.getSizeFromDimensionRange(dims, 0, axis); + } + static getSizeFromDimensionRange(dims, start, end) { + let size = 1; + for (let i = start; i < end; i++) { + if (dims[i] <= 0) { + throw new Error( + "cannot get valid size from specified dimension range. Most likely the range contains 0 or negative values in them." + ); + } + size *= dims[i]; + } + return size; + } + static computeStrides(dims) { + const rank = dims.length; + if (rank === 0) { + return []; + } else if (rank === 1) { + return [1]; + } + const strides = new Array(rank); + strides[rank - 1] = 1; + strides[rank - 2] = dims[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * dims[i + 1]; + } + return strides; + } + static transpose(dims) { + const copy = dims.slice(); + return copy.reverse(); + } + static indicesToOffset(indices, strides, axis) { + if (axis === void 0) { + axis = indices.length; + } + let offset = 0; + for (let i = 0; i < axis; ++i) { + offset += strides[i] * indices[i]; + } + return offset; + } + static offsetToIndices(offset, strides) { + const rank = strides.length; + if (rank === 0) { + return []; + } else if (rank === 1) { + return [offset * strides[0]]; + } + const indices = new Array(strides.length); + for (let i = 0; i < indices.length - 1; ++i) { + indices[i] = Math.floor(offset / strides[i]); + offset -= indices[i] * strides[i]; + } + indices[indices.length - 1] = offset; + return indices; + } + /** + * normalize axis of range [-r, r) into [0, r). + */ + static normalizeAxis(axis, tensorRank) { + if (axis < -tensorRank && axis >= tensorRank) { + throw new Error("unsupported axis for this operation."); + } + return axis < 0 ? axis + tensorRank : axis; + } + static normalizeAxes(axes, tensorRank) { + return axes.map((x) => this.normalizeAxis(x, tensorRank)); + } + // Increment an index into a tensor (in lexicographic + // ordering), wrapping around the specified upper_bound. + /** + * Increment an index into a tensor (in lexicographic ordering), wrapping around the specified upper_bound. + * @param index Given index to increment (Will be mutated) + * @param dims The dimensions of the tensor for which the given index corresponds to + * @param axisToIncrementOn The 1-indexed axis to increment on. If undefined, axisToIncrementOn == rank + */ + static incrementIndex(index, dims, axisToIncrementOn) { + if (dims.length === 0 || index.length === 0) { + throw new Error("Index incrementing unsupported for scalar Tensor"); + } + if (axisToIncrementOn === void 0) { + axisToIncrementOn = dims.length; + } else { + if (axisToIncrementOn <= 0 || axisToIncrementOn > dims.length) { + throw new Error("Incorrect axis to increment on"); + } + } + for (let k = axisToIncrementOn - 1; k >= 0; --k) { + index[k]++; + if (index[k] < dims[k]) { + break; + } + index[k] = 0; + } + } + /** + * Produces a new dimensions array based on the values in the 'originalDimensions' and 'shape' array + * Used in Reshape + * @param originalDims Original Shape array + * @param shapeHints array containing values to compute the new dimensions + * For example: + * originalDims = [2,2] and shapeHints = [0,-1] will return [2,2] + * originalDims = [2,2] and shapeHints = [4] will return [4] + * originalDims = [2,2] and shapeHints = [5] will throw an exception + * https://github.com/onnx/onnx/blob/main/docs/Operators.md#Reshape + */ + static calculateReshapedDims(originalDims, shapeHints) { + if (shapeHints.length === 0) { + if (originalDims.length === 0 || _ShapeUtil.size(originalDims) === 1) { + return []; + } else { + throw new Error("cannot reshape to a scalar Tensor"); + } + } + const nDims = shapeHints.length; + const reshapedDims = new Array(nDims); + let unknownDimension = -1; + let newTensorSize = 1; + for (let i = 0; i < nDims; i++) { + if (shapeHints[i] < -1) { + throw new Error("a dimension in shape hints cannot be less than -1"); + } + if (shapeHints[i] === -1) { + if (unknownDimension !== -1) { + throw new Error("at most one dimension in shape hints can be -1"); + } + unknownDimension = i; + } else { + if (shapeHints[i] === 0) { + if (i >= originalDims.length) { + throw new Error("the dimension with value zero exceeds the dimension size of the input tensor"); + } + reshapedDims[i] = originalDims[i]; + } else { + reshapedDims[i] = shapeHints[i]; + } + newTensorSize *= reshapedDims[i]; + } + } + const oldTensorSize = _ShapeUtil.size(originalDims); + if (unknownDimension !== -1) { + if (oldTensorSize % newTensorSize !== 0) { + throw new Error( + `the input tensor cannot be reshaped to the requested shape. Input shape: [${originalDims}] Output shape: [${shapeHints}]` + ); + } + reshapedDims[unknownDimension] = oldTensorSize / newTensorSize; + } else { + if (newTensorSize !== oldTensorSize) { + throw new Error("reshapedDims and originalDims don't have matching sizes"); + } + } + return reshapedDims; + } + /** + * Sorts a given array based on the indices in the Perm array + * Used in Transpose + * @param a Array to be sorted such as dims or strides + * @param perm Perm given; if null a will be reversed + */ + static sortBasedOnPerm(a, perm) { + if (perm) { + return perm.map((v) => a[v]); + } else { + return a.slice().reverse(); + } + } + /** + * Pads a given shape according to the padding values + * @param dims shape of the Tensor to be padded + * @param pad pad values + */ + static padShape(dims, pad) { + const rank = dims.length; + return dims.map((v, i) => v + pad[i] + pad[i + rank]); + } + /** + * Determines if the two shapes are identical + * @param shape1 + * @param shape2 + */ + static areEqual(shape1, shape2) { + if (shape1.length !== shape2.length) { + return false; + } + return shape1.every((v, i) => v === shape2[i]); + } + /** + * Validates if the given `dims` or `shape` is valid in ONNX.js context and returns data size + * @param dims - input `dims` that needs to be checked + */ + static validateDimsAndCalcSize(dims) { + if (dims.length > 6) { + throw new TypeError("Only rank 0 to 6 is supported for tensor shape."); + } + let size = 1; + for (const n of dims) { + if (!Number.isInteger(n)) { + throw new TypeError(`Invalid shape: ${n} is not an integer`); + } + if (n < 0 || n > 2147483647) { + throw new TypeError(`Invalid shape: length ${n} is not allowed`); + } + size *= n; + } + return size; + } + /** + * Determines the shape of output tensor y = flatten(x, axis) + * @param dims - shape of input tensor + * @param axis - flatten axis, in the range [-r, r] + */ + static flattenShape(dims, axis) { + if (axis < 0) { + axis += dims.length; + } + const total = dims.reduce((x, y) => x * y, 1); + const right = dims.slice(axis).reduce((x, y) => x * y, 1); + const outputDims = [total / right, right]; + return outputDims; + } + /** + * Determines the shape of output tensor y = squeeze(x, axes) + * @param dims - shape of input tensor + * @param axes - squeeze axes + */ + static squeezeShape(dims, axes) { + const outputDims = new Array(); + axes = _ShapeUtil.normalizeAxes(axes, dims.length); + for (let i = 0; i < dims.length; i++) { + const inSqueezeList = axes.indexOf(i) >= 0; + if (inSqueezeList && dims[i] !== 1) { + throw new Error("squeeze an axis of size different than 1"); + } + if (axes.length === 0 && dims[i] > 1 || axes.length > 0 && !inSqueezeList) { + outputDims.push(dims[i]); + } + } + return outputDims; + } + /** + * Determines the shape of output tensor y = unsqueeze(x, axes) + * @param dims - shape of input tensor + * @param axes - unsqueeze axes + */ + static unsqueezeShape(dims, axes) { + const outputDims = new Array(dims.length + axes.length); + outputDims.fill(0); + for (let i = 0; i < axes.length; i++) { + const axis = _ShapeUtil.normalizeAxis(axes[i], outputDims.length); + if (axis >= outputDims.length) { + throw new Error("'axes' has an out of range axis"); + } + if (outputDims[axis] !== 0) { + throw new Error("'axes' has a duplicate axis"); + } + outputDims[axis] = 1; + } + let inputDimsIterator = 0; + for (let i = 0; i < outputDims.length; i++) { + if (outputDims[i] === 0) { + outputDims[i] = dims[inputDimsIterator++]; + } + } + if (inputDimsIterator !== dims.length) { + throw new Error("the unsqueezed dimension could not be established"); + } + return outputDims; + } + }; + SplitUtil = class _SplitUtil { + /** + * Calculates new Shapes from existing one and the splits given along the axis provides + * @param dims Shape of the Tensor to be splitted into two or more Shapes + * @param axis The dimension along which the Tensor will be split + * @param splits Offsets for the start of each split + */ + static splitShape(dims, axis, split2, numOutputs) { + if (split2.length === 0) { + if (!numOutputs) { + throw new Error("need to know number of outputs when the 'split' attribute is not specified"); + } + _SplitUtil.determineSplit(dims[axis], numOutputs, split2); + } + const shapes = []; + const offsets = [0]; + for (let i = 0; i < split2.length; ++i) { + if (i !== 0) { + offsets.push(offsets[i - 1] + split2[i - 1]); + } + const shape2 = dims.slice(); + shape2[axis] = split2[i]; + shapes.push(shape2); + } + return [shapes, offsets]; + } + static determineSplit(numElementsAlongAxis, numOutputs, split2) { + if (numElementsAlongAxis % numOutputs !== 0) { + throw new Error("cannot split tensor to equal sized parts"); + } + for (let i = 0; i < numOutputs; ++i) { + split2.push(numElementsAlongAxis / numOutputs); + } + } + }; + PoolConvUtil = class _PoolConvUtil { + /** + * Adjust the kernel, strides, pads to correct rank. Set to default value if not present + * @param isGlobalOperator If true, perform global pooling. + * @param inputDims The input tensor dimension. + * @param kernelShape The size of the kernel along each axis. + * @param strides Stride along each axis. + * @param dilations Dilation along each axis. + * @param pads Padding for the beginning and ending along each axis. + */ + static adjustPoolAttributes(isGlobalOperator, inputDims, kernelShape, strides, dilations, pads) { + if (!isGlobalOperator && kernelShape.length !== inputDims.length - 2) { + throw new Error("length of specified kernel shapes should be 2 less than length of input dimensions"); + } + if (isGlobalOperator) { + for (let dim = 0; dim < inputDims.length - 2; dim++) { + if (dim >= kernelShape.length) { + kernelShape.push(inputDims[dim + 2]); + } else { + kernelShape[dim] = inputDims[dim + 2]; + } + } + } + for (let dim = 0; dim < kernelShape.length; dim++) { + if (dim < strides.length) { + if (strides[dim] < 0) { + throw new Error("strides should be greater than or equal to 1"); + } + } else { + strides.push(1); + } + } + for (let dim = 0; dim < kernelShape.length; dim++) { + if (dim < dilations.length) { + if (dilations[dim] < 0) { + throw new Error("dilations should be greater than or equal to 1"); + } + } else { + dilations.push(1); + } + } + for (let dim = 0; dim < kernelShape.length * 2; dim++) { + if (dim < pads.length) { + if (pads[dim] < 0) { + throw new Error("pad should be greater than or equal to 1"); + } + } else { + pads.push(0); + } + } + for (let dim = 0; dim < kernelShape.length; dim++) { + if (kernelShape[dim] <= 0) { + throw new Error("kernel shapes need to be greater than 0"); + } + if (pads[dim] >= kernelShape[dim] || pads[dim + kernelShape.length] >= kernelShape[dim]) { + throw new Error("pads should be smaller than kernel"); + } + } + } + // adjust pad values based on 'autoPad' attribute + static adjustPadsBasedOnAutoPad(inputDims, strides, dilations, kernelShape, pads, autoPad) { + if (!autoPad) { + return; + } + if (pads.length !== 2 * (inputDims.length - 2)) { + throw new Error("length of pads should be twice the length of data dimensions"); + } + if (strides.length !== inputDims.length - 2) { + throw new Error("length of strides should be the length of data dimensions"); + } + if (kernelShape.length !== inputDims.length - 2) { + throw new Error("length of kernel shapes should be the length of data dimensions"); + } + for (let dim = 0; dim < inputDims.length - 2; dim++) { + _PoolConvUtil.adjustPadAndReturnShape( + inputDims[dim + 2], + strides[dim], + dilations[dim], + kernelShape[dim], + pads, + dim, + dim + inputDims.length - 2, + autoPad + ); + } + } + /** + * Calculate the output shape for Pool ops based on input attributes. (Should be used only for Pool ops) + * @param isGlobalOperator If true, perform global pooling. + * @param inputDims The input tensor dimension. (inputs[0].dims) + * @param strides Stride along each axis. + * @param dilations Dilation along each axis. + * @param kernelShape The size of the kernel along each axis. + * @param pads Padding for the beginning and ending along each axis. + * @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each + * dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID. + * @param ceilMode When set to 1, use ceil() instead of floor() to compute the output spatial size (and apply the + * "shrink the last window if it starts entirely in padding" rule). Defaults to 0 (floor). + */ + static computePoolOutputShape(isGlobalOperator, inputDims, strides, dilations, kernelShape, pads, autoPad, ceilMode = 0) { + 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, + ceilMode + ); + 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, ceilMode = 0) { + 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, + ceilMode + ) + ); + } + } + } + // Computes the output spatial size for a single dimension. + // Produces results identical to the C++ PoolAttributes::ComputeOutputSize + // (onnxruntime/core/providers/cpu/nn/pool_attributes.h), including the ceil_mode + // "shrink the last window if it starts entirely in the trailing padding" rule. The JS + // signature takes a pre-computed `numerator` (equal to `inSize + padHead + padTail - dkernel`, + // matching the C++ `in_size + pad_head + pad_tail - dilation * (kernel - 1) - 1`) instead of + // the raw pooling attributes, but the computed output size is the same. + // Keep in sync with the onnxjs/jsep copy. + // NOTE: In this onnxjs copy the ceilMode path exists for shape-test parity with the jsep copy; + // the onnxjs WebGL pooling caller (backends/webgl/ops/pool.ts) intentionally does NOT pass + // ceilMode (legacy path still throws on ceil_mode != 0), so it always uses the floor default. + static computeOutputSize(numerator, stride, inSize, padHead, ceilMode) { + let outSize = Math.floor(numerator / stride) + 1; + if (ceilMode === 1) { + outSize = Math.ceil(numerator / stride) + 1; + if ((outSize - 1) * stride >= inSize + padHead) { + outSize -= 1; + } + } + return outSize; + } + // 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, ceilMode = 0) { + const dkernel = dilation * (kernel - 1) + 1; + if (autoPad && autoPad !== "NOTSET") { + switch (autoPad) { + case "VALID": + pads[padHeadIndex] = 0; + pads[padTailIndex] = 0; + return _PoolConvUtil.computeOutputSize(inSize - dkernel, stride, inSize, 0, ceilMode); + case "SAME_LOWER": + case "SAME_UPPER": + if (dilation !== 1) { + throw new Error("Dilation not supported for SAME_UPPER or SAME_LOWER"); + } else { + const legacyTargetSize = Math.floor((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 _PoolConvUtil.computeOutputSize( + inSize + pads[padHeadIndex] + pads[padTailIndex] - dkernel, + stride, + inSize, + pads[padHeadIndex], + ceilMode + ); + } + default: + throw new Error("Unsupported AutoPad type"); + } + } else { + return _PoolConvUtil.computeOutputSize( + inSize + pads[padHeadIndex] + pads[padTailIndex] - dkernel, + stride, + inSize, + pads[padHeadIndex], + ceilMode + ); + } + } + }; + MIN_CLIP = -34028234663852886e22; + MAX_CLIP = 34028234663852886e22; + } +}); + +// web/lib/onnxjs/tensor.ts +function sizeof(type) { + switch (type) { + case "bool": + case "int8": + case "uint8": + return 1; + case "int16": + case "uint16": + return 2; + case "int32": + case "uint32": + case "float32": + return 4; + case "float64": + return 8; + default: + throw new Error(`cannot calculate sizeof() on type ${type}`); + } +} +function sizeofProto(type) { + switch (type) { + case import_onnx2.onnx.TensorProto.DataType.UINT8: + case import_onnx2.onnx.TensorProto.DataType.INT8: + case import_onnx2.onnx.TensorProto.DataType.BOOL: + return 1; + case import_onnx2.onnx.TensorProto.DataType.UINT16: + case import_onnx2.onnx.TensorProto.DataType.INT16: + return 2; + case import_onnx2.onnx.TensorProto.DataType.FLOAT: + case import_onnx2.onnx.TensorProto.DataType.INT32: + case import_onnx2.onnx.TensorProto.DataType.UINT32: + return 4; + case import_onnx2.onnx.TensorProto.DataType.INT64: + case import_onnx2.onnx.TensorProto.DataType.DOUBLE: + case import_onnx2.onnx.TensorProto.DataType.UINT64: + return 8; + default: + throw new Error(`cannot calculate sizeof() on type ${import_onnx2.onnx.TensorProto.DataType[type]}`); + } +} +function createView(dataBuffer, type) { + return new (dataviewConstructor(type))(dataBuffer); +} +function dataviewConstructor(type) { + switch (type) { + case "bool": + case "uint8": + return Uint8Array; + case "int8": + return Int8Array; + case "int16": + return Int16Array; + case "uint16": + return Uint16Array; + case "int32": + return Int32Array; + case "uint32": + return Uint32Array; + case "int64": + return BigInt64Array; + case "float32": + return Float32Array; + case "float64": + return Float64Array; + default: + throw new Error("unspecified error"); + } +} +function longToNumber(i, type) { + if (type === import_onnx2.onnx.TensorProto.DataType.INT64 || type === import_tensor_data_type.TensorDataType.INT64) { + if (i.greaterThanOrEqual(2147483648) || i.lessThan(-2147483648)) { + throw new TypeError("int64 is not supported"); + } + } else if (type === import_onnx2.onnx.TensorProto.DataType.UINT32 || type === import_tensor_data_type.TensorDataType.UINT32 || type === import_onnx2.onnx.TensorProto.DataType.UINT64 || type === import_tensor_data_type.TensorDataType.UINT64) { + if (i.greaterThanOrEqual(4294967296) || i.lessThan(0)) { + throw new TypeError("uint64 is not supported"); + } + } else { + throw new TypeError(`not a LONG type: ${import_onnx2.onnx.TensorProto.DataType[type]}`); + } + return i.toNumber(); +} +function readProto(view, type, byteOffset) { + switch (type) { + case import_onnx2.onnx.TensorProto.DataType.BOOL: + case import_onnx2.onnx.TensorProto.DataType.UINT8: + return view.getUint8(byteOffset); + case import_onnx2.onnx.TensorProto.DataType.INT8: + return view.getInt8(byteOffset); + case import_onnx2.onnx.TensorProto.DataType.UINT16: + return view.getUint16(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.INT16: + return view.getInt16(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.FLOAT: + return view.getFloat32(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.INT32: + return view.getInt32(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.UINT32: + return view.getUint32(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.INT64: + return longToNumber( + long_default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), false), + type + ); + case import_onnx2.onnx.TensorProto.DataType.DOUBLE: + return view.getFloat64(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.UINT64: + return longToNumber( + long_default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), true), + type + ); + default: + throw new Error(`cannot read from DataView for type ${import_onnx2.onnx.TensorProto.DataType[type]}`); + } +} +var import_guid_typescript, import_onnx2, Tensor4; +var init_tensor2 = __esm({ + "web/lib/onnxjs/tensor.ts"() { + "use strict"; + import_guid_typescript = __toESM(require_guid()); + init_long(); + init_ort_generated(); + import_onnx2 = __toESM(require_onnx()); + init_util(); + Tensor4 = class _Tensor { + constructor(dims, type, dataProvider, asyncDataProvider, cache2, dataId = import_guid_typescript.Guid.create()) { + this.dims = dims; + this.type = type; + this.dataProvider = dataProvider; + this.asyncDataProvider = asyncDataProvider; + this.cache = cache2; + this.dataId = dataId; + this.size = ShapeUtil.validateDimsAndCalcSize(dims); + const size = this.size; + const empty = dataProvider === void 0 && asyncDataProvider === void 0 && cache2 === void 0; + if (cache2 !== void 0) { + if (cache2.length !== size) { + throw new RangeError("Input dims doesn't match data length."); + } + } + if (type === "string") { + if (cache2 !== void 0 && (!Array.isArray(cache2) || !cache2.every((i) => typeof i === "string"))) { + throw new TypeError("cache should be a string array"); + } + if (empty) { + this.cache = new Array(size); + } + } else { + if (cache2 !== void 0) { + const constructor = dataviewConstructor(type); + if (!(cache2 instanceof constructor)) { + throw new TypeError(`cache should be type ${constructor.name}`); + } + } + if (empty) { + const buf = new ArrayBuffer(size * sizeof(type)); + this.cache = createView(buf, type); + } + } + } + /** + * get the underlying tensor data + */ + get data() { + if (this.cache === void 0) { + const data = this.dataProvider(this.dataId); + if (data.length !== this.size) { + throw new Error("Length of data provided by the Data Provider is inconsistent with the dims of this Tensor."); + } + this.cache = data; + } + return this.cache; + } + /** + * get the underlying string tensor data. Should only use when type is STRING + */ + get stringData() { + if (this.type !== "string") { + throw new TypeError("data type is not string"); + } + return this.data; + } + /** + * get the underlying integer tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16, + * INT16, INT32, UINT32, BOOL) + */ + get integerData() { + switch (this.type) { + case "uint8": + case "int8": + case "uint16": + case "int16": + case "int32": + case "uint32": + case "bool": + return this.data; + default: + throw new TypeError("data type is not integer (uint8, int8, uint16, int16, int32, uint32, bool)"); + } + } + /** + * get the underlying float tensor data. Should only use when type is one of the following: (FLOAT, DOUBLE) + */ + get floatData() { + switch (this.type) { + case "float32": + case "float64": + return this.data; + default: + throw new TypeError("data type is not float (float32, float64)"); + } + } + /** + * get the underlying number tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16, + * INT16, INT32, UINT32, BOOL, FLOAT, DOUBLE) + */ + get numberData() { + if (this.type !== "string") { + return this.data; + } + throw new TypeError("type cannot be non-number (string)"); + } + /** + * get value of an element at the given indices + */ + get(indices) { + return this.data[ShapeUtil.indicesToOffset(indices, this.strides)]; + } + /** + * set value of an element at the given indices + */ + set(indices, value) { + this.data[ShapeUtil.indicesToOffset(indices, this.strides)] = value; + } + /** + * get the underlying tensor data asynchronously + */ + async getData() { + if (this.cache === void 0) { + this.cache = await this.asyncDataProvider(this.dataId); + } + return this.cache; + } + /** + * get the strides for each dimension + */ + get strides() { + if (!this._strides) { + this._strides = ShapeUtil.computeStrides(this.dims); + } + return this._strides; + } + /** + * Construct new Tensor from a ONNX Tensor object + * @param tensorProto the ONNX Tensor + */ + static fromProto(tensorProto) { + if (!tensorProto) { + throw new Error("cannot construct Value from an empty tensor"); + } + const type = ProtoUtil.tensorDataTypeFromProto(tensorProto.dataType); + const dims = ProtoUtil.tensorDimsFromProto(tensorProto.dims); + const value = new _Tensor(dims, type); + if (type === "string") { + tensorProto.stringData.forEach((str, i) => { + value.data[i] = decodeUtf8String(str); + }); + } else if (tensorProto.rawData && typeof tensorProto.rawData.byteLength === "number" && tensorProto.rawData.byteLength > 0) { + const dataDest = value.data; + const dataSource = new DataView( + tensorProto.rawData.buffer, + tensorProto.rawData.byteOffset, + tensorProto.rawData.byteLength + ); + const elementSize = sizeofProto(tensorProto.dataType); + const length = tensorProto.rawData.byteLength / elementSize; + if (tensorProto.rawData.byteLength % elementSize !== 0) { + throw new Error("invalid buffer length"); + } + if (dataDest.length !== length) { + throw new Error("buffer length mismatch"); + } + for (let i = 0; i < length; i++) { + const n = readProto(dataSource, tensorProto.dataType, i * elementSize); + dataDest[i] = n; + } + } else { + let array; + switch (tensorProto.dataType) { + case import_onnx2.onnx.TensorProto.DataType.FLOAT: + array = tensorProto.floatData; + break; + case import_onnx2.onnx.TensorProto.DataType.INT32: + case import_onnx2.onnx.TensorProto.DataType.INT16: + case import_onnx2.onnx.TensorProto.DataType.UINT16: + case import_onnx2.onnx.TensorProto.DataType.INT8: + case import_onnx2.onnx.TensorProto.DataType.UINT8: + case import_onnx2.onnx.TensorProto.DataType.BOOL: + array = tensorProto.int32Data; + break; + case import_onnx2.onnx.TensorProto.DataType.INT64: + array = tensorProto.int64Data; + break; + case import_onnx2.onnx.TensorProto.DataType.DOUBLE: + array = tensorProto.doubleData; + break; + case import_onnx2.onnx.TensorProto.DataType.UINT32: + case import_onnx2.onnx.TensorProto.DataType.UINT64: + array = tensorProto.uint64Data; + break; + default: + throw new Error("unspecific error"); + } + if (array === null || array === void 0) { + throw new Error("failed to populate data from a tensorproto value"); + } + const data = value.data; + if (data.length !== array.length) { + throw new Error("array length mismatch"); + } + for (let i = 0; i < array.length; i++) { + const element = array[i]; + if (long_default.isLong(element)) { + data[i] = longToNumber(element, tensorProto.dataType); + } else { + data[i] = element; + } + } + } + return value; + } + /** + * Construct new Tensor from raw data + * @param data the raw data object. Should be a string array for 'string' tensor, and the corresponding typed array + * for other types of tensor. + * @param dims the dimensions of the tensor + * @param type the type of the tensor + */ + static fromData(data, dims, type) { + return new _Tensor(dims, type, void 0, void 0, data); + } + static fromOrtTensor(ortTensor) { + if (!ortTensor) { + throw new Error("cannot construct Value from an empty tensor"); + } + const dims = ProtoUtil.tensorDimsFromORTFormat(ortTensor); + const type = ProtoUtil.tensorDataTypeFromProto(ortTensor.dataType()); + const value = new _Tensor(dims, type); + if (type === "string") { + for (let i = 0; i < ortTensor.stringDataLength(); i++) { + value.data[i] = ortTensor.stringData(i); + } + } else if (ortTensor.rawDataArray() && typeof ortTensor.rawDataLength() === "number" && ortTensor.rawDataLength() > 0) { + const dataDest = value.data; + const dataSource = new DataView( + ortTensor.rawDataArray().buffer, + ortTensor.rawDataArray().byteOffset, + ortTensor.rawDataLength() + ); + const elementSize = sizeofProto(ortTensor.dataType()); + const length = ortTensor.rawDataLength() / elementSize; + if (ortTensor.rawDataLength() % elementSize !== 0) { + throw new Error("invalid buffer length"); + } + if (dataDest.length !== length) { + throw new Error("buffer length mismatch"); + } + for (let i = 0; i < length; i++) { + const n = readProto(dataSource, ortTensor.dataType(), i * elementSize); + dataDest[i] = n; + } + } + return value; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-source.ts +function getGlsl(version3) { + return version3 === 1 ? GLSL_ES_2_0 : GLSL_ES_3_0; +} +function getVertexShaderSource(version3) { + const glsl = getGlsl(version3); + return `${glsl.version} + precision highp float; + ${glsl.attribute} vec3 position; + ${glsl.attribute} vec2 textureCoord; + + ${glsl.varyingVertex} vec2 TexCoords; + + void main() + { + gl_Position = vec4(position, 1.0); + TexCoords = textureCoord; + }`; +} +function getFragShaderPreamble(version3) { + const glsl = getGlsl(version3); + return `${glsl.version} + precision highp float; + precision highp int; + precision highp sampler2D; + ${glsl.varyingFrag} vec2 TexCoords; + ${glsl.outputDeclaration} + const vec2 halfCR = vec2(0.5, 0.5); + + // Custom vector types to handle higher dimenalities. + struct ivec5 + { + int x; + int y; + int z; + int w; + int u; + }; + + struct ivec6 + { + int x; + int y; + int z; + int w; + int u; + int v; + }; + + int imod(int x, int y) { + return x - y * (x / y); + } + + `; +} +function getDefaultFragShaderMain(version3, outputShapeLength) { + const glsl = getGlsl(version3); + return ` + void main() { + int indices[${outputShapeLength}]; + toVec(TexCoords, indices); + vec4 result = vec4(process(indices)); + ${glsl.output} = result; + } + `; +} +var GLSL_ES_2_0, GLSL_ES_3_0; +var init_glsl_source = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-source.ts"() { + "use strict"; + GLSL_ES_2_0 = { + version: "", + attribute: "attribute", + varyingVertex: "varying", + varyingFrag: "varying", + texture2D: "texture2D", + output: "gl_FragColor", + outputDeclaration: "" + }; + GLSL_ES_3_0 = { + version: "#version 300 es", + attribute: "in", + varyingVertex: "out", + varyingFrag: "in", + texture2D: "texture", + output: "outputColor", + outputDeclaration: "out vec4 outputColor;" + }; + } +}); + +// web/lib/onnxjs/backends/webgl/types.ts +var init_types = __esm({ + "web/lib/onnxjs/backends/webgl/types.ts"() { + "use strict"; + } +}); + +// web/lib/onnxjs/backends/webgl/utils.ts +async function repeatedTry(checkFn, delayFn = (_counter) => 0, maxCounter) { + return new Promise((resolve, reject) => { + let tryCount = 0; + const tryFn = () => { + if (checkFn()) { + resolve(); + return; + } + tryCount++; + const nextBackoff = delayFn(tryCount); + if (maxCounter != null && tryCount >= maxCounter) { + reject(); + return; + } + setTimeout(tryFn, nextBackoff); + }; + tryFn(); + }); +} +function generateShaderFuncNameFromInputSamplerName(samplerName) { + assert(typeof samplerName !== "undefined" && samplerName.length !== 0, () => "empty string found for sampler name"); + return "get" + samplerName.charAt(0).toUpperCase() + samplerName.slice(1); +} +function generateShaderFuncNameFromInputSamplerNameAtOutCoords(samplerName) { + assert(typeof samplerName !== "undefined" && samplerName.length !== 0, () => "empty string found for sampler name"); + return "get" + samplerName.charAt(0).toUpperCase() + samplerName.slice(1) + "AtOutCoords"; +} +function squeezeInputShape(inputShape, squeezedShape) { + let newInputShape = JSON.parse(JSON.stringify(inputShape)); + newInputShape = squeezedShape; + return newInputShape; +} +function getSqueezedParams(params, keptDims) { + return keptDims.map((d) => params[d]).join(", "); +} +function getCoordsDataType(rank) { + if (rank <= 1) { + return "int"; + } else if (rank === 2) { + return "ivec2"; + } else if (rank === 3) { + return "ivec3"; + } else if (rank === 4) { + return "ivec4"; + } else if (rank === 5) { + return "ivec5"; + } else if (rank === 6) { + return "ivec6"; + } else { + throw Error(`GPU for rank ${rank} is not yet supported`); + } +} +function getGlChannels(rank = 6) { + return ["x", "y", "z", "w", "u", "v"].slice(0, rank); +} +var init_utils = __esm({ + "web/lib/onnxjs/backends/webgl/utils.ts"() { + "use strict"; + init_util(); + } +}); + +// web/lib/onnxjs/backends/webgl/ops/packing-utils.ts +function getVecChannels(name2, rank) { + return getGlChannels(rank).map((d) => `${name2}.${d}`); +} +function getChannels(name2, rank) { + if (rank === 1) { + return [name2]; + } + return getVecChannels(name2, rank); +} +function unpackFromChannel() { + return ` + float getChannel(vec4 frag, int dim) { + int modCoord = imod(dim, 2); + return modCoord == 0 ? frag.r : frag.g; + } + + float getChannel(vec4 frag, vec2 innerDims) { + vec2 modCoord = mod(innerDims, 2.); + return modCoord.x == 0. ? + (modCoord.y == 0. ? frag.r : frag.g) : + (modCoord.y == 0. ? frag.b : frag.a); + } + `; +} +var init_packing_utils = __esm({ + "web/lib/onnxjs/backends/webgl/ops/packing-utils.ts"() { + "use strict"; + init_utils(); + } +}); + +// web/lib/onnxjs/backends/webgl/ops/pack.ts +function getOutOfBoundsCondition(rank, shape2, dims) { + if (rank === 0) { + return "false"; + } + if (rank === 1) { + return `rc > ${shape2[0]}`; + } + let cond = ""; + for (let i = rank - 2; i < rank; i++) { + cond += `${dims[i]} >= ${shape2[i - rank + 2]}`; + if (i < rank - 1) { + cond += "||"; + } + } + return cond; +} +function getOutput(shape2, dims) { + const rank = shape2.length; + if (rank === 0) { + return "getA(), 0, 0, 0"; + } + if (rank === 1) { + return `getA(rc), + rc + 1 >= ${shape2[0]} ? 0. : getA(rc + 1), + 0, 0`; + } + const coord00 = "r, c"; + const coord01 = "r, cp1"; + const coord10 = "rp1, c"; + const coord11 = "rp1, cp1"; + let D = ""; + if (rank > 2) { + for (let i = 0; i < rank - 2; ++i) { + D = D + `${dims[i]},`; + } + } + return `getA(${D}${coord00}), + rEdge ? 0. : getA(${D}${coord10}), + cEdge ? 0. : getA(${D}${coord01}), + rEdge || cEdge ? 0. : getA(${D}${coord11})`; +} +function getSetup(rank, dims, rows, cols) { + if (rank === 0 || rank === 1) { + return ""; + } else { + const setup = ` + int r = ${dims[rank - 2]}; + int c = ${dims[rank - 1]}; + int rp1 = ${dims[rank - 2]} + 1; + int cp1 = ${dims[rank - 1]} + 1; + bool rEdge = rp1 >= ${cols}; + bool cEdge = cp1 >= ${rows}; + `; + return setup; + } +} +var packProgramMetadata, createPackProgramInfo, createPackProgramInfoLoader; +var init_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/pack.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + packProgramMetadata = { + name: "pack", + inputNames: ["A"], + inputTypes: [1 /* unpackedReversed */] + }; + createPackProgramInfo = (handler, input) => { + const glsl = getGlsl(handler.session.backend.glContext.version); + const inputShape = input.dims; + const inputRank = inputShape.length; + const outputRank = input.dims.length; + const coordsDataType = getCoordsDataType(outputRank); + const channels = getChannels("rc", outputRank); + const setup = getSetup(outputRank, channels, inputShape[inputShape.length - 2], inputShape[inputShape.length - 1]); + let reversedInputWH; + if (inputRank === 0) { + reversedInputWH = [1, 1]; + } else if (inputRank === 1) { + reversedInputWH = [inputShape[0], 1]; + } else { + reversedInputWH = [inputShape[outputRank - 1], inputShape[outputRank - 2]]; + } + const outOfBoundsCondition = getOutOfBoundsCondition(outputRank, reversedInputWH, channels); + const output = getOutput(inputShape, channels); + const shaderSource = ` + void main() { + ${coordsDataType} rc = getOutputCoords(); + + if(${outOfBoundsCondition}) { + ${glsl.output} = vec4(0); + } else { + ${setup} + + ${glsl.output} = vec4(${output}); + } + } + `; + return { + ...packProgramMetadata, + hasMain: true, + output: { dims: input.dims, type: input.type, textureType: 2 /* packed */ }, + shaderSource + }; + }; + createPackProgramInfoLoader = (handler, input) => ({ + ...packProgramMetadata, + get: () => createPackProgramInfo(handler, input) + }); + } +}); + +// web/lib/onnxjs/backends/webgl/ops/reshape-packed.ts +function processDims3D(shape2) { + if (shape2.length === 0) { + return [1, 1, 1]; + } + let batch = 1; + for (let i = 0; i < shape2.length - 2; ++i) { + batch *= shape2[i]; + } + return [batch, shape2.length > 1 ? shape2[shape2.length - 2] : 1, shape2[shape2.length - 1]]; +} +function isReshapeCheap(dims, reshapedDims) { + let isCheapReshape = false; + if (dims.length === 0 || reshapedDims.length === 0) { + isCheapReshape = true; + } else if (dims.length < 2 || reshapedDims.length < 2) { + isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1]; + } else { + isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1] && dims[dims.length - 2] === reshapedDims[reshapedDims.length - 2]; + } + return isCheapReshape; +} +function getReshapedInputCoords(shape2) { + const strides = ShapeUtil.computeStrides(shape2); + const coords = ["b", "r", "c"]; + const index = "index"; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coords[i]} = ${index} / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coords[i + 1]} = ${index} - ${coords[i]} * ${stride}` : `index -= ${coords[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + return ` + ivec3 inputCoordsFromReshapedOutCoords(int index) { + ${coordsFromIndexSnippet} + return ivec3(b, r, c); + } + `; +} +function getFlattenedIndexFrom3D(shape2) { + const strides = ShapeUtil.computeStrides(shape2); + return ` + int getFlattenedIndex(ivec3 coords) { + // reverse y, z order + return coords.x * ${strides[0]} + coords.z * ${strides[1]} + coords.y; + } +`; +} +var createPackedReshape3DProgramMetadata, createPackedReshape3DProgramInfo, createPackedReshape3DProgramInfoLoader; +var init_reshape_packed = __esm({ + "web/lib/onnxjs/backends/webgl/ops/reshape-packed.ts"() { + "use strict"; + init_util(); + init_glsl_source(); + init_types(); + init_packing_utils(); + createPackedReshape3DProgramMetadata = (outputShape3D) => ({ + name: "Reshape (packed)", + inputTypes: [2 /* packed */], + inputNames: ["A"], + cacheHint: `${outputShape3D}` + }); + createPackedReshape3DProgramInfo = (handler, input3D, metadata, outputShape3D) => { + const inputShape3D = input3D.dims; + const squeezedOutputShape = outputShape3D; + let mainLoop = ""; + for (let i = 0; i < 4; i++) { + let outputCoords = ""; + switch (i) { + case 0: + outputCoords = "outputCoords = rc;"; + break; + case 1: + outputCoords = "outputCoords = ivec3(rc.x, rc.y+1, rc.z);"; + break; + case 2: + outputCoords = "outputCoords = ivec3(rc.x, rc.y, rc.z+1);"; + break; + case 3: + outputCoords = "outputCoords = ivec3(rc.x, rc.y+1, rc.z+1);"; + break; + default: + throw new Error(); + } + mainLoop += ` + ${outputCoords} + ${i > 0 ? "if(outputCoords.y < rows && outputCoords.z < cols){" : ""} + int flattenedIndex = getFlattenedIndex(outputCoords); + + ivec3 inputRC = inputCoordsFromReshapedOutCoords(flattenedIndex); + vec2 innerDims = vec2(float(inputRC.y),float(inputRC.z)); + + result[${i}] = getChannel(getA(inputRC.x, inputRC.y, inputRC.z), innerDims); + + ${i > 0 ? "}" : ""} + `; + } + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${getReshapedInputCoords(inputShape3D)} + ${getFlattenedIndexFrom3D(squeezedOutputShape)} + ${unpackFromChannel()} + + void main() { + ivec3 rc = getOutputCoords(); + + vec4 result = vec4(0.0); + + ivec3 outputCoords; + int rows = ${squeezedOutputShape[2]}; + int cols = ${squeezedOutputShape[1]}; + + ${mainLoop} + ${glsl.output} = result; + } + `; + return { + ...metadata, + output: { dims: squeezedOutputShape, type: input3D.type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedReshape3DProgramInfoLoader = (handler, input3D, outputShape3D) => { + const metadata = createPackedReshape3DProgramMetadata(outputShape3D); + return { ...metadata, get: () => createPackedReshape3DProgramInfo(handler, input3D, metadata, outputShape3D) }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/uint8-encode.ts +var encodeAsUint8; +var init_uint8_encode = __esm({ + "web/lib/onnxjs/backends/webgl/ops/uint8-encode.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + encodeAsUint8 = (inferenceHandler, input) => { + const outputShape = input.shape; + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` + const float FLOAT_MAX = 1.70141184e38; + const float FLOAT_MIN = 1.17549435e-38; + + bool isNaN(float val) { + return (val < 1.0 || 0.0 < val || val == 0.0) ? false : true; + } + + highp vec4 encodeAsUint8(highp float v) { + if (isNaN(v)) { + return vec4(255, 255, 255, 255); + } + + highp float av = abs(v); + + if(av < FLOAT_MIN) { + return vec4(0.0, 0.0, 0.0, 0.0); + } else if(v > FLOAT_MAX) { + return vec4(0.0, 0.0, 128.0, 127.0) / 255.0; + } else if(v < -FLOAT_MAX) { + return vec4(0.0, 0.0, 128.0, 255.0) / 255.0; + } + + highp vec4 c = vec4(0,0,0,0); + + highp float e = floor(log2(av)); + highp float m = exp2(fract(log2(av))) - 1.0; + + c[2] = floor(128.0 * m); + m -= c[2] / 128.0; + c[1] = floor(32768.0 * m); + m -= c[1] / 32768.0; + c[0] = floor(8388608.0 * m); + + highp float ebias = e + 127.0; + c[3] = floor(ebias / 2.0); + ebias -= c[3] * 2.0; + c[2] += floor(ebias) * 128.0; + + c[3] += 128.0 * step(0.0, -v); + + return c / 255.0; + } + + void main() { + float value = ${glsl.texture2D}(X,TexCoords).r; + ${glsl.output} = encodeAsUint8(value); + }`; + const programInfo = { + name: "Uint8Encode", + inputTypes: [0 /* unpacked */], + inputNames: ["X"], + output: { dims: outputShape, type: input.tensor.type, textureType: 3 /* downloadUint8AsFloat */ }, + shaderSource, + hasMain: true + }; + return inferenceHandler.executeProgram(programInfo, [input.tensor]); + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/unpack.ts +function getSourceCoords(rank, dims) { + if (rank === 1) { + return "rc"; + } + let coords = ""; + for (let i = 0; i < rank; i++) { + coords += dims[i]; + if (i < rank - 1) { + coords += ","; + } + } + return coords; +} +var unpackProgramMetadata, createUnpackProgramInfo, createUnpackProgramInfoLoader; +var init_unpack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/unpack.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + unpackProgramMetadata = { + name: "unpack", + inputNames: ["A"], + inputTypes: [2 /* packed */] + }; + createUnpackProgramInfo = (handler, input) => { + const rank = input.dims.length; + const channels = getChannels("rc", rank); + const innerDims = channels.slice(-2); + const coordsDataType = getCoordsDataType(rank); + const unpackChannel = unpackFromChannel(); + const isScalar = input.dims.length === 0; + const sourceCoords = isScalar ? "" : getSourceCoords(rank, channels); + const coords = rank <= 1 ? "rc" : `vec2(${innerDims.join(",")})`; + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${unpackChannel} + void main() { + ${coordsDataType} rc = getOutputCoords(); + + // Sample the texture with the coords to get the rgba channel value. + vec4 packedInput = getA(${sourceCoords}); + + ${glsl.output} = vec4(getChannel(packedInput, ${coords}), 0, 0, 0); + } + `; + return { + ...unpackProgramMetadata, + hasMain: true, + output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createUnpackProgramInfoLoader = (handler, input) => ({ + ...unpackProgramMetadata, + get: () => createUnpackProgramInfo(handler, input) + }); + } +}); + +// web/lib/onnxjs/backends/webgl/texture-data-encoder.ts +var RedFloat32DataEncoder, RGBAFloatDataEncoder, Uint8DataEncoder; +var init_texture_data_encoder = __esm({ + "web/lib/onnxjs/backends/webgl/texture-data-encoder.ts"() { + "use strict"; + init_instrument(); + RedFloat32DataEncoder = class { + constructor(gl, channels = 1) { + if (channels === 1) { + this.internalFormat = gl.R32F; + this.format = gl.RED; + this.textureType = gl.FLOAT; + this.channelSize = channels; + } else if (channels === 4) { + this.internalFormat = gl.RGBA32F; + this.format = gl.RGBA; + this.textureType = gl.FLOAT; + this.channelSize = channels; + } else { + throw new Error(`Invalid number of channels: ${channels}`); + } + } + encode(src, textureSize) { + let result; + let source; + if (src.constructor !== Float32Array) { + Logger.warning("Encoder", "data was not of type Float32; creating new Float32Array"); + source = new Float32Array(src); + } + if (textureSize * this.channelSize > src.length) { + Logger.warning("Encoder", "Source data too small. Allocating larger array"); + source = src; + result = this.allocate(textureSize * this.channelSize); + source.forEach((v, i) => result[i] = v); + } else { + source = src; + result = source; + } + return result; + } + allocate(size) { + return new Float32Array(size * 4); + } + decode(buffer, dataSize) { + if (this.channelSize === 1) { + const filteredData = buffer.filter((_value, index) => index % 4 === 0).subarray(0, dataSize); + return filteredData; + } + return buffer.subarray(0, dataSize); + } + }; + RGBAFloatDataEncoder = class { + constructor(gl, channels = 1, textureType) { + if (channels !== 1 && channels !== 4) { + throw new Error(`Invalid number of channels: ${channels}`); + } + this.internalFormat = gl.RGBA; + this.format = gl.RGBA; + this.channelSize = channels; + this.textureType = textureType || gl.FLOAT; + } + encode(src, textureSize) { + let dest = src; + if (this.channelSize === 1) { + Logger.verbose("Encoder", "Exploding into a larger array"); + dest = this.allocate(textureSize); + src.forEach((v, i) => dest[i * 4] = v); + } + return dest; + } + allocate(size) { + return new Float32Array(size * 4); + } + decode(buffer, dataSize) { + if (this.channelSize === 1) { + const filteredData = buffer.filter((_value, index) => index % 4 === 0).subarray(0, dataSize); + return filteredData; + } + return buffer.subarray(0, dataSize); + } + }; + Uint8DataEncoder = class { + constructor(gl, channels = 1) { + this.channelSize = 4; + if (channels === 1) { + this.internalFormat = gl.ALPHA; + this.format = gl.ALPHA; + this.textureType = gl.UNSIGNED_BYTE; + this.channelSize = channels; + } else if (channels === 4) { + this.internalFormat = gl.RGBA; + this.format = gl.RGBA; + this.textureType = gl.UNSIGNED_BYTE; + this.channelSize = channels; + } else { + throw new Error(`Invalid number of channels: ${channels}`); + } + } + encode(src, _textureSize) { + return new Uint8Array(src.buffer, src.byteOffset, src.byteLength); + } + allocate(size) { + return new Uint8Array(size * this.channelSize); + } + decode(buffer, dataSize) { + if (buffer instanceof Uint8Array) { + return buffer.subarray(0, dataSize); + } + throw new Error(`Invalid array type: ${buffer.constructor}`); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/texture-layout.ts +var createTextureLayoutFromTextureType, calculateTextureWidthAndHeight, createTextureLayoutFromShape; +var init_texture_layout = __esm({ + "web/lib/onnxjs/backends/webgl/texture-layout.ts"() { + "use strict"; + init_util(); + init_types(); + createTextureLayoutFromTextureType = (textureLayoutStrategy, shape2, textureType) => { + const channel = textureType === 0 /* unpacked */ || textureType === 1 /* unpackedReversed */ ? 1 : 4; + const isPacked = textureType === 2 /* packed */; + const reverseWH = textureType === 1 /* unpackedReversed */ || textureType === 2 /* packed */; + const breakAxis = textureType === 4 /* packedLastDimension */ ? shape2.length - 1 : void 0; + const unpackedShape = textureType === 4 /* packedLastDimension */ ? shape2.map((d, i) => i === shape2.length - 1 ? d * 4 : d) : void 0; + return createTextureLayoutFromShape(textureLayoutStrategy, shape2, channel, unpackedShape, { + isPacked, + reverseWH, + breakAxis + }); + }; + calculateTextureWidthAndHeight = (textureLayoutStrategy, shape2, textureType) => { + const layout = createTextureLayoutFromTextureType(textureLayoutStrategy, shape2, textureType); + return [layout.width, layout.height]; + }; + createTextureLayoutFromShape = (textureLayoutStrategy, shape2, channels = 1, unpackedShape, prefs) => { + const isPacked = !!(prefs && prefs.isPacked); + const [width, height] = textureLayoutStrategy.computeTextureWH(isPacked ? unpackedShape || shape2 : shape2, prefs); + const rank = shape2.length; + let inferredDims = shape2.slice(0); + if (rank === 0) { + inferredDims = [1]; + } + if (channels === 1) { + unpackedShape = shape2; + } else if (isPacked) { + if (channels !== 4) { + throw new Error("a packed texture must be 4-channel"); + } + unpackedShape = shape2; + if (rank > 0) { + inferredDims[rank - 1] = Math.ceil(inferredDims[rank - 1] / 2); + } + if (rank > 1) { + inferredDims[rank - 2] = Math.ceil(inferredDims[rank - 2] / 2); + } + } else if (!unpackedShape) { + throw new Error("Unpacked shape is needed when using channels > 1"); + } + return { + width, + height, + channels, + isPacked, + shape: inferredDims, + strides: ShapeUtil.computeStrides(inferredDims), + unpackedShape, + reversedWH: prefs && prefs.reverseWH + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/inference-handler.ts +var getProgramInfoUniqueKey, WebGLInferenceHandler; +var init_inference_handler = __esm({ + "web/lib/onnxjs/backends/webgl/inference-handler.ts"() { + "use strict"; + init_instrument(); + init_tensor2(); + init_util(); + init_pack(); + init_reshape_packed(); + init_uint8_encode(); + init_unpack(); + init_texture_data_encoder(); + init_texture_layout(); + init_types(); + getProgramInfoUniqueKey = (programInfo, inputTextureDatas) => { + const inputs = inputTextureDatas.map((texture) => `${texture.unpackedShape.join(",")};${texture.width}x${texture.height}`).join("_"); + let key = programInfo.name; + if (programInfo.cacheHint) { + key += "[" + programInfo.cacheHint + "]"; + } + key += ":" + inputs; + return key; + }; + WebGLInferenceHandler = class { + constructor(session) { + this.session = session; + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + } + /** + * @returns [width, height] + */ + calculateTextureWidthAndHeight(shape2, textureType) { + return calculateTextureWidthAndHeight(this.session.layoutStrategy, shape2, textureType); + } + executeProgram(program, inputs) { + if (inputs.length < program.inputNames.length) { + throw new Error(`Input size mustn't be less than ${program.inputNames.length}.`); + } + if (program.inputNames.length !== program.inputTypes.length) { + throw new Error("input names size does not match input types"); + } + const inputTextureDatas = []; + for (let i = 0; i < program.inputNames.length; ++i) { + inputTextureDatas[i] = this.getOrCreateTextureData(inputs[i], program.inputTypes[i]); + } + const key = getProgramInfoUniqueKey(program, inputTextureDatas); + let artifact = this.session.programManager.getArtifact(key); + const programInfo = artifact ? artifact.programInfo : typeof program.get === "function" ? program.get() : program; + const outputTextureLayout = createTextureLayoutFromTextureType( + this.session.layoutStrategy, + programInfo.output.dims, + programInfo.output.textureType + ); + const outputTextureData = this.createTextureData(outputTextureLayout, programInfo.output.type); + if (!artifact) { + artifact = this.session.programManager.build(programInfo, inputTextureDatas, outputTextureData); + this.session.programManager.setArtifact(key, artifact); + } + this.runProgram(artifact, inputTextureDatas, outputTextureData); + return outputTextureData; + } + run(program, inputs) { + const outputTextureData = this.executeProgram(program, inputs); + return outputTextureData.tensor; + } + runProgram(artifact, inputs, output) { + for (let i = 0; i < inputs.length; ++i) { + if (!!inputs[i].isPacked !== (artifact.programInfo.inputTypes[i] === 2 /* packed */)) { + throw new Error(`input[${i}] property packed inconsistent`); + } + } + if (!!output.isPacked !== (artifact.programInfo.output.textureType === 2 /* packed */)) { + throw new Error("output property packed inconsistent"); + } + this.session.programManager.run(artifact, inputs, output); + } + /** + * Create a TextureData object from a tensor. + * Usage = EncoderUsage.UploadOnly. + * If a related texture data is found in cache, returns it; + * Otherwise: + * Creates a new texture layout if not provided; + * Creates WebGLTexture with the layout; + * Upload tensor data to the texture; + * Creates a texture data object associated with the given tensor. + * @param tensor the tensor with data to upload + */ + getOrCreateTextureData(tensor, textureType) { + let td = this.getTextureData(tensor.dataId, textureType === 2 /* packed */); + if (!td) { + td = this.getTextureData(tensor.dataId, textureType !== 2 /* packed */); + if (td) { + if (textureType === 2 /* packed */) { + return this.pack(td); + } else { + return this.unpack(td); + } + } + } + if (!td) { + const layout = createTextureLayoutFromTextureType(this.session.layoutStrategy, tensor.dims, textureType); + if (textureType === 4 /* packedLastDimension */) { + const group = 1; + const channels = 4; + const shape2 = tensor.dims; + if (shape2.length === 4) { + const adjustedKernelShape = [shape2[0], Math.ceil(shape2[1] * shape2[2] * shape2[3] / channels)]; + const adjustedLayout = createTextureLayoutFromTextureType( + this.session.layoutStrategy, + adjustedKernelShape, + textureType + ); + let buffer = tensor.numberData; + if (shape2[1] * shape2[2] * shape2[3] % channels !== 0) { + const numFeatureMaps = shape2[0]; + const oldRowSize = shape2[1] * shape2[2] * shape2[3]; + const newRowSize = Math.ceil(oldRowSize * group / channels) * channels; + const newSize = numFeatureMaps * newRowSize; + buffer = new Float32Array(newSize); + for (let f = 0; f < numFeatureMaps; ++f) { + const oldOffset = f * oldRowSize; + const newOffset = f * newRowSize + f % group * oldRowSize; + buffer.set(tensor.numberData.subarray(oldOffset, oldOffset + oldRowSize), newOffset); + } + } + return this.createTextureData(adjustedLayout, tensor.type, buffer, tensor, 1 /* UploadOnly */); + } + } + if (textureType === 2 /* packed */) { + const unpackedTextureLayout = createTextureLayoutFromShape(this.session.layoutStrategy, tensor.dims, 1, [], { + reverseWH: true + }); + const unpackedTextureData = this.createTextureData( + unpackedTextureLayout, + tensor.type, + tensor.numberData, + tensor, + 1 /* UploadOnly */ + ); + td = this.pack(unpackedTextureData); + } else { + td = this.createTextureData(layout, tensor.type, tensor.numberData, tensor, 1 /* UploadOnly */); + } + } + return td; + } + /** + * Create a TextureData object using the given data and bind to the given tensor. + * Usage = EncoderUsage.UploadOnly. + * NOTE: this function is a hack for Conv implementation. should remove this function, after rewriting Conv + * implementation by Graph.Transformer + * @param dataType the tensor data type + * @param data the actual data to upload + * @param tensor the tensor to bind. tensor's data is ignored. + */ + createTextureDataFromLayoutBindTensor(layout, dataType, data, tensor) { + return this.createTextureData(layout, dataType, data, tensor, 1 /* UploadOnly */); + } + createTextureData(layout, dataType, data, tensor, usage) { + Logger.verbose("InferenceHandler", `Creating TextureData: layout:[${JSON.stringify(layout)}]`); + const texture = this.session.textureManager.createTextureFromLayout(dataType, layout, data, usage); + return this.createTextureDataFromTexture(layout, dataType, texture, tensor); + } + reshapeUnpacked(input, reshapedDims) { + const inputTD = this.getOrCreateTextureData(input, 0 /* unpacked */); + const newTextureLayout = { + channels: inputTD.channels, + height: inputTD.height, + width: inputTD.width, + // handle reshaping into scalar Tensors + shape: reshapedDims.length !== 0 ? reshapedDims : [1], + strides: ShapeUtil.computeStrides(reshapedDims), + unpackedShape: reshapedDims + }; + const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture); + return newTextureData.tensor; + } + reshapePacked(input, reshapedDims) { + const inputTD = this.getOrCreateTextureData(input, 2 /* packed */); + if (isReshapeCheap(input.dims, reshapedDims)) { + const newTextureLayout = { + channels: inputTD.channels, + height: inputTD.height, + width: inputTD.width, + // handle reshaping into scalar Tensors + shape: reshapedDims.length !== 0 ? reshapedDims : [1], + strides: ShapeUtil.computeStrides(reshapedDims), + unpackedShape: reshapedDims, + isPacked: true + }; + const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture); + return newTextureData.tensor; + } + const squeezedInputShape = processDims3D(input.dims); + const squeezedOutputShape = processDims3D(reshapedDims); + const squeezedInputTensor = this.reshapePacked(input, squeezedInputShape); + const squeezedOutputTensor = this.run( + createPackedReshape3DProgramInfoLoader(this, squeezedInputTensor, squeezedOutputShape), + [squeezedInputTensor] + ); + const outputTensor = this.reshapePacked(squeezedOutputTensor, reshapedDims); + return outputTensor; + } + cast(input, type) { + const inputTD = this.getOrCreateTextureData(input, 0 /* unpacked */); + const newTextureData = this.createTextureDataFromTexture(inputTD, type, inputTD.texture); + return newTextureData.tensor; + } + createTextureDataFromTexture(layout, dataType, texture, tensor, tensorId) { + const textureData = { + ...layout, + tensor: tensor || new Tensor4( + layout.unpackedShape, + dataType, + (_id) => this.readTexture(textureData), + async (_id) => this.readTextureAsync(textureData), + void 0, + tensorId + ), + texture + }; + this.setTextureData(textureData.tensor.dataId, textureData, layout.isPacked); + return textureData; + } + getTextureData(tensorId, isPacked = false) { + return this.session.isInitializer(tensorId) ? this.session.getTextureData(tensorId, isPacked) : isPacked ? this.packedTextureDataCache.get(tensorId) : this.unpackedTextureDataCache.get(tensorId); + } + setTextureData(tensorId, td, isPacked = false) { + if (this.session.isInitializer(tensorId)) { + this.session.setTextureData(tensorId, td, isPacked); + } else { + (isPacked ? this.packedTextureDataCache : this.unpackedTextureDataCache).set(tensorId, td); + } + } + isTextureLayoutCached(tensor, isPacked = false) { + return !!this.getTextureData(tensor.dataId, isPacked); + } + dispose() { + this.session.textureManager.clearActiveTextures(); + this.packedTextureDataCache.forEach((td) => this.session.textureManager.releaseTexture(td)); + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache.forEach((td) => this.session.textureManager.releaseTexture(td)); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + } + readTexture(textureData) { + if (textureData.isPacked) { + return this.readTexture(this.unpack(textureData)); + } + if (!this.session.backend.glContext.isFloat32DownloadSupported) { + return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData)); + } + return this.session.textureManager.readTexture(textureData, textureData.tensor.type, textureData.channels); + } + async readTextureAsync(textureData) { + if (textureData.isPacked) { + return this.readTextureAsync(this.unpack(textureData)); + } + if (!this.session.backend.glContext.isFloat32DownloadSupported) { + return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData)); + } + return this.session.textureManager.readTextureAsync(textureData, textureData.tensor.type, textureData.channels); + } + pack(input) { + const outputTextureData = this.executeProgram(createPackProgramInfoLoader(this, input.tensor), [input.tensor]); + return outputTextureData; + } + unpack(input) { + const outputTextureData = this.executeProgram(createUnpackProgramInfoLoader(this, input.tensor), [input.tensor]); + return outputTextureData; + } + }; + } +}); + +// web/lib/onnxjs/attribute-with-cache-key.ts +var AttributeWithCacheKeyImpl, createAttributeWithCacheKey; +var init_attribute_with_cache_key = __esm({ + "web/lib/onnxjs/attribute-with-cache-key.ts"() { + "use strict"; + AttributeWithCacheKeyImpl = class { + constructor(attribute) { + Object.assign(this, attribute); + } + get cacheKey() { + if (!this.key) { + this.key = Object.getOwnPropertyNames(this).sort().map((name2) => `${this[name2]}`).join(";"); + } + return this.key; + } + }; + createAttributeWithCacheKey = (attribute) => new AttributeWithCacheKeyImpl(attribute); + } +}); + +// web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts +var batchNormalizationProgramMetadata, batchNormalization, parseBatchNormalizationAttributes, createBatchNormalizationProgramInfo, validateInputs; +var init_batch_normalization = __esm({ + "web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_glsl_source(); + init_types(); + batchNormalizationProgramMetadata = { + name: "BatchNormalization", + inputNames: ["A", "Scale", "B", "Mean", "Variance"], + inputTypes: [ + 0 /* unpacked */, + 0 /* unpacked */, + 0 /* unpacked */, + 0 /* unpacked */, + 0 /* unpacked */ + ] + }; + batchNormalization = (inferenceHandler, inputs, attributes) => { + validateInputs(inputs); + const output = inferenceHandler.run( + { + ...batchNormalizationProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createBatchNormalizationProgramInfo(inferenceHandler, inputs, attributes) + }, + inputs + ); + return [output]; + }; + parseBatchNormalizationAttributes = (node) => { + const epsilon = node.attributes.getFloat("epsilon", 1e-5); + const momentum = node.attributes.getFloat("momentum", 0.9); + const spatial = node.attributes.getInt("spatial", 1); + return createAttributeWithCacheKey({ epsilon, momentum, spatial }); + }; + createBatchNormalizationProgramInfo = (inferenceHandler, inputs, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const rank = inputs[0].dims.length; + const [scaleWidth, scaleHeight] = inferenceHandler.calculateTextureWidthAndHeight( + inputs[1].dims, + 0 /* unpacked */ + ); + const shaderSource = ` + float process(int[${rank}] indices) { + vec2 position = offsetToCoords(indices[1], ${scaleWidth}, ${scaleHeight}); + float scale = getColorAsFloat(${glsl.texture2D}(Scale, position)); + float mean = getColorAsFloat(${glsl.texture2D}(Mean, position)); + float variance = getColorAsFloat(${glsl.texture2D}(Variance, position)); + float b = getColorAsFloat(${glsl.texture2D}(B, position)); + + return scale * ( (_A(indices) - mean) / sqrt(variance + float(${attributes.epsilon})) ) + b; + }`; + return { + ...batchNormalizationProgramMetadata, + output: { dims: inputs[0].dims, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs = (inputs) => { + if (!inputs || inputs.length !== 5) { + throw new Error("BatchNormalization requires 5 inputs."); + } + const X = inputs[0]; + const scale = inputs[1]; + const B = inputs[2]; + const mean = inputs[3]; + const var_ = inputs[4]; + if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1 || mean.dims.length !== 1 || var_.dims.length !== 1) { + throw new Error("invalid input shape."); + } + if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1] || mean.dims[0] !== X.dims[1] || var_.dims[0] !== X.dims[1]) { + throw new Error("invalid input shape."); + } + if (X.type !== "float32" && X.type !== "float64" || scale.type !== "float32" && scale.type !== "float64" || B.type !== "float32" && B.type !== "float64" || mean.type !== "float32" && mean.type !== "float64" || var_.type !== "float32" && var_.type !== "float64") { + throw new Error("invalid input tensor types."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-definitions.ts +var GlslContext, GlslLib, GlslLibRoutine, GlslLibRoutineNode, TopologicalSortGlslRoutines; +var init_glsl_definitions = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-definitions.ts"() { + "use strict"; + GlslContext = class { + constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) { + this.glContext = glContext; + this.programInfo = programInfo; + this.inputTextureLayouts = inputTextureLayouts; + this.outputTextureLayout = outputTextureLayout; + } + }; + GlslLib = class { + constructor(context) { + this.context = context; + } + }; + GlslLibRoutine = class { + constructor(routineBody, dependencies) { + this.routineBody = routineBody; + this.dependencies = dependencies; + } + }; + GlslLibRoutineNode = class { + constructor(name2, routineBody, dependencies) { + this.name = name2; + if (dependencies) { + this.dependencies = dependencies; + } else { + this.dependencies = []; + } + if (routineBody) { + this.routineBody = routineBody; + } + } + addDependency(node) { + if (node) { + this.dependencies.push(node); + } + } + }; + TopologicalSortGlslRoutines = class { + static returnOrderedNodes(nodes) { + if (!nodes || nodes.length === 0) { + return []; + } + if (nodes.length === 1) { + return nodes; + } + const cycleCheck = /* @__PURE__ */ new Set(); + const alreadyTraversed = /* @__PURE__ */ new Set(); + const result = new Array(); + this.createOrderedNodes(nodes, cycleCheck, alreadyTraversed, result); + return result; + } + static createOrderedNodes(graphNodes, cycleCheck, alreadyTraversed, result) { + for (let i = 0; i < graphNodes.length; ++i) { + this.dfsTraverse(graphNodes[i], cycleCheck, alreadyTraversed, result); + } + } + static dfsTraverse(root, cycleCheck, alreadyTraversed, result) { + if (!root || alreadyTraversed.has(root.name)) { + return; + } + if (cycleCheck.has(root.name)) { + throw new Error("Cyclic dependency detected. Can't topologically sort routines needed for shader."); + } + cycleCheck.add(root.name); + const dependencies = root.dependencies; + if (dependencies && dependencies.length > 0) { + for (let i = 0; i < dependencies.length; ++i) { + this.dfsTraverse(dependencies[i], cycleCheck, alreadyTraversed, result); + } + } + result.push(root); + alreadyTraversed.add(root.name); + cycleCheck.delete(root.name); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/binary-op.ts +function glslAdd() { + const name2 = "add_"; + const body = ` + float ${name2}(float a, float b) { + return a + b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 + v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslDiv() { + const name2 = "div_"; + const body = ` + float ${name2}(float a, float b) { + return a / b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 / v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslMul() { + const name2 = "mul_"; + const body = ` + float ${name2}(float a, float b) { + return a * b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 * v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslSub() { + const name2 = "sub_"; + const body = ` + float ${name2}(float a, float b) { + return a - b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 - v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslEqual() { + const name2 = "equal_"; + const body = ` + float ${name2}(float a, float b) { + return float(a == b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4(equal(v1, v2)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslGreater() { + const name2 = "greater_"; + const body = ` + float ${name2}(float a, float b) { + return float(a > b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4( v1.r > v2.r , + v1.g > v2.g, + v1.b > v2.b, + v1.a > v2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslLess() { + const name2 = "less_"; + const body = ` + float ${name2}(float a, float b) { + return float(a < b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4( v1.r < v2.r , + v1.g < v2.g, + v1.b < v2.b, + v1.a < v2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslAnd() { + const name2 = "and_"; + const body = ` + float ${name2}(float a, float b) { + return float( bool(a) && bool(b) ); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + bvec4 b1 = bvec4(v1); + bvec4 b2 = bvec4(v2); + return vec4( b1.r && b2.r , + b1.g && b2.g, + b1.b && b2.b, + b1.a && b2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslOr() { + const name2 = "or_"; + const body = ` + float ${name2}(float a, float b) { + return float( bool(a) || bool(b) ); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + bvec4 b1 = bvec4(v1); + bvec4 b2 = bvec4(v2); + return vec4( b1.r || b2.r , + b1.g || b2.g, + b1.b || b2.b, + b1.a || b2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslXor() { + const name2 = "xor_"; + const body = ` + float ${name2}(float a, float b) { + return float( bool(a) ^^ bool(b) ); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + bvec4 b1 = bvec4(v1); + bvec4 b2 = bvec4(v2); + return vec4( b1.r ^^ b2.r , + b1.g ^^ b2.g, + b1.b ^^ b2.b, + b1.a ^^ b2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslPow() { + return glslBuiltinBinary("pow"); +} +function glslPRelu() { + const name2 = "prelu_"; + const body = ` + float ${name2}(float a, float b) { + return a < 0.0 ? a * b: a; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4( + v1.r < 0.0 ? v1.r * v2.r: v1.r, + v1.g < 0.0 ? v1.g * v2.g: v1.g, + v1.b < 0.0 ? v1.b * v2.b: v1.b, + v1.a < 0.0 ? v1.a * v2.a: v1.a + ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslBuiltinBinary(fname) { + const name2 = `${fname}_`; + const body = ` + float ${name2}(float a, float b) { + return ${fname}(a, b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return ${fname}(v1, v2); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +var createBinaryProgramInfoLoader, createBinaryProgramInfo, add2, and2, div, equal, greater, less, mul, or2, pow, pRelu, sub, xor2; +var init_binary_op = __esm({ + "web/lib/onnxjs/backends/webgl/ops/binary-op.ts"() { + "use strict"; + init_util(); + init_glsl_definitions(); + init_glsl_source(); + init_types(); + createBinaryProgramInfoLoader = (handler, inputs, glslFunc, outputTensorType = inputs[0].type, cacheKey) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + return { + name: glslFunc.name, + inputNames: ["A", "B"], + inputTypes: [textureType, textureType], + cacheHint: cacheKey, + get: () => createBinaryProgramInfo(handler, inputs, glslFunc, outputTensorType) + }; + }; + createBinaryProgramInfo = (handler, inputs, glslFunc, outputTensorType = inputs[0].type) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims); + let outputShape = inputs[0].dims; + const usePackedTexture = handler.session.pack; + if (isBroadcast) { + const calculatedShape = BroadcastUtil.calcShape(inputs[0].dims, inputs[1].dims, false); + if (!calculatedShape) { + throw new Error("Can't perform binary op on the given tensors"); + } + outputShape = calculatedShape; + const outputRank = outputShape.length; + const aRank = inputs[0].dims.length !== 0 ? inputs[0].dims.length : 1; + const bRank = inputs[1].dims.length !== 0 ? inputs[1].dims.length : 1; + const aBcast = inputs[0].dims.length !== 0 ? "bcastIndices_A(indices, aindices);" : "aindices[0] = 0;"; + const bBcast = inputs[1].dims.length !== 0 ? "bcastIndices_B(indices, bindices);" : "bindices[0] = 0;"; + const glsl2 = getGlsl(handler.session.backend.glContext.version); + const shaderSource2 = usePackedTexture ? ` + ${glslFunc.body} + void main() { + vec4 a = getAAtOutCoords(); + vec4 b = getBAtOutCoords(); + vec4 result = ${glslFunc.name}(a, b); + ${glsl2.output} = result; + }` : ` + ${glslFunc.body} + float process(int indices[${outputRank}]) { + int aindices[${aRank}]; + int bindices[${bRank}]; + ${aBcast} + ${bBcast} + return ${glslFunc.name}(_A(aindices), _B(bindices)); + }`; + return { + name: glslFunc.name, + inputNames: ["A", "B"], + inputTypes: [textureType, textureType], + output: { dims: outputShape, type: outputTensorType, textureType }, + shaderSource: shaderSource2, + hasMain: usePackedTexture + }; + } + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${glslFunc.body} + void main() { + vec4 v1 = ${glsl.texture2D}(A, TexCoords); + vec4 v2 = ${glsl.texture2D}(B, TexCoords); + vec4 result = ${glslFunc.name}(v1, v2); + ${glsl.output} = result; + } + `; + return { + name: glslFunc.name, + inputNames: ["A", "B"], + inputTypes: [textureType, textureType], + output: { dims: inputs[0].dims, type: outputTensorType, textureType }, + shaderSource, + hasMain: true + }; + }; + add2 = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAdd()), inputs) + ]; + and2 = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAnd(), "bool"), inputs) + ]; + div = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslDiv()), inputs) + ]; + equal = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslEqual(), "bool"), inputs) + ]; + greater = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslGreater(), "bool"), inputs) + ]; + less = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslLess(), "bool"), inputs) + ]; + mul = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslMul()), inputs) + ]; + or2 = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslOr(), "bool"), inputs) + ]; + pow = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPow()), inputs) + ]; + pRelu = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPRelu()), inputs) + ]; + sub = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslSub()), inputs) + ]; + xor2 = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslXor(), "bool"), inputs) + ]; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/cast.ts +var cast, parseCastAttributes, validateInputs2; +var init_cast = __esm({ + "web/lib/onnxjs/backends/webgl/ops/cast.ts"() { + "use strict"; + init_util(); + cast = (handler, inputs, to) => { + validateInputs2(inputs); + return [handler.cast(inputs[0], to)]; + }; + parseCastAttributes = (node) => ProtoUtil.tensorDataTypeFromProto(node.attributes.getInt("to")); + validateInputs2 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Cast requires 1 input."); + } + if (inputs[0].type === "string") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/concat-packed.ts +var createPackedConcatProgramMetadata, createPackedConcatProgramInfo, createPackedConcatProgramInfoLoader, getShiftedChannelsSnippet; +var init_concat_packed = __esm({ + "web/lib/onnxjs/backends/webgl/ops/concat-packed.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + createPackedConcatProgramMetadata = (inputCount, cacheHint) => ({ + name: "Concat (packed)", + inputNames: Array.from({ length: inputCount }, (_v, i) => `X${i}`), + inputTypes: Array(inputCount).fill(2 /* packed */), + cacheHint + }); + createPackedConcatProgramInfo = (handler, metadata, inputs, axis) => { + const inputShape = inputs[0].dims.slice(); + if (axis >= inputShape.length || axis < -1 * inputShape.length) { + throw new Error("axis specified for concat doesn't match input dimensionality"); + } + if (axis < 0) { + axis = inputShape.length + axis; + } + const outputShape = inputShape.slice(0); + for (let i = 1; i < inputs.length; i++) { + const dataNShape = inputs[i].dims.slice(); + for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) { + if (axisIndex === axis) { + outputShape[axis] += dataNShape[axisIndex]; + } else if (inputShape[axisIndex] !== dataNShape[axisIndex]) { + throw new Error("non concat dimensions must match"); + } + } + } + const rank = outputShape.length; + const coords = getChannels("coords", rank); + const dtype = getCoordsDataType(rank); + const unpackChannel = unpackFromChannel(); + const shapes = inputs.map((i) => i.dims); + const channels = getGlChannels(rank); + const offsets = new Array(shapes.length - 1); + offsets[0] = shapes[0][axis]; + for (let i = 1; i < offsets.length; i++) { + offsets[i] = offsets[i - 1] + shapes[i][axis]; + } + const channel = channels[axis]; + const lastChannels = channels.slice(-2); + const allChannels = channels.join(); + let getValueSnippet = `if (${channel} < ${offsets[0]}) { + return getChannel( + getX0(${allChannels}), vec2(${lastChannels.join()})); + }`; + for (let i = 1; i < offsets.length; i++) { + const shift2 = offsets[i - 1]; + getValueSnippet += ` + if (${channel} < ${offsets[i]} && ${channel} >= ${offsets[i - 1]}) { + return getChannel( + getX${i}(${getShiftedChannelsSnippet(channels, channel, shift2)}), + vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift2)})); + }`; + } + const lastIndex = offsets.length; + const shift = offsets[offsets.length - 1]; + getValueSnippet += ` + return getChannel( + getX${lastIndex}(${getShiftedChannelsSnippet(channels, channel, shift)}), + vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));`; + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${unpackChannel} + float getValue(${channels.map((x) => "int " + x)}) { + ${getValueSnippet} + } + + void main() { + ${dtype} coords = getOutputCoords(); + int lastDim = coords.${channels[rank - 1]}; + coords.${channels[rank - 1]} = coords.${channels[rank - 2]}; + coords.${channels[rank - 2]} = lastDim; + + vec4 result = vec4(getValue(${coords}), 0., 0., 0.); + + ${coords[rank - 1]} = ${coords[rank - 1]} + 1; + if (${coords[rank - 1]} < ${outputShape[rank - 1]}) { + result.g = getValue(${coords}); + } + + ${coords[rank - 2]} = ${coords[rank - 2]} + 1; + if (${coords[rank - 2]} < ${outputShape[rank - 2]}) { + result.a = getValue(${coords}); + } + + ${coords[rank - 1]} = ${coords[rank - 1]} - 1; + if (${coords[rank - 2]} < ${outputShape[rank - 2]} && + ${coords[rank - 1]} < ${outputShape[rank - 1]}) { + result.b = getValue(${coords}); + } + ${glsl.output} = result; + } + `; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedConcatProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = createPackedConcatProgramMetadata(inputs.length, attributes.cacheKey); + return { ...metadata, get: () => createPackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) }; + }; + getShiftedChannelsSnippet = (channels, channel, shift) => { + const channelIdx = channels.indexOf(channel); + const res = channels.map((c, idx) => { + if (idx === channelIdx) { + return `${c} - ${shift}`; + } else { + return c; + } + }); + return res.join(); + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/concat.ts +var concat, createUnpackedConcatProgramMetadata, createUnpackedConcatProgramInfo, createUnpackedConcatProgramInfoLoader, getTextureIndexWhereDataResidesLinearSearch, getTextureIndexWhereDataResidesBinarySearch, getFetchDataFromCorrectTextureMethod, getGetSizeInConcatAxisValueFromIndexMethod, parseConcatAttributes, validateInputs3; +var init_concat = __esm({ + "web/lib/onnxjs/backends/webgl/ops/concat.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_types(); + init_concat_packed(); + concat = (inferenceHandler, inputs, attributes) => { + validateInputs3(inputs); + if (inferenceHandler.session.pack && inputs[0].dims.length > 1) { + const output = inferenceHandler.run( + createPackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), + inputs + ); + return [output]; + } else { + const output = inferenceHandler.run( + createUnpackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), + inputs + ); + return [output]; + } + }; + createUnpackedConcatProgramMetadata = (inputCount, cacheHint) => ({ + name: "Concat", + inputNames: Array.from({ length: inputCount }, (_v, i) => `X${i}`), + inputTypes: Array(inputCount).fill(0 /* unpacked */), + cacheHint + }); + createUnpackedConcatProgramInfo = (_handler, metadata, inputs, axis) => { + const inputShape = inputs[0].dims.slice(); + if (axis >= inputShape.length || axis < -1 * inputShape.length) { + throw new Error("axis specified for concat doesn't match input dimensionality"); + } + if (axis < 0) { + axis = inputShape.length + axis; + } + const outputShape = inputShape.slice(0); + for (let i = 1; i < inputs.length; i++) { + const dataNShape = inputs[i].dims.slice(); + for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) { + if (axisIndex === axis) { + outputShape[axis] += dataNShape[axisIndex]; + } else if (inputShape[axisIndex] !== dataNShape[axisIndex]) { + throw new Error("non concat dimensions must match"); + } + } + } + const rank = outputShape.length; + const sizeInConcatAxis = new Array(inputs.length); + let previousSum = 0; + for (let i = 0; i < sizeInConcatAxis.length; ++i) { + previousSum += inputs[i].dims[axis]; + sizeInConcatAxis[i] = previousSum; + } + let getTextureIndexWhereDataResidesMethod = ""; + if (inputs.length < 5) { + getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis); + } else { + getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesBinarySearch(sizeInConcatAxis); + } + const fetchDataFromCorrectTextureMethod = getFetchDataFromCorrectTextureMethod(inputs.length, rank); + const getSizeInConcatAxisValueFromIndexMethod = getGetSizeInConcatAxisValueFromIndexMethod(sizeInConcatAxis); + const shaderSource = ` + ${fetchDataFromCorrectTextureMethod} + ${getSizeInConcatAxisValueFromIndexMethod} + ${getTextureIndexWhereDataResidesMethod} + float process(int indices[${rank}]) { + int textureIndex = getTextureWhereDataResides (indices[${axis}]); + + if(textureIndex != 0) { + indices[${axis}] = indices[${axis}] - int(getSizeInConcatAxisValueFromIndex(textureIndex-int(1))); + } + + return fetchDataFromCorrectTexture(textureIndex, indices); + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createUnpackedConcatProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = createUnpackedConcatProgramMetadata(inputs.length, attributes.cacheKey); + return { ...metadata, get: () => createUnpackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) }; + }; + getTextureIndexWhereDataResidesLinearSearch = (sizeInConcatAxis) => { + const searchAxis = sizeInConcatAxis.map( + (size, i) => `if(index<${size}) {return ${i};} +` + ); + return `int getTextureWhereDataResides(int index) { + ${searchAxis.join("")} + }`; + }; + getTextureIndexWhereDataResidesBinarySearch = (sizeInConcatAxis) => getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis); + getFetchDataFromCorrectTextureMethod = (numberOfTensors, tensorRank) => { + const codeLines = [`float fetchDataFromCorrectTexture(int textureIndex, int indices[${tensorRank}]) {`]; + for (let i = 0; i < numberOfTensors; ++i) { + if (i === 0) { + codeLines.push(` if (textureIndex == ${i}) { return _X${i}(indices); }`); + } else if (i === numberOfTensors - 1) { + codeLines.push(` else { return _X${i}(indices); }`); + } else { + codeLines.push(` else if (textureIndex == ${i}) { return _X${i}(indices); }`); + } + } + codeLines.push(" }"); + return codeLines.join("\n"); + }; + getGetSizeInConcatAxisValueFromIndexMethod = (sizeInConcatAxis) => { + const codeLines = ["int getSizeInConcatAxisValueFromIndex(int index) {"]; + for (let i = 0; i < sizeInConcatAxis.length; ++i) { + if (i === 0) { + codeLines.push(` if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`); + } else if (i === sizeInConcatAxis.length - 1) { + codeLines.push(` else { return ${sizeInConcatAxis[i]}; }`); + } else { + codeLines.push(` else if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`); + } + } + codeLines.push(" }"); + return codeLines.join("\n"); + }; + parseConcatAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis") }); + validateInputs3 = (inputs) => { + if (!inputs || inputs.length < 1) { + throw new Error("too few inputs"); + } + const inputType = inputs[0].type; + const inputDimensionality = inputs[0].dims.length; + if (inputType === "string") { + throw new Error("string tensor is not supported yet"); + } + for (const input of inputs) { + if (input.type !== inputType) { + throw new Error("input tensors should be one type"); + } + if (input.dims.length !== inputDimensionality) { + throw new Error("input tensors should have the same shape"); + } + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/unary-op.ts +function glslAbs() { + return glslBuiltinUnary("abs"); +} +function glslAcos() { + return glslBuiltinUnary("acos"); +} +function glslAsin() { + return glslBuiltinUnary("asin"); +} +function glslAtan() { + return glslBuiltinUnary("atan"); +} +function glslCeil() { + return glslBuiltinUnary("ceil"); +} +function glslCos() { + return glslBuiltinUnary("cos"); +} +function glslElu(alpha) { + const name2 = "elu"; + const body = ` + const float alpha = float(${alpha}); + + float ${name2}_(float a) { + return a >= 0.0 ? a: (exp(a) - 1.0) * alpha; + } + vec4 ${name2}_(vec4 v) { + return vec4(${name2}_(v.x), ${name2}_(v.y), ${name2}_(v.z), ${name2}_(v.w)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslExp() { + return glslBuiltinUnary("exp"); +} +function glslFloor() { + return glslBuiltinUnary("floor"); +} +function glslClip(min, max) { + const name2 = "clip"; + const body = ` + const float min = float(${min}); + const float max = float(${max}); + + float ${name2}_(float a) { + return clamp(a, min, max); + } + vec4 ${name2}_(vec4 v) { + return clamp(v, min, max); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslIdentity() { + const name2 = "indentity"; + const body = ` + float ${name2}_(float a) { + return a; + } + vec4 ${name2}_(vec4 v) { + return v; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslLeakyRelu(alpha) { + const name2 = "leakyRelu"; + const body = ` + const float alpha = float(${alpha}); + + float ${name2}_(float a) { + return a < 0.0 ? a * alpha : a; + } + vec4 ${name2}_(vec4 v) { + return vec4(${name2}_(v.x), ${name2}_(v.y), ${name2}_(v.z), ${name2}_(v.w)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslLog() { + return glslBuiltinUnary("log"); +} +function glslNeg() { + const name2 = "neg"; + const body = ` + float ${name2}_(float a) { + return -a; + } + vec4 ${name2}_(vec4 v) { + return -v; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslNot() { + const name2 = "not"; + const body = ` + float ${name2}_(float a) { + return float( ! bool(a) ); + } + bool ${name2}_(bool a) { + return !a; + } + vec4 ${name2}_(vec4 v) { + return vec4(!bool(v.x), !bool(v.y), !bool(v.z), !bool(v.w)); + } + bvec4 ${name2}_(bvec4 v) { + return bvec4(!v.x, !v.y, !v.z, !v.w); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslSin() { + return glslBuiltinUnary("sin"); +} +function glslRelu() { + const name2 = "relu"; + const body = ` + float ${name2}_(float a) { + return max( a, 0.0 ); + } + vec4 ${name2}_(vec4 v) { + return max( v, 0.0 ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslSigmoid() { + const name2 = "sigmoid"; + const body = ` + float ${name2}_(float a) { + return 1.0 / (1.0 + exp(-a)); + } + vec4 ${name2}_(vec4 v) { + return 1.0 / (1.0 + exp(-v)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslSqrt() { + return glslBuiltinUnary("sqrt"); +} +function glslTan() { + return glslBuiltinUnary("tan"); +} +function glslTanh() { + const name2 = "tanh"; + const body = ` + float ${name2}_(float a) { + a = clamp(a, -10., 10.); + a = exp(2.*a); + return (a - 1.) / (a + 1.); + } + vec4 ${name2}_(vec4 v) { + v = clamp(v, -10., 10.); + v = exp(2.*v); + return (v - 1.) / (v + 1.); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslBuiltinUnary(name2) { + const body = ` + float ${name2}_(float a) { + return ${name2}(a); + } + vec4 ${name2}_(vec4 v) { + return ${name2}(v); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +var createElementwiseProgramInfo, createElementwiseProgramInfoLoader, abs, acos, asin, atan, clip, parseClipAttributes, clipV11, generateClipAttributesFromInputs, ceil, cos, elu, parseEluAttributes, exp, floor, identity, leakyRelu, parseLeakyReluAttributes, log2, neg, not2, relu, sigmoid, sin, sqrt, tan, tanh; +var init_unary_op = __esm({ + "web/lib/onnxjs/backends/webgl/ops/unary-op.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_glsl_definitions(); + init_glsl_source(); + init_types(); + createElementwiseProgramInfo = (handler, metadata, input, glslFunc) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + const glsl = getGlsl(handler.session.backend.glContext.version); + return { + ...metadata, + output: { dims: input.dims, type: input.type, textureType }, + shaderSource: ` + ${glslFunc.body} + void main() { + vec4 v = ${glsl.texture2D}(A, TexCoords); + v = ${glslFunc.name}_(v); + ${glsl.output} = v; + } + `, + hasMain: true + }; + }; + createElementwiseProgramInfoLoader = (handler, input, glslFunc, cacheKey) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + const metadata = { name: glslFunc.name, inputTypes: [textureType], inputNames: ["A"], cacheHint: cacheKey }; + return { ...metadata, get: () => createElementwiseProgramInfo(handler, metadata, input, glslFunc) }; + }; + abs = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAbs()), inputs) + ]; + acos = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAcos()), inputs) + ]; + asin = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAsin()), inputs) + ]; + atan = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAtan()), inputs) + ]; + clip = (handler, inputs, attributes) => [ + handler.run( + createElementwiseProgramInfoLoader( + handler, + inputs[0], + glslClip(attributes.min, attributes.max), + attributes.cacheKey + ), + inputs + ) + ]; + parseClipAttributes = (node) => createAttributeWithCacheKey({ + min: node.attributes.getFloat("min", MIN_CLIP), + max: node.attributes.getFloat("max", MAX_CLIP) + }); + clipV11 = (handler, inputs) => { + const attributes = generateClipAttributesFromInputs(handler, inputs); + return clip(handler, [inputs[0]], attributes); + }; + generateClipAttributesFromInputs = (handler, inputs) => { + if (inputs.length >= 3 && (!handler.session.isInitializer(inputs[1].dataId) || !handler.session.isInitializer(inputs[2].dataId))) { + throw new Error("dynamic clip attributes are not allowed"); + } + const min = inputs.length >= 3 ? inputs[1].numberData[0] : MIN_CLIP; + const max = inputs.length >= 3 ? inputs[2].numberData[0] : MAX_CLIP; + return createAttributeWithCacheKey({ min, max }); + }; + ceil = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCeil()), inputs) + ]; + cos = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCos()), inputs) + ]; + elu = (handler, inputs, attributes) => [ + handler.run( + createElementwiseProgramInfoLoader(handler, inputs[0], glslElu(attributes.alpha), attributes.cacheKey), + inputs + ) + ]; + parseEluAttributes = (node) => createAttributeWithCacheKey({ alpha: node.attributes.getFloat("alpha", 1) }); + exp = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslExp()), inputs) + ]; + floor = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslFloor()), inputs) + ]; + identity = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslIdentity()), inputs) + ]; + leakyRelu = (handler, inputs, attributes) => [ + handler.run( + createElementwiseProgramInfoLoader(handler, inputs[0], glslLeakyRelu(attributes.alpha), attributes.cacheKey), + inputs + ) + ]; + parseLeakyReluAttributes = (node) => createAttributeWithCacheKey({ alpha: node.attributes.getFloat("alpha", 0.01) }); + log2 = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslLog()), inputs) + ]; + neg = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNeg()), inputs) + ]; + not2 = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNot()), inputs) + ]; + relu = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslRelu()), inputs) + ]; + sigmoid = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSigmoid()), inputs) + ]; + sin = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSin()), inputs) + ]; + sqrt = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSqrt()), inputs) + ]; + tan = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTan()), inputs) + ]; + tanh = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTanh()), inputs) + ]; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts +function getActivationSnippet(attributes) { + let func; + switch (attributes.activation) { + case "Relu": + func = glslRelu(); + break; + case "Sigmoid": + func = glslSigmoid(); + break; + case "Clip": + func = glslClip(attributes.clipMin, attributes.clipMax); + break; + // TODO: adding other activations that can be fused. + default: + return { activationFunction: "", applyActivation: "" }; + } + const activationName = func.name; + const activationFunction = func.body; + const applyActivation = `value = ${activationName}_(value);`; + return { activationFunction, applyActivation }; +} +var parseInternalActivationAttributes; +var init_fuse_utils = __esm({ + "web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts"() { + "use strict"; + init_util(); + init_unary_op(); + parseInternalActivationAttributes = (attributes) => { + const activation = attributes.getString("activation", ""); + if (activation === "Clip") { + const [clipMin, clipMax] = attributes.getFloats("activation_params", [MIN_CLIP, MAX_CLIP]); + return { activation, clipMax, clipMin, activationCacheKey: `${activation}:${clipMin},${clipMax}` }; + } + return { activation, activationCacheKey: activation }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts +var createUnpackedGroupedConvProgramMetadata, createUnpackedGroupedConvProgramInfo, createUnpackedGroupedConvProgramInfoLoader; +var init_conv_grouped = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts"() { + "use strict"; + init_instrument(); + init_glsl_source(); + init_types(); + init_conv(); + init_fuse_utils(); + createUnpackedGroupedConvProgramMetadata = (hasBias, cacheHint) => ({ + name: "GroupedConv", + inputNames: hasBias ? ["X", "W", "Bias"] : ["X", "W"], + inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + cacheHint + }); + createUnpackedGroupedConvProgramInfo = (inferenceHandler, inputs, metadata, attributes) => { + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += getBias(output_channel);" : ""; + const xShape = inputs[0].dims.slice(); + const wShape = inputs[1].dims.slice(); + const outputChannelsPerGroup = wShape[0] / attributes.group; + Logger.verbose( + "GroupedConv", + `autpPad:${attributes.autoPad}, dilations:${attributes.dilations}, group:${attributes.group}, kernelShape:${attributes.kernelShape}, pads:${attributes.pads}, strides:${attributes.strides}` + ); + const outputShape = calculateOutputShape(xShape, wShape, attributes.dilations, attributes.pads, attributes.strides); + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const { activationFunction, applyActivation } = getActivationSnippet(attributes); + const shaderSource = ` + const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]}); + const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]}); + ${activationFunction} + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + int output_channel = coords.y; + ivec2 xRCCorner = coords.zw * strides - pads; + int group_id = output_channel / ${outputChannelsPerGroup}; + + float value = 0.0; + for (int wInChannel = 0; wInChannel < ${wShape[1]}; wInChannel++) { + int input_channel = group_id * ${wShape[1]} + wInChannel; + for (int wHeight = 0; wHeight < ${wShape[2]}; wHeight++) { + int xHeight = xRCCorner.x + wHeight * ${attributes.dilations[0]}; + + if (xHeight < 0 || xHeight >= ${xShape[2]}) { + continue; + } + + for (int wWidth = 0; wWidth < ${wShape[3]}; wWidth++) { + int xWidth = xRCCorner.y + wWidth * ${attributes.dilations[1]}; + if (xWidth < 0 || xWidth >= ${xShape[3]}) { + continue; + } + + float xVal = getX(batch, input_channel, xWidth, xHeight); + float wVal = getW(output_channel, wInChannel, wWidth, wHeight); + value += xVal*wVal; + } + } + } + ${processBias} + ${applyActivation} + ${glsl.output} = vec4(value, .0, .0, .0); + } +`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource, + hasMain: true + }; + }; + createUnpackedGroupedConvProgramInfoLoader = (inferenceHandler, inputs, attributes) => { + const metadata = createUnpackedGroupedConvProgramMetadata(inputs.length > 2, attributes.cacheKey); + return { + ...metadata, + get: () => createUnpackedGroupedConvProgramInfo(inferenceHandler, inputs, metadata, attributes) + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts +var createPackedIm2ColProgramMetadata, createPackedIm2ColProgramInfo, createPackedIm2ColProgramInfoLoader; +var init_im2col_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_packing_utils(); + createPackedIm2ColProgramMetadata = (cacheHint) => ({ + name: "Im2Col (packed)", + inputNames: ["A"], + inputTypes: [2 /* packed */], + cacheHint + }); + createPackedIm2ColProgramInfo = (inferenceHandler, metadata, x, w, outputShape, attributes) => { + const xshape = x.dims; + const wshape = w.dims; + const rowDim = 2; + const colDim = 3; + const rank = outputShape.length; + const im2colShape = [wshape[1] * wshape[2] * wshape[3], outputShape[2] * outputShape[3]]; + const kernelSize = wshape[2] * wshape[3]; + const unpackChannel = unpackFromChannel(); + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + let unrolled = ""; + for (let row = 0; row <= 1; row++) { + for (let col = 0; col <= 1; col++) { + unrolled += ` + blockIndex = rc.x + ${col}; + pos = rc.y + ${row}; + + if(blockIndex < ${im2colShape[1]} && pos < ${im2colShape[0]}) { + offsetY = int(blockIndex / (${outputShape[rank - 1]})) * ${attributes.strides[0]} - + ${attributes.pads[0]}; + d0 = offsetY + ${attributes.dilations[0]} * (imod(pos, ${kernelSize}) / ${wshape[2]}); + + if(d0 < ${xshape[rowDim]} && d0 >= 0) { + offsetX = imod(blockIndex, ${outputShape[rank - 1]}) * ${attributes.strides[1]} - + ${attributes.pads[1]}; + d1 = offsetX + ${attributes.dilations[1]} * imod(imod(pos, ${kernelSize}), ${wshape[2]}); + + if(d1 < ${xshape[colDim]} && d1 >= 0) { + + ch = int(float(pos)/ ${kernelSize}.); + innerDims = vec2(d0, d1); + result[${row * 2 + col}] = getChannel( + getA(0, ch, int(innerDims.x), + int(innerDims.y)), innerDims); + } + } + } + + `; + } + } + const shaderSource = ` + ${unpackChannel} + + void main() { + ivec2 rc = getOutputCoords(); + vec4 result = vec4(0.0); + int blockIndex, pos, offsetY, d0, offsetX, d1, ch; + vec2 innerDims; + ${unrolled} + ${glsl.output} = result; + } + `; + return { + ...metadata, + output: { dims: im2colShape, type: x.type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => { + const metadata = createPackedIm2ColProgramMetadata(attributes.cacheKey); + return { + ...metadata, + get: () => createPackedIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/matmul.ts +function createMatmulProgramInfo(metadata, inputs, activationAttributes) { + const aShape = inputs[0].dims; + const bShape = inputs[1].dims; + const outputShape = BroadcastUtil.calcShape(aShape, bShape, true); + if (!outputShape) { + throw new Error("Can't use matmul on the given tensors"); + } + const coordsDataType = getCoordsDataType(outputShape.length); + const allGlChannels = getGlChannels(); + const { activationFunction, applyActivation } = getActivationSnippet(activationAttributes); + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += getBiasForMatmul();" : ""; + const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, false)}` : ""; + const rank = outputShape.length; + const arank = aShape.length; + const brank = bShape.length; + const sharedDim = aShape[aShape.length - 1]; + const shaderSource = ` + ${activationFunction} + ${getBiasForMatmulSnippet} + float process(int indices[${rank}]) { + int a[${arank}]; + int b[${brank}]; + bcastMatmulIndices_A(indices, a); + bcastMatmulIndices_B(indices, b); + + float value; + for (int k=0; k<${sharedDim}; ++k) { + a[${arank - 1}] = k; + b[${brank - 2}] = k; + value += _A(a) * _B(b); + } + ${processBias} + ${applyActivation} + return value; + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; +} +function createMatmulProgramInfoLoader(inputs, activationAttributes) { + const metadata = createMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey); + return { ...metadata, get: () => createMatmulProgramInfo(metadata, inputs, activationAttributes) }; +} +function getBiasForMatmul(coordsDataType, allGlChannels, inShape, outShape, isPacked) { + let unpackedCoordsSnippet = ""; + const inRank = inShape.length; + const outRank = outShape.length; + const rankDiff = outRank - inRank; + if (outRank < 2 && inRank > 0) { + unpackedCoordsSnippet = "coords"; + } else { + unpackedCoordsSnippet = inShape.map((_s, i) => `coords.${allGlChannels[i + rankDiff]}`).join(", "); + } + const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); + const coordsSnippet = broadcastDims.map((d) => `coords.${allGlChannels[d + rankDiff]} = 0;`).join("\n"); + const inSize = ShapeUtil.size(inShape); + const isInputScalar = inSize === 1; + let output = "vec4(outputValue.xx, outputValue.yy)"; + if (isInputScalar) { + output = "vec4(outputValue.x)"; + } + const getBiasForMatmulSource = isPacked ? ` +vec4 getBiasForMatmul() { + ${coordsDataType} coords = getOutputCoords(); + ${coordsSnippet} + vec4 outputValue = getBias(${unpackedCoordsSnippet}); + return ${output}; +}` : ` +float getBiasForMatmul() { + ${coordsDataType} coords = getOutputCoords(); + ${coordsSnippet} + return getBias(coords.x); +}`; + return getBiasForMatmulSource; +} +var matMul, parseMatMulAttributes, createMatmulProgramMetadata, validateInputs4; +var init_matmul = __esm({ + "web/lib/onnxjs/backends/webgl/ops/matmul.ts"() { + "use strict"; + init_util(); + init_types(); + init_utils(); + init_fuse_utils(); + init_matmul_pack(); + matMul = (inferenceHandler, inputs, attributes) => { + validateInputs4(inputs); + if (inferenceHandler.session.pack) { + return [inferenceHandler.run(createPackedMatmulProgramInfoLoader(inferenceHandler, inputs, attributes), inputs)]; + } else { + return [inferenceHandler.run(createMatmulProgramInfoLoader(inputs, attributes), inputs)]; + } + }; + parseMatMulAttributes = (node) => parseInternalActivationAttributes(node.attributes); + createMatmulProgramMetadata = (hasBias, cacheHint) => ({ + name: "MatMul", + inputNames: hasBias ? ["A", "B", "Bias"] : ["A", "B"], + inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + cacheHint + }); + validateInputs4 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("MatMul requires 2 inputs."); + } + if (inputs[0].dims[inputs[0].dims.length - 1] !== inputs[1].dims[inputs[1].dims.length - 2]) { + throw new Error("shared dimension does not match."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64" || inputs[1].type !== "float32" && inputs[1].type !== "float64") { + throw new Error("inputs should be float type"); + } + if (inputs[0].type !== inputs[1].type) { + throw new Error("inputs types should match"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts +function getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outShape) { + let unpackedACoordsSnippet = []; + let unpackedBCoordsSnippet = []; + const inAShape = inputs[0].dims; + const inBShape = inputs[1].dims; + const inARank = inAShape.length; + const inBRank = inBShape.length; + const outRank = outShape.length; + const rankADiff = outRank - inARank; + const rankBDiff = outRank - inBRank; + unpackedACoordsSnippet = inAShape.map((_s, i) => `coords.${allGlChannels[i + rankADiff]}`); + unpackedACoordsSnippet[inARank - 1] = "i*2"; + unpackedACoordsSnippet.join(", "); + unpackedBCoordsSnippet = inBShape.map((_s, i) => `coords.${allGlChannels[i + rankBDiff]}`); + unpackedBCoordsSnippet[inBRank - 2] = "i*2"; + unpackedBCoordsSnippet.join(", "); + const broadcastADims = BroadcastUtil.getBroadcastDims(inAShape, outShape); + const broadcastBDims = BroadcastUtil.getBroadcastDims(inBShape, outShape); + const coordsASnippet = broadcastADims.map((d) => `coords.${allGlChannels[d + rankADiff]} = 0;`).join("\n"); + const coordsBSnippet = broadcastBDims.map((d) => `coords.${allGlChannels[d + rankBDiff]} = 0;`).join("\n"); + const swapDimSnippet = `int lastDim = coords.${allGlChannels[outRank - 1]}; + coords.${allGlChannels[outRank - 1]} = coords.${allGlChannels[outRank - 2]}; + coords.${allGlChannels[outRank - 2]} = lastDim;`; + const getBcastSamplerMatmulSource = ` +vec4 getAAtOutCoordsMatmul(int i) { + ${coordsDataType} coords = getOutputCoords(); + ${swapDimSnippet} + ${coordsASnippet} + vec4 outputValue = getA(${unpackedACoordsSnippet}); + return outputValue; +} + +vec4 getBAtOutCoordsMatmul(int i) { + ${coordsDataType} coords = getOutputCoords(); + ${swapDimSnippet} + ${coordsBSnippet} + vec4 outputValue = getB(${unpackedBCoordsSnippet}); + return outputValue; +}`; + return getBcastSamplerMatmulSource; +} +function getA(allGlChannels, rank) { + let res = ""; + for (let i = 0; i < rank - 2; i++) { + res += `rc.${allGlChannels[i]}, `; + } + res += `rc.${allGlChannels[rank - 2]}, i*2`; + return res; +} +function getB(allGlChannels, rank) { + let res = ""; + for (let i = 0; i < rank - 2; i++) { + res += `rc.${allGlChannels[i]}, `; + } + res += `i*2, rc.${allGlChannels[rank - 1]}`; + return res; +} +var createPackedMatmulProgramMetadata, createPackedMatmulProgramInfo, createPackedMatmulProgramInfoLoader; +var init_matmul_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts"() { + "use strict"; + init_util(); + init_glsl_source(); + init_types(); + init_utils(); + init_fuse_utils(); + init_matmul(); + createPackedMatmulProgramMetadata = (hasBias, cacheHint) => ({ + name: "MatMul (packed)", + inputNames: hasBias ? ["A", "B", "Bias"] : ["A", "B"], + inputTypes: hasBias ? [2 /* packed */, 2 /* packed */, 2 /* packed */] : [2 /* packed */, 2 /* packed */], + cacheHint + }); + createPackedMatmulProgramInfo = (inferenceHandler, metadata, inputs, activationAttributes) => { + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += getBiasForMatmul();" : ""; + const aShape = inputs[0].dims; + const bShape = inputs[1].dims; + const outputShape = BroadcastUtil.calcShape(aShape, bShape, true); + const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims); + if (!outputShape) { + throw new Error("Can't use matmul on the given tensors"); + } + const sharedDim = aShape[aShape.length - 1]; + const sharedDimIndex = Math.ceil(sharedDim / 2); + const aRank = aShape.length; + const bRank = bShape.length; + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const coordsDataType = getCoordsDataType(outputShape.length); + const outRank = outputShape.length; + const allGlChannels = getGlChannels(); + const { activationFunction, applyActivation } = getActivationSnippet(activationAttributes); + const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, true)}` : ""; + const getBcastedSamplerForMatmulSnippet = isBroadcast ? `${getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outputShape)}` : ""; + const getSamplerAInLoopSnippet = isBroadcast ? "getAAtOutCoordsMatmul(i)" : `getA(${getA(allGlChannels, aRank)})`; + const getSamplerBInLoopSnippet = isBroadcast ? "getBAtOutCoordsMatmul(i)" : `getB(${getB(allGlChannels, bRank)})`; + const getOutputCoordsSnippet = isBroadcast ? "" : `${coordsDataType} rc = + getOutputCoords(); int lastDim = rc.${allGlChannels[outRank - 1]}; rc.${allGlChannels[outRank - 1]} = + rc.${allGlChannels[outRank - 2]}; rc.${allGlChannels[outRank - 2]} = lastDim; + `; + const shaderSource = ` + ${getBcastedSamplerForMatmulSnippet} + ${getBiasForMatmulSnippet} + ${activationFunction} + void main() { + ${getOutputCoordsSnippet} + + vec4 value = vec4(0); + for (int i = 0; i < ${sharedDimIndex}; i++) { + vec4 a = ${getSamplerAInLoopSnippet}; + vec4 b = ${getSamplerBInLoopSnippet}; + + value += (a.rrbb * b.rgrg); + value += (a.ggaa * b.baba); + } + ${processBias} + ${applyActivation} + ${glsl.output} = value; + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedMatmulProgramInfoLoader = (inferenceHandler, inputs, activationAttributes) => { + const metadata = createPackedMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey); + return { + ...metadata, + get: () => createPackedMatmulProgramInfo(inferenceHandler, metadata, inputs, activationAttributes) + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/conv-pack.ts +var conv2DPacked; +var init_conv_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv-pack.ts"() { + "use strict"; + init_conv(); + init_im2col_pack(); + init_matmul_pack(); + conv2DPacked = (inferenceHandler, inputs, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); + const im2colOutput = inferenceHandler.run( + createPackedIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), + [inputs[0]] + ); + const kernelReshaped = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1] * kshape[2] * kshape[3]]); + const matmulInputs = inputs.length === 3 ? [kernelReshaped, im2colOutput, inputs[2]] : [kernelReshaped, im2colOutput]; + const matmulOutput = inferenceHandler.run( + createPackedMatmulProgramInfoLoader(inferenceHandler, matmulInputs, attributes), + matmulInputs + ); + const outputReshaped = inferenceHandler.reshapePacked(matmulOutput, outputShape); + return outputReshaped; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/im2col.ts +var createIm2ColProgramMetadata, createIm2ColProgramInfo, createIm2ColProgramInfoLoader, calculateIm2ColDims; +var init_im2col = __esm({ + "web/lib/onnxjs/backends/webgl/ops/im2col.ts"() { + "use strict"; + init_types(); + createIm2ColProgramMetadata = (cacheHint) => ({ + name: "Im2Col", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint + }); + createIm2ColProgramInfo = (_inferenceHandler, metadata, x, w, outputShape, attributes) => { + const xshape = x.dims; + const wshape = w.dims; + const rank = outputShape.length; + const im2colDims = calculateIm2ColDims(xshape, wshape, outputShape, 4); + const shaderSource = ` + const int XC = ${xshape[1]}; + const int XH = ${xshape[2]}; + const int XW = ${xshape[3]}; + const int KH = ${attributes.kernelShape[0]}; + const int KW = ${attributes.kernelShape[1]}; + const int dilationH = ${attributes.dilations[0]}; + const int dilationW = ${attributes.dilations[1]}; + const int strideH = ${attributes.strides[0]}; + const int strideW = ${attributes.strides[1]}; + const int padH = ${attributes.pads[0]}; + const int padW = ${attributes.pads[1]}; + const int KHKW = KH*KW; + const int XCKHKW = XC * KHKW; + const int outputChannels = 4; + vec4 process(int indices[${rank}]) { + int b = indices[0]; // batch size + int oh = indices[1] * strideH - padH; //output height + int ow = indices[2] * strideW - padW; //output width + int p = indices[3] * outputChannels; //patch + vec4 value = vec4(0.0); + for(int i=0; i < outputChannels; ++i) { + if(p < XCKHKW) { + int patchC = p / KHKW; + int patchH = (p - patchC*KHKW) / KW; + int patchW = (p - patchC*KHKW) - patchH * KW; + int xh2 = oh + patchH * dilationH; + int xw2 = ow + patchW * dilationW; + int x[${xshape.length}]; + x[0] = b; + x[1] = patchC; + x[2] = xh2; + x[3] = xw2; + if(xh2 >= 0 && + xh2 < XH && + xw2 >= 0 && + xw2 < XW) { + value[i] = _X(x); + } + } + ++p; + } + return value; + } + `; + return { + ...metadata, + output: { dims: im2colDims, type: x.type, textureType: 4 /* packedLastDimension */ }, + shaderSource + }; + }; + createIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => { + const metadata = createIm2ColProgramMetadata(attributes.cacheKey); + return { + ...metadata, + get: () => createIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) + }; + }; + calculateIm2ColDims = (inputShape, kernelShape, outputShape, channels = 4) => [ + outputShape[0], + outputShape[2], + outputShape[3], + Math.ceil(inputShape[1] * kernelShape[2] * kernelShape[3] / channels) + ]; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/dot-product.ts +var createDotProductProgramMetadata, createDotProductProgramInfo, createDotProductProgramInfoLoader; +var init_dot_product = __esm({ + "web/lib/onnxjs/backends/webgl/ops/dot-product.ts"() { + "use strict"; + init_util(); + init_glsl_source(); + init_types(); + init_fuse_utils(); + init_im2col(); + createDotProductProgramMetadata = (hasBias, attributes) => ({ + name: "ConvDotProduct", + inputNames: hasBias ? ["Im2Col", "K", "B"] : ["Im2Col", "K"], + inputTypes: hasBias ? [0 /* unpacked */, 4 /* packedLastDimension */, 0 /* unpacked */] : [0 /* unpacked */, 4 /* packedLastDimension */], + cacheKey: attributes.activationCacheKey + }); + createDotProductProgramInfo = (inferenceHandler, metadata, inputs, outputShape, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const adjustedKernelShape = [kshape[0], Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4)]; + const im2colShape = calculateIm2ColDims(xshape, kshape, outputShape); + const [kWidth, kHeight] = inferenceHandler.calculateTextureWidthAndHeight( + adjustedKernelShape, + 4 /* packedLastDimension */ + ); + const im2colStrides = ShapeUtil.computeStrides(im2colShape); + const [im2colWidth, im2colHeight] = inferenceHandler.calculateTextureWidthAndHeight( + im2colShape, + 4 /* packedLastDimension */ + ); + const rank = outputShape.length; + const initValue = inputs.length < 3 ? "0.0" : "_B(b)"; + const sharedDim = Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4); + const { activationFunction, applyActivation } = getActivationSnippet(attributes); + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` +${activationFunction} +float process(int indices[${rank}]) { + int b[1]; + b[0] = indices[1]; + int im2col[4]; + im2col[0] = indices[0]; + im2col[1] = indices[2]; + im2col[2] = indices[3]; + int im2colOffset = im2col[0] * ${im2colStrides[0]} + im2col[1] * ${im2colStrides[1]} + im2col[2] * ${im2colStrides[2]}; + int kernelOffset = indices[1] * ${adjustedKernelShape[1]}; + float value = ${initValue}; + for (int i = 0; i < ${sharedDim}; ++i) { + vec2 im2colCoords = offsetToCoords(im2colOffset, ${im2colWidth}, ${im2colHeight}); + vec2 kernelCoords = offsetToCoords(kernelOffset, ${kWidth}, ${kHeight}); + value += dot(${glsl.texture2D}(Im2Col, im2colCoords), ${glsl.texture2D}(K, kernelCoords)); + ++im2colOffset; + ++kernelOffset; + } + ${applyActivation} + return value; +}`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createDotProductProgramInfoLoader = (inferenceHandler, inputs, outputShape, attributes) => { + const metadata = createDotProductProgramMetadata(inputs.length > 2, attributes); + return { + ...metadata, + get: () => createDotProductProgramInfo(inferenceHandler, metadata, inputs, outputShape, attributes) + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/conv.ts +var calculateOutputShape, conv, conv2d, conv2DUnpackedPointwise, conv2DUnpacked, getAdjustedConvAttributes, parseConvAttributes, validateInputs5; +var init_conv = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_conv_grouped(); + init_conv_pack(); + init_dot_product(); + init_fuse_utils(); + init_im2col(); + init_matmul(); + calculateOutputShape = (inputShape, kernelShape, dilations, adjustPads, strides) => { + const batchSize = inputShape[0]; + const inputSpatialShape = inputShape.slice(2); + const spatialRank = inputSpatialShape.length; + const outChannels = kernelShape[0]; + const kernelSpatialShape = kernelShape.slice(2); + const dilatedKernelShape = kernelSpatialShape.map((v, i) => v + (v - 1) * (dilations[i] - 1)); + const inputSpatialShapeWithPad = inputSpatialShape.map((v, i) => v + adjustPads[i] + adjustPads[i + spatialRank]); + const outputSpatialShape = inputSpatialShapeWithPad.map( + (v, i) => Math.floor((v - dilatedKernelShape[i] + strides[i]) / strides[i]) + ); + const outputShape = [batchSize, outChannels].concat(...outputSpatialShape); + return outputShape; + }; + conv = (inferenceHandler, inputs, attributes) => { + validateInputs5(inputs, attributes); + return conv2d(inferenceHandler, inputs, attributes); + }; + conv2d = (inferenceHandler, inputs, attributes) => { + const adjustedAttributes = getAdjustedConvAttributes(attributes, inputs); + const packMode = inferenceHandler.session.pack; + const isPointwise = adjustedAttributes.kernelShape[0] === 1 && adjustedAttributes.kernelShape[1] === 1; + if (adjustedAttributes.group > 1) { + const result = inferenceHandler.run( + createUnpackedGroupedConvProgramInfoLoader(inferenceHandler, inputs, adjustedAttributes), + inputs + ); + return [result]; + } else if (isPointwise && packMode) { + return [conv2DUnpackedPointwise(inferenceHandler, inputs, adjustedAttributes)]; + } else if (packMode && inputs[0].dims.length === 4 && inputs[0].dims[0] === 1 && !isPointwise) { + return [conv2DPacked(inferenceHandler, inputs, adjustedAttributes)]; + } else { + return [conv2DUnpacked(inferenceHandler, inputs, adjustedAttributes)]; + } + }; + conv2DUnpackedPointwise = (inferenceHandler, inputs, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); + const reshapedX = inferenceHandler.reshapeUnpacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]); + const reshapedK = inferenceHandler.reshapeUnpacked(inputs[1], [kshape[0], kshape[1]]); + const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX]; + const matmulOutput = inferenceHandler.run(createMatmulProgramInfoLoader(matmulInputs, attributes), matmulInputs); + return inferenceHandler.reshapeUnpacked(matmulOutput, outputShape); + }; + conv2DUnpacked = (inferenceHandler, inputs, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); + const xIm2Col = inferenceHandler.run( + createIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), + [inputs[0]] + ); + const dotProductInputs = inputs.length === 3 ? [xIm2Col, inputs[1], inputs[2]] : [xIm2Col, inputs[1]]; + const output = inferenceHandler.run( + createDotProductProgramInfoLoader(inferenceHandler, inputs, outputShape, attributes), + dotProductInputs + ); + return output; + }; + getAdjustedConvAttributes = (attributes, inputs) => { + const kernelShape = attributes.kernelShape.slice(); + if (attributes.kernelShape.length === 0) { + for (let i = 2; i < inputs[1].dims.length; ++i) { + kernelShape.push(inputs[1].dims[i]); + } + } + const pads = attributes.pads.slice(); + PoolConvUtil.adjustPadsBasedOnAutoPad( + inputs[0].dims, + attributes.strides, + attributes.dilations, + kernelShape, + pads, + attributes.autoPad + ); + const newAttributes = Object.assign({}, attributes); + Object.assign(newAttributes, { kernelShape, pads, cacheKey: attributes.cacheKey }); + return newAttributes; + }; + parseConvAttributes = (node) => { + const attributes = node.attributes; + const activationAttributes = parseInternalActivationAttributes(attributes); + const autoPad = attributes.getString("auto_pad", "NOTSET"); + const dilations = attributes.getInts("dilations", [1, 1]); + const group = attributes.getInt("group", 1); + const kernelShape = attributes.getInts("kernel_shape", []); + const pads = attributes.getInts("pads", [0, 0, 0, 0]); + const strides = attributes.getInts("strides", [1, 1]); + return createAttributeWithCacheKey({ + autoPad, + dilations, + group, + kernelShape, + pads, + strides, + ...activationAttributes + }); + }; + validateInputs5 = (inputs, attributes) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Conv requires 2 or 3 inputs"); + } + if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) { + throw new Error("currently only support 2-dimensional conv"); + } + const dataChannel = inputs[0].dims[1]; + const filterInChannel = inputs[1].dims[1] * attributes.group; + if (dataChannel !== filterInChannel) { + throw new Error("FILTER_IN_CHANNEL should be equal to DATA_CHANNEL"); + } + if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[1].dims[0] !== inputs[2].dims[0])) { + throw new Error("invalid bias"); + } + const spatialRank = inputs[0].dims.length - 2; + if (attributes.dilations.length !== spatialRank) { + throw new Error(`dilations should be ${spatialRank}D`); + } + if (attributes.strides.length !== spatialRank) { + throw new Error(`strides should be ${spatialRank}D`); + } + if (attributes.pads.length !== spatialRank * 2) { + throw new Error(`pads should be ${spatialRank * 2}D`); + } + if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) { + throw new Error("invalid kernel shape"); + } + if (inputs[0].type !== "float32" || inputs[1].type !== "float32") { + throw new Error("Conv input(X,W) should be float tensor"); + } + if (inputs.length === 3 && inputs[2].type !== "float32") { + throw new Error("Conv input(bias) should be float tensor"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts +var computeTotalPad, distributePadding, calculateOutputShapeAndPads, convTranspose, convTranspose2d, createConvTransposeProgramMetadata, createUnpackedConvTransposeProgramInfo, createUnpackedConvTransposeProgramInfoLoader, convTranspose2DUnpacked, getAdjustedConvTransposeAttributes, parseConvTransposeAttributes, validateInputs6; +var init_conv_transpose = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_glsl_source(); + init_types(); + init_fuse_utils(); + computeTotalPad = (inDim, stride, adj, kernel, dilation, outSize) => (inDim - 1) * stride + adj + (kernel - 1) * dilation + 1 - outSize; + distributePadding = (totalPad, autoPad, pads, head, tail) => { + const smallPad = Math.floor(totalPad / 2); + if (autoPad === "SAME_UPPER") { + pads[head] = smallPad; + pads[tail] = totalPad - smallPad; + } else if (autoPad === "SAME_LOWER") { + pads[head] = totalPad - smallPad; + pads[tail] = smallPad; + } + }; + calculateOutputShapeAndPads = (inputShape, kernelShape, dilations, autoPad, pads, strides, outputPadding, outputShape) => { + const spatialRank = inputShape.length - 2; + const updateShape = outputShape.length === 0; + for (let i = 0; i < spatialRank; ++i) { + const outSize = updateShape ? inputShape[i + 2] * strides[i] : outputShape[i]; + const totalPad = computeTotalPad(inputShape[i + 2], strides[i], pads[i], kernelShape[i], dilations[i], outSize); + distributePadding(totalPad, autoPad, pads, i, i + spatialRank); + if (updateShape) { + outputShape.push( + strides[i] * (inputShape[i + 2] - 1) + outputPadding[i] + (kernelShape[i] - 1) * dilations[i] + 1 - pads[i] - pads[i + spatialRank] + ); + } + } + }; + convTranspose = (inferenceHandler, inputs, attributes) => { + validateInputs6(inputs, attributes); + return convTranspose2d(inferenceHandler, inputs, attributes); + }; + convTranspose2d = (inferenceHandler, inputs, attributes) => { + const adjustedAttributes = getAdjustedConvTransposeAttributes(attributes, inputs); + return [convTranspose2DUnpacked(inferenceHandler, inputs, adjustedAttributes)]; + }; + createConvTransposeProgramMetadata = (hasBias, cacheHint) => ({ + name: "ConvTranspose", + inputNames: hasBias ? ["X", "W", "B"] : ["X", "W"], + inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + cacheHint + }); + createUnpackedConvTransposeProgramInfo = (inferenceHandler, inputs, metadata, attributes) => { + const hasBias = inputs.length > 2; + const valueInit = hasBias ? "getB(output_channel)" : "0.0"; + const xShape = inputs[0].dims; + const wShape = inputs[1].dims; + const outputChannelsPerGroup = wShape[1]; + const inputChannelsPerGroup = wShape[0] / attributes.group; + const outputShape = [inputs[0].dims[0], inputs[1].dims[1] * attributes.group, ...attributes.outputShape]; + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const { activationFunction, applyActivation } = getActivationSnippet(attributes); + const shaderSource = ` + const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]}); + const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]}); + ${activationFunction} + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + int output_channel = coords.y; + + ivec2 loc = coords.zw + pads; + + int group_id = output_channel / ${outputChannelsPerGroup}; + int wOutChannel = output_channel - group_id * ${outputChannelsPerGroup}; + + float value = ${valueInit}; + for (int inChannelOffset = 0; inChannelOffset < ${inputChannelsPerGroup}; inChannelOffset++) { + int input_channel = group_id * ${inputChannelsPerGroup} + inChannelOffset; + for (int wWOff = 0; wWOff < ${wShape[2]}; wWOff++) { + for (int wHOff = 0; wHOff < ${wShape[3]}; wHOff++) { + ivec2 wOff = ivec2(wWOff * ${attributes.dilations[0]}, wHOff * ${attributes.dilations[1]}); + ivec2 wLoc = loc - wOff; + ivec2 wLocIn = wLoc / strides; + if ( + wLocIn * strides == wLoc && + wLocIn.x >= 0 && wLocIn.x < ${xShape[2]} && + wLocIn.y >= 0 && wLocIn.y < ${xShape[3]} + ) { + float xVal = getX(batch, input_channel, wLocIn.y, wLocIn.x); + float wVal = getW(input_channel, wOutChannel, wHOff, wWOff); + value += xVal * wVal; + } + } + } + } + ${applyActivation} + ${glsl.output} = vec4(value, .0, .0, .0); + } +`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource, + hasMain: true + }; + }; + createUnpackedConvTransposeProgramInfoLoader = (inferenceHandler, inputs, attributes) => { + const metadata = createConvTransposeProgramMetadata(inputs.length > 2, attributes.cacheKey); + return { + ...metadata, + get: () => createUnpackedConvTransposeProgramInfo(inferenceHandler, inputs, metadata, attributes) + }; + }; + convTranspose2DUnpacked = (inferenceHandler, inputs, attributes) => { + const result = inferenceHandler.run( + createUnpackedConvTransposeProgramInfoLoader(inferenceHandler, inputs, attributes), + inputs + ); + return result; + }; + getAdjustedConvTransposeAttributes = (attributes, inputs) => { + const kernelShape = attributes.kernelShape.slice(); + if (attributes.kernelShape.length === 0) { + for (let i = 2; i < inputs[1].dims.length; ++i) { + kernelShape.push(inputs[1].dims[i]); + } + } + const pads = attributes.pads.slice(); + const outputShape = attributes.outputShape.slice(); + const inputShape = inputs[0].dims; + calculateOutputShapeAndPads( + inputShape, + kernelShape, + attributes.dilations, + attributes.autoPad, + pads, + attributes.strides, + attributes.outputPadding, + outputShape + ); + const newAttributes = Object.assign({}, attributes); + Object.assign(newAttributes, { kernelShape, pads, outputShape, cacheKey: attributes.cacheKey }); + return newAttributes; + }; + parseConvTransposeAttributes = (node) => { + const attributes = node.attributes; + const activationAttributes = parseInternalActivationAttributes(attributes); + const autoPad = attributes.getString("auto_pad", "NOTSET"); + const dilations = attributes.getInts("dilations", [1, 1]); + const group = attributes.getInt("group", 1); + const kernelShape = attributes.getInts("kernel_shape", []); + const outputPadding = attributes.getInts("output_padding", [0, 0]); + const outputShape = attributes.getInts("output_shape", []); + const pads = attributes.getInts("pads", [0, 0, 0, 0]); + const strides = attributes.getInts("strides", [1, 1]); + return createAttributeWithCacheKey({ + autoPad, + dilations, + group, + kernelShape, + outputPadding, + outputShape, + pads, + strides, + ...activationAttributes + }); + }; + validateInputs6 = (inputs, attributes) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Conv requires 2 or 3 inputs"); + } + if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) { + throw new Error("currently only support 2-dimensional conv"); + } + const dataChannel = inputs[0].dims[1]; + const filterInChannel = inputs[1].dims[0]; + if (dataChannel !== filterInChannel) { + throw new Error("FILTER_IN_CHANNEL should be equal to DATA_CHANNEL"); + } + const featureMaps = inputs[1].dims[1] * attributes.group; + if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[2].dims[0] !== featureMaps)) { + throw new Error("invalid bias"); + } + const spatialRank = inputs[0].dims.length - 2; + if (attributes.dilations.length !== spatialRank) { + throw new Error(`dilations should be ${spatialRank}D`); + } + if (attributes.strides.length !== spatialRank) { + throw new Error(`strides should be ${spatialRank}D`); + } + if (attributes.pads.length !== spatialRank * 2) { + throw new Error(`pads should be ${spatialRank * 2}D`); + } + if (attributes.outputPadding.length !== spatialRank) { + throw new Error(`output_padding should be ${spatialRank}D`); + } + if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) { + throw new Error("invalid kernel shape"); + } + if (attributes.outputShape.length !== 0 && attributes.outputShape.length !== inputs[0].dims.length - 2) { + throw new Error("invalid output shape"); + } + if (inputs[0].type !== "float32" || inputs[1].type !== "float32") { + throw new Error("ConvTranspose input(X,W) should be float tensor"); + } + if (inputs.length === 3 && inputs[2].type !== "float32") { + throw new Error("ConvTranspose input(bias) should be float tensor"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/transpose.ts +var transposeProgramMetadata, transpose, parseTransposeAttributes, createTransposeProgramInfo, getAdjustedPerm, getOutputShape, getPermFunctionBody, validateInputs7; +var init_transpose = __esm({ + "web/lib/onnxjs/backends/webgl/ops/transpose.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + transposeProgramMetadata = { + name: "Transpose", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + transpose = (inferenceHandler, inputs, attributes) => { + validateInputs7(inputs); + const output = inferenceHandler.run( + { + ...transposeProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createTransposeProgramInfo(inferenceHandler, inputs[0], attributes.perm) + }, + inputs + ); + return [output]; + }; + parseTransposeAttributes = (node) => createAttributeWithCacheKey({ perm: node.attributes.getInts("perm", []) }); + createTransposeProgramInfo = (_inferenceHandler, input, perm) => { + const inputShape = input.dims; + perm = getAdjustedPerm(inputShape, perm); + const unpackedOutputShape = getOutputShape(inputShape, perm); + const rank = inputShape.length; + const shaderSource = ` + ${getPermFunctionBody("perm", perm, rank)} + float process(int indices[${rank}]) { + int a[${rank}]; + perm(a, indices); + return _A(a); + }`; + return { + ...transposeProgramMetadata, + output: { dims: unpackedOutputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + getAdjustedPerm = (inputShape, perm) => { + if (perm && perm.length !== inputShape.length) { + perm = [...inputShape.keys()].reverse(); + } + return perm; + }; + getOutputShape = (inputShape, perm) => { + perm = getAdjustedPerm(inputShape, perm); + return ShapeUtil.sortBasedOnPerm(inputShape, perm); + }; + getPermFunctionBody = (name2, perm, rank) => { + const reverseFunc = []; + reverseFunc.push(`void ${name2}(out int a[${rank}], int src[${rank}]) {`); + for (let i = 0; i < rank; ++i) { + reverseFunc.push(` a[${perm[i]}]=src[${i}];`); + } + reverseFunc.push(" }"); + return reverseFunc.join("\n"); + }; + validateInputs7 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Transpose requires 1 input."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("input should be float tensor"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts +var depthToSpace, parseDepthToSpaceAttributes, validateInputs8; +var init_depth_to_space = __esm({ + "web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts"() { + "use strict"; + init_transpose(); + depthToSpace = (inferenceHandler, inputs, attributes) => { + validateInputs8(inputs); + const blocksize = attributes.blocksize; + const blocksizeSqr = blocksize * blocksize; + const transposePerm = attributes.mode === "DCR" ? [0, 3, 4, 1, 5, 2] : [0, 1, 4, 2, 5, 3]; + const firstReshapeShape = attributes.mode === "DCR" ? [ + inputs[0].dims[0], + blocksize, + blocksize, + inputs[0].dims[1] / blocksizeSqr, + inputs[0].dims[2], + inputs[0].dims[3] + ] : [ + inputs[0].dims[0], + inputs[0].dims[1] / blocksizeSqr, + blocksize, + blocksize, + inputs[0].dims[2], + inputs[0].dims[3] + ]; + const firstReshapedTensor = inferenceHandler.reshapeUnpacked(inputs[0], firstReshapeShape); + const transposeAttributes = { perm: transposePerm, cacheKey: `${transposePerm}` }; + const [transposeOutput] = transpose(inferenceHandler, [firstReshapedTensor], transposeAttributes); + const secondReshapeShape = [ + inputs[0].dims[0], + inputs[0].dims[1] / blocksizeSqr, + inputs[0].dims[2] * blocksize, + inputs[0].dims[3] * blocksize + ]; + const result = inferenceHandler.reshapeUnpacked(transposeOutput, secondReshapeShape); + return [result]; + }; + parseDepthToSpaceAttributes = (node) => { + const blocksize = node.attributes.getInt("blocksize"); + if (blocksize < 1) { + throw new Error(`blocksize must be >= 1, but got : ${blocksize} for DepthToSpace`); + } + const mode = node.attributes.getString("mode", "DCR"); + if (mode !== "DCR" && mode !== "CRD") { + throw new Error(`unrecognized mode: ${mode} for DepthToSpace`); + } + return { mode, blocksize }; + }; + validateInputs8 = (inputs) => { + if (inputs.length !== 1) { + throw new Error(`DepthToSpace expect 1 inputs, but got ${inputs.length}`); + } + if (inputs[0].type === "string" || inputs[0].dims.length !== 4) { + throw new TypeError("DepthToSpace input should be a 4-D numeric tensor"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/flatten.ts +var flatten, parseFlattenAttributes, validateInputs9; +var init_flatten = __esm({ + "web/lib/onnxjs/backends/webgl/ops/flatten.ts"() { + "use strict"; + init_util(); + flatten = (inferenceHandler, inputs, axis) => { + validateInputs9(inputs, axis); + const outputDims = ShapeUtil.flattenShape(inputs[0].dims, axis); + return [inferenceHandler.reshapeUnpacked(inputs[0], outputDims)]; + }; + parseFlattenAttributes = (node) => node.attributes.getInt("axis", 1); + validateInputs9 = (inputs, axis) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Flatten requires 1 input."); + } + const r = inputs[0].dims.length; + if (r === 0) { + throw new Error("scalar tensor is not supported."); + } + if (axis < -r || axis > r) { + throw new Error("Invalid axis"); + } + if (inputs[0].type === "string") { + throw new Error("string tensor is not supported."); + } + }; + } +}); + +// web/lib/onnxjs/operators.ts +var NUMBER_TYPES; +var init_operators = __esm({ + "web/lib/onnxjs/operators.ts"() { + "use strict"; + NUMBER_TYPES = [ + "float32", + "float64", + "int32", + "int16", + "int8", + "uint16", + "uint32", + "uint8" + ]; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/gather.ts +var gather, parseGatherAttributes, gatherProgramMetadata, createGatherProgramInfo, createGatherProgramInfoLoader, validateInputs10; +var init_gather = __esm({ + "web/lib/onnxjs/backends/webgl/ops/gather.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_operators(); + init_util(); + init_types(); + gather = (inferenceHandler, inputs, attributes) => { + validateInputs10(inputs, attributes.axis); + const output = inferenceHandler.run(createGatherProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); + return [output]; + }; + parseGatherAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", 0) }); + gatherProgramMetadata = { + name: "Gather", + inputNames: ["A", "B"], + inputTypes: [0 /* unpacked */, 0 /* unpacked */] + }; + createGatherProgramInfo = (_handler, metadata, inputs, axis) => { + const inputShape = inputs[0].dims.slice(); + const indexDataShape = inputs[1].dims.slice(); + const outputShape = new Array(inputShape.length + indexDataShape.length - 1); + axis = ShapeUtil.normalizeAxis(axis, inputShape.length); + const indexCopyOps = []; + for (let i = 0; i < outputShape.length; i++) { + if (i < axis) { + outputShape[i] = inputShape[i]; + indexCopyOps.push(`inputIdx[${i}] = outputIdx[${i}];`); + } else { + if (i < axis + indexDataShape.length) { + outputShape[i] = indexDataShape[i - axis]; + indexCopyOps.push(`indexDataIdx[${i - axis}] = outputIdx[${i}];`); + } else { + outputShape[i] = inputShape[i - indexDataShape.length + 1]; + indexCopyOps.push(`inputIdx[${i - indexDataShape.length + 1}] = outputIdx[${i}];`); + } + } + } + const orank = outputShape.length || 1; + const irank = inputShape.length; + const iDrank = indexDataShape.length || 1; + const shaderSource = ` + float process(int outputIdx[${orank}]) { + int inputIdx[${irank}]; + int indexDataIdx[${iDrank}]; + indexDataIdx[0] = 0; + ${indexCopyOps.join("\n ")} + int idx = int(_B(indexDataIdx)); + inputIdx[${axis}] = idx < 0 ? idx + ${inputShape[axis]} : idx; + return _A(inputIdx); + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createGatherProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = { ...gatherProgramMetadata, cacheHint: attributes.cacheKey }; + return { ...metadata, get: () => createGatherProgramInfo(handler, metadata, inputs, attributes.axis) }; + }; + validateInputs10 = (inputs, axis) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Gather requires 2 inputs."); + } + const tensorRank = inputs[0].dims.length; + if (tensorRank < 1) { + throw new Error("Invalid input shape."); + } + if (axis < -tensorRank || axis > tensorRank - 1) { + throw new Error("Invalid axis."); + } + if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { + throw new Error("Invaid input type."); + } + if (inputs[1].type !== "int32" && inputs[1].type !== "int16") { + throw new Error("Invaid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/gemm.ts +var gemm, parseGemmAttributes, parseGemmAttributesV7, parseGemmAttributesV11, createGemmProgramInfoLoader, createGemmProgramInfo, validateInputs11; +var init_gemm = __esm({ + "web/lib/onnxjs/backends/webgl/ops/gemm.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + gemm = (inferenceHandler, inputs, attributes) => { + validateInputs11(inputs, attributes); + const output = inferenceHandler.run(createGemmProgramInfoLoader(inputs, attributes), inputs); + return [output]; + }; + parseGemmAttributes = (node, isOptionalC) => { + const transA = node.attributes.getInt("transA", 0) !== 0; + const transB = node.attributes.getInt("transB", 0) !== 0; + const alpha = node.attributes.getFloat("alpha", 1); + const beta = node.attributes.getFloat("beta", 1); + return createAttributeWithCacheKey({ transA, transB, alpha, beta, isOptionalC }); + }; + parseGemmAttributesV7 = (node) => parseGemmAttributes(node, false); + parseGemmAttributesV11 = (node) => parseGemmAttributes(node, true); + createGemmProgramInfoLoader = (inputs, attributes) => { + const metadata = { + name: "Gemm", + inputNames: inputs.length === 3 ? ["A", "B", "C"] : ["A", "B"], + inputTypes: inputs.length === 3 ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + key: attributes.cacheKey + }; + return { ...metadata, get: () => createGemmProgramInfo(metadata, inputs, attributes) }; + }; + createGemmProgramInfo = (metadata, inputs, attributes) => { + const aShape = inputs[0].dims.slice(); + const bShape = inputs[1].dims.slice(); + const [M, N] = GemmUtil.getShapeOfGemmResult( + aShape, + attributes.transA, + bShape, + attributes.transB, + inputs.length === 3 ? inputs[2].dims : void 0 + ); + const outputShape = [M, N]; + if (!outputShape) { + throw new Error("Can't use gemm on the given tensors"); + } + let sharedDim = aShape[aShape.length - 1]; + let line = ""; + if (attributes.transA) { + sharedDim = aShape[0]; + } + if (attributes.transA && attributes.transB) { + line = "value += _A_T(a) * _B_T(b);"; + } else if (attributes.transA && !attributes.transB) { + line = "value += _A_T(a) * _B(b);"; + } else if (!attributes.transA && attributes.transB) { + line = "value += _A(a) * _B_T(b);"; + } else if (!attributes.transA && !attributes.transB) { + line = "value += _A(a) * _B(b);"; + } + const rank = outputShape.length; + const declareC = inputs.length === 3 ? `int c[${inputs[2].dims.length}];` : ""; + const broadcastC = inputs.length === 3 ? "bcastIndices_C(indices, c);" : ""; + const calculateC = inputs.length === 3 ? "value += beta * _C(c);" : ""; + const shaderSource = ` + float process(int indices[${rank}]) { + int a[${rank}]; + int b[${rank}]; + ${declareC} + + copyVec(indices, a); + copyVec(indices, b); + ${broadcastC} + + float value = 0.0; + for (int k=0; k<${sharedDim}; ++k) { + a[${rank - 1}] = k; + b[${rank - 2}] = k; + ${line} + } + + value = value * alpha; + ${calculateC} + return value; + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + variables: [ + { name: "alpha", type: "float", data: attributes.alpha }, + { name: "beta", type: "float", data: attributes.beta } + ], + shaderSource + }; + }; + validateInputs11 = (inputs, attributes) => { + if (!inputs) { + throw new Error("Input is missing"); + } + if (attributes.isOptionalC && (inputs.length < 2 || inputs.length > 3)) { + throw new Error("Invaid input shape."); + } + if (!attributes.isOptionalC && inputs.length !== 3) { + throw new Error("Gemm requires 3 inputs"); + } + if (inputs.length === 3 && inputs[2].dims.length !== 1 && inputs[2].dims.length !== 2) { + throw new Error("Invalid input shape of C"); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64" || inputs[1].type !== "float32" && inputs[1].type !== "float64" || inputs.length === 3 && inputs[2].type !== "float32" && inputs[2].type !== "float64") { + throw new Error("Invalid input type."); + } + if (inputs[0].type !== inputs[1].type || inputs.length === 3 && inputs[0].type !== inputs[2].type) { + throw new Error("Input types are mismatched"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/image-scaler.ts +var imageScaler, parseImageScalerAttributes, imageScalerProgramMetadata, createImageScalerProgramInfo, createImageScalerProgramInfoLoader, createGetBiasMethod, validateInputs12; +var init_image_scaler = __esm({ + "web/lib/onnxjs/backends/webgl/ops/image-scaler.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_types(); + imageScaler = (inferenceHandler, inputs, attributes) => { + validateInputs12(inputs); + const output = inferenceHandler.run(createImageScalerProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); + return [output]; + }; + parseImageScalerAttributes = (node) => { + const scale = node.attributes.getFloat("scale"); + const bias = node.attributes.getFloats("bias"); + return createAttributeWithCacheKey({ scale, bias }); + }; + imageScalerProgramMetadata = { + name: "ImageScaler", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + createImageScalerProgramInfo = (_handler, metadata, inputs, attributes) => { + const outputShape = inputs[0].dims.slice(); + const rank = outputShape.length; + const getBiasMethod = createGetBiasMethod(attributes.bias.length); + const shaderSource = ` + ${getBiasMethod} + float process(int indices[${rank}]) { + return _X(indices) * scale + getBias(bias, indices[1]); + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + variables: [ + { name: "bias", type: "float", arrayLength: attributes.bias.length, data: attributes.bias }, + { name: "scale", type: "float", data: attributes.scale } + ], + shaderSource + }; + }; + createImageScalerProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = { ...imageScalerProgramMetadata, cacheHint: attributes.cacheKey }; + return { ...metadata, get: () => createImageScalerProgramInfo(handler, metadata, inputs, attributes) }; + }; + createGetBiasMethod = (numChannels) => { + const codeLines = [`float getBias(float bias[${numChannels}], int channel) {`]; + for (let i = 0; i < numChannels; ++i) { + if (i === 0) { + codeLines.push(` if (channel == ${i}) { return bias[${i}]; }`); + } else if (i === numChannels - 1) { + codeLines.push(` else { return bias[${i}]; }`); + } else { + codeLines.push(` else if (channel == ${i}) { return bias[${i}]; }`); + } + } + codeLines.push(" }"); + return codeLines.join("\n"); + }; + validateInputs12 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("ImageScaler requires 1 input."); + } + if (inputs[0].dims.length !== 4) { + throw new Error("Invalid input shape."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts +var instanceNormalization, parseInstanceNormalizationAttributes, meanAndVarianceProgramMetadata, createMeanAndVarianceProgramInfo, createMeanAndVarianceProgramInfoLoader, computeOutputProgramMetadata, createComputeOutputProgramInfo, createComputeOutputProgramInfoLoader, validateInputs13; +var init_instance_normalization = __esm({ + "web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + instanceNormalization = (inferenceHandler, inputs, epsilon) => { + validateInputs13(inputs); + const meanAndVariance = inferenceHandler.run(createMeanAndVarianceProgramInfoLoader(inputs[0]), inputs); + const output = inferenceHandler.run( + createComputeOutputProgramInfoLoader(inferenceHandler, inputs[0], epsilon, meanAndVariance.dims), + [inputs[0], meanAndVariance, inputs[1], inputs[2]] + ); + return [output]; + }; + parseInstanceNormalizationAttributes = (node) => node.attributes.getFloat("epsilon", 1e-5); + meanAndVarianceProgramMetadata = { + name: "InstanceNormalization_MeanAndVariance", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + createMeanAndVarianceProgramInfo = (metadata, input) => { + const xDims = input.dims.slice(); + const channel = xDims[1]; + const channelSize = xDims[2] * xDims[3]; + const outputShape = [xDims[0], channel]; + const shaderSource = ` + vec4 process(int[2] indices) { + vec4 v = vec4(0.0); + int a[4]; + a[0] = indices[0]; + a[1] = indices[1]; + float temp = 0.0; + for(int a2=0; a2<${xDims[2]}; a2++) { + a[2] = a2; + for(int a3=0; a3<${xDims[3]}; a3++) { + a[3] = a3; + float x = _X(a); + temp += x; + } + } + float mean = temp / float(${channelSize}); + temp = 0.0; + for(int a2=0; a2<${xDims[2]}; a2++) { + a[2] = a2; + for(int a3=0; a3<${xDims[3]}; a3++) { + a[3] = a3; + float x = _X(a); + temp += (x - mean) * (x - mean); + } + } + v.r = mean; + v.g = temp / float(${channelSize}); + + return v; + }`; + return { + ...metadata, + output: { dims: outputShape, type: input.type, textureType: 4 /* packedLastDimension */ }, + shaderSource + }; + }; + createMeanAndVarianceProgramInfoLoader = (input) => ({ + ...meanAndVarianceProgramMetadata, + get: () => createMeanAndVarianceProgramInfo(meanAndVarianceProgramMetadata, input) + }); + computeOutputProgramMetadata = { + name: "InstanceNormalization_ComputeOutput", + inputNames: ["X", "MeanAndVariance", "Scale", "B"], + inputTypes: [0 /* unpacked */, 4 /* packedLastDimension */, 0 /* unpacked */, 0 /* unpacked */] + }; + createComputeOutputProgramInfo = (inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight( + meanAndVarianceShape, + 4 /* packedLastDimension */ + ); + const [meanAndVarianceWidth, meanAndVarianceHeight] = [textureWidth / 4, textureHeight]; + const shaderSource = ` + vec4 get_MeanAndVariance(int[2] mv) { + int offset = indicesToOffset_MeanAndVariance(mv); + vec2 coords = offsetToCoords(offset, ${meanAndVarianceWidth}, ${meanAndVarianceHeight}); + return ${glsl.texture2D}(MeanAndVariance, coords); + } + + float process(int[4] indices) { + int mv[2]; + mv[0] = indices[0]; + mv[1] = indices[1]; + vec4 mean_and_variance = get_MeanAndVariance(mv); + float mean = mean_and_variance.r; + float variance = mean_and_variance.g; + + int sb[1]; + sb[0] = indices[1]; + float scale = _Scale(sb); + float b = _B(sb); + + return scale * (_X(indices) - mean) / sqrt(variance + epsilon) + b; + }`; + return { + ...metadata, + output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, + variables: [{ name: "epsilon", type: "float", data: epsilon }], + shaderSource + }; + }; + createComputeOutputProgramInfoLoader = (inferenceHandler, input, epsilon, meanAndVarianceShape) => { + const metadata = { ...computeOutputProgramMetadata, cacheHint: `${epsilon}` }; + return { + ...metadata, + get: () => createComputeOutputProgramInfo(inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) + }; + }; + validateInputs13 = (inputs) => { + if (!inputs || inputs.length !== 3) { + throw new Error("InstanceNormalization requires 3 inputs."); + } + const X = inputs[0]; + const scale = inputs[1]; + const B = inputs[2]; + if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1) { + throw new Error("Invalid input shape."); + } + if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1]) { + throw new Error("Input shapes are mismatched."); + } + if (X.type !== "float32" && X.type !== "float64" || scale.type !== "float32" && scale.type !== "float64" || B.type !== "float32" && B.type !== "float64") { + throw new Error("Invalid input type."); + } + if (inputs[0].dims.length !== 4) { + throw new Error("Only support 4-D input shape."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/lrn.ts +function createLrnProgramInfo(inputs, attributes) { + const C = inputs[0].dims[1]; + const rank = inputs[0].dims.length; + const from = -Math.floor((attributes.size - 1) / 2); + const to = Math.ceil((attributes.size - 1) / 2); + const alpha = `float(${attributes.alpha}) / float(${attributes.size})`; + const bias = `float(${attributes.bias})`; + const beta = `float(${attributes.beta})`; + const shaderSource = ` + float process(int indices[${rank}]) { + int c = indices[1]; + float x = _X(indices); + float square_sum = 0.0; + + for (int i = ${from}; i <= ${to}; i++) { + int idx = c + i; + if (c >= 0 && c < ${C}) { + indices[1] = idx; + float j = _X(indices); + square_sum += j * j; + } + } + return x / pow(${bias} + ${alpha} * square_sum, ${beta}); + }`; + return { + ...lrnProgramMetadata, + cacheHint: attributes.cacheKey, + output: { dims: inputs[0].dims, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; +} +function createLrnProgramInfoLoader(inputs, attributes) { + return { ...lrnProgramMetadata, cacheHint: attributes.cacheKey, get: () => createLrnProgramInfo(inputs, attributes) }; +} +var lrn, parseLrnAttributes, lrnProgramMetadata, validateInputs14; +var init_lrn = __esm({ + "web/lib/onnxjs/backends/webgl/ops/lrn.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_types(); + lrn = (inferenceHandler, inputs, attributes) => { + validateInputs14(inputs); + return [inferenceHandler.run(createLrnProgramInfoLoader(inputs, attributes), inputs)]; + }; + parseLrnAttributes = (node) => { + const alpha = node.attributes.getFloat("alpha", 1e-4); + const beta = node.attributes.getFloat("beta", 0.75); + const bias = node.attributes.getFloat("bias", 1); + const size = node.attributes.getInt("size"); + return createAttributeWithCacheKey({ alpha, beta, bias, size }); + }; + lrnProgramMetadata = { + name: "LRN", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + validateInputs14 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("LRN requires 1 input."); + } + if (inputs[0].dims.length !== 4) { + throw new Error('currently only support LRN for input with "NCHW" format'); + } + if (inputs[0].type !== "float32") { + throw new Error("input should be float type"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/pad.ts +var padProgramMetadata, padV2, parsePadAttributesV2, padV11, parsePadAttributesV11, generatePadAttributesFromInputs, createPadProgramInfo, validateInputsV2, validateInputsV11, getPadFunction, getPadConstant, getPadReflect, getPadEdge; +var init_pad = __esm({ + "web/lib/onnxjs/backends/webgl/ops/pad.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_glsl_source(); + init_types(); + padProgramMetadata = { + name: "Pad", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + padV2 = (inferenceHandler, inputs, attributes) => { + validateInputsV2(inputs); + const output = inferenceHandler.run( + { + ...padProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createPadProgramInfo(inferenceHandler, inputs[0], attributes) + }, + inputs + ); + return [output]; + }; + parsePadAttributesV2 = (node) => { + const mode = node.attributes.getString("mode", "constant"); + const value = node.attributes.getFloat("value", 0); + const pads = node.attributes.getInts("pads"); + return createAttributeWithCacheKey({ mode, value, pads }); + }; + padV11 = (inferenceHandler, inputs, mode) => { + validateInputsV11(inputs); + const attrubutes = generatePadAttributesFromInputs(inferenceHandler, inputs, mode); + return padV2(inferenceHandler, [inputs[0]], attrubutes); + }; + parsePadAttributesV11 = (node) => node.attributes.getString("mode", "constant"); + generatePadAttributesFromInputs = (inferenceHandler, inputs, mode) => { + if (!inferenceHandler.session.isInitializer(inputs[1].dataId) || inputs.length >= 3 && !inferenceHandler.session.isInitializer(inputs[2].dataId)) { + throw new Error("dynamic pad attributes are not allowed"); + } + const pads = Array.from(inputs[1].integerData); + const value = inputs.length >= 3 ? inputs[2].floatData[0] : 0; + return createAttributeWithCacheKey({ mode, pads, value }); + }; + createPadProgramInfo = (inferenceHandler, input, attributes) => { + const outputShape = ShapeUtil.padShape(input.dims.slice(), attributes.pads); + const rank = outputShape.length; + const padFunction = getPadFunction(inferenceHandler, input, attributes); + const shaderSource = ` + ${padFunction} + float process(int[${rank}] indices) { + return padA(indices); + }`; + return { + name: "Pad", + inputNames: ["A"], + inputTypes: [0 /* unpacked */], + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputsV2 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Pad requires 1 input"); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + }; + validateInputsV11 = (inputs) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Pad requires 2 or 3 inputs"); + } + if (inputs[1].type !== "int32") { + throw new Error("Invalid input type."); + } + if (inputs.length >= 3 && inputs[2].type === "string") { + throw new Error("Invalid input type."); + } + }; + getPadFunction = (inferenceHandler, input, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [width, height] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, 0 /* unpacked */); + const strides = ShapeUtil.computeStrides(input.dims); + switch (attributes.mode) { + case "constant": + return getPadConstant(glsl, input.dims, strides, width, height, attributes.pads, attributes.value); + case "reflect": + return getPadReflect(glsl, input.dims, strides, width, height, attributes.pads); + case "edge": + return getPadEdge(glsl, input.dims, strides, width, height, attributes.pads); + default: + throw new Error("Invalid mode"); + } + }; + getPadConstant = (glsl, shape2, strides, width, height, pads, value) => { + const rank = shape2.length; + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + k = m[${i}] - ${pads[i]}; + if (k < 0) return constant; + if (k >= ${shape2[i]}) return constant; + offset += k * ${strides[i]}; + `; + } + return ` + float padA(int m[${rank}]) { + const float constant = float(${value}); + int offset = 0; + int k = 0; + ${block} + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(A, coords)); + return value; + } + `; + }; + getPadReflect = (glsl, shape2, strides, width, height, pads) => { + const rank = shape2.length; + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + k = m[${i}] - ${pads[i]}; + if (k < 0) { k = -k; } + { + const int _2n_1 = ${2 * (shape2[i] - 1)}; + k = int( mod( float(k), float(_2n_1) ) ) ; + if(k >= ${shape2[i]}) { k = _2n_1 - k; } + } + offset += k * ${strides[i]}; + `; + } + return ` + float padA(int m[${rank}]) { + int offset = 0; + int k = 0; + ${block} + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(A, coords)); + return value; + } + `; + }; + getPadEdge = (glsl, shape2, strides, width, height, pads) => { + const rank = shape2.length; + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + k = m[${i}] - ${pads[i]}; + if (k < 0) k = 0; + if (k >= ${shape2[i]}) k = ${shape2[i] - 1}; + offset += k * ${strides[i]}; + `; + } + return ` + float padA(int m[${rank}]) { + int offset = 0; + int k = 0; + ${block} + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(A, coords)); + return value; + } + `; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/pool.ts +var averagePool, parseAveragePoolAttributes, createAveragePoolProgramInfo, globalAveragePool, parseGlobalAveragePoolAttributes, maxPool, parseMaxPoolAttributes, createMaxPoolProgramInfo, getAdjustedPoolAttributesAndOutputShape, globalMaxPoolAttributes, globalMaxPoolMetadata, globalMaxPool, validateInputs15, generatePoolingCode, copyArray, offsetToIndices; +var init_pool = __esm({ + "web/lib/onnxjs/backends/webgl/ops/pool.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + averagePool = (inferenceHandler, inputs, attributes) => { + validateInputs15(inputs); + const metadata = { + name: "AveragePool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint: attributes.cacheKey + }; + const output = inferenceHandler.run( + { ...metadata, get: () => createAveragePoolProgramInfo(inputs, metadata, false, attributes) }, + inputs + ); + return [output]; + }; + parseAveragePoolAttributes = (node) => { + const autoPad = node.attributes.getString("auto_pad", "NOTSET"); + const ceilMode = node.attributes.getInt("ceil_mode", 0); + const countIncludePad = node.attributes.getInt("count_include_pad", 0) === 0 ? false : true; + const kernelShape = node.attributes.getInts("kernel_shape"); + const strides = node.attributes.getInts("strides", []); + const pads = node.attributes.getInts("pads", []); + if (ceilMode !== 0) { + throw new Error("using ceil() in shape computation is not yet supported for AveragePool"); + } + return createAttributeWithCacheKey({ autoPad, ceilMode, countIncludePad, kernelShape, strides, pads }); + }; + createAveragePoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => { + const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape( + inputs, + attributes, + isGlobalOperator + ); + const kernelSize = ShapeUtil.size(adjustedAttributes.kernelShape); + const op1 = "value += _X(x);"; + let op2 = ""; + if (adjustedAttributes.countIncludePad) { + op2 += `value /= float(${kernelSize});`; + } else { + op2 += `value /= float(${kernelSize} - pad);`; + } + const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, "0.0"); + const shaderSource = ` + ${poolingCode} + `; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + globalAveragePool = (inferenceHandler, inputs, attributes) => { + validateInputs15(inputs); + const metadata = { + name: "GlobalAveragePool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint: `${attributes.countIncludePad}` + }; + const output = inferenceHandler.run( + { ...metadata, get: () => createAveragePoolProgramInfo(inputs, metadata, true, attributes) }, + inputs + ); + return [output]; + }; + parseGlobalAveragePoolAttributes = (node) => { + const countIncludePad = node.attributes.getInt("count_include_pad", 0) === 0 ? false : true; + return createAttributeWithCacheKey({ + autoPad: "", + ceilMode: 0, + countIncludePad, + kernelShape: [], + strides: [], + pads: [] + }); + }; + maxPool = (inferenceHandler, inputs, attributes) => { + validateInputs15(inputs); + const metadata = { + name: "MaxPool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint: attributes.cacheKey + }; + const output = inferenceHandler.run( + { ...metadata, get: () => createMaxPoolProgramInfo(inputs, metadata, false, attributes) }, + inputs + ); + return [output]; + }; + parseMaxPoolAttributes = (node) => { + const autoPad = node.attributes.getString("auto_pad", "NOTSET"); + const ceilMode = node.attributes.getInt("ceil_mode", 0); + const kernelShape = node.attributes.getInts("kernel_shape"); + const strides = node.attributes.getInts("strides", []); + const pads = node.attributes.getInts("pads", []); + const storageOrder = node.attributes.getInt("storage_order", 0); + const dilations = node.attributes.getInts("dilations", []); + if (storageOrder !== 0) { + throw new Error("column major storage order is not yet supported for MaxPool"); + } + if (ceilMode !== 0) { + throw new Error("using ceil() in shape computation is not yet supported for MaxPool"); + } + return createAttributeWithCacheKey({ + autoPad, + ceilMode, + countIncludePad: false, + kernelShape, + strides, + pads, + storageOrder, + dilations + }); + }; + createMaxPoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => { + const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape( + inputs, + attributes, + isGlobalOperator + ); + const op1 = ` + value = max(_X(x), value); + `; + const op2 = ""; + const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, "-1e5"); + const shaderSource = ` + ${poolingCode} + `; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + getAdjustedPoolAttributesAndOutputShape = (inputs, attributes, isGlobalOperator) => { + const inputShape = inputs[0].dims.slice(); + const hasDilations = Object.hasOwnProperty.call(attributes, "dilations"); + const kernelShape = attributes.kernelShape.slice(); + const strides = attributes.strides.slice(); + const dilations = hasDilations ? attributes.dilations.slice() : []; + const pads = attributes.pads.slice(); + PoolConvUtil.adjustPoolAttributes(isGlobalOperator, inputShape, kernelShape, strides, dilations, pads); + const outputShape = PoolConvUtil.computePoolOutputShape( + isGlobalOperator, + inputShape, + strides, + dilations, + kernelShape, + pads, + attributes.autoPad + ); + const newAttributes = Object.assign({}, attributes); + if (hasDilations) { + Object.assign(newAttributes, { kernelShape, strides, pads, dilations, cacheKey: attributes.cacheKey }); + } else { + Object.assign(newAttributes, { kernelShape, strides, pads, cacheKey: attributes.cacheKey }); + } + return [newAttributes, outputShape]; + }; + globalMaxPoolAttributes = { + autoPad: "", + ceilMode: 0, + countIncludePad: false, + kernelShape: [], + strides: [], + pads: [], + storageOrder: 0, + dilations: [], + cacheKey: "" + }; + globalMaxPoolMetadata = { + name: "GlobalMaxPool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + globalMaxPool = (inferenceHandler, inputs) => { + validateInputs15(inputs); + const output = inferenceHandler.run( + { + ...globalMaxPoolMetadata, + get: () => createMaxPoolProgramInfo(inputs, globalMaxPoolMetadata, true, globalMaxPoolAttributes) + }, + inputs + ); + return [output]; + }; + validateInputs15 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Pool ops requires 1 input."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + }; + generatePoolingCode = (inputDims, attributes, op1, op2, start) => { + const rank = inputDims.length; + if (attributes.kernelShape.length <= 2) { + const kw = attributes.kernelShape[attributes.kernelShape.length - 1]; + const sw = attributes.strides[attributes.strides.length - 1]; + const pwStart = attributes.pads[attributes.pads.length / 2 - 1]; + const pwEnd = attributes.pads[attributes.pads.length - 1]; + const dimW = inputDims[rank - 1]; + let codeW = ""; + let codeH = ""; + let codeHEnd = ""; + if (pwStart + pwEnd !== 0) { + codeW = ` + for (int i = 0; i < ${kw}; i++) { + x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i; + if (x[${rank} - 1] < 0 || x[${rank} - 1] >= ${dimW}) { + pad++; + continue; + } + ${op1} + }`; + } else { + codeW = ` + for (int i = 0; i < ${kw}; i++) { + x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i; + ${op1} + }`; + } + if (attributes.kernelShape.length === 2) { + const kh = attributes.kernelShape[attributes.kernelShape.length - 2]; + const sh = attributes.strides[attributes.strides.length - 2]; + const phStart = attributes.pads[attributes.pads.length / 2 - 2]; + const phEnd = attributes.pads[attributes.pads.length - 2]; + const dimH = inputDims[rank - 2]; + if (phStart + phEnd !== 0) { + codeH = ` + for (int j = 0; j < ${kh}; j++) { + x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j; + if (x[${rank} - 2] < 0 || x[${rank} - 2] >= ${dimH}) { + pad+= ${kw}; + continue; + } + `; + } else { + codeH = ` + for (int j = 0; j < ${kh}; j++) { + x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j; + `; + } + codeHEnd = ` + } + `; + } + const poolingCode = ` + float process(int indices[${rank}]) { + int x[${rank}]; + copyVec(indices, x); + + float value = ${start}; + int pad = 0; + ${codeH} + ${codeW} + ${codeHEnd} + ${op2} + return value; + } + `; + return poolingCode; + } else { + const kernelSize = ShapeUtil.size(attributes.kernelShape); + const kernelStrides = ShapeUtil.computeStrides(attributes.kernelShape); + const stridesRank = kernelStrides.length; + const padsRank = attributes.pads.length; + const offsetToIndicesFunction = offsetToIndices(stridesRank); + const copyInputDims = copyArray(inputDims, "inputDims"); + const copyPads = copyArray(attributes.pads, "pads"); + const copyKernelStrides = copyArray(kernelStrides, "kernelStrides"); + const copyStrides = copyArray(attributes.strides, "strides"); + const hasPads = attributes.pads.reduce((sum2, cur) => sum2 + cur); + let padCode = ""; + if (hasPads) { + padCode = ` + if (x[j] >= inputDims[j] || x[j] < 0) { + pad++; + isPad = true; + break; + } + } + if (!isPad) { + ${op1} + }`; + } else { + padCode = ` + } + ${op1} + `; + } + const poolingCode = ` + ${offsetToIndicesFunction} + float process(int indices[${rank}]) { + int x[${rank}]; + copyVec(indices, x); + int offset[${stridesRank}]; + int pads[${padsRank}]; + int inputDims[${rank}]; + int kernelStrides[${stridesRank}]; + int strides[${stridesRank}]; + ${copyPads} + ${copyInputDims} + ${copyStrides} + ${copyKernelStrides} + + float value = ${start}; + int pad = 0; + bool isPad = false; + for (int i = 0; i < ${kernelSize}; i++) { + offsetToIndices(i, kernelStrides, offset); + isPad = false; + for (int j = ${rank} - ${stridesRank}; j < ${rank}; j++) { + x[j] = indices[j] * strides[j - ${rank} + ${stridesRank}] + + offset[j - ${rank} + ${stridesRank}] - pads[j - 2]; + ${padCode} + } + ${op2} + + return value; + } + `; + return poolingCode; + } + }; + copyArray = (array, arrayName) => { + let block = ""; + for (let i = 0; i < array.length; i++) { + block += ` + ${arrayName}[${i}] = ${array[i]}; + `; + } + return block; + }; + offsetToIndices = (rank) => ` + void offsetToIndices(int offset, int[${rank}] strides, out int[${rank}] indices) { + if (${rank} == 0) { + return; + } + for (int i = 0; i < ${rank} - 1; ++i) { + indices[i] = offset / strides[i]; + offset -= indices[i] * strides[i]; + } + indices[${rank} - 1] = offset; + }`; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/reduce.ts +var reduce, parseReduceAttributes, createReduceProgramInfo, validateInputs16, reduceSum, reduceMean, reduceMax, reduceMin, reduceProd, reduceLogSum, reduceLogSumSquare; +var init_reduce = __esm({ + "web/lib/onnxjs/backends/webgl/ops/reduce.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_operators(); + init_util(); + init_types(); + reduce = (inferenceHandler, inputs, attributes, name2, reduceOp) => { + validateInputs16(inputs); + const reduceProgramMetadata = { + name: name2, + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + const output = inferenceHandler.run( + { + ...reduceProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createReduceProgramInfo(inferenceHandler, inputs, attributes, name2, reduceOp, reduceProgramMetadata) + }, + inputs + ); + return [output]; + }; + parseReduceAttributes = (node) => { + const axes = node.attributes.getInts("axes", []); + const keepDims = node.attributes.getInt("keepdims", 1) === 1; + return createAttributeWithCacheKey({ axes, keepDims }); + }; + createReduceProgramInfo = (_handler, inputs, attributes, _name, reduceOp, reduceProgramMetadata) => { + const outputShape = []; + const iRank = inputs[0].dims.length || 1; + const idxCopy = []; + const axes = ShapeUtil.normalizeAxes(attributes.axes, inputs[0].dims.length); + const ops = reduceOp(inputs, axes); + let reduceOps = ops[1]; + for (let k = 0; k < inputs[0].dims.length; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + if (attributes.keepDims) { + outputShape.push(1); + } + reduceOps = ` + for(int j${k} = 0; j${k} < ${inputs[0].dims[k]}; j${k}++) { + inputIdx[${k}] = j${k}; + ${reduceOps} + }`; + } else { + idxCopy.push(`inputIdx[${k}] = outputIdx[${outputShape.length}];`); + outputShape.push(inputs[0].dims[k]); + } + } + const oRank = outputShape.length || 1; + const shaderSource = ` + float process(int outputIdx[${oRank}]) { + float value; // final result + int inputIdx[${iRank}]; // addressing input data + ${idxCopy.join("\n")} + ${ops[0]} // init ops for reduce max/min + ${reduceOps} + ${ops[2]} // final computation for reduce mean + return value; + }`; + return { + ...reduceProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs16 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Reduce op requires 1 input."); + } + if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { + throw new Error("Invalid input type."); + } + }; + reduceSum = (inferenceHandler, inputs, attributes) => { + const reduceOp = () => ["value = 0.0;", "value += _A(inputIdx);", ""]; + return reduce(inferenceHandler, inputs, attributes, "ReduceSum", reduceOp); + }; + reduceMean = (inferenceHandler, inputs, attributes) => { + const reduceOp = (inputs2, axes) => { + let size = 1; + for (let k = 0; k < inputs2[0].dims.length; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + size *= inputs2[0].dims[k]; + } + } + return ["value = 0.0;", "value += _A(inputIdx);", `value /= ${size}.;`]; + }; + return reduce(inferenceHandler, inputs, attributes, "ReduceMean", reduceOp); + }; + reduceMax = (inferenceHandler, inputs, attributes) => { + const reduceOp = (inputs2, axes) => { + const idxZero = []; + for (let k = 0; k < inputs2[0].dims.length; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + idxZero.push(`inputIdx[${k}] = 0;`); + } + } + return [`${idxZero.join("\n")} +value = _A(inputIdx);`, "value = max(value, _A(inputIdx));", ""]; + }; + return reduce(inferenceHandler, inputs, attributes, "ReduceMax", reduceOp); + }; + reduceMin = (inferenceHandler, inputs, attributes) => { + const reduceOp = (inputs2, axes) => { + const idxZero = []; + for (let k = 0; k < inputs2[0].dims.length; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + idxZero.push(`inputIdx[${k}] = 0;`); + } + } + return [`${idxZero.join("\n")} +value = _A(inputIdx);`, "value = min(value, _A(inputIdx));", ""]; + }; + return reduce(inferenceHandler, inputs, attributes, "ReduceMin", reduceOp); + }; + reduceProd = (inferenceHandler, inputs, attributes) => { + const reduceOp = () => ["value = 1.0;", "value *= _A(inputIdx);", ""]; + return reduce(inferenceHandler, inputs, attributes, "ReduceProd", reduceOp); + }; + reduceLogSum = (inferenceHandler, inputs, attributes) => { + const reduceOp = () => ["value = 0.0;", "value += _A(inputIdx);", "value = log(value);"]; + return reduce(inferenceHandler, inputs, attributes, "ReduceLogSum", reduceOp); + }; + reduceLogSumSquare = (inferenceHandler, inputs, attributes) => { + const reduceOp = () => ["float t; value = 0.0;", "t = _A(inputIdx); value += t * t;", ""]; + return reduce(inferenceHandler, inputs, attributes, "ReduceLogSumSquare", reduceOp); + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/reshape.ts +var reshape; +var init_reshape = __esm({ + "web/lib/onnxjs/backends/webgl/ops/reshape.ts"() { + "use strict"; + init_util(); + reshape = (handler, inputs) => { + const reshapedDims = ShapeUtil.calculateReshapedDims(inputs[0].dims, inputs[1].integerData); + if (handler.session.pack) { + return [handler.reshapePacked(inputs[0], reshapedDims)]; + } else { + return [handler.reshapeUnpacked(inputs[0], reshapedDims)]; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/upsample.ts +var upsampleProgramMetadata, upsample, parseUpsampleAttributesV7, parseUpsampleAttributesV9, parseUpsampleAttributes, createUpsampleProgramInfo, validateInputs17, scalesValidation; +var init_upsample = __esm({ + "web/lib/onnxjs/backends/webgl/ops/upsample.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_glsl_source(); + init_types(); + upsampleProgramMetadata = { + name: "Upsample", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + upsample = (inferenceHandler, inputs, attributes) => { + validateInputs17(inputs, attributes); + const output = inferenceHandler.run( + { + ...upsampleProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createUpsampleProgramInfo(inferenceHandler, inputs, attributes) + }, + inputs + ); + return [output]; + }; + parseUpsampleAttributesV7 = (node) => parseUpsampleAttributes(node, 7); + parseUpsampleAttributesV9 = (node) => parseUpsampleAttributes(node, 9); + parseUpsampleAttributes = (node, opset) => { + const isResize = opset >= 10; + const mode = node.attributes.getString("mode", "nearest"); + if (mode !== "nearest" && mode !== "linear" && (opset < 11 || mode !== "cubic")) { + throw new Error(`unrecognized mode: ${mode}`); + } + let scales = []; + if (opset < 9) { + scales = node.attributes.getFloats("scales"); + scalesValidation(scales, mode, isResize); + } + const extrapolationValue = node.attributes.getFloat("extrapolation_value", 0); + const coordinateTransformMode = opset > 10 ? node.attributes.getString("coordinate_transformation_mode", "half_pixel") : "asymmetric"; + if ([ + "asymmetric", + "pytorch_half_pixel", + "tf_half_pixel_for_nn", + "align_corners", + "tf_crop_and_resize", + "half_pixel" + ].indexOf(coordinateTransformMode) === -1) { + throw new Error(`coordinate_transform_mode '${coordinateTransformMode}' is not supported`); + } + const needRoiInput = coordinateTransformMode === "tf_crop_and_resize"; + const useExtrapolation = needRoiInput; + const nearestMode = mode === "nearest" && opset >= 11 ? node.attributes.getString("nearest_mode", "round_prefer_floor") : ""; + if (["round_prefer_floor", "round_prefer_ceil", "floor", "ceil", ""].indexOf(nearestMode) === -1) { + throw new Error(`nearest_mode '${nearestMode}' is not supported`); + } + const cubicCoefficientA = node.attributes.getFloat("cubic_coeff_a", -0.75); + const excludeOutside = node.attributes.getInt("exclude_outside", 0) !== 0; + if (excludeOutside && mode !== "cubic") { + throw new Error("exclude_outside can be set to 1 only when mode is CUBIC."); + } + const useNearest2xOptimization = opset < 11 ? true : mode === "nearest" && coordinateTransformMode === "asymmetric" && nearestMode === "floor"; + let roiInputIdx = 0; + let scalesInputIdx = 0; + let sizesInputIdx = 0; + if (opset > 10) { + if (node.inputs.length > 2) { + roiInputIdx = 1; + scalesInputIdx = 2; + sizesInputIdx = 3; + } else { + scalesInputIdx = 1; + sizesInputIdx = 2; + } + } else if (opset === 9) { + scalesInputIdx = 1; + } + return createAttributeWithCacheKey({ + opset, + isResize, + mode, + scales, + extrapolationValue, + coordinateTransformMode, + useExtrapolation, + needRoiInput, + nearestMode, + cubicCoefficientA, + excludeOutside, + useNearest2xOptimization, + roiInputIdx, + scalesInputIdx, + sizesInputIdx + }); + }; + createUpsampleProgramInfo = (inferenceHandler, inputs, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [inputWidth, inputHeight] = inferenceHandler.calculateTextureWidthAndHeight( + inputs[0].dims, + 0 /* unpacked */ + ); + const outputShape = inputs[0].dims.map((dim2, i) => Math.floor(dim2 * attributes.scales[i])); + const [outputWidth, outputHeight] = inferenceHandler.calculateTextureWidthAndHeight( + outputShape, + 0 /* unpacked */ + ); + const dim = outputShape.length; + const outputPitches = new Array(dim); + const inputPitches = new Array(dim); + let precalculatedPitches = ` + int output_pitches[${dim}]; + int input_pitches[${dim}]; + `; + for (let d = dim - 1; d >= 0; d--) { + outputPitches[d] = d === dim - 1 ? 1 : outputPitches[d + 1] * outputShape[d + 1]; + inputPitches[d] = d === dim - 1 ? 1 : inputPitches[d + 1] * inputs[0].dims[d + 1]; + precalculatedPitches += ` + output_pitches[${d}] = ${outputPitches[d]}; + input_pitches[${d}] = ${inputPitches[d]}; + `; + } + const getInputFloatFunction = ` + float getInputFloat(int index) { + vec2 coords = offsetToCoords(index, ${inputWidth}, ${inputHeight}); + float value = getColorAsFloat(${glsl.texture2D}(X, coords)); + return value; + } + `; + const shaderSource = attributes.mode === "nearest" ? ( + // nearest + ` + ${getInputFloatFunction} + float process(int indices[${dim}]) { + int input_index = 0; + int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight}); + + ${precalculatedPitches} + + int d, m; + for (int dim = 0; dim < ${dim}; ++dim) { + d = output_index / output_pitches[dim]; + m = output_index - d * output_pitches[dim]; + output_index = m; + + if (scales[dim] != 1 && d > 0) { + int d2 = d / scales[dim]; + m = d - d2 * scales[dim]; + d = d2; + } + input_index += input_pitches[dim] * d; + } + + return getInputFloat(input_index); + }` + ) : dim === 4 ? ( + // bilinear 4D + ` + ${getInputFloatFunction} + float process(int indices[4]) { + int input_index = 0; + int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight}); + + ${precalculatedPitches} + + int m; + int index_of_dim0, index_of_dim1, index_of_dim2, index_of_dim3; + index_of_dim0 = output_index / output_pitches[0]; + m = output_index - index_of_dim0 * output_pitches[0]; + index_of_dim1 = m / output_pitches[1]; + m = m - index_of_dim1 * output_pitches[1]; + index_of_dim2 = m / output_pitches[2]; + m = m - index_of_dim2 * output_pitches[2]; + index_of_dim3 = m; + + int index_of_input_dim2, index_of_input_dim3, x_offset, y_offset; + index_of_input_dim2 = index_of_dim2 / scales[2]; + y_offset = index_of_dim2 - index_of_input_dim2 * scales[2]; + index_of_input_dim3 = index_of_dim3 / scales[3]; + x_offset = index_of_dim3 - index_of_input_dim3 * scales[3]; + + input_index = index_of_dim0 * input_pitches[0] + + index_of_dim1 * input_pitches[1] + + index_of_input_dim2 * input_pitches[2] + + index_of_input_dim3; + + float x00 = getInputFloat(input_index); + float x10, x01, x11; + + bool end_of_dim2 = false; + if (index_of_input_dim2 == (${inputs[0].dims[2]} - 1)) { + // It's the end in dimension 2 + x01 = x00; + end_of_dim2 = true; + } else { + x01 = getInputFloat(input_index + input_pitches[2]); + } + + if (index_of_input_dim3 == (input_pitches[2] - 1)) { + // It's the end in dimension 3 + x10 = x00; + x11 = x01; + } + else { + x10 = getInputFloat(input_index + 1); + x11 = end_of_dim2 ? x10 : getInputFloat(input_index + input_pitches[2] + 1); + } + + float y0 = x00 + float(y_offset) * (x01 - x00) / float(scales[2]); + float y1 = x10 + float(y_offset) * (x11 - x10) / float(scales[2]); + return y0 + float(x_offset) * (y1 - y0) / float(scales[3]); + }` + ) : ( + // bilinear 2D + ` + ${getInputFloatFunction} + float process(int indices[2]) { + int input_index = 0; + int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight}); + + ${precalculatedPitches} + + int m; + int index_of_dim0, index_of_dim1; + index_of_dim0 = output_index / output_pitches[0]; + m = output_index - index_of_dim0 * output_pitches[0]; + index_of_dim1 = m; + + int index_of_input_dim0, index_of_input_dim1, x_offset, y_offset; + index_of_input_dim0 = index_of_dim0 / scales[0]; + y_offset = index_of_dim0 - index_of_input_dim0 * scales[0]; + index_of_input_dim1 = index_of_dim1 / scales[1]; + x_offset = index_of_dim1 - index_of_input_dim1 * scales[1]; + + input_index = index_of_input_dim0 * input_pitches[0] + index_of_input_dim1; + + float x00 = getInputFloat(input_index); + float x10, x01, x11; + + bool end_of_dim0 = false; + if (index_of_input_dim0 == (${inputs[0].dims[0]} - 1)) { + // It's the end in dimension 0 + x01 = x00; + end_of_dim0 = true; + } else { + x01 = getInputFloat(input_index + input_pitches[0]); + } + + if (index_of_input_dim1 == (input_pitches[0] - 1)) { + // It's the end in dimension 1 + x10 = x00; + x11 = x01; + } + else { + x10 = getInputFloat(input_index + 1); + x11 = end_of_dim0 ? x10 : getInputFloat(input_index + input_pitches[0] + 1); + } + + float y0 = x00 + float(y_offset) * (x01 - x00) / float(scales[0]); + float y1 = x10 + float(y_offset) * (x11 - x10) / float(scales[0]); + return y0 + float(x_offset) * (y1 - y0) / float(scales[1]); + }` + ); + return { + ...upsampleProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource, + variables: [ + { + name: "scales", + type: "int", + arrayLength: attributes.scales.length, + data: attributes.scales.map((x) => Math.ceil(x)) + } + ] + }; + }; + validateInputs17 = (inputs, attribute) => { + if (!inputs || attribute.opset < 9 && inputs.length !== 1 || attribute.opset >= 9 && attribute.opset < 11 && inputs.length !== 2 || attribute.opset >= 11 && inputs.length < 2) { + throw new Error("invalid inputs."); + } + if (attribute.scales.length > 0 && inputs[0].dims.length !== attribute.scales.length) { + throw new Error("Invalid input shape."); + } + if (inputs[0].type === "string") { + throw new Error("Invalid input tensor types."); + } + }; + scalesValidation = (scales, mode, isResize) => { + if (!isResize) { + for (const scale of scales) { + if (scale < 1) { + throw new Error("Scale value should be greater than or equal to 1."); + } + } + } else { + for (const scale of scales) { + if (scale <= 0) { + throw new Error("Scale value should be greater than 0."); + } + } + } + if (mode === "linear" || mode === "cubic") { + if (scales.length !== 2 && (scales.length !== 4 || scales[0] !== 1 || scales[1] !== 1)) { + throw new Error(`'Linear' mode and 'Cubic' mode only support 2-D inputs ('Bilinear', 'Bicubic') or 4-D inputs with the corresponding outermost 2 scale values being 1 in the ${isResize ? "Resize" : "Upsample"} opeartor.`); + } + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/resize-packed.ts +var resizeProgramMetadata, resize, parseResizeAttributesV10, parseResizeAttributesV11, createPackedResizeProgramInfo, prepareInputs, parseScalesData, parseScalesDataFromOutputSize; +var init_resize_packed = __esm({ + "web/lib/onnxjs/backends/webgl/ops/resize-packed.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + init_upsample(); + resizeProgramMetadata = { + name: "Resize", + inputNames: ["A"], + inputTypes: [2 /* packed */] + }; + resize = (inferenceHandler, inputs, attributes) => { + validateInputs17(inputs, attributes); + const output = inferenceHandler.run( + { + ...resizeProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createPackedResizeProgramInfo(inferenceHandler, inputs, attributes) + }, + inputs + ); + return [output]; + }; + parseResizeAttributesV10 = (node) => parseUpsampleAttributes(node, 10); + parseResizeAttributesV11 = (node) => parseUpsampleAttributes(node, 11); + createPackedResizeProgramInfo = (inferenceHandler, inputs, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [scales, outputShape] = prepareInputs(inputs, attributes); + const isSame = scales.every((s) => s === 1) && attributes.coordinateTransformMode !== "tf_crop_and_resize"; + if (isSame) { + return { + ...resizeProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + hasMain: true, + shaderSource: `void main() { + vec4 v = ${glsl.texture2D}(X, TexCoords); + ${glsl.output} = v; + }` + }; + } + const dim = outputShape.length; + if (dim < 2) { + throw new Error(`output dimension should be at least 2, but got ${dim}`); + } + const outputHeight = outputShape[dim - 2]; + const outputWidth = outputShape[dim - 1]; + const inputShape = inputs[0].dims; + if (dim !== inputShape.length) { + throw new Error(`output dimension should match input ${inputShape.length}, but got ${dim}`); + } + const inputHeight = inputShape[dim - 2]; + const inputWidth = inputShape[dim - 1]; + const scalesHeight = scales[dim - 2]; + const scalesWidth = scales[dim - 1]; + let getSourceFracIndex = ""; + if (attributes.mode !== "linear") { + throw new Error(`resize (packed) does not support mode: '${attributes.mode}'`); + } + switch (attributes.coordinateTransformMode) { + case "asymmetric": + getSourceFracIndex = ` + vec4 getSourceFracIndex(ivec4 coords) { + return vec4(coords) / scaleWHWH; + } + `; + break; + case "half_pixel": + getSourceFracIndex = ` + vec4 getSourceFracIndex(ivec4 coords) { + return (vec4(coords) + 0.5) / scaleWHWH - 0.5; + } + `; + break; + case "pytorch_half_pixel": + getSourceFracIndex = ` + vec4 getSourceFracIndex(ivec4 coords) { + vec4 fcoords = vec4(coords); + return vec4( + ${outputWidth}.0 > 1.0 ? (fcoords.x + 0.5) / scaleWHWH.x - 0.5 : 0.0, + ${outputHeight}.0 > 1.0 ? (fcoords.y + 0.5) / scaleWHWH.y - 0.5 : 0.0, + ${outputWidth}.0 > 1.0 ? (fcoords.z + 0.5) / scaleWHWH.z - 0.5 : 0.0, + ${outputHeight}.0 > 1.0 ? (fcoords.w + 0.5) / scaleWHWH.w - 0.5 : 0.0 + ); + } + `; + break; + case "align_corners": + getSourceFracIndex = ` + vec4 getSourceFracIndex(ivec4 coords) { + vec4 resized = vec4(${outputWidth}.0 - 1.0, ${outputHeight}.0 - 1.0, ${outputWidth}.0 - 1.0, + ${outputHeight}.0 - 1.0); + vec4 original = vec4(${inputWidth}.0 - 1.0, ${inputHeight}.0 - 1.0, ${inputWidth}.0 - 1.0, + ${inputHeight}.0 - 1.0); + vec4 new_scale = original / resized; + return vec4(coords) * new_scale; + } + `; + break; + default: + throw new Error(`resize (packed) does not support coordinateTransformMode: '${attributes.coordinateTransformMode}'`); + } + const coordsDataType = getCoordsDataType(dim); + const unpackChannel = unpackFromChannel(); + const shaderSource = ` + const vec2 inputWH = vec2(${inputHeight}.0, ${inputWidth}.0); + const vec4 scaleWHWH = vec4(float(${scalesHeight}), float(${scalesWidth}), float(${scalesHeight}), float(${scalesWidth})); + ${unpackChannel} + ${getSourceFracIndex} + float getAValue(int x10, int r, int c, int d) { + return getChannel(getA(x10, r, c, d), vec2(c, d)); + } + void main() { + ${coordsDataType} rc = getOutputCoords(); + + int batch = rc[0]; + int depth = rc[1]; + + // retrieve the 4 coordinates that is used in the 4 packed output values. + ivec4 coords = ivec4(rc.wz, rc.w + 1, rc.z + 1); + + // calculate the source index in fraction + vec4 sourceFrac = getSourceFracIndex(coords); + + // get the lower and upper bound of the 4 values that will be packed into one texel. + ivec4 x00 = ivec4(max(sourceFrac.xy, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.xy))); + ivec4 x01 = ivec4(max(sourceFrac.xw, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.xw))); + ivec4 x10 = ivec4(max(sourceFrac.zy, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.zy))); + ivec4 x11 = ivec4(max(sourceFrac.zw, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.zw))); + + bool hasNextRow = rc.w < ${outputHeight - 1}; + bool hasNextCol = rc.z < ${outputWidth - 1}; + + // pack x00, x01, x10, x11's top-left corner into one vec4 structure + vec4 topLeft = vec4( + getAValue(batch, depth, x00.x, x00.y), + hasNextCol ? getAValue(batch, depth, x01.x, x01.y) : 0.0, + hasNextRow ? getAValue(batch, depth, x10.x, x10.y) : 0.0, + (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.x, x11.y) : 0.0); + + // pack x00, x01, x10, x11's top-right corner into one vec4 structure + vec4 topRight = vec4( + getAValue(batch, depth, x00.x, x00.w), + hasNextCol ? getAValue(batch, depth, x01.x, x01.w) : 0.0, + hasNextRow ? getAValue(batch, depth, x10.x, x10.w) : 0.0, + (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.x, x11.w) : 0.0); + + // pack x00, x01, x10, x11's bottom-left corner into one vec4 structure + vec4 bottomLeft = vec4( + getAValue(batch, depth, x00.z, x00.y), + hasNextCol ? getAValue(batch, depth, x01.z, x01.y) : 0.0, + hasNextRow ? getAValue(batch, depth, x10.z, x10.y) : 0.0, + (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.z, x11.y) : 0.0); + + // pack x00, x01, x10, x11's bottom-right corner into one vec4 structure + vec4 bottomRight = vec4( + getAValue(batch, depth, x00.z, x00.w), + hasNextCol ? getAValue(batch, depth, x01.z, x01.w) : 0.0, + hasNextRow ? getAValue(batch, depth, x10.z, x10.w) : 0.0, + (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.z, x11.w) : 0.0); + + // calculate the interpolation fraction on u and v direction + vec4 frac = vec4(sourceFrac) - floor(sourceFrac); + vec4 clampFrac = clamp(frac, vec4(0.0), vec4(1.0)); + + vec4 top = mix(topLeft, topRight, clampFrac.ywyw); + vec4 bottom = mix(bottomLeft, bottomRight, clampFrac.ywyw); + vec4 newValue = mix(top, bottom, clampFrac.xxzz); + + ${glsl.output} = vec4(newValue); + } + `; + return { + ...resizeProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + hasMain: true, + shaderSource + }; + }; + prepareInputs = (inputs, attributes) => { + const x = inputs[0]; + const xDims = x.dims; + let scales = attributes.scales; + let outputSizes; + if (scales.length === 0) { + const scalesTensor = inputs[attributes.scalesInputIdx]; + if (scalesTensor && scalesTensor.size !== 0) { + if (inputs[attributes.sizesInputIdx]) { + throw new Error("Only one of scales or sizes must be provided as input."); + } + scales = parseScalesData(scalesTensor, attributes.mode, attributes.isResize); + } else { + const sizesTensor = inputs[attributes.sizesInputIdx]; + if (!sizesTensor || sizesTensor.size === 0) { + throw new Error("Either scales or sizes MUST be provided as input."); + } + outputSizes = Array.from(sizesTensor.integerData); + scales = parseScalesDataFromOutputSize(outputSizes, xDims, attributes.mode, attributes.isResize); + } + } else { + if (inputs[attributes.sizesInputIdx]) { + throw new Error("Only one of scales or sizes must be provided as input."); + } + } + const yDims = outputSizes || xDims.map((dim, i) => Math.floor(dim * scales[i])); + return [scales, yDims]; + }; + parseScalesData = (scale, mode, isResize) => { + const scales = Array.from(scale.floatData); + scalesValidation(scales, mode, isResize); + return scales; + }; + parseScalesDataFromOutputSize = (yDims, xDims, mode, isResize) => { + const length = xDims.length; + const scales = new Array(length); + for (let i = 0, end = length; i < end; i++) { + if (xDims[i] === 0) { + if (yDims[i] !== 0) { + throw new Error("Input dim is zero but required output dim is non-zero."); + } + scales[i] = 1; + } else { + scales[i] = yDims[i] / xDims[i]; + } + } + scalesValidation(scales, mode, isResize); + return scales; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/shape.ts +var shape, validateInputs18; +var init_shape = __esm({ + "web/lib/onnxjs/backends/webgl/ops/shape.ts"() { + "use strict"; + init_tensor2(); + shape = (_inferenceHandler, inputs) => { + validateInputs18(inputs); + return [new Tensor4([inputs[0].dims.length], "int32", void 0, void 0, new Int32Array(inputs[0].dims))]; + }; + validateInputs18 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Shape requires 1 input."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/slice.ts +var sliceProgramMetadata, slice, parseSliceAttributes, createSliceProgramInfo, validateInputs19, sliceV10, generateSliceAttributesFromInputs, validateInputsV10; +var init_slice = __esm({ + "web/lib/onnxjs/backends/webgl/ops/slice.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_operators(); + init_util(); + init_types(); + sliceProgramMetadata = { + name: "Slice", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + slice = (inferenceHandler, inputs, attributes) => { + validateInputs19(inputs); + const output = inferenceHandler.run( + { + ...sliceProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createSliceProgramInfo(inferenceHandler, inputs[0], attributes) + }, + inputs + ); + return [output]; + }; + parseSliceAttributes = (node) => { + const starts = node.attributes.getInts("starts"); + const ends = node.attributes.getInts("ends"); + const axes = node.attributes.getInts("axes", []); + return createAttributeWithCacheKey({ starts, ends, axes }); + }; + createSliceProgramInfo = (_inferenceHandler, input, attributes) => { + const axes = attributes.axes.length === 0 ? input.dims.slice(0).map((_val, i) => i) : attributes.axes; + const normalizedAxes = ShapeUtil.normalizeAxes(axes, input.dims.length); + const starts = attributes.starts.map((start, i) => { + if (start > input.dims[normalizedAxes[i]] - 1) { + return input.dims[normalizedAxes[i]]; + } + return ShapeUtil.normalizeAxis(start, input.dims[normalizedAxes[i]]); + }); + const ends = attributes.ends.map((end, i) => { + if (end > input.dims[normalizedAxes[i]] - 1) { + return input.dims[normalizedAxes[i]]; + } + return ShapeUtil.normalizeAxis(end, input.dims[normalizedAxes[i]]); + }); + const outputShape = input.dims.slice(); + const sliceOps = []; + for (let i = 0; i < normalizedAxes.length; i++) { + outputShape[normalizedAxes[i]] = ends[i] - starts[i]; + if (starts[i] > 0) { + sliceOps.push(`outputIdx[${normalizedAxes[i]}] += ${starts[i]};`); + } + } + const rank = outputShape.length; + const shaderSource = ` + float process(int outputIdx[${rank}]) { + ${sliceOps.join("\n ")} + return _A(outputIdx); + }`; + return { + ...sliceProgramMetadata, + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs19 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Slice requires 1 input."); + } + if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { + throw new Error("Invalid input type."); + } + }; + sliceV10 = (inferenceHandler, inputs) => { + validateInputsV10(inputs); + const attributes = generateSliceAttributesFromInputs(inferenceHandler, inputs); + const output = inferenceHandler.run( + { + ...sliceProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createSliceProgramInfo(inferenceHandler, inputs[0], attributes) + }, + [inputs[0]] + ); + return [output]; + }; + generateSliceAttributesFromInputs = (inferenceHandler, inputs) => { + if (!inferenceHandler.session.isInitializer(inputs[1].dataId) || !inferenceHandler.session.isInitializer(inputs[2].dataId) || inputs.length >= 4 && !inferenceHandler.session.isInitializer(inputs[3].dataId) || inputs.length >= 5 && !inferenceHandler.session.isInitializer(inputs[4].dataId)) { + throw new Error("dynamic slice attributes are not allowed"); + } + if (inputs.length >= 5 && inputs[4].integerData.some((i) => i !== 1)) { + throw new Error("currently non-1 steps is not supported for Slice"); + } + const starts = Array.from(inputs[1].integerData); + const ends = Array.from(inputs[2].integerData); + const axes = inputs.length >= 4 ? Array.from(inputs[3].integerData) : []; + const cacheKey = `${axes};${starts};${ends}`; + return { starts, ends, axes, cacheKey }; + }; + validateInputsV10 = (inputs) => { + if (!inputs || inputs.length < 3 || inputs.length > 5) { + throw new Error("Invalid input number."); + } + if (inputs[1].type !== "int32" || inputs[1].dims.length !== 1) { + throw new Error("Invalid input type."); + } + if (inputs[2].type !== "int32" || inputs[2].dims.length !== 1) { + throw new Error("Invalid input type."); + } + if (inputs.length >= 4 && (inputs[3].type !== "int32" || inputs[3].dims.length !== 1)) { + throw new Error("Invalid input type."); + } + if (inputs.length >= 5 && (inputs[4].type !== "int32" || inputs[4].dims.length !== 1)) { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/softmax.ts +var softmaxComputeMaxProgramMetadata, softmaxComputeScaleProgramMetadata, softmaxProgramMetadata, softmax, parseSoftmaxAttributes, parseSoftmaxAttributesV13, softmaxV13, computeSoftmax, createComputeMaxProgramInfo, createComputScaleProgramInfo, createSoftMaxProgramInfo, validateInputs20; +var init_softmax = __esm({ + "web/lib/onnxjs/backends/webgl/ops/softmax.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_glsl_source(); + init_types(); + init_transpose(); + softmaxComputeMaxProgramMetadata = { + name: "SoftmaxComputeMax", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + softmaxComputeScaleProgramMetadata = { + name: "SoftmaxComputeScale", + inputNames: ["A", "Max"], + inputTypes: [0 /* unpacked */, 0 /* unpacked */] + }; + softmaxProgramMetadata = { + name: "SoftMax", + inputNames: ["A", "Max", "Norm"], + inputTypes: [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] + }; + softmax = (inferenceHandler, inputs, attributes) => { + validateInputs20(inputs); + const inputShape = inputs[0].dims.slice(); + const axis = ShapeUtil.normalizeAxis(attributes.axis, inputShape.length); + const logicalRowCount = ShapeUtil.sizeToDimension(inputShape, axis); + const featureCount = ShapeUtil.sizeFromDimension(inputShape, axis); + const output = computeSoftmax(inferenceHandler, inputs, attributes, logicalRowCount, featureCount); + return output; + }; + parseSoftmaxAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", 1) }); + parseSoftmaxAttributesV13 = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", -1) }); + softmaxV13 = (inferenceHandler, inputs, attributes) => { + validateInputs20(inputs); + const inputShape = inputs[0].dims.slice(); + const axis = ShapeUtil.normalizeAxis(attributes.axis, inputShape.length); + const rank = inputShape.length; + const isTransposeRequired = axis !== rank - 1 ? true : false; + const transposedInputShape = []; + let perm = []; + let transposedInputs = []; + let transposeAttribute; + if (isTransposeRequired) { + perm = Array.from({ length: rank }).map((_, i) => i); + perm[axis] = rank - 1; + perm[rank - 1] = axis; + perm.map((p) => transposedInputShape.push(inputShape[p])); + transposeAttribute = createAttributeWithCacheKey({ perm }); + transposedInputs = transpose(inferenceHandler, inputs, transposeAttribute); + } + const logicalRowCount = isTransposeRequired ? ShapeUtil.sizeToDimension(transposedInputShape, rank - 1) : ShapeUtil.sizeToDimension(inputShape, rank - 1); + const featureCount = isTransposeRequired ? ShapeUtil.sizeFromDimension(transposedInputShape, rank - 1) : ShapeUtil.sizeFromDimension(inputShape, rank - 1); + const output = computeSoftmax( + inferenceHandler, + isTransposeRequired ? transposedInputs : inputs, + attributes, + logicalRowCount, + featureCount + ); + if (isTransposeRequired) { + const reversedOutput = transpose(inferenceHandler, output, transposeAttribute); + return reversedOutput; + } else { + return output; + } + }; + computeSoftmax = (inferenceHandler, inputs, attributes, logicalRowCount, featureCount) => { + const computeMaxProgramInfo = createComputeMaxProgramInfo( + inferenceHandler, + inputs[0], + logicalRowCount, + featureCount, + [logicalRowCount] + ); + const max = inferenceHandler.run( + { ...softmaxComputeMaxProgramMetadata, cacheHint: attributes.cacheKey, get: () => computeMaxProgramInfo }, + inputs + ); + const computeScaleProgramInfo = createComputScaleProgramInfo( + inferenceHandler, + inputs[0], + logicalRowCount, + featureCount, + computeMaxProgramInfo.output.dims, + [logicalRowCount] + ); + const scale = inferenceHandler.run( + { ...softmaxComputeScaleProgramMetadata, cacheHint: attributes.cacheKey, get: () => computeScaleProgramInfo }, + [inputs[0], max] + ); + const softMaxProgramInfo = createSoftMaxProgramInfo( + inferenceHandler, + inputs[0], + logicalRowCount, + featureCount, + computeMaxProgramInfo.output.dims, + computeScaleProgramInfo.output.dims + ); + const output = inferenceHandler.run( + { ...softmaxProgramMetadata, cacheHint: attributes.cacheKey, get: () => softMaxProgramInfo }, + [inputs[0], max, scale] + ); + return [output]; + }; + createComputeMaxProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, outputShape) => { + const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight( + input.dims, + 0 /* unpacked */ + ); + const rank = outputShape.length; + if (logicalRowCount < 1 || featureCount < 1) { + throw new Error("Logical row count N and feature count D must be greater than or equal to 1"); + } + if (outputShape.length !== 1) { + throw new Error("Dimensionality of the output should be 1"); + } + if (outputShape[0] !== logicalRowCount) { + throw new Error("Shape of the output should be equal to logical row count"); + } + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` + float process(int[${rank}] indices) { + int logical_row_start_offset = indices[0] * ${featureCount}; + + float max = getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset, ${textureWidth}, + ${textureHeight} ))); + for(int i=1; i<${featureCount}; ++i) + { + float current = getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset + i, + ${textureWidth}, ${textureHeight}))); + if(current > max) + max = current; + } + + return max; + }`; + return { + ...softmaxComputeMaxProgramMetadata, + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createComputScaleProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, maxElementPerLogicalRow, outputShape) => { + const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight( + input.dims, + 0 /* unpacked */ + ); + const rank = outputShape.length; + if (logicalRowCount < 1 || featureCount < 1) { + throw new Error("Logical row count N and feature count D must be greater than or equal to 1"); + } + if (outputShape.length !== 1) { + throw new Error("Dimensionality of the output should be 1"); + } + if (outputShape[0] !== logicalRowCount) { + throw new Error("Shape of the output should be equal to logical row count"); + } + if (maxElementPerLogicalRow.length !== 1) { + throw new Error("Dimensionality of the intermediate results should be 1"); + } + if (maxElementPerLogicalRow[0] !== logicalRowCount) { + throw new Error("Shape of the intermediate results should be equal to logical row count"); + } + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` + float process(int[${rank}] indices) { + int logical_row_start_offset = indices[0] * ${featureCount}; + + float norm_factor = 0.0; + float max = _Max(indices); + for(int i=0; i<${featureCount}; ++i) + { + norm_factor += exp(getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset + i, + ${textureWidth}, ${textureHeight}))) - max); + } + + return norm_factor; + }`; + return { + ...softmaxComputeScaleProgramMetadata, + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createSoftMaxProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, maxElementPerLogicalRow, normalizationPerLogicalRow) => { + const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight( + input.dims, + 0 /* unpacked */ + ); + const rank = input.dims.length; + if (logicalRowCount < 1 || featureCount < 1) { + throw new Error("Logical row count N and feature count D must be greater than or equal to 1"); + } + if (maxElementPerLogicalRow.length !== 1 || normalizationPerLogicalRow.length !== 1) { + throw new Error("Dimensionality of the intermediate results should be 1"); + } + if (maxElementPerLogicalRow[0] !== logicalRowCount || normalizationPerLogicalRow[0] !== logicalRowCount) { + throw new Error("Shape of the intermediate results should be equal to logical row count"); + } + const shaderSource = ` + float process(int[${rank}] indices) { + + // get offset of current logical tensor index from the 2-D texture coordinates (TexCoords) + int offset = coordsToOffset(TexCoords, ${textureWidth}, ${textureHeight}); + + //determine the logical row for this index + int logical_row_index[1]; + logical_row_index[0] = offset / ${featureCount}; + + float norm_factor = _Norm(logical_row_index); + + // avoid possible division by 0 + // if norm_facor is 0, all elements are zero + // if so, return 0 + if(norm_factor == 0.0) + return 0.0; + + return exp(_A(indices) - _Max(logical_row_index)) / norm_factor; + }`; + return { + ...softmaxProgramMetadata, + output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs20 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Softmax requires 1 input."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/split.ts +var splitProgramMetadata, split, parseSplitAttributes, getProgramCount, createSplitProgramInfo, validateInputs21; +var init_split = __esm({ + "web/lib/onnxjs/backends/webgl/ops/split.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + splitProgramMetadata = { + name: "Split", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + split = (inferenceHandler, inputs, attributes) => { + validateInputs21(inputs); + const axis = ShapeUtil.normalizeAxis(attributes.axis, inputs[0].dims.length); + const count = getProgramCount(inferenceHandler, inputs, axis, attributes); + const output = []; + for (let i = 0; i < count; ++i) { + output.push( + inferenceHandler.run( + { + ...splitProgramMetadata, + cacheHint: `${attributes.cacheKey};${i}`, + get: () => createSplitProgramInfo(inferenceHandler, inputs[0], attributes, axis, i) + }, + inputs + ) + ); + } + return output; + }; + parseSplitAttributes = (node) => { + const axis = node.attributes.getInt("axis", 0); + const split2 = node.attributes.getInts("split", []); + const numOutputs = node.outputs.length; + return createAttributeWithCacheKey({ axis, split: split2, numOutputs }); + }; + getProgramCount = (_inferenceHandler, inputs, axis, attributes) => { + const [, offsets] = SplitUtil.splitShape(inputs[0].dims, axis, attributes.split, attributes.numOutputs); + return offsets.length; + }; + createSplitProgramInfo = (_inferenceHandler, input, attributes, axis, index) => { + const [shapes, offsets] = SplitUtil.splitShape(input.dims, axis, attributes.split, attributes.numOutputs); + const offset = offsets[index]; + const outputShape = shapes[index]; + const rank = outputShape.length; + const shaderSource = ` + float process(int indices[${rank}]) { + indices[${axis}] += ${offset}; + return _A(indices); + } + `; + return { + ...splitProgramMetadata, + cacheHint: `${attributes.cacheKey}:${index}`, + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs21 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Split requires one input."); + } + if (inputs[0].type !== "int8" && inputs[0].type !== "uint8" && inputs[0].type !== "int16" && inputs[0].type !== "uint16" && inputs[0].type !== "int32" && inputs[0].type !== "uint32" && inputs[0].type !== "float32" && inputs[0].type !== "float64" && inputs[0].type !== "bool") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/squeeze.ts +var squeeze, squeezeV13, parseSqueezeAttributes, validateInputs22, validateInputsV13; +var init_squeeze = __esm({ + "web/lib/onnxjs/backends/webgl/ops/squeeze.ts"() { + "use strict"; + init_util(); + squeeze = (inferenceHandler, inputs, axes) => { + validateInputs22(inputs); + const outputShape = ShapeUtil.squeezeShape(inputs[0].dims, axes); + const output = inferenceHandler.reshapeUnpacked(inputs[0], outputShape); + return [output]; + }; + squeezeV13 = (inferenceHandler, inputs) => { + validateInputsV13(inputs); + return squeeze(inferenceHandler, [inputs[0]], Array.from(inputs[1].integerData)); + }; + parseSqueezeAttributes = (node) => node.attributes.getInts("axes"); + validateInputs22 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Squeeze requires 1 input."); + } + if (inputs[0].type === "string") { + throw new Error("invalid input tensor types."); + } + }; + validateInputsV13 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Squeeze requires 2 inputs."); + } + if (inputs[1].type !== "int32") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/sum.ts +var sum, createSumProgramInfo, validateInputs23; +var init_sum = __esm({ + "web/lib/onnxjs/backends/webgl/ops/sum.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + sum = (inferenceHandler, inputs) => { + validateInputs23(inputs); + const sumProgramMetadata = { + name: "Sum", + inputNames: inputs.map((_v, i) => `X${i}`), + inputTypes: new Array(inputs.length).fill(0 /* unpacked */) + }; + const output = inferenceHandler.run( + { ...sumProgramMetadata, get: () => createSumProgramInfo(inferenceHandler, inputs, sumProgramMetadata) }, + inputs + ); + return [output]; + }; + createSumProgramInfo = (inferenceHandler, inputs, sumProgramMetadata) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const outputShape = inputs[0].dims.slice(); + const sumLine = inputs.map((_v, i) => `${glsl.texture2D}(X${i},TexCoords)`).join(" + "); + const shaderSource = ` + void main() { + vec4 result = ${sumLine}; + ${glsl.output} = result; + } + `; + return { + ...sumProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + hasMain: true, + shaderSource + }; + }; + validateInputs23 = (inputs) => { + if (!inputs || inputs.length === 0) { + throw new Error("Sum requires inputs."); + } + const length = inputs[0].dims.length; + for (let i = 1; i < inputs.length; i++) { + if (length !== inputs[i].dims.length) { + throw new Error("Input shapes are mismatched."); + } + for (let j = 0; j < length; j++) { + if (inputs[0].dims[j] !== inputs[i].dims[j]) { + throw new Error("Input shapes are not matched."); + } + } + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + for (let i = 1; i < inputs.length; i++) { + if (inputs[0].type !== inputs[i].type) { + throw new Error("Input types are not matched."); + } + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/tile.ts +var tile, createTileProgramInfo, validateInputs24; +var init_tile = __esm({ + "web/lib/onnxjs/backends/webgl/ops/tile.ts"() { + "use strict"; + init_operators(); + init_types(); + tile = (inferenceHandler, inputs) => { + validateInputs24(inputs); + const tileProgramMetadata = { + name: "Tile", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + const output = inferenceHandler.run( + { ...tileProgramMetadata, get: () => createTileProgramInfo(inferenceHandler, inputs, tileProgramMetadata) }, + inputs + ); + return [output]; + }; + createTileProgramInfo = (_handler, inputs, tileProgramMetadata) => { + const inputShape = inputs[0].dims.slice(); + const outputShape = new Array(inputShape.length); + const tileOps = []; + for (let i = 0; i < inputShape.length; i++) { + outputShape[i] = inputShape[i] * inputs[1].numberData[i]; + tileOps.push(`inputIdx[${i}] = int(mod(float(outputIdx[${i}]), ${inputShape[i]}.));`); + } + const rank = outputShape.length; + const shaderSource = ` + float process(int outputIdx[${rank}]) { + int inputIdx[${rank}]; + ${tileOps.join("\n")} + return _A(inputIdx); + } + `; + return { + ...tileProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs24 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Tile requires 2 input."); + } + if (inputs[1].dims.length !== 1) { + throw new Error("The second input shape must 1 dimension."); + } + if (inputs[1].dims[0] !== inputs[0].dims.length) { + throw new Error("Invalid input shape."); + } + if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { + throw new Error("Invalid input type."); + } + if (inputs[1].type !== "int32" && inputs[1].type !== "int16") { + throw new Error("Invalid repeat type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/unsqueeze.ts +var unsqueeze, unsqueezeV13, parseUnsqueezeAttributes, validateInputs25, validateInputsV132; +var init_unsqueeze = __esm({ + "web/lib/onnxjs/backends/webgl/ops/unsqueeze.ts"() { + "use strict"; + init_util(); + unsqueeze = (inferenceHandler, inputs, axes) => { + validateInputs25(inputs); + const outputShape = ShapeUtil.unsqueezeShape(inputs[0].dims, axes); + const output = inferenceHandler.reshapeUnpacked(inputs[0], outputShape); + return [output]; + }; + unsqueezeV13 = (inferenceHandler, inputs) => { + validateInputsV132(inputs); + return unsqueeze(inferenceHandler, [inputs[0]], Array.from(inputs[1].integerData)); + }; + parseUnsqueezeAttributes = (node) => node.attributes.getInts("axes"); + validateInputs25 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Unsqueeze requires 1 input."); + } + if (inputs[0].type === "string") { + throw new Error("invalid input tensor types."); + } + }; + validateInputsV132 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Unsqueeze requires 2 inputs."); + } + if (inputs[1].type !== "int32") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/op-resolve-rules.ts +var WEBGL_OP_RESOLVE_RULES; +var init_op_resolve_rules = __esm({ + "web/lib/onnxjs/backends/webgl/op-resolve-rules.ts"() { + "use strict"; + init_batch_normalization(); + init_binary_op(); + init_cast(); + init_concat(); + init_conv(); + init_conv_transpose(); + init_depth_to_space(); + init_flatten(); + init_gather(); + init_gemm(); + init_image_scaler(); + init_instance_normalization(); + init_lrn(); + init_matmul(); + init_pad(); + init_pool(); + init_reduce(); + init_reshape(); + init_resize_packed(); + init_shape(); + init_slice(); + init_softmax(); + init_split(); + init_squeeze(); + init_sum(); + init_tile(); + init_transpose(); + init_unary_op(); + init_unsqueeze(); + init_upsample(); + WEBGL_OP_RESOLVE_RULES = [ + ["Abs", "", "6+", abs], + ["Acos", "", "7+", acos], + ["Add", "", "7+", add2], + ["And", "", "7+", and2], + ["Asin", "", "7+", asin], + ["Atan", "", "7+", atan], + // TODO: support new attributes for AveragePool-10 + ["AveragePool", "", "7+", averagePool, parseAveragePoolAttributes], + ["BatchNormalization", "", "7+", batchNormalization, parseBatchNormalizationAttributes], + ["Cast", "", "6+", cast, parseCastAttributes], + ["Ceil", "", "6+", ceil], + ["Clip", "", "6-10", clip, parseClipAttributes], + ["Clip", "", "11+", clipV11], + ["Concat", "", "4+", concat, parseConcatAttributes], + ["Conv", "", "1+", conv, parseConvAttributes], + ["ConvTranspose", "", "1+", convTranspose, parseConvTransposeAttributes], + ["Cos", "", "7+", cos], + ["Div", "", "7+", div], + ["Dropout", "", "7+", identity], + ["DepthToSpace", "", "1+", depthToSpace, parseDepthToSpaceAttributes], + ["Equal", "", "7+", equal], + ["Elu", "", "6+", elu, parseEluAttributes], + ["Exp", "", "6+", exp], + ["Flatten", "", "1+", flatten, parseFlattenAttributes], + ["Floor", "", "6+", floor], + ["FusedConv", "com.microsoft", "1+", conv, parseConvAttributes], + ["Gather", "", "1+", gather, parseGatherAttributes], + ["Gemm", "", "7-10", gemm, parseGemmAttributesV7], + ["Gemm", "", "11+", gemm, parseGemmAttributesV11], + ["GlobalAveragePool", "", "1+", globalAveragePool, parseGlobalAveragePoolAttributes], + ["GlobalMaxPool", "", "1+", globalMaxPool], + ["Greater", "", "7+", greater], + ["Identity", "", "1+", identity], + ["ImageScaler", "", "1+", imageScaler, parseImageScalerAttributes], + ["InstanceNormalization", "", "6+", instanceNormalization, parseInstanceNormalizationAttributes], + ["LeakyRelu", "", "6+", leakyRelu, parseLeakyReluAttributes], + ["Less", "", "7+", less], + ["LRN", "", "1+", lrn, parseLrnAttributes], + ["Log", "", "6+", log2], + ["MatMul", "", "1+", matMul, parseMatMulAttributes], + // TODO: support new attributes for MaxPool-8 and MaxPool-10 + ["MaxPool", "", "1+", maxPool, parseMaxPoolAttributes], + ["Mul", "", "7+", mul], + ["Neg", "", "6+", neg], + ["Not", "", "1+", not2], + ["Or", "", "7+", or2], + ["Pad", "", "2-10", padV2, parsePadAttributesV2], + ["Pad", "", "11+", padV11, parsePadAttributesV11], + ["Pow", "", "7+", pow], + ["PRelu", "", "7+", pRelu], + ["ReduceLogSum", "", "1+", reduceLogSum, parseReduceAttributes], + ["ReduceMax", "", "1+", reduceMax, parseReduceAttributes], + ["ReduceMean", "", "1+", reduceMean, parseReduceAttributes], + ["ReduceMin", "", "1+", reduceMin, parseReduceAttributes], + ["ReduceProd", "", "1+", reduceProd, parseReduceAttributes], + ["ReduceSum", "", "1-12", reduceSum, parseReduceAttributes], + ["ReduceSumSquare", "", "1+", reduceLogSumSquare, parseReduceAttributes], + ["Relu", "", "6+", relu], + ["Reshape", "", "5+", reshape], + ["Resize", "", "10", resize, parseResizeAttributesV10], + ["Resize", "", "11+", resize, parseResizeAttributesV11], + ["Shape", "", "1+", shape], + ["Sigmoid", "", "6+", sigmoid], + ["Sin", "", "7+", sin], + ["Slice", "", "10+", sliceV10], + // TODO: support 'steps' for Slice-10 + ["Slice", "", "1-9", slice, parseSliceAttributes], + // The "semantic" meaning of axis has changed in opset-13. + ["Softmax", "", "1-12", softmax, parseSoftmaxAttributes], + ["Softmax", "", "13+", softmaxV13, parseSoftmaxAttributesV13], + // 'Split' operator has an optional attribute 'split' + // this attribute determines how the specified axis of input data is split. + // When the attribute is missing, we need the count of number of outputs + // so that we can determine the 'split' attribute from the runtime input to the Operator + ["Split", "", "2-12", split, parseSplitAttributes], + ["Sqrt", "", "6+", sqrt], + ["Squeeze", "", "1-12", squeeze, parseSqueezeAttributes], + ["Squeeze", "", "13+", squeezeV13], + ["Sub", "", "7+", sub], + ["Sum", "", "6+", sum], + ["Tan", "", "7+", tan], + ["Tanh", "", "6+", tanh], + ["Tile", "", "6+", tile], + ["Transpose", "", "1+", transpose, parseTransposeAttributes], + ["Upsample", "", "7-8", upsample, parseUpsampleAttributesV7], + ["Upsample", "", "9", upsample, parseUpsampleAttributesV9], + ["Unsqueeze", "", "1-12", unsqueeze, parseUnsqueezeAttributes], + ["Unsqueeze", "", "13+", unsqueezeV13], + ["Xor", "", "7+", xor2] + ]; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-function-inliner.ts +function replaceInlines(script) { + const inlineDefs = {}; + let match; + while ((match = INLINE_FUNC_DEF_REGEX.exec(script)) !== null) { + const params = match[3].split(",").map((s) => { + const tokens = s.trim().split(" "); + if (tokens && tokens.length === 2) { + return { type: tokens[0], name: tokens[1] }; + } + return null; + }).filter((v) => v !== null); + inlineDefs[match[2]] = { params, body: match[4] }; + } + for (const name2 in inlineDefs) { + const regexString = FUNC_CALL_REGEX.replace("__FUNC__", name2); + const regex = new RegExp(regexString, "gm"); + while ((match = regex.exec(script)) !== null) { + const type = match[1]; + const variable = match[2]; + const params = match[3].split(","); + const declLine = type ? `${type} ${variable};` : ""; + let newBody = inlineDefs[name2].body; + let paramRedecLine = ""; + inlineDefs[name2].params.forEach((v, i) => { + if (v) { + paramRedecLine += `${v.type} ${v.name} = ${params[i]}; +`; + } + }); + newBody = `${paramRedecLine} + ${newBody}`; + newBody = newBody.replace("return", `${variable} = `); + const replacement = ` + ${declLine} + { + ${newBody} + } + `; + script = script.replace(match[0], replacement); + } + } + script = script.replace(INLINE_FUNC_DEF_REGEX, ""); + return script; +} +var INLINE_FUNC_DEF_REGEX, FUNC_CALL_REGEX; +var init_glsl_function_inliner = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-function-inliner.ts"() { + "use strict"; + INLINE_FUNC_DEF_REGEX = /@inline[\s\n\r]+(\w+)[\s\n\r]+([0-9a-zA-Z_]+)\s*\(([^)]*)\)\s*{(([^}]|[\n\r])*)}/gm; + FUNC_CALL_REGEX = "(\\w+)?\\s+([_0-9a-zA-Z]+)\\s+=\\s+__FUNC__\\((.*)\\)\\s*;"; + } +}); + +// web/lib/onnxjs/backends/webgl/texture-layout-strategy.ts +function squeezeShape(shape2, axis) { + const newShape = []; + const keptDims = []; + const isEmptyArray = axis != null && Array.isArray(axis) && axis.length === 0; + const axes = axis == null || isEmptyArray ? null : parseAxisParam(axis, shape2).sort(); + let j = 0; + for (let i = 0; i < shape2.length; ++i) { + if (axes != null) { + if (axes[j] === i && shape2[i] !== 1) { + throw new Error(`Can't squeeze axis ${i} since its dim '${shape2[i]}' is not 1`); + } + if ((axes[j] == null || axes[j] > i) && shape2[i] === 1) { + newShape.push(shape2[i]); + keptDims.push(i); + } + if (axes[j] <= i) { + j++; + } + } + if (shape2[i] !== 1) { + newShape.push(shape2[i]); + keptDims.push(i); + } + } + return { newShape, keptDims }; +} +function parseAxisParam(axis, shape2) { + const rank = shape2.length; + axis = axis == null ? shape2.map((_s, i) => i) : [].concat(axis); + assert( + axis.every((ax) => ax >= -rank && ax < rank), + () => `All values in axis param must be in range [-${rank}, ${rank}) but got axis ${axis}` + ); + assert(axis.every(isInt), () => `All values in axis param must be integers but got axis ${axis}`); + return axis.map((a) => a < 0 ? rank + a : a); +} +function isInt(a) { + return a % 1 === 0; +} +function sizeFromShape(shape2) { + if (shape2.length === 0) { + return 1; + } + let size = shape2[0]; + for (let i = 1; i < shape2.length; i++) { + size *= shape2[i]; + } + return size; +} +function sizeToSquarishShape(size) { + const width = Math.ceil(Math.sqrt(size)); + return [width, Math.ceil(size / width)]; +} +var PreferLogicalStrategy; +var init_texture_layout_strategy = __esm({ + "web/lib/onnxjs/backends/webgl/texture-layout-strategy.ts"() { + "use strict"; + init_instrument(); + init_util(); + PreferLogicalStrategy = class { + constructor(maxTextureSize) { + this.maxTextureSize = maxTextureSize; + } + computeTextureWH(shape2, prefs) { + const wh = this.computeTexture(shape2, prefs); + if (prefs && prefs.isPacked) { + wh[0] /= 2; + wh[1] /= 2; + } + if (prefs && prefs.reverseWH) { + return [wh[1], wh[0]]; + } + return wh; + } + computeTexture(shape2, prefs) { + const isPacked = prefs && prefs.isPacked; + if (shape2.length === 0) { + return isPacked ? [2, 2] : [1, 1]; + } + let maxTextureSize = this.maxTextureSize; + if (prefs && prefs.breakAxis !== void 0) { + const wsize = prefs.breakAxis >= shape2.length ? 1 : shape2.slice(prefs.breakAxis).reduce((a, b) => a * b); + const hsize = prefs.breakAxis <= 0 ? 1 : shape2.slice(0, prefs.breakAxis).reduce((a, b) => a * b); + if (wsize > maxTextureSize || hsize > maxTextureSize) { + Logger.verbose( + "TextureLayout", + `Given width/height preferences were unattainable: shape:${shape2}, breakAxis:${prefs.breakAxis}` + ); + } else { + return [wsize, hsize]; + } + } + let logShape = shape2.slice(0); + if (isPacked) { + maxTextureSize = maxTextureSize * 2; + logShape = logShape.map( + (_d, i) => i >= logShape.length - 2 ? logShape[i] % 2 === 0 ? logShape[i] : logShape[i] + 1 : logShape[i] + ); + if (logShape.length === 1) { + logShape = [2, logShape[0]]; + } + } + if (logShape.length !== 2) { + const squeezeResult = squeezeShape(logShape); + logShape = squeezeResult.newShape; + } + const size = sizeFromShape(logShape); + if (logShape.length <= 1 && size <= maxTextureSize) { + return [1, size]; + } else if (logShape.length === 2 && logShape[0] <= maxTextureSize && logShape[1] <= maxTextureSize) { + return logShape; + } else if (logShape.length === 3 && logShape[0] * logShape[1] <= maxTextureSize && logShape[2] <= maxTextureSize) { + return [logShape[0] * logShape[1], logShape[2]]; + } else if (logShape.length === 3 && logShape[0] <= maxTextureSize && logShape[1] * logShape[2] <= maxTextureSize) { + return [logShape[0], logShape[1] * logShape[2]]; + } else if (logShape.length === 4 && logShape[0] * logShape[1] * logShape[2] <= maxTextureSize && logShape[3] <= maxTextureSize) { + return [logShape[0] * logShape[1] * logShape[2], logShape[3]]; + } else if (logShape.length === 4 && logShape[0] <= maxTextureSize && logShape[1] * logShape[2] * logShape[3] <= maxTextureSize) { + return [logShape[0], logShape[1] * logShape[2] * logShape[3]]; + } else { + if (isPacked) { + return sizeToSquarishShape(size / 4).map((d) => d * 2); + } + return sizeToSquarishShape(size); + } + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts +var CoordsGlslLib; +var init_glsl_coordinate_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts"() { + "use strict"; + init_util(); + init_glsl_definitions(); + init_glsl_source(); + init_texture_layout_strategy(); + init_utils(); + CoordsGlslLib = class extends GlslLib { + constructor(context) { + super(context); + } + getFunctions() { + return { + ...this.offsetToCoords(), + ...this.coordsToOffset(), + ...this.toVec(), + ...this.valueFrom(), + // TODO return these only when packing is enabled. + ...this.getCommonUtilFuncs(), + ...this.getInputsSamplingSnippets(), + ...this.getOutputSamplingSnippet() + }; + } + getCustomTypes() { + return {}; + } + /** + * Produces a function that can map from + * 2D normalzied coordinates (s,t) to a flat offset + */ + offsetToCoords() { + const funcName = "offsetToCoords"; + return { + offsetToCoords: new GlslLibRoutine(` + vec2 ${funcName}(int offset, int width, int height) { + int t = offset / width; + int s = offset - t*width; + vec2 coords = (vec2(s,t) + vec2(0.5,0.5)) / vec2(width, height); + return coords; + } + `) + }; + } + /** + * Produces a function that can map from + * 2D normalzied coordinates (s,t) to a flat offset + */ + coordsToOffset() { + const funcName = "coordsToOffset"; + return { + coordsToOffset: new GlslLibRoutine(` + int ${funcName}(vec2 coords, int width, int height) { + float s = coords.s * float(width); + float t = coords.t * float(height); + int offset = int(t) * width + int(s); + return offset; + } + `) + }; + } + /** + * Generates code for output sampler. + */ + getOutputSamplingSnippet() { + const outputLayout = this.context.outputTextureLayout; + if (outputLayout.isPacked) { + return this.getPackedOutputSamplingSnippet(outputLayout); + } else { + return this.getUnpackedOutputSamplingSnippet(outputLayout); + } + } + /** + * Generates code for packed output sampler. + */ + getPackedOutputSamplingSnippet(outputLayout) { + const outShape = outputLayout.unpackedShape; + const outTexShape = [outputLayout.width, outputLayout.height]; + const result = {}; + const funcName = "getOutputCoords"; + switch (outShape.length) { + case 0: + result[funcName] = this.getOutputScalarCoords(); + break; + case 1: + result[funcName] = this.getOutputPacked1DCoords(outShape, outTexShape); + break; + case 2: + result[funcName] = this.getOutputPacked2DCoords(outShape, outTexShape); + break; + case 3: + result[funcName] = this.getOutputPacked3DCoords( + outShape, + outTexShape + ); + break; + default: + result[funcName] = this.getOutputPackedNDCoords(outShape, outTexShape); + } + const glsl = getGlsl(this.context.glContext.version); + const floatTextureSetRGBASource = ` + void setOutput(vec4 val) { + ${glsl.output} = val; + } + `; + const floatTextureSetRGBAFuncName = "floatTextureSetRGBA"; + result[floatTextureSetRGBAFuncName] = new GlslLibRoutine(floatTextureSetRGBASource); + return result; + } + /** + * Generates code for unpacked output sampler. + */ + getUnpackedOutputSamplingSnippet(outputLayout) { + const outShape = outputLayout.unpackedShape; + const outTexShape = [outputLayout.width, outputLayout.height]; + const result = {}; + const funcName = "getOutputCoords"; + switch (outShape.length) { + case 0: + result[funcName] = this.getOutputScalarCoords(); + break; + case 1: + result[funcName] = this.getOutputUnpacked1DCoords(outShape, outTexShape); + break; + case 2: + result[funcName] = this.getOutputUnpacked2DCoords( + outShape, + outTexShape + ); + break; + case 3: + result[funcName] = this.getOutputUnpacked3DCoords( + outShape, + outTexShape + ); + break; + case 4: + result[funcName] = this.getOutputUnpacked4DCoords( + outShape, + outTexShape + ); + break; + case 5: + result[funcName] = this.getOutputUnpacked5DCoords( + outShape, + outTexShape + ); + break; + case 6: + result[funcName] = this.getOutputUnpacked6DCoords( + outShape, + outTexShape + ); + break; + default: + throw new Error(`Unsupported output dimensionality: ${outShape.length}`); + } + const glsl = getGlsl(this.context.glContext.version); + const floatTextureSetRSource = ` + void setOutput(float val) { + ${glsl.output} = vec4(val, 0, 0, 0); + } + `; + const floatTextureSetRFuncName = "floatTextureSetR"; + result[floatTextureSetRFuncName] = new GlslLibRoutine(floatTextureSetRSource); + return result; + } + /** + * Scalar output coordinates. + */ + getOutputScalarCoords() { + return new GlslLibRoutine(` + int getOutputCoords() { + return 0; + } + `); + } + /** + * 1D packed output coordinates. + */ + getOutputPacked1DCoords(_shape, texShape) { + const packedTexShape = texShape; + let source = ""; + if (packedTexShape[0] === 1) { + source = ` + int getOutputCoords() { + return 2 * int(TexCoords.y * ${packedTexShape[1]}.0); + } + `; + return new GlslLibRoutine(source); + } + if (packedTexShape[1] === 1) { + source = ` + int getOutputCoords() { + return 2 * int(TexCoords.x * ${packedTexShape[0]}.0); + } + `; + return new GlslLibRoutine(source); + } + source = ` + int getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + return 2 * (resTexRC.y * ${packedTexShape[0]} + resTexRC.x); + } + `; + return new GlslLibRoutine(source); + } + /** + * 2D packed output coordinates. + */ + getOutputPacked2DCoords(shape2, texShape) { + let source = ""; + if (ArrayUtil.arraysEqual(shape2, texShape)) { + source = ` + ivec2 getOutputCoords() { + return 2 * ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]})); + } + `; + return new GlslLibRoutine(source); + } + const packedTexShape = texShape; + const texelsInLogicalRow = Math.ceil(shape2[1] / 2); + source = ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + + int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x; + + // reverse r and c order for packed texture + int r = imod(index, ${texelsInLogicalRow}) * 2; + int c = 2 * (index / ${texelsInLogicalRow}); + + return ivec2(r, c); + } + `; + return new GlslLibRoutine(source); + } + /** + * 3D packed output coordinates. + */ + getOutputPacked3DCoords(shape2, texShape) { + const packedTexShape = [texShape[0], texShape[1]]; + const texelsInLogicalRow = Math.ceil(shape2[2] / 2); + const texelsInBatch = texelsInLogicalRow * Math.ceil(shape2[1] / 2); + const source = ` + ivec3 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x; + + int b = index / ${texelsInBatch}; + index -= b * ${texelsInBatch}; + + // reverse r and c order for packed texture + int r = imod(index, ${texelsInLogicalRow}) * 2; + int c = 2 * (index / ${texelsInLogicalRow}); + + return ivec3(b, r, c); + } + `; + return new GlslLibRoutine(source); + } + /** + * ND packed output coordinates. + */ + getOutputPackedNDCoords(shape2, texShape) { + const packedTexShape = [texShape[0], texShape[1]]; + const texelsInLogicalRow = Math.ceil(shape2[shape2.length - 1] / 2); + const texelsInBatch = texelsInLogicalRow * Math.ceil(shape2[shape2.length - 2] / 2); + let texelsInBatchN = texelsInBatch; + let batches = ""; + let coords = "b, r, c"; + for (let b = 2; b < shape2.length - 1; b++) { + texelsInBatchN *= shape2[shape2.length - b - 1]; + batches = ` + int b${b} = index / ${texelsInBatchN}; + index -= b${b} * ${texelsInBatchN}; + ` + batches; + coords = `b${b}, ` + coords; + } + const source = ` + ivec${shape2.length} getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x; + + ${batches} + + int b = index / ${texelsInBatch}; + index -= b * ${texelsInBatch}; + + // reverse r and c order for packed texture + int r = imod(index, ${texelsInLogicalRow}) * 2; + int c = 2 * (index / ${texelsInLogicalRow}); + + return ivec${shape2.length}(${coords}); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 1D output coordinates. + */ + getOutputUnpacked1DCoords(_shape, texShape) { + const source = ` + int getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + return resTexRC.y * ${texShape[0]} + resTexRC.x; + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 2D output coordinates. + */ + getOutputUnpacked2DCoords(shape2, texShape) { + const source = ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + int r = index / ${shape2[1]}; + int c = index - r * ${shape2[1]}; + return ivec2(r, c); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 3D output coordinates. + */ + getOutputUnpacked3DCoords(shape2, texShape) { + let source = ""; + const rank = shape2.length; + let strides = null; + if (rank < 2) { + strides = []; + } + strides = new Array(rank - 1); + strides[rank - 2] = shape2[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * shape2[i + 1]; + } + const coordsToCompute = ["r", "c", "d"]; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + source = ` + ivec3 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + ${coordsFromIndexSnippet} + return ivec3(r, c, d); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 4D output coordinates. + */ + getOutputUnpacked4DCoords(shape2, texShape) { + let source = ""; + const rank = shape2.length; + let strides = null; + if (rank < 2) { + strides = []; + } + strides = new Array(rank - 1); + strides[rank - 2] = shape2[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * shape2[i + 1]; + } + const coordsToCompute = ["r", "c", "d", "d2"]; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + source = ` + ivec4 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + ${coordsFromIndexSnippet} + return ivec4(r, c, d, d2); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 5D output coordinates. + */ + getOutputUnpacked5DCoords(shape2, texShape) { + let source = ""; + const rank = shape2.length; + let strides = null; + if (rank < 2) { + strides = []; + } + strides = new Array(rank - 1); + strides[rank - 2] = shape2[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * shape2[i + 1]; + } + const coordsToCompute = ["r", "c", "d", "d2", "d3"]; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + source = ` + ivec5 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + ${coordsFromIndexSnippet} + return ivec5(r, c, d, d2, d3); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 6D output coordinates. + */ + getOutputUnpacked6DCoords(shape2, texShape) { + let source = ""; + const rank = shape2.length; + let strides = null; + if (rank < 2) { + strides = []; + } + strides = new Array(rank - 1); + strides[rank - 2] = shape2[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * shape2[i + 1]; + } + const coordsToCompute = ["r", "c", "d", "d2", "d3", "d4"]; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + source = ` + ivec6 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + ${coordsFromIndexSnippet} + return ivec6(r, c, d, d2, d3, d4); + } + `; + return new GlslLibRoutine(source); + } + /** + * Generates code for common UV coords computation utility functions. + */ + getCommonUtilFuncs() { + const result = {}; + let funcName = "uvFromFlat"; + result[funcName] = new GlslLibRoutine(` + vec2 uvFromFlat(int texNumR, int texNumC, int index) { + int texC = index / texNumR; + int texR = index - texC * texNumR; + // TODO: swap texR, texC order in following function so row is corresponding to u and column is corresponding to + // v. + return (vec2(texR, texC) + halfCR) / vec2(texNumR, texNumC); + } + `); + funcName = "packedUVfrom1D"; + result[funcName] = new GlslLibRoutine(` + vec2 packedUVfrom1D(int texNumR, int texNumC, int index) { + int texelIndex = index / 2; + int texR = texelIndex / texNumC; + int texC = texelIndex - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); + } + `); + funcName = "packedUVfrom2D"; + result[funcName] = new GlslLibRoutine(` + vec2 packedUVfrom2D(int texNumR, int texNumC, int texelsInLogicalRow, int row, int col) { + int texelIndex = (row / 2) * texelsInLogicalRow + (col / 2); + int texR = texelIndex / texNumC; + int texC = texelIndex - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); + } + `); + funcName = "packedUVfrom3D"; + result[funcName] = new GlslLibRoutine(` + vec2 packedUVfrom3D(int texNumR, int texNumC, + int texelsInBatch, int texelsInLogicalRow, int b, + int row, int col) { + int index = b * texelsInBatch + (row / 2) * texelsInLogicalRow + (col / 2); + int texR = index / texNumC; + int texC = index - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); + } + `); + funcName = "sampleTexture"; + const glsl = getGlsl(this.context.glContext.version); + result[funcName] = new GlslLibRoutine(` + float sampleTexture(sampler2D textureSampler, vec2 uv) { + return ${glsl.texture2D}(textureSampler, uv).r; + }`); + return result; + } + /** + * Constructing snippets for inputs + */ + getInputsSamplingSnippets() { + const result = {}; + const outputLayout = this.context.outputTextureLayout; + this.context.programInfo.inputNames.forEach((samplerName, i) => { + const inputLayout = this.context.inputTextureLayouts[i]; + const funcName = generateShaderFuncNameFromInputSamplerName(samplerName); + if (inputLayout.isPacked) { + result[funcName] = this.getPackedSamplerFromInput(funcName, samplerName, inputLayout); + } else { + result[funcName] = this.getUnpackedSamplerFromInput(funcName, samplerName, inputLayout); + } + const outCoordFuncName = generateShaderFuncNameFromInputSamplerNameAtOutCoords(samplerName); + if (inputLayout.unpackedShape.length <= outputLayout.unpackedShape.length) { + if (inputLayout.isPacked) { + result[outCoordFuncName] = this.getPackedSamplerAtOutputCoords( + outCoordFuncName, + inputLayout, + outputLayout, + samplerName + ); + } else { + result[outCoordFuncName] = this.getUnpackedSamplerAtOutputCoords( + outCoordFuncName, + inputLayout, + outputLayout, + samplerName + ); + } + } + }); + return result; + } + /** + * Constructing snippets for output coordinates of samplers + */ + getPackedSamplerAtOutputCoords(funcName, inputLayout, outputLayout, name2) { + const inShape = inputLayout.unpackedShape; + const outShape = outputLayout.unpackedShape; + const texName = name2; + const texFuncSnippet = generateShaderFuncNameFromInputSamplerName(texName); + const inRank = inShape.length; + const outRank = outShape.length; + const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); + const type = getCoordsDataType(outRank); + const rankDiff = outRank - inRank; + let coordsSnippet; + const fields = getGlChannels(); + if (inRank === 0) { + coordsSnippet = ""; + } else if (outRank < 2 && broadcastDims.length >= 1) { + coordsSnippet = "coords = 0;"; + } else { + coordsSnippet = broadcastDims.map((d) => `coords.${fields[d + rankDiff]} = 0;`).join("\n"); + } + let unpackedCoordsSnippet = ""; + if (outRank < 2 && inRank > 0) { + unpackedCoordsSnippet = "coords"; + } else { + unpackedCoordsSnippet = inShape.map((_s, i) => `coords.${fields[i + rankDiff]}`).join(", "); + } + let output = "return outputValue;"; + const inSize = ShapeUtil.size(inShape); + const isInputScalar = inSize === 1; + const outSize = ShapeUtil.size(outShape); + const isOutputScalar = outSize === 1; + if (inRank === 1 && !isInputScalar && !isOutputScalar) { + output = ` + return vec4(outputValue.xy, outputValue.xy); + `; + } else if (isInputScalar && !isOutputScalar) { + if (outRank === 1) { + output = ` + return vec4(outputValue.x, outputValue.x, 0., 0.); + `; + } else { + output = ` + return vec4(outputValue.x); + `; + } + } else if (broadcastDims.length) { + const rows = inRank - 2; + const cols = inRank - 1; + if (broadcastDims.indexOf(rows) > -1 && broadcastDims.indexOf(cols) > -1) { + output = "return vec4(outputValue.x);"; + } else if (broadcastDims.indexOf(rows) > -1) { + output = "return vec4(outputValue.x, outputValue.y, outputValue.x, outputValue.y);"; + } else if (broadcastDims.indexOf(cols) > -1) { + output = "return vec4(outputValue.xx, outputValue.zz);"; + } + } + const swapLastDimsSnippet = ` + int lastDim = coords.${fields[outRank - 1]}; + coords.${fields[outRank - 1]} = coords.${fields[outRank - 2]}; + coords.${fields[outRank - 2]} = lastDim; + `; + const source = ` + vec4 ${funcName}() { + ${type} coords = getOutputCoords(); + ${swapLastDimsSnippet} + ${coordsSnippet} + vec4 outputValue = ${texFuncSnippet}(${unpackedCoordsSnippet}); + ${output} + } + `; + return new GlslLibRoutine(source, ["coordinates.getOutputCoords"]); + } + /** + * Constructing snippets for unpacked output coordinates of samplers + */ + getUnpackedSamplerAtOutputCoords(funcName, inputLayout, outputLayout, name2) { + const outTexShape = [outputLayout.width, outputLayout.height]; + const inTexShape = [inputLayout.width, inputLayout.height]; + const inRank = inputLayout.unpackedShape.length; + const outRank = outputLayout.unpackedShape.length; + const inShape = inputLayout.unpackedShape; + const outShape = outputLayout.unpackedShape; + const texFuncSnippet = generateShaderFuncNameFromInputSamplerName(name2); + if (inRank === outRank && ArrayUtil.arraysEqual(inTexShape, outTexShape)) { + const source2 = ` + float ${funcName}() { + return sampleTexture(${name2}, TexCoords); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const type = getCoordsDataType(outRank); + const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); + const rankDiff = outRank - inRank; + let coordsSnippet; + const fields = getGlChannels(); + if (inRank === 0) { + coordsSnippet = ""; + } else if (outRank < 2 && broadcastDims.length >= 1) { + coordsSnippet = "coords = 0;"; + } else { + coordsSnippet = broadcastDims.map((d) => `coords.${fields[d + rankDiff]} = 0;`).join("\n"); + } + let unpackedCoordsSnippet = ""; + if (outRank < 2 && inRank > 0) { + unpackedCoordsSnippet = "coords"; + } else { + unpackedCoordsSnippet = inputLayout.unpackedShape.map((_s, i) => `coords.${fields[i + rankDiff]}`).join(", "); + } + const source = ` + float ${funcName}() { + ${type} coords = getOutputCoords(); + ${coordsSnippet} + return ${texFuncSnippet}(${unpackedCoordsSnippet}); + } + `; + return new GlslLibRoutine(source, ["coordinates.getOutputCoords"]); + } + /** + * Constructing snippets for packed operations. + */ + getPackedSamplerFromInput(funcName, name2, inputLayout) { + switch (inputLayout.unpackedShape.length) { + case 0: + return this.getPackedSamplerScalar(funcName, name2); + case 1: + return this.getPackedSampler1D(funcName, name2, inputLayout); + case 2: + return this.getPackedSampler2D(funcName, name2, inputLayout); + case 3: + return this.getPackedSampler3D(funcName, name2, inputLayout); + default: + return this.getPackedSamplerND(funcName, name2, inputLayout); + } + } + /** + * Constructing snippets for unpacked operations. + */ + getUnpackedSamplerFromInput(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + switch (shape2.length) { + case 0: + return this.getUnpackedSamplerScalar(funcName, name2, inputLayout); + case 1: + return this.getUnpackedSampler1D(funcName, name2, inputLayout); + case 2: + return this.getUnpackedSampler2D(funcName, name2, inputLayout); + case 3: + return this.getUnpackedSampler3D(funcName, name2, inputLayout); + case 4: + return this.getUnpackedSampler4D(funcName, name2, inputLayout); + case 5: + return this.getUnpackedSampler5D(funcName, name2, inputLayout); + case 6: + return this.getUnpackedSampler6D(funcName, name2, inputLayout); + default: + throw new Error(`Unsupported dimension ${shape2.length}-D`); + } + } + /** + * Packed scalar snippet. + */ + getPackedSamplerScalar(funcName, name2) { + const glsl = getGlsl(this.context.glContext.version); + const source = ` + vec4 ${funcName}() { + return ${glsl.texture2D}(${name2}, halfCR); + } + `; + return new GlslLibRoutine(source); + } + /** + * Packed 1D snippet. + */ + getPackedSampler1D(funcName, name2, inputLayout) { + const texShape = [inputLayout.width, inputLayout.height]; + const packedTexShape = [texShape[1], texShape[0]]; + const glsl = getGlsl(this.context.glContext.version); + const packedSampler = `vec4 ${funcName}(int index) { + vec2 uv = packedUVfrom1D( + ${packedTexShape[0]}, ${packedTexShape[1]}, index); + return ${glsl.texture2D}(${name2}, uv); + }`; + const source = packedSampler; + return new GlslLibRoutine(source, ["coordinates.packedUVfrom1D"]); + } + /** + * Packed 2D snippet. + */ + getPackedSampler2D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const texShape = [inputLayout.width, inputLayout.height]; + const glsl = getGlsl(this.context.glContext.version); + const texNumR = texShape[0]; + const texNumC = texShape[1]; + if (texShape != null && ArrayUtil.arraysEqual(shape2, texShape)) { + const packedSampler2 = `vec4 ${funcName}(int row, int col) { + vec2 uv = (vec2(col, row) + halfCR) / vec2(${texNumC}.0, ${texNumR}.0); + return ${glsl.texture2D}(${name2}, uv); + }`; + return new GlslLibRoutine(packedSampler2); + } + const packedTexShape = texShape; + const valuesPerRow = Math.ceil(shape2[1] / 2); + const packedSampler = `vec4 ${funcName}(int row, int col) { + vec2 uv = packedUVfrom2D(${packedTexShape[1]}, ${packedTexShape[0]}, ${valuesPerRow}, row, col); + return ${glsl.texture2D}(${name2}, uv); + }`; + const source = packedSampler; + return new GlslLibRoutine(source, ["coordinates.packedUVfrom2D"]); + } + /** + * Packed 3D snippet. + */ + getPackedSampler3D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const texShape = [inputLayout.width, inputLayout.height]; + const packedTexShape = [texShape[0], texShape[1]]; + const glsl = getGlsl(this.context.glContext.version); + if (shape2[0] === 1) { + const squeezedShape = shape2.slice(1); + const keptDims = [1, 2]; + const newInputShape = squeezeInputShape(shape2, squeezedShape); + const params = ["b", "row", "col"]; + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const samplerRoutine = this.getPackedSamplerFromInput(funcName, name2, newInputLayout); + const packedSampler2 = `${samplerRoutine.routineBody} + vec4 ${funcName}(int b, int row, int col) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } `; + const source2 = packedSampler2; + return new GlslLibRoutine(source2, samplerRoutine.dependencies); + } + const texNumR = packedTexShape[0]; + const texNumC = packedTexShape[1]; + const valuesPerRow = Math.ceil(shape2[2] / 2); + const texelsInBatch = valuesPerRow * Math.ceil(shape2[1] / 2); + const packedSampler = `vec4 ${funcName}(int b, int row, int col) { + vec2 uv = packedUVfrom3D( + ${texNumC}, ${texNumR}, ${texelsInBatch}, ${valuesPerRow}, b, row, col); + return ${glsl.texture2D}(${name2}, uv);}`; + const source = packedSampler; + return new GlslLibRoutine(source, ["coordinates.packedUVfrom3D"]); + } + /* + * Packed ND snippet. + */ + getPackedSamplerND(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const rank = shape2.length; + const texShape = [inputLayout.width, inputLayout.height]; + const glsl = getGlsl(this.context.glContext.version); + const packedTexShape = [texShape[0], texShape[1]]; + const texNumR = packedTexShape[1]; + const texNumC = packedTexShape[0]; + const valuesPerRow = Math.ceil(shape2[rank - 1] / 2); + let texelsInBatch = valuesPerRow * Math.ceil(shape2[rank - 2] / 2); + let params = "int b, int row, int col"; + let index = `b * ${texelsInBatch} + (row / 2) * ${valuesPerRow} + (col / 2)`; + for (let b = 2; b < rank - 1; b++) { + params = `int b${b}, ` + params; + texelsInBatch *= shape2[rank - b - 1]; + index = `b${b} * ${texelsInBatch} + ` + index; + } + const packedSampler = `vec4 ${funcName}(${params}) { + int index = ${index}; + int texR = index / ${texNumC}; + int texC = index - texR * ${texNumC}; + vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${texNumC}, ${texNumR}); + return ${glsl.texture2D}(${name2}, uv); + }`; + const source = packedSampler; + return new GlslLibRoutine(source); + } + /** + * Unpacked scalar snippet. + */ + getUnpackedSamplerScalar(funcName, name2, inputLayout) { + const [texNumR, texNumC] = [inputLayout.width, inputLayout.height]; + if (texNumR === 1 && texNumC === 1) { + const source2 = ` + float ${funcName}() { + return sampleTexture(${name2}, halfCR); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const source = ` + float ${funcName}() { + int offset_${name2} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC}); + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, offset_${name2}); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, [ + "coordinates.uvFromFlat", + "coordinates.sampleTexture", + "coordinates.coordsToOffset" + ]); + } + /** + * Unpacked 1D snippet. + */ + getUnpackedSampler1D(funcName, name2, inputLayout) { + const tNumR = inputLayout.width; + const tNumC = inputLayout.height; + if (tNumC === 1 && tNumR === 1) { + const source2 = ` + float ${funcName}(int index) { + return sampleTexture(${name2}, halfCR); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + if (tNumC === 1) { + const source2 = ` + float ${funcName}(int index) { + vec2 uv = vec2((float(index) + 0.5) / ${tNumR}.0, 0.5); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + if (tNumR === 1) { + const source2 = ` + float ${funcName}(int index) { + vec2 uv = vec2(0.5, (float(index) + 0.5) / ${tNumC}.0); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const source = ` + float ${funcName}(int index) { + vec2 uv = uvFromFlat(${tNumR}, ${tNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, ["coordinates.uvFromFlat", "coordinates.sampleTexture"]); + } + /** + * Unpacked 2D snippet. + */ + getUnpackedSampler2D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const texShape = [inputLayout.height, inputLayout.width]; + if (texShape != null && ArrayUtil.arraysEqual(shape2, texShape)) { + const texNumR2 = texShape[1]; + const texNumC2 = texShape[0]; + const source2 = ` + float ${funcName}(int row, int col) { + vec2 uv = (vec2(row, col) + halfCR) / vec2(${texNumR2}.0, ${texNumC2}.0); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const { newShape, keptDims } = squeezeShape(shape2); + const squeezedShape = newShape; + if (squeezedShape.length < shape2.length) { + const newInputShape = squeezeInputShape(shape2, squeezedShape); + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const params = ["col", "row"]; + const source2 = ` + ${this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout).routineBody} + float ${funcName}(int row, int col) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const texNumR = texShape[1]; + const texNumC = texShape[0]; + if (texNumC === 1) { + const source2 = ` + float ${funcName}(int row, int col) { + int offset_${name2} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC}); + float index = dot(vec3(row, col, offset_${name2}), vec3(${shape2[1]}, 1, 1)); + vec2 uv = vec2(0.5, (index + 0.5) / ${texNumR}.0); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.coordsToOffset"]); + } + if (texNumR === 1) { + const source2 = ` + float ${funcName}(int row, int col) { + int offset_${name2} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC}); + float index = dot(vec3(row, col, offset_${name2}), vec3(${shape2[1]}, 1, 1)); + vec2 uv = vec2((index + 0.5) / ${texNumC}.0, 0.5); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.coordsToOffset"]); + } + const source = ` + float ${funcName}(int row, int col) { + int index = col * ${shape2[1]} + row; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, [ + "coordinates.uvFromFlat", + "coordinates.sampleTexture", + "coordinates.coordsToOffset" + ]); + } + /** + * Unpacked 3D snippet. + */ + getUnpackedSampler3D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const stride0 = shape2[1] * shape2[2]; + const stride1 = shape2[2]; + const { newShape, keptDims } = squeezeShape(shape2); + const squeezedShape = newShape; + if (squeezedShape.length < shape2.length) { + const newInputShape = squeezeInputShape(shape2, squeezedShape); + const params = ["batch", "col", "row"]; + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const routine = this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout); + const revDims = keptDims.reverse(); + const source2 = ` + ${routine.routineBody} + float ${funcName}(int batch, int row, int col) { + return ${funcName}(${getSqueezedParams(params, revDims)}); + } + `; + return new GlslLibRoutine(source2, routine.dependencies); + } + const texNumR = inputLayout.width; + const texNumC = inputLayout.height; + const source = ` + float ${funcName}(int depth, int row, int col) { + // Explicitly use integer operations as dot() only works on floats. + int index = depth * ${stride0} + col * ${stride1} + row; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, [ + "coordinates.uvFromFlat", + "coordinates.sampleTexture", + "coordinates.coordsToOffset" + ]); + } + /** + * Unpacked 4D snippet. + */ + getUnpackedSampler4D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const stride2 = shape2[3]; + const stride1 = shape2[2] * stride2; + const stride0 = shape2[1] * stride1; + const texNumR = inputLayout.width; + const texNumC = inputLayout.height; + const source = ` + float ${funcName}(int row, int col, int depth, int depth2) { + int index = row * ${stride0} + col * ${stride1} + + depth2 * ${stride2} + depth; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, ["coordinates.uvFromFlat", "coordinates.sampleTexture"]); + } + /** + * Unpacked 5D snippet. + */ + getUnpackedSampler5D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const stride3 = shape2[4]; + const stride2 = shape2[3] * stride3; + const stride1 = shape2[2] * stride2; + const stride0 = shape2[1] * stride1; + const { newShape, keptDims } = squeezeShape(shape2); + if (newShape.length < shape2.length) { + const newInputShape = squeezeInputShape(shape2, newShape); + const params = ["row", "col", "depth", "depth2", "depth3"]; + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const source2 = ` + ${this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout).routineBody} + float ${funcName}(int row, int col, int depth, int depth2, int depth3) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.uvFromFlat"]); + } + const texNumR = inputLayout.width; + const texNumC = inputLayout.height; + const source = ` + float ${funcName}(int row, int col, int depth, int depth2, int depth3) { + int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} + + depth3 * ${stride3} + depth2; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, ["coordinates.sampleTexture", "coordinates.uvFromFlat"]); + } + /** + * Unpacked 6D snippet. + */ + getUnpackedSampler6D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const stride4 = shape2[5]; + const stride3 = shape2[4] * stride4; + const stride2 = shape2[3] * stride3; + const stride1 = shape2[2] * stride2; + const stride0 = shape2[1] * stride1; + const { newShape, keptDims } = squeezeShape(shape2); + if (newShape.length < shape2.length) { + const newInputShape = squeezeInputShape(shape2, newShape); + const params = ["row", "col", "depth", "depth2", "depth3", "depth4"]; + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const source2 = ` + ${this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout).routineBody} + float ${funcName}(int row, int col, int depth, + int depth2, int depth3, int depth4) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.uvFromFlat"]); + } + const texNumR = inputLayout.width; + const texNumC = inputLayout.height; + const source = ` + float ${funcName}(int row, int col, int depth, + int depth2, int depth3, int depth4) { + int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} + + depth2 * ${stride3} + depth3 * ${stride4} + depth4; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, [ + "coordinates.uvFromFlat", + "coordinates.sampleTexture", + "coordinates.coordsToOffset" + ]); + } + /** + * This is the main function to map from the given texture coordinates (s,t) + * to logical indices for the output + * There will only be one single variation of this + * Also see coordsToOffset and offsetToIndices for input-specific versions + */ + toVec() { + const output = this.context.outputTextureLayout; + const rank = output.shape.length; + const strides = output.strides; + const xScale = output.width; + const yScale = output.height; + const stridesBlock = []; + for (let i = 0; i < rank - 1; ++i) { + stridesBlock.push(` + c[${i}] = offset / ${strides[i]};`); + stridesBlock.push(` + offset -= c[${i}] * ${strides[i]};`); + } + stridesBlock.push(` + c[${rank - 1}] = offset;`); + const body = ` + void toVec(vec2 texCoords, out int c[${rank}]) { + int offset = coordsToOffset(texCoords, ${xScale}, ${yScale}); + ${stridesBlock.join("")} + } + void toVec(int offset, out int c[${rank}]) { + ${stridesBlock.join("")} + } + `; + return { toVec: new GlslLibRoutine(body, ["coordinates.coordsToOffset"]) }; + } + /** + * These are value getter functions generated for each input + * Each function is hardwired to the name and dimensions of the input + * An '_T' variation is also produced which accesses values as if the + * input was transposed + */ + valueFrom() { + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const layout = this.context.inputTextureLayouts[i]; + const shape2 = layout.unpackedShape.length > 0 ? layout.unpackedShape : layout.shape; + const rank = shape2.length; + let funcName = `_${name2}`; + result[funcName] = new GlslLibRoutine(this.getValueFromSingle(name2, rank, layout.width, layout.height, false), [ + `shapeUtils.indicesToOffset${funcName}`, + "coordinates.offsetToCoords", + "fragcolor.getColorAsFloat" + ]); + funcName = funcName + "_T"; + result[funcName] = new GlslLibRoutine(this.getValueFromSingle(name2, rank, layout.width, layout.height, true), [ + `shapeUtils.indicesToOffset${funcName}`, + "coordinates.offsetToCoords", + "fragcolor.getColorAsFloat" + ]); + }); + return result; + } + /** + * Produces one value getter function for the name and rank given + * If a transpose is set proper offsetToCoords mapping will be used + * @param name name of the function + * @param rank rank of the input + * @param transpose whether or not should generate a transpose variation + */ + getValueFromSingle(varName, rank, width, height, transpose2) { + let name2 = `_${varName}`; + if (transpose2) { + name2 = name2 + "_T"; + } + const glsl = getGlsl(this.context.glContext.version); + return ` + float ${name2}(int m[${rank}]) { + int offset = indicesToOffset${name2}(m); + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(${varName}, coords)); + return value; + } + `; + } + /** + * Produces a packed value getter function for the name and rank given + * If a transpose is set proper offsetToCoords mapping will be used + * @param name name of the function + * @param rank rank of the input + * @param transpose whether or not should generate a transpose variation + */ + getPackedValueFrom(varName, rank, width, height, transpose2) { + let name2 = `_${varName}_Pack`; + if (transpose2) { + name2 = name2 + "_T"; + } + const glsl = getGlsl(this.context.glContext.version); + return ` + vec4 ${name2}(int m[${rank}]) { + int offset = indicesToOffset_${varName}(m); + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + return ${glsl.texture2D}(${varName}, coords); + } + `; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-encoding-lib.ts +var EncodingGlslLib; +var init_glsl_encoding_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-encoding-lib.ts"() { + "use strict"; + init_glsl_definitions(); + EncodingGlslLib = class _EncodingGlslLib extends GlslLib { + constructor(context) { + super(context); + } + getFunctions() { + return { ...this.encodeFloat32(), ...this.decodeFloat32() }; + } + getCustomTypes() { + return {}; + } + encodeFloat32() { + return { + encode: new GlslLibRoutine(`highp vec4 encode(highp float f) { + return vec4(f, 0.0, 0.0, 0.0); + } + `) + }; + } + decodeFloat32() { + return { + decode: new GlslLibRoutine(`highp float decode(highp vec4 rgba) { + return rgba.r; + } + `) + }; + } + /** + * returns the routine to encode encode a 32bit float to a vec4 (of unsigned bytes) + * @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float + */ + encodeUint8() { + const endianness = _EncodingGlslLib.isLittleEndian() ? "rgba.rgba=rgba.abgr;" : ""; + return { + encode: new GlslLibRoutine(` + highp vec4 encode(highp float f) { + highp float F = abs(f); + highp float Sign = step(0.0,-f); + highp float Exponent = floor(log2(F)); + highp float Mantissa = (exp2(- Exponent) * F); + Exponent = floor(log2(F) + 127.0) + floor(log2(Mantissa)); + highp vec4 rgba; + rgba[0] = 128.0 * Sign + floor(Exponent*exp2(-1.0)); + rgba[1] = 128.0 * mod(Exponent,2.0) + mod(floor(Mantissa*128.0),128.0); + rgba[2] = floor(mod(floor(Mantissa*exp2(23.0 -8.0)),exp2(8.0))); + rgba[3] = floor(exp2(23.0)*mod(Mantissa,exp2(-15.0))); + ${endianness} + rgba = rgba / 255.0; // values need to be normalized to [0,1] + return rgba; + } + `) + }; + } + /** + * returns the routine to encode a vec4 of unsigned bytes to float32 + * @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float + */ + decodeUint8() { + const endianness = _EncodingGlslLib.isLittleEndian() ? "rgba.rgba=rgba.abgr;" : ""; + return { + decode: new GlslLibRoutine(` + highp float decode(highp vec4 rgba) { + rgba = rgba * 255.0; // values need to be de-normalized from [0,1] to [0,255] + ${endianness} + highp float Sign = 1.0 - step(128.0,rgba[0])*2.0; + highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0; + highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000); + highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 )); + return Result; + } + `) + }; + } + /** + * Determines if the machine is little endian or not + * @credit: https://gist.github.com/TooTallNate/4750953 + */ + static isLittleEndian() { + const b = new ArrayBuffer(4); + const a = new Uint32Array(b); + const c = new Uint8Array(b); + a[0] = 3735928559; + if (c[0] === 239) { + return true; + } + if (c[0] === 222) { + return false; + } + throw new Error("unknown endianness"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts +var FragColorGlslLib; +var init_glsl_fragcolor_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts"() { + "use strict"; + init_glsl_definitions(); + init_glsl_source(); + FragColorGlslLib = class extends GlslLib { + constructor(context) { + super(context); + } + getFunctions() { + return { ...this.setFragColor(), ...this.getColorAsFloat() }; + } + getCustomTypes() { + return {}; + } + setFragColor() { + const glsl = getGlsl(this.context.glContext.version); + return { + setFragColor: new GlslLibRoutine( + ` + void setFragColor(float value) { + ${glsl.output} = encode(value); + } + `, + ["encoding.encode"] + ) + }; + } + getColorAsFloat() { + return { + getColorAsFloat: new GlslLibRoutine( + ` + float getColorAsFloat(vec4 color) { + return decode(color); + } + `, + ["encoding.decode"] + ) + }; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts +var ShapeUtilsGlslLib; +var init_glsl_shape_utils_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts"() { + "use strict"; + init_glsl_definitions(); + ShapeUtilsGlslLib = class _ShapeUtilsGlslLib extends GlslLib { + constructor(context) { + super(context); + } + getFunctions() { + return { + ...this.bcastIndex(), + ...this.bcastMatmulIndex(), + ...this.offsetToIndices(), + ...this.indicesToOffset(), + ...this.incrementIndices() + }; + } + getCustomTypes() { + return {}; + } + bcastIndex() { + const outputRank = this.context.outputTextureLayout.shape.length; + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].unpackedShape; + if (shape2.length <= outputRank) { + const rank = shape2.length; + const dimOffset = outputRank - rank; + const funcName = `bcastIndices_${name2}`; + let block = ""; + for (let i2 = 0; i2 < rank; ++i2) { + block += ` + realIndices[${i2}] = int( mod(float(bcastedIndices[${dimOffset + i2}]), ${shape2[i2]}.0) ); + `; + } + const body = ` + void ${funcName} (int bcastedIndices[${outputRank}], out int realIndices[${rank}]) { + ${block} + } + `; + result[funcName] = new GlslLibRoutine(body); + } + }); + return result; + } + bcastMatmulIndex() { + const outputRank = this.context.outputTextureLayout.shape.length; + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].shape; + if (!(shape2.length < 2 || shape2.length > outputRank)) { + const rank = shape2.length; + const dimOffset = outputRank - rank; + const funcName = `bcastMatmulIndices_${name2}`; + let block = ""; + for (let i2 = 0; i2 < rank - 2; ++i2) { + block += ` + realIndices[${i2}] = int( mod(float(bcastedIndices[${dimOffset + i2}]), ${shape2[i2]}.0) ); + `; + } + const body = ` + void ${funcName}(int bcastedIndices[${outputRank}], out int realIndices[${rank}]) { + ${block} + realIndices[${rank - 1}] = bcastedIndices[${outputRank - 1}]; + realIndices[${rank - 2}] = bcastedIndices[${outputRank - 2}]; + } + `; + result[funcName] = new GlslLibRoutine(body); + } + }); + return result; + } + indicesToOffset() { + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].shape; + const strides = this.context.inputTextureLayouts[i].strides; + const rank = shape2.length; + let funcName = `indicesToOffset_${name2}`; + result[funcName] = new GlslLibRoutine(_ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides)); + funcName = `indicesToOffset_${name2}_T`; + result[funcName] = new GlslLibRoutine( + _ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides.slice().reverse()) + ); + }); + return result; + } + static indexToOffsetSingle(name2, rank, strides) { + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + offset += indices[${i}] * ${strides[i]}; + `; + } + return ` + int ${name2}(int indices[${rank}]) { + int offset = 0; + ${block} + return offset; + } + `; + } + offsetToIndices() { + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].shape; + const strides = this.context.inputTextureLayouts[i].strides; + const rank = shape2.length; + let funcName = `offsetToIndices_${name2}`; + result[funcName] = new GlslLibRoutine(_ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides)); + funcName = `offsetToIndices_${name2}_T`; + result[funcName] = new GlslLibRoutine( + _ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides.slice().reverse()) + ); + }); + return result; + } + static offsetToIndicesSingle(name2, rank, strides) { + const stridesBlock = []; + for (let i = 0; i < rank - 1; ++i) { + stridesBlock.push(` + indices[${i}] = offset / ${strides[i]};`); + stridesBlock.push(` + offset -= indices[${i}] * ${strides[i]};`); + } + stridesBlock.push(` + indices[${rank - 1}] = offset;`); + return ` + void ${name2}(int offset, out int indices[${rank}]) { + ${stridesBlock.join("")} + } + `; + } + incrementIndices() { + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].shape; + const rank = shape2.length; + const funcName = `incrementIndices_${name2}`; + let shapeInit = ""; + for (let i2 = 0; i2 < rank; ++i2) { + shapeInit += ` + shape[${i2}] = ${shape2[i2]};`; + } + const body = ` + void ${funcName}(int axis, out int indices[${rank}]) { + int shape[${rank}]; + ${shapeInit}; + for(int i = ${rank} -1 ; i >= 0; --i) { + if(i > axis) continue; + indices[i] += 1; + if(indices[i] < shape[i]) { + break; + } + indices[i] = 0; + } + } + `; + result[funcName] = new GlslLibRoutine(body); + }); + return result; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-vec-lib.ts +var VecGlslLib; +var init_glsl_vec_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-vec-lib.ts"() { + "use strict"; + init_glsl_definitions(); + VecGlslLib = class extends GlslLib { + constructor(context) { + super(context); + } + getCustomTypes() { + return {}; + } + getFunctions() { + return { ...this.binaryVecFunctions(), ...this.copyVec(), ...this.setVecItem(), ...this.getVecItem() }; + } + binaryVecFunctions() { + const outputLayout = this.context.outputTextureLayout; + const rank = outputLayout.shape.length; + const nameOp = { add: "+=", sub: "-=", mul: "*=", div: "/=" }; + const result = {}; + for (const name2 in nameOp) { + const fname = `${name2}Vec`; + let assignmentBlock = ""; + for (let i = 0; i < rank; ++i) { + assignmentBlock += ` + dest[${i}] ${nameOp[name2]} src[${i}]; + `; + } + const body = ` + void ${fname}(int src[${rank}], out int dest[${rank}]) { + ${assignmentBlock} + } + `; + result[fname] = new GlslLibRoutine(body); + } + return result; + } + copyVec() { + const outputLayout = this.context.outputTextureLayout; + const rank = outputLayout.shape.length; + let assignmentBlock = ""; + for (let i = 0; i < rank; ++i) { + assignmentBlock += ` + dest[${i}] = src[${i}]; + `; + } + const body = ` + void copyVec(int src[${rank}], out int dest[${rank}]) { + ${assignmentBlock} + } + `; + return { copyVec: new GlslLibRoutine(body) }; + } + setVecItem() { + const outputLayout = this.context.outputTextureLayout; + const rank = outputLayout.shape.length; + let block = ` + if(index < 0) + index =${rank} + index; + if (index == 0) + m[0] = value; + `; + for (let i = 1; i < rank - 1; ++i) { + block += ` + else if (index == ${i}) + m[${i}] = value; + `; + } + block += ` + else + m[${rank - 1}] = value; + `; + const body = ` + void setVecItem(out int m[${rank}], int index, int value) { + ${block} + } + `; + return { setVecItem: new GlslLibRoutine(body) }; + } + getVecItem() { + const outputLayout = this.context.outputTextureLayout; + const rank = outputLayout.shape.length; + let block = ` + if(index < 0) + index = ${rank} + index; + if (index == 0) + return m[0]; + `; + for (let i = 1; i < rank - 1; ++i) { + block += ` + else if (index == ${i}) + return m[${i}]; + `; + } + block += ` + else + return m[${rank - 1}]; + `; + const body = ` + int getVecItem(int m[${rank}], int index) { + ${block} + } + `; + return { getVecItem: new GlslLibRoutine(body) }; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-registered-libs.ts +var glslRegistry; +var init_glsl_registered_libs = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-registered-libs.ts"() { + "use strict"; + init_glsl_coordinate_lib(); + init_glsl_encoding_lib(); + init_glsl_fragcolor_lib(); + init_glsl_shape_utils_lib(); + init_glsl_vec_lib(); + glslRegistry = { + encoding: EncodingGlslLib, + fragcolor: FragColorGlslLib, + vec: VecGlslLib, + shapeUtils: ShapeUtilsGlslLib, + coordinates: CoordsGlslLib + // 'arrays': ArrayGlslSLib + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-preprocessor.ts +var GlslPreprocessor; +var init_glsl_preprocessor = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-preprocessor.ts"() { + "use strict"; + init_glsl_definitions(); + init_glsl_function_inliner(); + init_glsl_registered_libs(); + init_glsl_source(); + GlslPreprocessor = class { + constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) { + this.libs = {}; + this.glslLibRoutineDependencyGraph = {}; + this.context = new GlslContext(glContext, programInfo, inputTextureLayouts, outputTextureLayout); + Object.keys(glslRegistry).forEach((name2) => { + const lib = new glslRegistry[name2](this.context); + this.libs[name2] = lib; + }); + const map = this.glslLibRoutineDependencyGraph; + for (const libName in this.libs) { + const lib = this.libs[libName]; + const routinesInLib = lib.getFunctions(); + for (const routine in routinesInLib) { + const key = libName + "." + routine; + let currentNode; + if (map[key]) { + currentNode = map[key]; + currentNode.routineBody = routinesInLib[routine].routineBody; + } else { + currentNode = new GlslLibRoutineNode(key, routinesInLib[routine].routineBody); + map[key] = currentNode; + } + const dependencies = routinesInLib[routine].dependencies; + if (dependencies) { + for (let i = 0; i < dependencies.length; ++i) { + if (!map[dependencies[i]]) { + const node = new GlslLibRoutineNode(dependencies[i]); + map[dependencies[i]] = node; + currentNode.addDependency(node); + } else { + currentNode.addDependency(map[dependencies[i]]); + } + } + } + } + } + } + preprocess() { + const programInfo = this.context.programInfo; + let source = programInfo.shaderSource; + if (!this.context.programInfo.hasMain) { + source = `${source} + ${getDefaultFragShaderMain(this.context.glContext.version, this.context.outputTextureLayout.shape.length)}`; + } + source = replaceInlines(source); + return `${getFragShaderPreamble(this.context.glContext.version)} + ${this.getUniforms(programInfo.inputNames, programInfo.variables)} + ${this.getImports(source)} + ${source}`; + } + getImports(script) { + const routinesIncluded = this.selectGlslLibRoutinesToBeIncluded(script); + if (routinesIncluded.length === 0) { + return ""; + } + let routines = ""; + for (let i = 0; i < routinesIncluded.length; ++i) { + if (routinesIncluded[i].routineBody) { + routines += routinesIncluded[i].routineBody + "\n"; + } else { + throw new Error(`Missing body for the Glsl Library routine: ${routinesIncluded[i].name}`); + } + } + return routines; + } + selectGlslLibRoutinesToBeIncluded(script) { + const nodes = []; + Object.keys(this.glslLibRoutineDependencyGraph).forEach((classAndRoutine) => { + const routine = classAndRoutine.split(".")[1]; + if (script.indexOf(routine) !== -1) { + nodes.push(this.glslLibRoutineDependencyGraph[classAndRoutine]); + } + }); + return TopologicalSortGlslRoutines.returnOrderedNodes(nodes); + } + getUniforms(samplers, variables) { + const uniformLines = []; + if (samplers) { + for (const sampler of samplers) { + uniformLines.push(`uniform sampler2D ${sampler};`); + } + } + if (variables) { + for (const variable of variables) { + uniformLines.push( + `uniform ${variable.type} ${variable.name}${variable.arrayLength ? `[${variable.arrayLength}]` : ""};` + ); + } + } + return uniformLines.join("\n"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/program-manager.ts +var ProgramManager; +var init_program_manager = __esm({ + "web/lib/onnxjs/backends/webgl/program-manager.ts"() { + "use strict"; + init_esm(); + init_instrument(); + init_glsl_preprocessor(); + init_glsl_source(); + ProgramManager = class { + constructor(profiler, glContext, textureLayoutStrategy) { + this.profiler = profiler; + this.glContext = glContext; + this.textureLayoutStrategy = textureLayoutStrategy; + this.repo = /* @__PURE__ */ new Map(); + this.attributesBound = false; + } + getArtifact(key) { + return this.repo.get(key); + } + setArtifact(key, artifact) { + this.repo.set(key, artifact); + } + run(buildArtifact, inputs, output) { + this.profiler.event( + "op", + `ProgramManager.run ${buildArtifact.programInfo.name ?? "unknown kernel"}`, + () => { + const gl = this.glContext.gl; + const program = buildArtifact.program; + gl.useProgram(program); + try { + this.bindOutput(output); + if (!this.attributesBound) { + this.bindAttributes(buildArtifact.attribLocations); + } + this.bindUniforms(buildArtifact.uniformLocations, buildArtifact.programInfo.variables ?? [], inputs); + } catch (err) { + Logger.error("ProgramManager", buildArtifact.programInfo.shaderSource); + throw err; + } + this.profiler.event("backend", "GlContext.draw()", () => { + this.glContext.draw(); + }); + }, + this.glContext + ); + } + dispose() { + if (this.vertexShader) { + this.glContext.deleteShader(this.vertexShader); + } + this.repo.forEach((a) => this.glContext.deleteProgram(a.program)); + } + build(programInfo, inputTextureLayouts, outputTextureLayout) { + return this.profiler.event("backend", "ProgramManager.build", () => { + const preprocessor = new GlslPreprocessor(this.glContext, programInfo, inputTextureLayouts, outputTextureLayout); + const fragScript = preprocessor.preprocess(); + const program = this.compile(fragScript); + const artifact = { + programInfo, + program, + uniformLocations: this.getUniformLocations( + program, + preprocessor.context.programInfo.inputNames, + preprocessor.context.programInfo.variables + ), + attribLocations: this.getAttribLocations(program) + }; + return artifact; + }); + } + compile(fragShaderScript) { + if (!this.vertexShader) { + Logger.verbose("ProrgramManager", "Compiling and caching Vertex shader for the first time"); + const vertexShaderScript = getVertexShaderSource(this.glContext.version); + this.vertexShader = this.glContext.compileShader(vertexShaderScript, this.glContext.gl.VERTEX_SHADER); + } + if (env2.debug) { + Logger.verbose( + "ProrgramManager", + `FragShader: +${fragShaderScript} +` + ); + } + const fragShader = this.glContext.compileShader(fragShaderScript, this.glContext.gl.FRAGMENT_SHADER); + const program = this.glContext.createProgram(this.vertexShader, fragShader); + this.glContext.deleteShader(fragShader); + return program; + } + bindOutput(td) { + const width = td.width; + const height = td.height; + Logger.verbose( + "ProrgramManager", + `Binding output texture to Framebuffer: w/h=${width}/${height}, shape=${td.shape}, type=${td.tensor.type}` + ); + this.glContext.attachFramebuffer(td.texture, width, height); + } + bindAttributes(attribLocations) { + const positionHandle = attribLocations.position; + const textureCoordHandle = attribLocations.textureCoord; + this.glContext.setVertexAttributes(positionHandle, textureCoordHandle); + this.attributesBound = true; + } + bindUniforms(uniformLocations, variables, textures) { + const gl = this.glContext.gl; + let texturePosition = 0; + for (const { name: name2, type, location, arrayLength } of uniformLocations) { + const value = variables.find((v) => v.name === name2)?.data; + if (type !== "sampler2D" && !value) { + throw new Error(`variable '${name2}' does not have data defined in program info`); + } + switch (type) { + case "sampler2D": + this.bindTexture(textures[texturePosition], location, texturePosition); + texturePosition++; + break; + case "float": + if (arrayLength) { + gl.uniform1fv(location, value); + } else { + gl.uniform1f(location, value); + } + break; + case "int": + if (arrayLength) { + gl.uniform1iv(location, value); + } else { + gl.uniform1i(location, value); + } + break; + default: + throw new Error(`Uniform not implemented: ${type}`); + } + } + } + bindTexture(td, uniformHandle, position) { + this.glContext.bindTextureToUniform(td.texture, position, uniformHandle); + } + getAttribLocations(program) { + return { + position: this.getAttribLocation(program, "position"), + textureCoord: this.getAttribLocation(program, "textureCoord") + }; + } + getUniformLocations(program, samplers, variables) { + const uniformLocations = []; + if (samplers) { + for (const sampler of samplers) { + uniformLocations.push({ + name: sampler, + type: "sampler2D", + location: this.getUniformLocation(program, sampler) + }); + } + } + if (variables) { + for (const variable of variables) { + uniformLocations.push({ ...variable, location: this.getUniformLocation(program, variable.name) }); + } + } + return uniformLocations; + } + getUniformLocation(program, name2) { + const gl = this.glContext.gl; + const reference = gl.getUniformLocation(program, name2); + if (reference === null) { + throw new Error(`Uniform ${name2} not found.`); + } + return reference; + } + getAttribLocation(program, name2) { + const gl = this.glContext.gl; + const attributeLocation = gl.getAttribLocation(program, name2); + return attributeLocation; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/texture-manager.ts +var TextureManager; +var init_texture_manager = __esm({ + "web/lib/onnxjs/backends/webgl/texture-manager.ts"() { + "use strict"; + init_instrument(); + init_texture_data_encoder(); + TextureManager = class { + constructor(glContext, layoutStrategy, profiler, config) { + this.glContext = glContext; + this.layoutStrategy = layoutStrategy; + this.profiler = profiler; + this.config = config; + this.pendingRead = /* @__PURE__ */ new Map(); + if (config.reuseTextures) { + this.inUseTextures = /* @__PURE__ */ new Map(); + this.idleTextures = /* @__PURE__ */ new Map(); + this.textureLookup = /* @__PURE__ */ new Map(); + } + } + createTextureFromLayout(dataType, layout, data, usage) { + const textureDataType = this.toEncoderType(dataType); + const encoder = this.glContext.getEncoder(textureDataType, layout.channels || 1, usage); + if (layout.isPacked && usage === 1 /* UploadOnly */) { + throw new Error("not implemented"); + } + const width = layout.width; + const height = layout.height; + let key; + let inUseTextures; + if (this.config.reuseTextures) { + key = `${width}x${height}_${encoder.format}_${encoder.internalFormat}_${encoder.textureType}`; + inUseTextures = this.inUseTextures.get(key); + if (!inUseTextures) { + inUseTextures = []; + this.inUseTextures.set(key, inUseTextures); + } + const idleTextures = this.idleTextures.get(key); + if (idleTextures && idleTextures.length > 0) { + const texture2 = idleTextures.pop(); + inUseTextures.push(texture2); + if (usage === 1 /* UploadOnly */) { + this.glContext.updateTexture(texture2, width, height, encoder, this.toTextureData(dataType, data)); + } + return texture2; + } + } + Logger.verbose("TextureManager", `Creating new texture of size ${layout.width}x${layout.height}`); + const texture = this.glContext.allocateTexture(width, height, encoder, this.toTextureData(dataType, data)); + if (this.config.reuseTextures) { + inUseTextures.push(texture); + this.textureLookup.set(texture, key); + } + return texture; + } + readTexture(td, dataType, channels) { + if (!channels) { + channels = 1; + } + return this.profiler.event("backend", "TextureManager.readTexture", () => { + const dataSize = td.shape.reduce((a, b) => a * b) * channels; + const data = this.glContext.readTexture( + td.texture, + td.width, + td.height, + dataSize, + this.toEncoderType(dataType), + channels + ); + return this.toTensorData(dataType, data); + }); + } + async readTextureAsync(td, dataType, channels) { + const dataId = td.tensor.dataId; + if (!channels) { + channels = 1; + } + if (this.pendingRead.has(dataId)) { + const subscribers = this.pendingRead.get(dataId); + return new Promise((resolve) => subscribers?.push(resolve)); + } + return this.profiler.event("backend", "TextureManager.readTextureAsync", async () => { + this.pendingRead.set(dataId, []); + const dataSize = td.shape.reduce((a, b) => a * b) * channels; + await this.glContext.createAndWaitForFence(); + const data = this.glContext.readTexture( + td.texture, + td.width, + td.height, + dataSize, + this.toEncoderType(dataType), + channels + ); + const tensorData = this.toTensorData(dataType, data); + const subscribers = this.pendingRead.get(dataId); + this.pendingRead.delete(dataId); + subscribers?.forEach((resolve) => resolve(tensorData)); + return tensorData; + }); + } + readUint8TextureAsFloat(td) { + return this.profiler.event("backend", "TextureManager.readUint8TextureAsFloat", () => { + const dataSize = td.shape.reduce((a, b) => a * b); + const data = this.glContext.readTexture(td.texture, td.width, td.height, dataSize * 4, "byte", 4); + return new Float32Array(data.buffer, data.byteOffset, dataSize); + }); + } + releaseTexture(textureData, deleteTexture) { + let key; + if (this.config.reuseTextures) { + key = this.textureLookup.get(textureData.texture); + if (key) { + if (deleteTexture) { + this.textureLookup.delete(key); + } + const inUseTextures = this.inUseTextures.get(key); + if (inUseTextures) { + const index = inUseTextures.indexOf(textureData.texture); + if (index !== -1) { + inUseTextures.splice(index, 1); + let idleTextures = this.idleTextures.get(key); + if (!idleTextures) { + idleTextures = []; + this.idleTextures.set(key, idleTextures); + } + idleTextures.push(textureData.texture); + } + } + } + } + if (!key || deleteTexture) { + Logger.verbose("TextureManager", `Deleting texture of size ${textureData.width}x${textureData.height}`); + this.glContext.deleteTexture(textureData.texture); + } + } + toTensorData(dataType, data) { + switch (dataType) { + case "int16": + return data instanceof Int16Array ? data : Int16Array.from(data); + case "int32": + return data instanceof Int32Array ? data : Int32Array.from(data); + case "int8": + return data instanceof Int8Array ? data : Int8Array.from(data); + case "uint16": + return data instanceof Uint16Array ? data : Uint16Array.from(data); + case "uint32": + return data instanceof Uint32Array ? data : Uint32Array.from(data); + case "uint8": + case "bool": + return data instanceof Uint8Array ? data : Uint8Array.from(data); + case "float32": + return data instanceof Float32Array ? data : Float32Array.from(data); + case "float64": + return data instanceof Float64Array ? data : Float64Array.from(data); + default: + throw new Error(`TensorData type ${dataType} is not supported`); + } + } + toTextureData(_dataType, data) { + if (!data) { + return void 0; + } + return data instanceof Float32Array ? data : new Float32Array(data); + } + toEncoderType(_dataType) { + return "float"; + } + clearActiveTextures() { + this.glContext.clearActiveTextures(); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/session-handler.ts +var WebGLSessionHandler; +var init_session_handler = __esm({ + "web/lib/onnxjs/backends/webgl/session-handler.ts"() { + "use strict"; + init_instrument(); + init_opset(); + init_inference_handler(); + init_op_resolve_rules(); + init_program_manager(); + init_texture_layout_strategy(); + init_texture_manager(); + WebGLSessionHandler = class { + constructor(backend2, context) { + this.backend = backend2; + this.context = context; + this.layoutStrategy = new PreferLogicalStrategy(backend2.glContext.maxTextureSize); + this.programManager = new ProgramManager(this.context.profiler, backend2.glContext, this.layoutStrategy); + this.textureManager = new TextureManager(backend2.glContext, this.layoutStrategy, this.context.profiler, { + reuseTextures: backend2.textureCacheMode === "full" + }); + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + this.pack = backend2.pack; + this.pack2unpackMap = /* @__PURE__ */ new Map(); + this.unpack2packMap = /* @__PURE__ */ new Map(); + } + createInferenceHandler() { + return new WebGLInferenceHandler(this); + } + onGraphInitialized(graph) { + const initializers = graph.getValues().filter((v) => v.from === -1 && v.tensor).map((v) => v.tensor.dataId); + this.initializers = new Set(initializers); + } + isInitializer(tensorId) { + return this.initializers ? this.initializers.has(tensorId) : false; + } + addInitializer(tensorId) { + this.initializers.add(tensorId); + } + getTextureData(tensorId, isPacked) { + if (isPacked) { + return this.packedTextureDataCache.get(tensorId); + } else { + return this.unpackedTextureDataCache.get(tensorId); + } + } + setTextureData(tensorId, textureData, isPacked = false) { + Logger.verbose("WebGLSessionHandler", "Storing Texture data in cache"); + if (isPacked) { + this.packedTextureDataCache.set(tensorId, textureData); + } else { + this.unpackedTextureDataCache.set(tensorId, textureData); + } + } + dispose() { + this.programManager.dispose(); + this.textureManager.clearActiveTextures(); + this.packedTextureDataCache.forEach((td) => this.textureManager.releaseTexture(td, true)); + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache.forEach((td) => this.textureManager.releaseTexture(td, true)); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + } + resolve(node, opsets, graph) { + const op = resolveOperator(node, opsets, WEBGL_OP_RESOLVE_RULES); + return { impl: op.opImpl, context: op.opInit ? op.opInit(node, graph) : node }; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/webgl-context.ts +function linearSearchLastTrue(arr) { + let i = 0; + for (; i < arr.length; ++i) { + const isDone = arr[i](); + if (!isDone) { + break; + } + } + return i - 1; +} +var WebGLContext; +var init_webgl_context = __esm({ + "web/lib/onnxjs/backends/webgl/webgl-context.ts"() { + "use strict"; + init_esm(); + init_texture_data_encoder(); + init_texture_data_encoder(); + init_utils(); + WebGLContext = class { + constructor(gl, version3) { + this.frameBufferBound = false; + this.itemsToPoll = []; + this.gl = gl; + this.version = version3; + this.getExtensions(); + this.vertexbuffer = this.createVertexbuffer(); + this.framebuffer = this.createFramebuffer(); + this.queryVitalParameters(); + } + allocateTexture(width, height, encoder, data) { + const gl = this.gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + const buffer = data ? encoder.encode(data, width * height) : null; + gl.texImage2D( + gl.TEXTURE_2D, + 0, + // Level of detail. + encoder.internalFormat, + width, + height, + 0, + // Always 0 in OpenGL ES. + encoder.format, + encoder.textureType, + buffer + ); + this.checkError(); + return texture; + } + updateTexture(texture, width, height, encoder, data) { + const gl = this.gl; + gl.bindTexture(gl.TEXTURE_2D, texture); + const buffer = encoder.encode(data, width * height); + gl.texSubImage2D( + gl.TEXTURE_2D, + 0, + // level + 0, + // xoffset + 0, + // yoffset + width, + height, + encoder.format, + encoder.textureType, + buffer + ); + this.checkError(); + } + attachFramebuffer(texture, width, height) { + const gl = this.gl; + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + this.checkError(); + gl.viewport(0, 0, width, height); + gl.scissor(0, 0, width, height); + } + readTexture(texture, width, height, dataSize, dataType, channels) { + const gl = this.gl; + if (!channels) { + channels = 1; + } + if (!this.frameBufferBound) { + this.attachFramebuffer(texture, width, height); + } + const encoder = this.getEncoder(dataType, channels); + const buffer = encoder.allocate(width * height); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + gl.readPixels(0, 0, width, height, gl.RGBA, encoder.textureType, buffer); + this.checkError(); + return encoder.decode(buffer, dataSize); + } + isFramebufferReady() { + return true; + } + getActiveTexture() { + const gl = this.gl; + const n = gl.getParameter(this.gl.ACTIVE_TEXTURE); + return `TEXTURE${n - gl.TEXTURE0}`; + } + getTextureBinding() { + return this.gl.getParameter(this.gl.TEXTURE_BINDING_2D); + } + getFramebufferBinding() { + return this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING); + } + setVertexAttributes(positionHandle, textureCoordHandle) { + const gl = this.gl; + gl.vertexAttribPointer(positionHandle, 3, gl.FLOAT, false, 20, 0); + gl.enableVertexAttribArray(positionHandle); + if (textureCoordHandle !== -1) { + gl.vertexAttribPointer(textureCoordHandle, 2, gl.FLOAT, false, 20, 12); + gl.enableVertexAttribArray(textureCoordHandle); + } + this.checkError(); + } + createProgram(vertexShader, fragShader) { + const gl = this.gl; + const program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragShader); + gl.linkProgram(program); + return program; + } + compileShader(shaderSource, shaderType) { + const gl = this.gl; + const shader = gl.createShader(shaderType); + if (!shader) { + throw new Error(`createShader() returned null with type ${shaderType}`); + } + gl.shaderSource(shader, shaderSource); + gl.compileShader(shader); + if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) === false) { + throw new Error(`Failed to compile shader: ${gl.getShaderInfoLog(shader)} +Shader source: +${shaderSource}`); + } + return shader; + } + deleteShader(shader) { + this.gl.deleteShader(shader); + } + bindTextureToUniform(texture, position, uniformHandle) { + const gl = this.gl; + gl.activeTexture(gl.TEXTURE0 + position); + this.checkError(); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.checkError(); + gl.uniform1i(uniformHandle, position); + this.checkError(); + } + draw() { + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + this.checkError(); + } + checkError() { + if (env2.debug) { + const gl = this.gl; + const error = gl.getError(); + let label = ""; + switch (error) { + case gl.NO_ERROR: + return; + case gl.INVALID_ENUM: + label = "INVALID_ENUM"; + break; + case gl.INVALID_VALUE: + label = "INVALID_VALUE"; + break; + case gl.INVALID_OPERATION: + label = "INVALID_OPERATION"; + break; + case gl.INVALID_FRAMEBUFFER_OPERATION: + label = "INVALID_FRAMEBUFFER_OPERATION"; + break; + case gl.OUT_OF_MEMORY: + label = "OUT_OF_MEMORY"; + break; + case gl.CONTEXT_LOST_WEBGL: + label = "CONTEXT_LOST_WEBGL"; + break; + default: + label = `Unknown WebGL Error: ${error.toString(16)}`; + } + throw new Error(label); + } + } + deleteTexture(texture) { + this.gl.deleteTexture(texture); + } + deleteProgram(program) { + this.gl.deleteProgram(program); + } + getEncoder(dataType, channels, usage = 0 /* Default */) { + if (this.version === 2) { + return new RedFloat32DataEncoder(this.gl, channels); + } + switch (dataType) { + case "float": + if (usage === 1 /* UploadOnly */ || this.isRenderFloat32Supported) { + return new RGBAFloatDataEncoder(this.gl, channels); + } else { + return new RGBAFloatDataEncoder( + this.gl, + channels, + this.textureHalfFloatExtension.HALF_FLOAT_OES + ); + } + case "int": + throw new Error("not implemented"); + case "byte": + return new Uint8DataEncoder(this.gl, channels); + default: + throw new Error(`Invalid dataType: ${dataType}`); + } + } + clearActiveTextures() { + const gl = this.gl; + for (let unit = 0; unit < this.maxTextureImageUnits; ++unit) { + gl.activeTexture(gl.TEXTURE0 + unit); + gl.bindTexture(gl.TEXTURE_2D, null); + } + } + dispose() { + if (this.disposed) { + return; + } + const gl = this.gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(this.framebuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.deleteBuffer(this.vertexbuffer); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + gl.finish(); + this.disposed = true; + } + createDefaultGeometry() { + return new Float32Array([ + -1, + 1, + 0, + 0, + 1, + // upper left + -1, + -1, + 0, + 0, + 0, + // lower left + 1, + 1, + 0, + 1, + 1, + // upper right + 1, + -1, + 0, + 1, + 0 + // lower right + ]); + } + createVertexbuffer() { + const gl = this.gl; + const buffer = gl.createBuffer(); + if (!buffer) { + throw new Error("createBuffer() returned null"); + } + const geometry = this.createDefaultGeometry(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, geometry, gl.STATIC_DRAW); + this.checkError(); + return buffer; + } + createFramebuffer() { + const fb = this.gl.createFramebuffer(); + if (!fb) { + throw new Error("createFramebuffer returned null"); + } + return fb; + } + queryVitalParameters() { + const gl = this.gl; + this.isFloatTextureAttachableToFrameBuffer = this.checkFloatTextureAttachableToFrameBuffer(); + this.isRenderFloat32Supported = this.checkRenderFloat32(); + this.isFloat32DownloadSupported = this.checkFloat32Download(); + if (this.version === 1 && !this.textureHalfFloatExtension && !this.isRenderFloat32Supported) { + throw new Error("both float32 and float16 TextureType are not supported"); + } + this.isBlendSupported = !this.isRenderFloat32Supported || this.checkFloat32Blend(); + this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this.maxTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + if (this.version === 2) { + } + } + getExtensions() { + if (this.version === 2) { + this.colorBufferFloatExtension = this.gl.getExtension("EXT_color_buffer_float"); + this.disjointTimerQueryWebgl2Extension = this.gl.getExtension("EXT_disjoint_timer_query_webgl2"); + } else { + this.textureFloatExtension = this.gl.getExtension("OES_texture_float"); + this.textureHalfFloatExtension = this.gl.getExtension("OES_texture_half_float"); + } + } + checkFloatTextureAttachableToFrameBuffer() { + const gl = this.gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA; + gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); + const frameBuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + const isComplete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE; + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteTexture(texture); + gl.deleteFramebuffer(frameBuffer); + return isComplete; + } + checkRenderFloat32() { + if (this.version === 2) { + if (!this.colorBufferFloatExtension) { + return false; + } + } else { + if (!this.textureFloatExtension) { + return false; + } + } + return this.isFloatTextureAttachableToFrameBuffer; + } + checkFloat32Download() { + if (this.version === 2) { + if (!this.colorBufferFloatExtension) { + return false; + } + } else { + if (!this.textureFloatExtension) { + return false; + } + if (!this.gl.getExtension("WEBGL_color_buffer_float")) { + return false; + } + } + return this.isFloatTextureAttachableToFrameBuffer; + } + /** + * Check whether GL_BLEND is supported + */ + checkFloat32Blend() { + const gl = this.gl; + let texture; + let frameBuffer; + let vertexShader; + let fragmentShader; + let program; + try { + texture = gl.createTexture(); + frameBuffer = gl.createFramebuffer(); + gl.bindTexture(gl.TEXTURE_2D, texture); + const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA; + gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + gl.enable(gl.BLEND); + vertexShader = gl.createShader(gl.VERTEX_SHADER); + if (!vertexShader) { + return false; + } + gl.shaderSource(vertexShader, "void main(){}"); + gl.compileShader(vertexShader); + fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + if (!fragmentShader) { + return false; + } + gl.shaderSource(fragmentShader, "precision highp float;void main(){gl_FragColor=vec4(0.5);}"); + gl.compileShader(fragmentShader); + program = gl.createProgram(); + if (!program) { + return false; + } + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + gl.useProgram(program); + gl.drawArrays(gl.POINTS, 0, 1); + return gl.getError() === gl.NO_ERROR; + } finally { + gl.disable(gl.BLEND); + if (program) { + gl.deleteProgram(program); + } + if (vertexShader) { + gl.deleteShader(vertexShader); + } + if (fragmentShader) { + gl.deleteShader(fragmentShader); + } + if (frameBuffer) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(frameBuffer); + } + if (texture) { + gl.bindTexture(gl.TEXTURE_2D, null); + gl.deleteTexture(texture); + } + } + } + beginTimer() { + if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { + const gl2 = this.gl; + const ext = this.disjointTimerQueryWebgl2Extension; + const query = gl2.createQuery(); + gl2.beginQuery(ext.TIME_ELAPSED_EXT, query); + return query; + } else { + throw new Error("WebGL1 profiling currently not supported."); + } + } + endTimer() { + if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { + const gl2 = this.gl; + const ext = this.disjointTimerQueryWebgl2Extension; + gl2.endQuery(ext.TIME_ELAPSED_EXT); + return; + } else { + throw new Error("WebGL1 profiling currently not supported"); + } + } + isTimerResultAvailable(query) { + let available = false, disjoint = false; + if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { + const gl2 = this.gl; + const ext = this.disjointTimerQueryWebgl2Extension; + available = gl2.getQueryParameter(query, gl2.QUERY_RESULT_AVAILABLE); + disjoint = gl2.getParameter(ext.GPU_DISJOINT_EXT); + } else { + throw new Error("WebGL1 profiling currently not supported"); + } + return available && !disjoint; + } + getTimerResult(query) { + let timeElapsed = 0; + if (this.version === 2) { + const gl2 = this.gl; + timeElapsed = gl2.getQueryParameter(query, gl2.QUERY_RESULT); + gl2.deleteQuery(query); + } else { + throw new Error("WebGL1 profiling currently not supported"); + } + return timeElapsed / 1e6; + } + async waitForQueryAndGetTime(query) { + await repeatedTry(() => this.isTimerResultAvailable(query)); + return this.getTimerResult(query); + } + async createAndWaitForFence() { + const fenceContext = this.createFence(this.gl); + return this.pollFence(fenceContext); + } + createFence(gl) { + let isFencePassed; + const gl2 = gl; + const query = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0); + gl.flush(); + if (query === null) { + isFencePassed = () => true; + } else { + isFencePassed = () => { + const status = gl2.clientWaitSync(query, 0, 0); + return status === gl2.ALREADY_SIGNALED || status === gl2.CONDITION_SATISFIED; + }; + } + return { query, isFencePassed }; + } + async pollFence(fenceContext) { + return new Promise((resolve) => { + void this.addItemToPoll( + () => fenceContext.isFencePassed(), + () => resolve() + ); + }); + } + pollItems() { + const index = linearSearchLastTrue(this.itemsToPoll.map((x) => x.isDoneFn)); + for (let i = 0; i <= index; ++i) { + const { resolveFn } = this.itemsToPoll[i]; + resolveFn(); + } + this.itemsToPoll = this.itemsToPoll.slice(index + 1); + } + async addItemToPoll(isDoneFn, resolveFn) { + this.itemsToPoll.push({ isDoneFn, resolveFn }); + if (this.itemsToPoll.length > 1) { + return; + } + await repeatedTry(() => { + this.pollItems(); + return this.itemsToPoll.length === 0; + }); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/webgl-context-factory.ts +function createWebGLContext(contextId) { + let context; + if ((!contextId || contextId === "webgl2") && "webgl2" in cache) { + context = cache.webgl2; + } else if ((!contextId || contextId === "webgl") && "webgl" in cache) { + context = cache.webgl; + } + if (!context) { + try { + const offscreenCanvas = createOffscreenCanvas(); + context = createNewWebGLContext(offscreenCanvas, contextId); + } catch { + const canvas = createCanvas(); + context = createNewWebGLContext(canvas, contextId); + } + } + contextId = contextId || context.version === 1 ? "webgl" : "webgl2"; + const gl = context.gl; + cache[contextId] = context; + if (gl.isContextLost()) { + delete cache[contextId]; + return createWebGLContext(contextId); + } + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.STENCIL_TEST); + gl.disable(gl.BLEND); + gl.disable(gl.DITHER); + gl.disable(gl.POLYGON_OFFSET_FILL); + gl.disable(gl.SAMPLE_COVERAGE); + gl.enable(gl.SCISSOR_TEST); + gl.enable(gl.CULL_FACE); + gl.cullFace(gl.BACK); + return context; +} +function createNewWebGLContext(canvas, contextId) { + const contextAttributes = { + alpha: false, + depth: false, + antialias: false, + stencil: false, + preserveDrawingBuffer: false, + premultipliedAlpha: false, + failIfMajorPerformanceCaveat: false + }; + let gl; + const ca = contextAttributes; + if (!contextId || contextId === "webgl2") { + gl = canvas.getContext("webgl2", ca); + if (gl) { + try { + return new WebGLContext(gl, 2); + } catch (err) { + Logger.warning("GlContextFactory", `failed to create WebGLContext using contextId 'webgl2'. Error: ${err}`); + } + } + } + if (!contextId || contextId === "webgl") { + gl = canvas.getContext("webgl", ca) || canvas.getContext("experimental-webgl", ca); + if (gl) { + try { + return new WebGLContext(gl, 1); + } catch (err) { + Logger.warning( + "GlContextFactory", + `failed to create WebGLContext using contextId 'webgl' or 'experimental-webgl'. Error: ${err}` + ); + } + } + } + throw new Error("WebGL is not supported"); +} +function createCanvas() { + if (typeof document === "undefined") { + throw new TypeError("failed to create canvas: document is not supported"); + } + const canvas = document.createElement("canvas"); + canvas.width = 1; + canvas.height = 1; + return canvas; +} +function createOffscreenCanvas() { + if (typeof OffscreenCanvas === "undefined") { + throw new TypeError("failed to create offscreen canvas: OffscreenCanvas is not supported"); + } + return new OffscreenCanvas(1, 1); +} +var cache; +var init_webgl_context_factory = __esm({ + "web/lib/onnxjs/backends/webgl/webgl-context-factory.ts"() { + "use strict"; + init_instrument(); + init_webgl_context(); + cache = {}; + } +}); + +// web/lib/onnxjs/backends/backend-webgl.ts +var WebGLBackend; +var init_backend_webgl = __esm({ + "web/lib/onnxjs/backends/backend-webgl.ts"() { + "use strict"; + init_esm(); + init_instrument(); + init_session_handler(); + init_webgl_context_factory(); + WebGLBackend = class { + get contextId() { + return env2.webgl.contextId; + } + set contextId(value) { + env2.webgl.contextId = value; + } + get matmulMaxBatchSize() { + return env2.webgl.matmulMaxBatchSize; + } + set matmulMaxBatchSize(value) { + env2.webgl.matmulMaxBatchSize = value; + } + get textureCacheMode() { + return env2.webgl.textureCacheMode; + } + set textureCacheMode(value) { + env2.webgl.textureCacheMode = value; + } + get pack() { + return env2.webgl.pack; + } + set pack(value) { + env2.webgl.pack = value; + } + get async() { + return env2.webgl.async; + } + set async(value) { + env2.webgl.async = value; + } + initialize() { + try { + this.glContext = createWebGLContext(this.contextId); + if (typeof this.matmulMaxBatchSize !== "number") { + this.matmulMaxBatchSize = 16; + } + if (typeof this.textureCacheMode !== "string") { + this.textureCacheMode = "full"; + } + if (typeof this.pack !== "boolean") { + this.pack = false; + } + if (typeof this.async !== "boolean") { + this.async = false; + } + Logger.setWithEnv(env2); + if (!env2.webgl.context) { + Object.defineProperty(env2.webgl, "context", { value: this.glContext.gl }); + } + Logger.verbose( + "WebGLBackend", + `Created WebGLContext: ${typeof this.glContext} with matmulMaxBatchSize: ${this.matmulMaxBatchSize}; textureCacheMode: ${this.textureCacheMode}; pack: ${this.pack}; async: ${this.async}.` + ); + return true; + } catch (e) { + Logger.warning("WebGLBackend", `Unable to initialize WebGLBackend. ${e}`); + return false; + } + } + createSessionHandler(context) { + return new WebGLSessionHandler(this, context); + } + dispose() { + this.glContext.dispose(); + } + }; + } +}); + +// web/lib/onnxjs/backend.ts +async function resolveBackend(hint) { + if (!hint) { + return resolveBackend(["webgl"]); + } else { + const hints = typeof hint === "string" ? [hint] : hint; + for (const backendHint of hints) { + const cache2 = backendsCache.get(backendHint); + if (cache2) { + return cache2; + } + const backend2 = await tryLoadBackend(backendHint); + if (backend2) { + return backend2; + } + } + } + throw new Error("no available backend to use"); +} +async function tryLoadBackend(backendHint) { + const backendObj = backend; + if (typeof backendObj[backendHint] !== "undefined" && isBackend(backendObj[backendHint])) { + const backend2 = backendObj[backendHint]; + let init = backend2.initialize(); + if (typeof init === "object" && "then" in init) { + init = await init; + } + if (init) { + backendsCache.set(backendHint, backend2); + return backend2; + } + } + return void 0; +} +function isBackend(obj) { + const o = obj; + if ("initialize" in o && typeof o.initialize === "function" && // initialize() + "createSessionHandler" in o && typeof o.createSessionHandler === "function" && // createSessionHandler() + "dispose" in o && typeof o.dispose === "function") { + return true; + } + return false; +} +var backendsCache, backend; +var init_backend2 = __esm({ + "web/lib/onnxjs/backend.ts"() { + "use strict"; + init_backend_webgl(); + backendsCache = /* @__PURE__ */ new Map(); + backend = { + webgl: new WebGLBackend() + }; + } +}); + +// web/lib/onnxjs/execution-plan.ts +var KernelOp, ExecutionPlan; +var init_execution_plan = __esm({ + "web/lib/onnxjs/execution-plan.ts"() { + "use strict"; + init_instrument(); + KernelOp = class { + constructor(op, node) { + this.op = op; + this.node = node; + } + }; + ExecutionPlan = class { + constructor(graph, ops, profiler) { + this.graph = graph; + this.profiler = profiler; + this.initialize(ops); + } + initialize(ops) { + this.profiler.event("session", "ExecutionPlan.initialize", () => { + const graphNodes = this.graph.getNodes(); + if (graphNodes.length !== ops.length) { + throw new Error("The size of nodes and OPs do not match."); + } + this._ops = ops.map((op, i) => new KernelOp(op, graphNodes[i])); + this.reset(); + this._starter = []; + this._ops.forEach((op, i) => { + let resolved = true; + for (const input of op.node.inputs) { + if (!this._values[input] && // not an initialized input + this.graph.getInputIndices().indexOf(input) === -1) { + resolved = false; + break; + } + } + if (resolved) { + this._starter.push(i); + } + }); + }); + } + reset() { + this._values = this.graph.getValues().map((i) => i.tensor); + } + async execute(sessionHandler, modelInputs) { + return this.profiler.event("session", "ExecutionPlan.execute", async () => { + this.reset(); + const inferenceHandler = sessionHandler.createInferenceHandler(); + const graphInputs = this.graph.getInputIndices(); + if (modelInputs.length !== graphInputs.length) { + throw new Error( + `number of input tensors don't match the number of inputs to the model: actual: ${modelInputs.length} expected: ${graphInputs.length}` + ); + } + modelInputs.forEach((input, i) => { + const index = graphInputs[i]; + this._values[index] = input; + }); + const sequence = this._starter.slice(0); + const graphValues = this.graph.getValues(); + const graphNodes = this.graph.getNodes(); + let rear = 0; + while (rear < sequence.length) { + const thisOpIndex = sequence[rear++]; + const thisOp = this._ops[thisOpIndex]; + const inputList = thisOp.node.inputs.map((i) => this._values[i]); + if (inputList.indexOf(void 0) !== -1) { + throw new Error(`unresolved input detected: op: ${thisOp.node}`); + } + const inputTensors = inputList; + Logger.verbose( + "ExecPlan", + `Running op:${thisOp.node.name} (${inputTensors.map((t, i) => `'${thisOp.node.inputs[i]}': ${t.type}[${t.dims.join(",")}]`).join(", ")})` + ); + const outputList = await this.profiler.event( + "node", + thisOp.node.name, + async () => thisOp.op.impl(inferenceHandler, inputTensors, thisOp.op.context) + ); + if (outputList.length !== thisOp.node.outputs.length) { + throw new Error("the size of output does not match model definition."); + } + outputList.forEach((output2, i) => { + const j = thisOp.node.outputs[i]; + if (this._values[j]) { + throw new Error(`output [${j}] already has value: op:${thisOp.node.name}`); + } + this._values[j] = output2; + }); + const downstreamNodes = /* @__PURE__ */ new Set(); + outputList.forEach((_output, i) => { + const j = thisOp.node.outputs[i]; + for (const currentDownstreamNodeIndex of graphValues[j].to) { + const currentDownstreamNode = graphNodes[currentDownstreamNodeIndex]; + let resolved = true; + for (const k of currentDownstreamNode.inputs) { + if (!this._values[k]) { + resolved = false; + break; + } + } + if (resolved) { + downstreamNodes.add(currentDownstreamNodeIndex); + } + } + }); + sequence.push(...downstreamNodes); + } + const output = []; + for (let i = 0; i < this.graph.getOutputIndices().length; i++) { + const outputIndex = this.graph.getOutputIndices()[i]; + const outputTensor = this._values[outputIndex]; + if (outputTensor === void 0) { + throw new Error(`required output [${outputIndex}] does not have value`); + } + if (outputIndex === 0) { + await outputTensor.getData(); + } else { + void outputTensor.data; + } + output.push(outputTensor); + } + Logger.verbose("ExecPlan", "disposing of inferenceHandler"); + inferenceHandler.dispose(); + return output; + }); + } + }; + } +}); + +// web/lib/onnxjs/attribute.ts +var import_onnx3, Attribute2; +var init_attribute = __esm({ + "web/lib/onnxjs/attribute.ts"() { + "use strict"; + init_ort_generated(); + import_onnx3 = __toESM(require_onnx()); + init_tensor2(); + init_util(); + Attribute2 = class _Attribute { + constructor(attributes) { + this._attributes = /* @__PURE__ */ new Map(); + if (attributes !== null && attributes !== void 0) { + for (const attr of attributes) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + this._attributes.set(attr.name, [_Attribute.getValue(attr), _Attribute.getType(attr)]); + } else if (attr instanceof import_attribute.Attribute) { + this._attributes.set(attr.name(), [_Attribute.getValue(attr), _Attribute.getType(attr)]); + } + } + if (this._attributes.size < attributes.length) { + throw new Error("duplicated attribute names"); + } + } + } + set(key, type, value) { + this._attributes.set(key, [value, type]); + } + delete(key) { + this._attributes.delete(key); + } + getFloat(key, defaultValue) { + return this.get(key, "float", defaultValue); + } + getInt(key, defaultValue) { + return this.get(key, "int", defaultValue); + } + getString(key, defaultValue) { + return this.get(key, "string", defaultValue); + } + getTensor(key, defaultValue) { + return this.get(key, "tensor", defaultValue); + } + getFloats(key, defaultValue) { + return this.get(key, "floats", defaultValue); + } + getInts(key, defaultValue) { + return this.get(key, "ints", defaultValue); + } + getStrings(key, defaultValue) { + return this.get(key, "strings", defaultValue); + } + getTensors(key, defaultValue) { + return this.get(key, "tensors", defaultValue); + } + get(key, type, defaultValue) { + const valueAndType = this._attributes.get(key); + if (valueAndType === void 0) { + if (defaultValue !== void 0) { + return defaultValue; + } + throw new Error(`required attribute not found: ${key}`); + } + if (valueAndType[1] !== type) { + throw new Error(`type mismatch: expected ${type} but got ${valueAndType[1]}`); + } + return valueAndType[0]; + } + static getType(attr) { + const type = attr instanceof import_onnx3.onnx.AttributeProto ? attr.type : attr.type(); + switch (type) { + case import_onnx3.onnx.AttributeProto.AttributeType.FLOAT: + return "float"; + case import_onnx3.onnx.AttributeProto.AttributeType.INT: + return "int"; + case import_onnx3.onnx.AttributeProto.AttributeType.STRING: + return "string"; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSOR: + return "tensor"; + case import_onnx3.onnx.AttributeProto.AttributeType.FLOATS: + return "floats"; + case import_onnx3.onnx.AttributeProto.AttributeType.INTS: + return "ints"; + case import_onnx3.onnx.AttributeProto.AttributeType.STRINGS: + return "strings"; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSORS: + return "tensors"; + default: + throw new Error(`attribute type is not supported yet: ${import_onnx3.onnx.AttributeProto.AttributeType[type]}`); + } + } + static getValue(attr) { + const attrType = attr instanceof import_onnx3.onnx.AttributeProto ? attr.type : attr.type(); + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.GRAPH || attrType === import_onnx3.onnx.AttributeProto.AttributeType.GRAPHS) { + throw new Error("graph attribute is not supported yet"); + } + const value = this.getValueNoCheck(attr); + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.INT && LongUtil.isLong(value)) { + return LongUtil.longToNumber(value); + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.INTS) { + const arr = value; + const numberValue = new Array(arr.length); + for (let i = 0; i < arr.length; i++) { + const maybeLong = arr[i]; + numberValue[i] = LongUtil.longToNumber(maybeLong); + } + return numberValue; + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.TENSOR) { + return attr instanceof import_onnx3.onnx.AttributeProto ? Tensor4.fromProto(value) : Tensor4.fromOrtTensor(value); + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.TENSORS) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + const tensorProtos = value; + return tensorProtos.map((value2) => Tensor4.fromProto(value2)); + } else if (attr instanceof import_attribute.Attribute) { + const tensorProtos = value; + return tensorProtos.map((value2) => Tensor4.fromOrtTensor(value2)); + } + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.STRING) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + const utf8String = value; + return decodeUtf8String(utf8String); + } + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.STRINGS) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + const utf8Strings = value; + return utf8Strings.map(decodeUtf8String); + } + } + return value; + } + static getValueNoCheck(attr) { + return attr instanceof import_onnx3.onnx.AttributeProto ? this.getValueNoCheckFromOnnxFormat(attr) : this.getValueNoCheckFromOrtFormat(attr); + } + static getValueNoCheckFromOnnxFormat(attr) { + switch (attr.type) { + case import_onnx3.onnx.AttributeProto.AttributeType.FLOAT: + return attr.f; + case import_onnx3.onnx.AttributeProto.AttributeType.INT: + return attr.i; + case import_onnx3.onnx.AttributeProto.AttributeType.STRING: + return attr.s; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSOR: + return attr.t; + case import_onnx3.onnx.AttributeProto.AttributeType.GRAPH: + return attr.g; + case import_onnx3.onnx.AttributeProto.AttributeType.FLOATS: + return attr.floats; + case import_onnx3.onnx.AttributeProto.AttributeType.INTS: + return attr.ints; + case import_onnx3.onnx.AttributeProto.AttributeType.STRINGS: + return attr.strings; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSORS: + return attr.tensors; + case import_onnx3.onnx.AttributeProto.AttributeType.GRAPHS: + return attr.graphs; + default: + throw new Error(`unsupported attribute type: ${import_onnx3.onnx.AttributeProto.AttributeType[attr.type]}`); + } + } + static getValueNoCheckFromOrtFormat(attr) { + switch (attr.type()) { + case import_attribute_type.AttributeType.FLOAT: + return attr.f(); + case import_attribute_type.AttributeType.INT: + return attr.i(); + case import_attribute_type.AttributeType.STRING: + return attr.s(); + case import_attribute_type.AttributeType.TENSOR: + return attr.t(); + case import_attribute_type.AttributeType.GRAPH: + return attr.g(); + case import_attribute_type.AttributeType.FLOATS: + return attr.floatsArray(); + case import_attribute_type.AttributeType.INTS: { + const ints = []; + for (let i = 0; i < attr.intsLength(); i++) { + ints.push(attr.ints(i)); + } + return ints; + } + case import_attribute_type.AttributeType.STRINGS: { + const strings = []; + for (let i = 0; i < attr.stringsLength(); i++) { + strings.push(attr.strings(i)); + } + return strings; + } + case import_attribute_type.AttributeType.TENSORS: { + const tensors = []; + for (let i = 0; i < attr.tensorsLength(); i++) { + tensors.push(attr.tensors(i)); + } + return tensors; + } + // case ortFbs.AttributeType.GRAPHS: + // TODO: Subgraph not supported yet. + // const graphs = []; + // for (let i = 0; i < attr.graphsLength(); i++) { + // graphs.push(attr.graphs(i)!); + // } + // return graphs; + default: + throw new Error(`unsupported attribute type: ${import_attribute_type.AttributeType[attr.type()]}`); + } + } + }; + } +}); + +// web/lib/onnxjs/graph.ts +var import_onnx4, Graph2, Value, Node2, GraphImpl; +var init_graph = __esm({ + "web/lib/onnxjs/graph.ts"() { + "use strict"; + init_attribute(); + init_ort_generated(); + import_onnx4 = __toESM(require_onnx()); + init_tensor2(); + init_util(); + Graph2 = { + /** + * construct a graph from a graph protobuf type + */ + from: (graphProto, initializer) => new GraphImpl(graphProto, initializer) + }; + Value = class { + constructor(valueInfo) { + this._from = void 0; + this._to = []; + this.tensor = void 0; + this.type = void 0; + if (valueInfo) { + this.type = ProtoUtil.tensorValueTypeFromProto(valueInfo.type.tensorType); + } + } + // -1 represent from initializer + get from() { + return this._from; + } + get to() { + return this._to; + } + }; + Node2 = class { + constructor(_nodeProto, name2) { + if (_nodeProto instanceof import_onnx4.onnx.NodeProto) { + this.name = _nodeProto.name; + this.opType = _nodeProto.opType; + this.attributes = new Attribute2(_nodeProto.attribute); + } else if (_nodeProto instanceof import_node.Node) { + this.name = name2 ?? _nodeProto.name(); + this.opType = _nodeProto.opType(); + this.attributes = new Attribute2(ProtoUtil.tensorAttributesFromORTFormat(_nodeProto)); + } + this.inputs = []; + this.outputs = []; + this.executeNode = true; + } + }; + GraphImpl = class { + constructor(graph, graphInitializer) { + if (!graph) { + throw new TypeError("graph is empty"); + } + this.buildGraph(graph); + this.transformGraph(graphInitializer); + this.checkIsAcyclic(); + } + getInputIndices() { + return this._allInputIndices; + } + getInputNames() { + return this._allInputNames; + } + getOutputIndices() { + return this._allOutputIndices; + } + getOutputNames() { + return this._allOutputNames; + } + getValues() { + return this._allData; + } + getNodes() { + return this._nodes; + } + buildGraph(graph) { + if (graph instanceof import_onnx4.onnx.GraphProto) { + this.buildGraphFromOnnxFormat(graph); + } else if (graph instanceof import_graph.Graph) { + this.buildGraphFromOrtFormat(graph); + } else { + throw new TypeError("Graph type is not supported."); + } + } + buildGraphFromOnnxFormat(graph) { + const dataIndices = /* @__PURE__ */ new Map(); + this._allData = []; + this._allInputIndices = []; + this._allInputNames = []; + this._allOutputIndices = []; + this._allOutputNames = []; + this._nodes = []; + const nodesIndices = /* @__PURE__ */ new Map(); + if (!graph.input) { + throw new Error("missing information in graph: input"); + } + const inputValueNames = []; + for (const i of graph.input) { + if (dataIndices.has(i.name)) { + throw new Error(`duplicated input name: ${i.name}`); + } + const currentIndex = this._allData.push(new Value(i)) - 1; + dataIndices.set(i.name, currentIndex); + inputValueNames.push(i.name); + } + if (!graph.initializer) { + throw new Error("missing information in graph: initializer"); + } + for (const i of graph.initializer) { + let index = dataIndices.get(i.name); + if (index === void 0) { + const value = new Value(); + value.type = { + shape: { dims: ProtoUtil.tensorDimsFromProto(i.dims) }, + tensorType: ProtoUtil.tensorDataTypeFromProto(i.dataType) + }; + index = this._allData.push(value) - 1; + dataIndices.set(i.name, index); + } + this._allData[index]._from = -1; + this._allData[index].tensor = Tensor4.fromProto(i); + } + for (let i = 0; i < this._allData.length; i++) { + if (!this._allData[i].tensor) { + this._allInputIndices.push(i); + this._allInputNames.push(inputValueNames[i]); + } + } + if (!graph.output) { + throw new Error("missing information in graph: output"); + } + for (const i of graph.output) { + if (dataIndices.has(i.name)) { + throw new Error(`duplicated output name: ${i.name}`); + } + const currentIndex = this._allData.push(new Value(i)) - 1; + dataIndices.set(i.name, currentIndex); + this._allOutputIndices.push(currentIndex); + this._allOutputNames.push(i.name); + } + if (!graph.node) { + throw new Error("missing information in graph: node"); + } + for (const nodeProto of graph.node) { + if (!nodeProto.name) { + for (let pick = 0; ; pick++) { + const name2 = `unnamed_${nodeProto.opType}_${pick}`; + if (!nodesIndices.has(name2)) { + nodeProto.name = name2; + break; + } + } + } + if (nodesIndices.has(nodeProto.name)) { + throw new Error(`duplicated node name: ${nodeProto.name}`); + } + const currentIndex = this._nodes.push(new Node2(nodeProto)) - 1; + nodesIndices.set(nodeProto.name, currentIndex); + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.node[i]; + if (!nodeProto.output) { + throw new Error(`missing output for node: ${nodeProto.name}`); + } + for (const output of nodeProto.output) { + let dataIndex = dataIndices.get(output); + if (typeof dataIndex === "undefined") { + dataIndex = this._allData.push(new Value()) - 1; + dataIndices.set(output, dataIndex); + } + node.outputs.push(dataIndex); + if (this._allData[dataIndex]._from !== void 0) { + throw new Error(`multiple nodes output to one data value: ${dataIndex}`); + } + this._allData[dataIndex]._from = i; + if (nodeProto.opType === "Constant") { + if (!nodeProto.attribute || nodeProto.attribute.length !== 1 || !nodeProto.attribute[0].t) { + throw new Error("missing attributes or missing tensor value in attributes for this Constant operator"); + } + if (!nodeProto.output || nodeProto.output.length !== 1) { + throw new Error("missing output or incorrect number of outputs for this Constant operator"); + } + node.outputs.pop(); + node.executeNode = false; + this._allData[dataIndex]._from = -1; + this._allData[dataIndex].tensor = Tensor4.fromProto(nodeProto.attribute[0].t); + } + } + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.node[i]; + if (!nodeProto.input) { + throw new Error(`missing input for node: ${nodeProto.name}`); + } + for (const input of nodeProto.input) { + const dataIndex = dataIndices.get(input); + if (typeof dataIndex === "undefined") { + if (input === "" && (nodeProto.input.length === 3 || nodeProto.input.length === 4) && nodeProto.opType === "Resize") { + continue; + } + throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name}`); + } + node.inputs.push(dataIndex); + this._allData[dataIndex]._to.push(i); + } + } + return true; + } + buildGraphFromOrtFormat(graph) { + const dataIndices = /* @__PURE__ */ new Map(); + this._allData = []; + this._allInputIndices = []; + this._allInputNames = []; + this._allOutputIndices = []; + this._allOutputNames = []; + this._nodes = []; + const nodesIndices = /* @__PURE__ */ new Map(); + const inputValueNames = []; + for (let i = 0; i < graph.inputsLength(); i++) { + const inputName = graph.inputs(i); + if (dataIndices.has(inputName)) { + throw new Error(`duplicated input name: ${inputName}`); + } + for (let j = 0; j < graph.nodeArgsLength(); j++) { + if (graph.nodeArgs(j)?.name() === inputName) { + const value = new Value(); + const valueType = graph.nodeArgs(j)?.type()?.valueType(); + if (valueType !== import_type_info_value.TypeInfoValue.tensor_type) { + throw new Error("Unexpected value type for the nodeArg."); + } + const valueInfo = graph.nodeArgs(j).type().value(new import_tensor_type_and_shape.TensorTypeAndShape()); + const type = ProtoUtil.tensorDataTypeFromProto(valueInfo.elemType()); + const shape2 = valueInfo.shape(); + const dims = []; + for (let k = 0; k < shape2.dimLength(); k++) { + dims.push(LongUtil.longToNumber(shape2.dim(k).value().dimValue())); + } + value.type = { shape: { dims }, tensorType: type }; + const currentIndex = this._allData.push(value) - 1; + dataIndices.set(inputName, currentIndex); + inputValueNames.push(inputName); + } + } + } + for (let i = 0; i < graph.initializersLength(); i++) { + const initializer = graph.initializers(i); + let index = dataIndices.get(initializer.name()); + if (index === void 0) { + const value = new Value(); + const dims = ProtoUtil.tensorDimsFromORTFormat(initializer); + const type = ProtoUtil.tensorDataTypeFromProto(initializer.dataType()); + value.type = { shape: { dims }, tensorType: type }; + index = this._allData.push(value) - 1; + dataIndices.set(initializer.name(), index); + } + this._allData[index]._from = -1; + this._allData[index].tensor = Tensor4.fromOrtTensor(initializer); + } + for (let i = 0; i < this._allData.length; i++) { + if (!this._allData[i].tensor) { + this._allInputIndices.push(i); + this._allInputNames.push(inputValueNames[i]); + } + } + for (let i = 0; i < graph.outputsLength(); i++) { + const outputName = graph.outputs(i); + if (dataIndices.has(outputName)) { + throw new Error(`duplicated output name: ${outputName}`); + } + const currentIndex = this._allData.push(new Value()) - 1; + dataIndices.set(outputName, currentIndex); + this._allOutputIndices.push(currentIndex); + this._allOutputNames.push(outputName); + } + if (!graph.nodes) { + throw new Error("missing information in graph: node"); + } + for (let i = 0; i < graph.nodesLength(); i++) { + const nodeProto = graph.nodes(i); + let name2 = nodeProto.name(); + if (!name2) { + for (let pick = 0; ; pick++) { + name2 = `unnamed_${nodeProto.opType()}_${pick}`; + if (!nodesIndices.has(name2)) { + break; + } + } + } + if (nodesIndices.has(name2)) { + throw new Error(`duplicated node name: ${name2}`); + } + const currentIndex = this._nodes.push(new Node2(nodeProto, name2)) - 1; + nodesIndices.set(name2, currentIndex); + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.nodes(i); + if (nodeProto == null) { + throw new Error(`No node exists at index ${i}`); + } + if (nodeProto?.outputsLength() === 0) { + throw new Error(`missing output for node: ${nodeProto.name}`); + } + for (let j = 0; j < nodeProto?.outputsLength(); j++) { + const output = nodeProto?.outputs(j); + let dataIndex = dataIndices.get(output); + if (typeof dataIndex === "undefined") { + dataIndex = this._allData.push(new Value()) - 1; + dataIndices.set(output, dataIndex); + } + node.outputs.push(dataIndex); + if (this._allData[dataIndex]._from !== void 0) { + throw new Error(`multiple nodes output to one data value: ${dataIndex}`); + } + this._allData[dataIndex]._from = i; + if (nodeProto.opType() === "Constant") { + if (nodeProto.attributesLength() !== 1 || !nodeProto.attributes(0).t()) { + throw new Error("missing attributes or missing tensor value in attributes for this Constant operator"); + } + if (nodeProto.outputsLength() !== 1) { + throw new Error("missing output or incorrect number of outputs for this Constant operator"); + } + node.outputs.pop(); + node.executeNode = false; + this._allData[dataIndex]._from = -1; + this._allData[dataIndex].tensor = Tensor4.fromOrtTensor(nodeProto.attributes(0).t()); + } + } + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.nodes(i); + if (nodeProto.inputsLength() === 0) { + throw new Error(`missing input for node: ${nodeProto.name}`); + } + for (let j = 0; j < nodeProto.inputsLength(); j++) { + const input = nodeProto.inputs(j); + const dataIndex = dataIndices.get(input); + if (typeof dataIndex === "undefined") { + throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name()}`); + } + node.inputs.push(dataIndex); + this._allData[dataIndex]._to.push(i); + } + } + } + checkIsAcyclic() { + const starters = /* @__PURE__ */ new Set(); + this._allInputIndices.forEach((i) => { + const data = this._allData[i]; + data._to.forEach((j) => { + starters.add(j); + }); + }); + const nodesStack = Array.from(starters); + const nodesState = new Array(this._nodes.length).fill("white"); + while (nodesStack.length > 0) { + const nodeIndex = nodesStack.pop(); + if (nodesState[nodeIndex] === "gray") { + nodesState[nodeIndex] = "black"; + } else { + nodesStack.push(nodeIndex); + nodesState[nodeIndex] = "gray"; + this._nodes[nodeIndex].outputs.forEach((outgoingEdgeIndex) => { + const data = this._allData[outgoingEdgeIndex]; + if (typeof data.tensor !== "undefined") { + throw new Error("node outputs should not be initialized"); + } + if (data._from !== nodeIndex) { + throw new Error("from property of the Value object doesn't match index of Node being processed"); + } + data._to.forEach((downstreamNodeIndex) => { + if (nodesState[downstreamNodeIndex] === "gray") { + throw new Error("model graph is cyclic"); + } else if (nodesState[downstreamNodeIndex] === "white") { + nodesStack.push(downstreamNodeIndex); + } + }); + }); + } + } + } + transformGraph(graphInitializer) { + this.removeAllIdentityNodes(); + this.removeAllDropoutNodes(); + this.fuseConvActivationNodes(); + if (graphInitializer) { + graphInitializer.transformGraph(this); + } + this.finalizeGraph(); + } + /** + * finalize the graph. + * + * this function should be called after all the transformation completed. + * this function removes all unnecessary nodes and values from the graph + */ + finalizeGraph() { + let offset = 0; + const newIndices = new Array(this._nodes.length, 0); + let nodePossition = 0; + for (let i = 0; i < this._nodes.length; i++) { + newIndices[i] = nodePossition; + if (this._nodes[i].executeNode) { + if (nodePossition !== i) { + this._nodes[nodePossition] = this._nodes[i]; + } + nodePossition++; + } else { + this._nodes[i].outputs.forEach((ind) => { + this._allData[ind]._from = -2; + }); + } + } + this._nodes.splice(nodePossition, this._nodes.length - nodePossition); + for (let i = 0; i < this._allData.length; i++) { + const currentData = this._allData[i]; + if (currentData._from !== void 0 && currentData._from !== -1 && currentData._from !== -2) { + currentData._from = newIndices[currentData._from]; + } + for (let j = 0; j < currentData._to.length; j++) { + if (currentData._to[j] >= 0) { + currentData._to[j] = newIndices[currentData._to[j]]; + } else { + throw new Error("Trying to update a removed node"); + } + } + } + offset = 0; + for (let i = 0; i < this._allData.length; i++) { + if (this._allData[i].from === -2 && this._allOutputIndices.indexOf(i + offset) === -1) { + offset++; + this._allData.splice(i, 1); + i--; + continue; + } + if (offset > 0) { + let ind = -1; + if (this._allData[i].from !== void 0 && this._allData[i].from !== -1) { + ind = this._nodes[this._allData[i].from].outputs.indexOf(i + offset); + if (ind !== -1) { + this._nodes[this._allData[i].from].outputs[ind] = i; + } + } else { + ind = this._allInputIndices.indexOf(i + offset); + if (ind !== -1) { + this._allInputIndices[ind] = i; + } + } + this._allData[i].to.forEach((node) => { + ind = this._nodes[node].inputs.indexOf(i + offset); + if (ind !== -1) { + this._nodes[node].inputs[ind] = i; + } + }); + if (this._allData[i].to.length === 0) { + ind = this._allOutputIndices.indexOf(i + offset); + if (ind !== -1) { + this._allOutputIndices[ind] = i; + } + } + } + } + } + /** + * Delete the specified node. Assume the node has one incoming input and the first output connected to other nodes. + * An input validation must be done before calling this function. + * @param nodeIndex The index of node to be deleted + */ + deleteNode(nodeIndex) { + const node = this._nodes[nodeIndex]; + if (node.outputs.length > 1) { + for (let i = 1; i < node.outputs.length; i++) { + if (this._allData[node.outputs[i]].to.length > 0) { + throw new Error("Node deletion with more than one output connected to other nodes is not supported. "); + } + } + } + node.executeNode = false; + const inputValueIndex = node.inputs[0]; + const outputValueIndex = node.outputs[0]; + const nodesConsumingOutput = this._allData[outputValueIndex].to; + for (let i = 0; i < node.inputs.length; i++) { + const delIndex = this._allData[node.inputs[i]].to.indexOf(nodeIndex); + if (delIndex === -1) { + throw new Error("The Value object doesn't have the current Node in it's 'to' property "); + } + this._allData[node.inputs[i]].to.splice(delIndex, 1); + } + this._allData[outputValueIndex]._to = []; + const index = this._allOutputIndices.indexOf(outputValueIndex); + if (index !== -1) { + this._allOutputIndices[index] = inputValueIndex; + } + if (nodesConsumingOutput && nodesConsumingOutput.length > 0) { + for (const nodeIndex2 of nodesConsumingOutput) { + const replaceIndex = this._nodes[nodeIndex2].inputs.indexOf(outputValueIndex); + if (replaceIndex === -1) { + throw new Error("The Node object doesn't have the output Value in it's 'inputs' property "); + } + this._nodes[nodeIndex2].inputs[replaceIndex] = inputValueIndex; + this._allData[inputValueIndex].to.push(nodeIndex2); + } + } + } + removeAllDropoutNodes() { + let nodeIndex = 0; + for (const node of this._nodes) { + if (node.opType === "Dropout") { + if (node.inputs.length !== 1) { + throw new Error("Dropout nodes should only contain one input. "); + } + if (node.outputs.length !== 1 && node.outputs.length !== 2) { + throw new Error("Dropout nodes should contain either 1 or 2 output(s)"); + } + if (node.outputs.length === 2 && this._allData[node.outputs[1]]._to.length !== 0) { + throw new Error("Dropout nodes's second output should not be referenced by other nodes"); + } + this.deleteNode(nodeIndex); + } + nodeIndex++; + } + } + removeAllIdentityNodes() { + let nodeIndex = 0; + for (const node of this._nodes) { + if (node.opType === "Identity") { + this.deleteNode(nodeIndex); + } + nodeIndex++; + } + } + isActivation(n) { + switch (n.opType) { + // TODO: add other activation methods + case "Relu": + case "Sigmoid": + case "Clip": + return true; + default: + return false; + } + } + fuseConvActivationNodes() { + for (const node of this._nodes) { + if (node.opType === "Conv") { + const next = this._allData[node.outputs[0]]._to; + if (next.length === 1 && this.isActivation(this._nodes[next[0]])) { + const child = this._nodes[next[0]]; + if (child.opType === "Clip") { + if (child.inputs.length === 1) { + try { + node.attributes.set("activation_params", "floats", [ + child.attributes.getFloat("min"), + child.attributes.getFloat("max") + ]); + } catch { + node.attributes.set("activation_params", "floats", [MIN_CLIP, MAX_CLIP]); + } + } else if (child.inputs.length >= 3 && this._allData[child.inputs[1]].tensor !== void 0 && this._allData[child.inputs[2]].tensor !== void 0) { + node.attributes.set("activation_params", "floats", [ + this._allData[child.inputs[1]].tensor.floatData[0], + this._allData[child.inputs[2]].tensor.floatData[0] + ]); + } else { + continue; + } + } + node.attributes.set("activation", "string", child.opType); + this.deleteNode(next[0]); + } + } + } + } + }; + } +}); + +// web/lib/onnxjs/model.ts +var flatbuffers, import_onnx5, Model2; +var init_model = __esm({ + "web/lib/onnxjs/model.ts"() { + "use strict"; + flatbuffers = __toESM(require_flatbuffers()); + init_graph(); + init_ort_generated(); + import_onnx5 = __toESM(require_onnx()); + init_util(); + Model2 = class { + // empty model + constructor() { + } + load(buf, graphInitializer, isOrtFormat) { + let onnxError; + if (!isOrtFormat) { + try { + this.loadFromOnnxFormat(buf, graphInitializer); + return; + } catch (e) { + if (isOrtFormat !== void 0) { + throw e; + } + onnxError = e; + } + } + try { + this.loadFromOrtFormat(buf, graphInitializer); + } catch (e) { + if (isOrtFormat !== void 0) { + throw e; + } + throw new Error(`Failed to load model as ONNX format: ${onnxError} +as ORT format: ${e}`); + } + } + loadFromOnnxFormat(buf, graphInitializer) { + const modelProto = import_onnx5.onnx.ModelProto.decode(buf); + const irVersion = LongUtil.longToNumber(modelProto.irVersion); + if (irVersion < 3) { + throw new Error("only support ONNX model with IR_VERSION>=3"); + } + this._opsets = modelProto.opsetImport.map((i) => ({ + domain: i.domain, + version: LongUtil.longToNumber(i.version) + })); + this._graph = Graph2.from(modelProto.graph, graphInitializer); + } + loadFromOrtFormat(buf, graphInitializer) { + const fb = new flatbuffers.ByteBuffer(buf); + const ortModel = import_inference_session.InferenceSession.getRootAsInferenceSession(fb).model(); + const irVersion = LongUtil.longToNumber(ortModel.irVersion()); + if (irVersion < 3) { + throw new Error("only support ONNX model with IR_VERSION>=3"); + } + this._opsets = []; + for (let i = 0; i < ortModel.opsetImportLength(); i++) { + const opsetId = ortModel.opsetImport(i); + this._opsets.push({ domain: opsetId?.domain(), version: LongUtil.longToNumber(opsetId.version()) }); + } + this._graph = Graph2.from(ortModel.graph(), graphInitializer); + } + get graph() { + return this._graph; + } + get opsets() { + return this._opsets; + } + }; + } +}); + +// web/lib/onnxjs/session.ts +var Session; +var init_session = __esm({ + "web/lib/onnxjs/session.ts"() { + "use strict"; + init_backend2(); + init_execution_plan(); + init_instrument(); + init_model(); + Session = class { + constructor(config = {}) { + this._initialized = false; + this.backendHint = config.backendHint; + this.profiler = Profiler.create(config.profiler); + this.context = { profiler: this.profiler, graphInputTypes: [], graphInputDims: [] }; + } + get inputNames() { + return this._model.graph.getInputNames(); + } + get outputNames() { + return this._model.graph.getOutputNames(); + } + startProfiling() { + this.profiler.start(); + } + endProfiling() { + this.profiler.stop(); + } + async loadModel(arg, byteOffset, length) { + await this.profiler.event("session", "Session.loadModel", async () => { + const backend2 = await resolveBackend(this.backendHint); + this.sessionHandler = backend2.createSessionHandler(this.context); + this._model = new Model2(); + if (typeof arg === "string") { + const isOrtFormat = arg.endsWith(".ort"); + if (false) { + const { readFile } = null; + const buf = await readFile(arg); + this.initialize(buf, isOrtFormat); + } else { + const response = await fetch(arg); + const buf = await response.arrayBuffer(); + this.initialize(new Uint8Array(buf), isOrtFormat); + } + } else if (!ArrayBuffer.isView(arg)) { + const arr = new Uint8Array(arg, byteOffset || 0, length || arg.byteLength); + this.initialize(arr); + } else { + this.initialize(arg); + } + }); + } + initialize(modelProtoBlob, isOrtFormat) { + if (this._initialized) { + throw new Error("already initialized"); + } + this.profiler.event("session", "Session.initialize", () => { + const graphInitializer = this.sessionHandler.transformGraph ? this.sessionHandler : void 0; + this._model.load(modelProtoBlob, graphInitializer, isOrtFormat); + if (this.sessionHandler.onGraphInitialized) { + this.sessionHandler.onGraphInitialized(this._model.graph); + } + this.initializeOps(this._model.graph); + this._executionPlan = new ExecutionPlan(this._model.graph, this._ops, this.profiler); + }); + this._initialized = true; + } + async run(inputs) { + if (!this._initialized) { + throw new Error("session not initialized yet"); + } + return this.profiler.event("session", "Session.run", async () => { + const inputTensors = this.normalizeAndValidateInputs(inputs); + const outputTensors = await this._executionPlan.execute(this.sessionHandler, inputTensors); + return this.createOutput(outputTensors); + }); + } + normalizeAndValidateInputs(inputs) { + const modelInputNames = this._model.graph.getInputNames(); + if (Array.isArray(inputs)) { + if (inputs.length !== modelInputNames.length) { + throw new Error(`incorrect input array length: expected ${modelInputNames.length} but got ${inputs.length}`); + } + } else { + if (inputs.size !== modelInputNames.length) { + throw new Error(`incorrect input map size: expected ${modelInputNames.length} but got ${inputs.size}`); + } + const sortedInputs = new Array(inputs.size); + let sortedInputsIndex = 0; + for (let i = 0; i < modelInputNames.length; ++i) { + const tensor = inputs.get(modelInputNames[i]); + if (!tensor) { + throw new Error(`missing input tensor for: '${name}'`); + } + sortedInputs[sortedInputsIndex++] = tensor; + } + inputs = sortedInputs; + } + if (!this.context.graphInputTypes || this.context.graphInputTypes.length === 0 || !this.context.graphInputDims || this.context.graphInputDims.length === 0) { + const modelInputIndices = this._model.graph.getInputIndices(); + const modelValues = this._model.graph.getValues(); + const graphInputDims = new Array(modelInputIndices.length); + for (let i = 0; i < modelInputIndices.length; ++i) { + const graphInput = modelValues[modelInputIndices[i]]; + graphInputDims[i] = graphInput.type.shape.dims; + this.context.graphInputTypes.push(graphInput.type.tensorType); + this.context.graphInputDims.push(inputs[i].dims); + } + this.validateInputTensorDims(graphInputDims, inputs, true); + } else { + this.validateInputTensorDims(this.context.graphInputDims, inputs, false); + } + this.validateInputTensorTypes(this.context.graphInputTypes, inputs); + return inputs; + } + validateInputTensorTypes(graphInputTypes, givenInputs) { + for (let i = 0; i < givenInputs.length; i++) { + const expectedType = graphInputTypes[i]; + const actualType = givenInputs[i].type; + if (expectedType !== actualType) { + throw new Error(`input tensor[${i}] check failed: expected type '${expectedType}' but got ${actualType}`); + } + } + } + validateInputTensorDims(graphInputDims, givenInputs, noneDimSupported) { + for (let i = 0; i < givenInputs.length; i++) { + const expectedDims = graphInputDims[i]; + const actualDims = givenInputs[i].dims; + if (!this.compareTensorDims(expectedDims, actualDims, noneDimSupported)) { + throw new Error( + `input tensor[${i}] check failed: expected shape '[${expectedDims.join(",")}]' but got [${actualDims.join( + "," + )}]` + ); + } + } + } + compareTensorDims(expectedDims, actualDims, noneDimSupported) { + if (expectedDims.length !== actualDims.length) { + return false; + } + for (let i = 0; i < expectedDims.length; ++i) { + if (expectedDims[i] !== actualDims[i] && (!noneDimSupported || expectedDims[i] !== 0)) { + return false; + } + } + return true; + } + createOutput(outputTensors) { + const modelOutputNames = this._model.graph.getOutputNames(); + if (outputTensors.length !== modelOutputNames.length) { + throw new Error("expected number of outputs do not match number of generated outputs"); + } + const output = /* @__PURE__ */ new Map(); + for (let i = 0; i < modelOutputNames.length; ++i) { + output.set(modelOutputNames[i], outputTensors[i]); + } + return output; + } + initializeOps(graph) { + const nodes = graph.getNodes(); + this._ops = new Array(nodes.length); + for (let i = 0; i < nodes.length; i++) { + this._ops[i] = this.sessionHandler.resolve(nodes[i], this._model.opsets, graph); + } + } + }; + } +}); + +// web/lib/onnxjs/session-handler-inference.ts +var OnnxjsSessionHandler; +var init_session_handler_inference = __esm({ + "web/lib/onnxjs/session-handler-inference.ts"() { + "use strict"; + init_esm(); + init_tensor2(); + OnnxjsSessionHandler = class { + constructor(session) { + this.session = session; + this.inputNames = this.session.inputNames; + this.outputNames = this.session.outputNames; + } + get inputMetadata() { + throw new Error("Getting model metadata is not supported in webgl backend."); + } + get outputMetadata() { + throw new Error("Getting model metadata is not supported in webgl backend."); + } + async dispose() { + } + async run(feeds, _fetches, _options) { + const inputMap = /* @__PURE__ */ new Map(); + for (const name2 in feeds) { + if (Object.hasOwnProperty.call(feeds, name2)) { + const feed = feeds[name2]; + inputMap.set( + name2, + new Tensor4( + feed.dims, + feed.type, + void 0, + void 0, + feed.data + ) + ); + } + } + const outputMap = await this.session.run(inputMap); + const output = {}; + outputMap.forEach((tensor, name2) => { + output[name2] = new Tensor2(tensor.type, tensor.data, tensor.dims); + }); + return output; + } + startProfiling() { + this.session.startProfiling(); + } + endProfiling() { + this.session.endProfiling(); + } + }; + } +}); + +// web/lib/backend-onnxjs.ts +var backend_onnxjs_exports = {}; +__export(backend_onnxjs_exports, { + onnxjsBackend: () => onnxjsBackend +}); +var OnnxjsBackend, onnxjsBackend; +var init_backend_onnxjs = __esm({ + "web/lib/backend-onnxjs.ts"() { + "use strict"; + init_session(); + init_session_handler_inference(); + OnnxjsBackend = class { + // eslint-disable-next-line @typescript-eslint/no-empty-function + async init() { + } + async createInferenceSessionHandler(pathOrBuffer, options) { + const session = new Session(options); + if (typeof pathOrBuffer === "string") { + await session.loadModel(pathOrBuffer); + } else { + await session.loadModel(pathOrBuffer); + } + return new OnnxjsSessionHandler(session); + } + }; + onnxjsBackend = new OnnxjsBackend(); + } +}); + +// web/lib/index.ts +init_esm(); +init_esm(); +init_esm(); + +// web/lib/version.ts +var version2 = "1.30.0"; + +// web/lib/index.ts +var index_default = esm_exports; +if (true) { + const onnxjsBackend2 = (init_backend_onnxjs(), __toCommonJS(backend_onnxjs_exports)).onnxjsBackend; + registerBackend("webgl", onnxjsBackend2, -10); +} +if (false) { + throw new Error( + "The current build is specified to enable both JSEP and WebGPU EP. This is not a valid configuration. JSEP and WebGPU EPs cannot be enabled at the same time." + ); +} +if (false) { + throw new Error( + "The current build is specified to enable WebNN EP without JSEP or WebGPU EP. This is not a valid configuration. WebNN EP requires either JSEP or WebGPU EP to be enabled." + ); +} +if (false) { + const wasmBackend = null.wasmBackend; + if (false) { + registerBackend("webgpu", wasmBackend, 5); + } + if (false) { + registerBackend("webnn", wasmBackend, 5); + } + registerBackend("cpu", wasmBackend, 10); + registerBackend("wasm", wasmBackend, 10); +} +Object.defineProperty(env2.versions, "web", { value: version2, enumerable: true }); +export { + InferenceSession2 as InferenceSession, + TRACE, + TRACE_EVENT_BEGIN, + TRACE_EVENT_END, + TRACE_FUNC_BEGIN, + TRACE_FUNC_END, + Tensor2 as Tensor, + index_default as default, + env2 as env, + registerBackend +}; +/*! Bundled license information: + +long/index.js: +long/umd/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,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vY29tbW9uL2xpYi9iYWNrZW5kLWltcGwudHMiLCAiLi4vLi4vY29tbW9uL2xpYi9iYWNrZW5kLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdmVyc2lvbi50cyIsICIuLi8uLi9jb21tb24vbGliL2Vudi1pbXBsLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvZW52LnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdGVuc29yLWNvbnZlcnNpb24taW1wbC50cyIsICIuLi8uLi9jb21tb24vbGliL3RlbnNvci1mYWN0b3J5LWltcGwudHMiLCAiLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItaW1wbC10eXBlLW1hcHBpbmcudHMiLCAiLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItdXRpbHMtaW1wbC50cyIsICIuLi8uLi9jb21tb24vbGliL3RlbnNvci1pbXBsLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdGVuc29yLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvdHJhY2UudHMiLCAiLi4vLi4vY29tbW9uL2xpYi9pbmZlcmVuY2Utc2Vzc2lvbi1pbXBsLnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvaW5mZXJlbmNlLXNlc3Npb24udHMiLCAiLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItY29udmVyc2lvbi50cyIsICIuLi8uLi9jb21tb24vbGliL3RlbnNvci1mYWN0b3J5LnRzIiwgIi4uLy4uL2NvbW1vbi9saWIvb25ueC1tb2RlbC50cyIsICIuLi8uLi9jb21tb24vbGliL29ubngtdmFsdWUudHMiLCAiLi4vLi4vY29tbW9uL2xpYi9pbmRleC50cyIsICIuLi9saWIvb25ueGpzL2luc3RydW1lbnQudHMiLCAiLi4vbGliL29ubnhqcy9vcHNldC50cyIsICIuLi9ub2RlX21vZHVsZXMvZ3VpZC10eXBlc2NyaXB0L2Rpc3QvZ3VpZC5qcyIsICIuLi9ub2RlX21vZHVsZXMvbG9uZy9pbmRleC5qcyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9jb25zdGFudHMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL3V0aWxzLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9lbmNvZGluZy5qcyIsICIuLi9ub2RlX21vZHVsZXMvZmxhdGJ1ZmZlcnMvanMvYnl0ZS1idWZmZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL2J1aWxkZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL2ZsYXRidWZmZXJzLmpzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvYXJnLXR5cGUtYW5kLWluZGV4LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvYXR0cmlidXRlLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2RlLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2RlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZWRnZS1lbmQudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2RlLWVkZ2UudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ub2Rlcy10by1vcHRpbWl6ZS1pbmRpY2VzLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLWNvbnRhaW5lci1lbnRyeS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9ucy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3RlbnNvci1kYXRhLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90ZW5zb3IudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zcGFyc2UtdGVuc29yLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbWFwLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zZXF1ZW5jZS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGltZW5zaW9uLXZhbHVlLXR5cGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kaW1lbnNpb24tdmFsdWUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kaW1lbnNpb24udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zaGFwZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3RlbnNvci10eXBlLWFuZC1zaGFwZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3R5cGUtaW5mby12YWx1ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3R5cGUtaW5mby50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3ZhbHVlLWluZm8udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ncmFwaC50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2F0dHJpYnV0ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQta2VybmVsLWNyZWF0ZS1pbmZvcy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQtbm9kZS1pbmRleC1hbmQta2VybmVsLWRlZi1oYXNoLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGVwcmVjYXRlZC1zdWItZ3JhcGgtc2Vzc2lvbi1zdGF0ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQtc2Vzc2lvbi1zdGF0ZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2tlcm5lbC10eXBlLXN0ci1hcmdzLWVudHJ5LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvb3AtaWQta2VybmVsLXR5cGUtc3RyLWFyZ3MtZW50cnkudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9rZXJuZWwtdHlwZS1zdHItcmVzb2x2ZXIudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9vcGVyYXRvci1zZXQtaWQudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9zdHJpbmctc3RyaW5nLWVudHJ5LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbW9kZWwudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9pbmZlcmVuY2Utc2Vzc2lvbi50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9hc3Byb21pc2UvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2Jhc2U2NC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvZXZlbnRlbWl0dGVyL2luZGV4LmpzIiwgIi4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9mbG9hdC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvaW5xdWlyZS9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvdXRmOC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvcG9vbC9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvdXRpbC9sb25nYml0cy5qcyIsICIuLi9ub2RlX21vZHVsZXMvbG9uZy91bWQvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3V0aWwvbWluaW1hbC5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvd3JpdGVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy93cml0ZXJfYnVmZmVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9yZWFkZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JlYWRlcl9idWZmZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JwYy9zZXJ2aWNlLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9ycGMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3Jvb3RzLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9pbmRleC1taW5pbWFsLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL21pbmltYWwuanMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubnguanMiLCAiLi4vbGliL29ubnhqcy91dGlsLnRzIiwgIi4uL2xpYi9vbm54anMvdGVuc29yLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1zb3VyY2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90eXBlcy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3V0aWxzLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3BhY2tpbmctdXRpbHMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcGFjay50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZXNoYXBlLXBhY2tlZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy91aW50OC1lbmNvZGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdW5wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdGV4dHVyZS1kYXRhLWVuY29kZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLWxheW91dC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2luZmVyZW5jZS1oYW5kbGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2JhdGNoLW5vcm1hbGl6YXRpb24udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWRlZmluaXRpb25zLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2JpbmFyeS1vcC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jYXN0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbmNhdC1wYWNrZWQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29uY2F0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3VuYXJ5LW9wLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2Z1c2UtdXRpbHMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi1ncm91cGVkLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2ltMmNvbC1wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL21hdG11bC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9tYXRtdWwtcGFjay50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LXBhY2sudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW0yY29sLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2RvdC1wcm9kdWN0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbnYudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi10cmFuc3Bvc2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdHJhbnNwb3NlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2RlcHRoLXRvLXNwYWNlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2ZsYXR0ZW4udHMiLCAiLi4vbGliL29ubnhqcy9vcGVyYXRvcnMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZ2F0aGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2dlbW0udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW1hZ2Utc2NhbGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2luc3RhbmNlLW5vcm1hbGl6YXRpb24udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvbHJuLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3BhZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9wb29sLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3JlZHVjZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZXNoYXBlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Vwc2FtcGxlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Jlc2l6ZS1wYWNrZWQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc2hhcGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc2xpY2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc29mdG1heC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zcGxpdC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zcXVlZXplLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3N1bS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy90aWxlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Vuc3F1ZWV6ZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wLXJlc29sdmUtcnVsZXMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWZ1bmN0aW9uLWlubGluZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLWxheW91dC1zdHJhdGVneS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtY29vcmRpbmF0ZS1saWIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWVuY29kaW5nLWxpYi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZnJhZ2NvbG9yLWxpYi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtc2hhcGUtdXRpbHMtbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC12ZWMtbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1yZWdpc3RlcmVkLWxpYnMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXByZXByb2Nlc3Nvci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3Byb2dyYW0tbWFuYWdlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3RleHR1cmUtbWFuYWdlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3Nlc3Npb24taGFuZGxlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3dlYmdsLWNvbnRleHQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC93ZWJnbC1jb250ZXh0LWZhY3RvcnkudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy9iYWNrZW5kLXdlYmdsLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZC50cyIsICIuLi9saWIvb25ueGpzL2V4ZWN1dGlvbi1wbGFuLnRzIiwgIi4uL2xpYi9vbm54anMvYXR0cmlidXRlLnRzIiwgIi4uL2xpYi9vbm54anMvZ3JhcGgudHMiLCAiLi4vbGliL29ubnhqcy9tb2RlbC50cyIsICIuLi9saWIvb25ueGpzL3Nlc3Npb24udHMiLCAiLi4vbGliL29ubnhqcy9zZXNzaW9uLWhhbmRsZXItaW5mZXJlbmNlLnRzIiwgIi4uL2xpYi9iYWNrZW5kLW9ubnhqcy50cyIsICIuLi9saWIvaW5kZXgudHMiLCAiLi4vbGliL3ZlcnNpb24udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBCYWNrZW5kIH0gZnJvbSAnLi9iYWNrZW5kLmpzJztcbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24gfSBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcblxuaW50ZXJmYWNlIEJhY2tlbmRJbmZvIHtcbiAgYmFja2VuZDogQmFja2VuZDtcbiAgcHJpb3JpdHk6IG51bWJlcjtcblxuICBpbml0UHJvbWlzZT86IFByb21pc2U8dm9pZD47XG4gIGluaXRpYWxpemVkPzogYm9vbGVhbjtcbiAgYWJvcnRlZD86IGJvb2xlYW47XG4gIGVycm9yPzogc3RyaW5nO1xufVxuXG5jb25zdCBiYWNrZW5kczogTWFwPHN0cmluZywgQmFja2VuZEluZm8+ID0gbmV3IE1hcCgpO1xuY29uc3QgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5OiBzdHJpbmdbXSA9IFtdO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGEgYmFja2VuZC5cbiAqXG4gKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIGFzIGEga2V5IHRvIGxvb2t1cCBhcyBhbiBleGVjdXRpb24gcHJvdmlkZXIuXG4gKiBAcGFyYW0gYmFja2VuZCAtIHRoZSBiYWNrZW5kIG9iamVjdC5cbiAqIEBwYXJhbSBwcmlvcml0eSAtIGFuIGludGVnZXIgaW5kaWNhdGluZyB0aGUgcHJpb3JpdHkgb2YgdGhlIGJhY2tlbmQuIEhpZ2hlciBudW1iZXIgbWVhbnMgaGlnaGVyIHByaW9yaXR5LiBpZiBwcmlvcml0eVxuICogPCAwLCBpdCB3aWxsIGJlIGNvbnNpZGVyZWQgYXMgYSAnYmV0YScgdmVyc2lvbiBhbmQgd2lsbCBub3QgYmUgdXNlZCBhcyBhIGZhbGxiYWNrIGJhY2tlbmQgYnkgZGVmYXVsdC5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCByZWdpc3RlckJhY2tlbmQgPSAobmFtZTogc3RyaW5nLCBiYWNrZW5kOiBCYWNrZW5kLCBwcmlvcml0eTogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmIChiYWNrZW5kICYmIHR5cGVvZiBiYWNrZW5kLmluaXQgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGJhY2tlbmQuY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCBjdXJyZW50QmFja2VuZCA9IGJhY2tlbmRzLmdldChuYW1lKTtcbiAgICBpZiAoY3VycmVudEJhY2tlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYmFja2VuZHMuc2V0KG5hbWUsIHsgYmFja2VuZCwgcHJpb3JpdHkgfSk7XG4gICAgfSBlbHNlIGlmIChjdXJyZW50QmFja2VuZC5wcmlvcml0eSA+IHByaW9yaXR5KSB7XG4gICAgICAvLyBzYW1lIG5hbWUgaXMgYWxyZWFkeSByZWdpc3RlcmVkIHdpdGggYSBoaWdoZXIgcHJpb3JpdHkuIHNraXAgcmVnaXN0ZXJhdGlvbi5cbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRCYWNrZW5kLnByaW9yaXR5ID09PSBwcmlvcml0eSkge1xuICAgICAgaWYgKGN1cnJlbnRCYWNrZW5kLmJhY2tlbmQgIT09IGJhY2tlbmQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgcmVnaXN0ZXIgYmFja2VuZCBcIiR7bmFtZX1cIiB1c2luZyBwcmlvcml0eSAke3ByaW9yaXR5fWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwcmlvcml0eSA+PSAwKSB7XG4gICAgICBjb25zdCBpID0gYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5LmluZGV4T2YobmFtZSk7XG4gICAgICBpZiAoaSAhPT0gLTEpIHtcbiAgICAgICAgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5LnNwbGljZShpLCAxKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGJhY2tlbmRzLmdldChiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHlbaV0pIS5wcmlvcml0eSA8PSBwcmlvcml0eSkge1xuICAgICAgICAgIGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5zcGxpY2UoaSwgMCwgbmFtZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkucHVzaChuYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignbm90IGEgdmFsaWQgYmFja2VuZCcpO1xufTtcblxuLyoqXG4gKiBUcnkgdG8gcmVzb2x2ZSBhbmQgaW5pdGlhbGl6ZSBhIGJhY2tlbmQuXG4gKlxuICogQHBhcmFtIGJhY2tlbmROYW1lIC0gdGhlIG5hbWUgb2YgdGhlIGJhY2tlbmQuXG4gKiBAcmV0dXJucyB0aGUgYmFja2VuZCBpbnN0YW5jZSBpZiByZXNvbHZlZCBhbmQgaW5pdGlhbGl6ZWQgc3VjY2Vzc2Z1bGx5LCBvciBhbiBlcnJvciBtZXNzYWdlIGlmIGZhaWxlZC5cbiAqL1xuY29uc3QgdHJ5UmVzb2x2ZUFuZEluaXRpYWxpemVCYWNrZW5kID0gYXN5bmMgKGJhY2tlbmROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEJhY2tlbmQgfCBzdHJpbmc+ID0+IHtcbiAgY29uc3QgYmFja2VuZEluZm8gPSBiYWNrZW5kcy5nZXQoYmFja2VuZE5hbWUpO1xuICBpZiAoIWJhY2tlbmRJbmZvKSB7XG4gICAgcmV0dXJuICdiYWNrZW5kIG5vdCBmb3VuZC4nO1xuICB9XG5cbiAgaWYgKGJhY2tlbmRJbmZvLmluaXRpYWxpemVkKSB7XG4gICAgcmV0dXJuIGJhY2tlbmRJbmZvLmJhY2tlbmQ7XG4gIH0gZWxzZSBpZiAoYmFja2VuZEluZm8uYWJvcnRlZCkge1xuICAgIHJldHVybiBiYWNrZW5kSW5mby5lcnJvciE7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgaXNJbml0aWFsaXppbmcgPSAhIWJhY2tlbmRJbmZvLmluaXRQcm9taXNlO1xuICAgIHRyeSB7XG4gICAgICBpZiAoIWlzSW5pdGlhbGl6aW5nKSB7XG4gICAgICAgIGJhY2tlbmRJbmZvLmluaXRQcm9taXNlID0gYmFja2VuZEluZm8uYmFja2VuZC5pbml0KGJhY2tlbmROYW1lKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGJhY2tlbmRJbmZvLmluaXRQcm9taXNlO1xuICAgICAgYmFja2VuZEluZm8uaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIGJhY2tlbmRJbmZvLmJhY2tlbmQ7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKCFpc0luaXRpYWxpemluZykge1xuICAgICAgICBiYWNrZW5kSW5mby5lcnJvciA9IGAke2V9YDtcbiAgICAgICAgYmFja2VuZEluZm8uYWJvcnRlZCA9IHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFja2VuZEluZm8uZXJyb3IhO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBkZWxldGUgYmFja2VuZEluZm8uaW5pdFByb21pc2U7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFJlc29sdmUgZXhlY3V0aW9uIHByb3ZpZGVycyBmcm9tIHRoZSBzcGVjaWZpYyBzZXNzaW9uIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSB0aGUgc2Vzc2lvbiBvcHRpb25zIG9iamVjdC5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgdHVwbGUgb2YgYW4gaW5pdGlhbGl6ZWQgYmFja2VuZCBpbnN0YW5jZSBhbmQgYSBzZXNzaW9uIG9wdGlvbnMgb2JqZWN0IHdpdGhcbiAqIGZpbHRlcmVkIEVQIGxpc3QuXG4gKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY29uc3QgcmVzb2x2ZUJhY2tlbmRBbmRFeGVjdXRpb25Qcm92aWRlcnMgPSBhc3luYyAoXG4gIG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4pOiBQcm9taXNlPFtiYWNrZW5kOiBCYWNrZW5kLCBvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zXT4gPT4ge1xuICAvLyBleHRyYWN0IGJhY2tlbmQgaGludHMgZnJvbSBzZXNzaW9uIG9wdGlvbnNcbiAgY29uc3QgZXBzID0gb3B0aW9ucy5leGVjdXRpb25Qcm92aWRlcnMgfHwgW107XG4gIGNvbnN0IGJhY2tlbmRIaW50cyA9IGVwcy5tYXAoKGkpID0+ICh0eXBlb2YgaSA9PT0gJ3N0cmluZycgPyBpIDogaS5uYW1lKSk7XG4gIGNvbnN0IGJhY2tlbmROYW1lcyA9IGJhY2tlbmRIaW50cy5sZW5ndGggPT09IDAgPyBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkgOiBiYWNrZW5kSGludHM7XG5cbiAgLy8gdHJ5IHRvIHJlc29sdmUgYW5kIGluaXRpYWxpemUgYWxsIHJlcXVlc3RlZCBiYWNrZW5kc1xuICBsZXQgYmFja2VuZDogQmFja2VuZCB8IHVuZGVmaW5lZDtcbiAgY29uc3QgZXJyb3JzID0gW107XG4gIGNvbnN0IGF2YWlsYWJsZUJhY2tlbmROYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IGJhY2tlbmROYW1lIG9mIGJhY2tlbmROYW1lcykge1xuICAgIGNvbnN0IHJlc29sdmVSZXN1bHQgPSBhd2FpdCB0cnlSZXNvbHZlQW5kSW5pdGlhbGl6ZUJhY2tlbmQoYmFja2VuZE5hbWUpO1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZVJlc3VsdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVycm9ycy5wdXNoKHsgbmFtZTogYmFja2VuZE5hbWUsIGVycjogcmVzb2x2ZVJlc3VsdCB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFiYWNrZW5kKSB7XG4gICAgICAgIGJhY2tlbmQgPSByZXNvbHZlUmVzdWx0O1xuICAgICAgfVxuICAgICAgaWYgKGJhY2tlbmQgPT09IHJlc29sdmVSZXN1bHQpIHtcbiAgICAgICAgYXZhaWxhYmxlQmFja2VuZE5hbWVzLmFkZChiYWNrZW5kTmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgbm8gYmFja2VuZCBpcyBhdmFpbGFibGUsIHRocm93IGVycm9yLlxuICBpZiAoIWJhY2tlbmQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIGF2YWlsYWJsZSBiYWNrZW5kIGZvdW5kLiBFUlI6ICR7ZXJyb3JzLm1hcCgoZSkgPT4gYFske2UubmFtZX1dICR7ZS5lcnJ9YCkuam9pbignLCAnKX1gKTtcbiAgfVxuXG4gIC8vIGZvciBlYWNoIGV4cGxpY2l0bHkgcmVxdWVzdGVkIGJhY2tlbmQsIGlmIGl0J3Mgbm90IGF2YWlsYWJsZSwgb3V0cHV0IHdhcm5pbmcgbWVzc2FnZS5cbiAgZm9yIChjb25zdCB7IG5hbWUsIGVyciB9IG9mIGVycm9ycykge1xuICAgIGlmIChiYWNrZW5kSGludHMuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGByZW1vdmluZyByZXF1ZXN0ZWQgZXhlY3V0aW9uIHByb3ZpZGVyIFwiJHtuYW1lfVwiIGZyb20gc2Vzc2lvbiBvcHRpb25zIGJlY2F1c2UgaXQgaXMgbm90IGF2YWlsYWJsZTogJHtlcnJ9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZmlsdGVyZWRFcHMgPSBlcHMuZmlsdGVyKChpKSA9PiBhdmFpbGFibGVCYWNrZW5kTmFtZXMuaGFzKHR5cGVvZiBpID09PSAnc3RyaW5nJyA/IGkgOiBpLm5hbWUpKTtcblxuICByZXR1cm4gW1xuICAgIGJhY2tlbmQsXG4gICAgbmV3IFByb3h5KG9wdGlvbnMsIHtcbiAgICAgIGdldDogKHRhcmdldCwgcHJvcCkgPT4ge1xuICAgICAgICBpZiAocHJvcCA9PT0gJ2V4ZWN1dGlvblByb3ZpZGVycycpIHtcbiAgICAgICAgICByZXR1cm4gZmlsdGVyZWRFcHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCk7XG4gICAgICB9LFxuICAgIH0pLFxuICBdO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiB9IGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24uanMnO1xuaW1wb3J0IHsgT25ueFZhbHVlIH0gZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBTZXNzaW9uSGFuZGxlciB7XG4gIHR5cGUgRmVlZHNUeXBlID0geyBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIH07XG4gIHR5cGUgRmV0Y2hlc1R5cGUgPSB7IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfCBudWxsIH07XG4gIHR5cGUgUmV0dXJuVHlwZSA9IHsgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB9O1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgc2hhcmVkIFNlc3Npb25IYW5kbGVyIGZ1bmN0aW9uYWxpdHlcbiAqXG4gKiBAaWdub3JlXG4gKi9cbmludGVyZmFjZSBTZXNzaW9uSGFuZGxlciB7XG4gIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPjtcblxuICByZWFkb25seSBpbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgb3V0cHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIHJlYWRvbmx5IGlucHV0TWV0YWRhdGE6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YVtdO1xuICByZWFkb25seSBvdXRwdXRNZXRhZGF0YTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW107XG59XG5cbi8qKlxuICogUmVwcmVzZW50IGEgaGFuZGxlciBpbnN0YW5jZSBvZiBhbiBpbmZlcmVuY2Ugc2Vzc2lvbi5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgZXh0ZW5kcyBTZXNzaW9uSGFuZGxlciB7XG4gIHN0YXJ0UHJvZmlsaW5nKCk6IHZvaWQ7XG4gIGVuZFByb2ZpbGluZygpOiB2b2lkO1xuXG4gIHJ1bihcbiAgICBmZWVkczogU2Vzc2lvbkhhbmRsZXIuRmVlZHNUeXBlLFxuICAgIGZldGNoZXM6IFNlc3Npb25IYW5kbGVyLkZldGNoZXNUeXBlLFxuICAgIG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPjtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBiYWNrZW5kIHRoYXQgcHJvdmlkZXMgaW1wbGVtZW50YXRpb24gb2YgbW9kZWwgaW5mZXJlbmNpbmcuXG4gKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tlbmQge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgYmFja2VuZCBhc3luY2hyb25vdXNseS4gU2hvdWxkIHRocm93IHdoZW4gZmFpbGVkLlxuICAgKi9cbiAgaW5pdChiYWNrZW5kTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPjtcblxuICBjcmVhdGVJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcihcbiAgICB1cmlPckJ1ZmZlcjogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcj47XG59XG5cbmV4cG9ydCB7IHJlZ2lzdGVyQmFja2VuZCB9IGZyb20gJy4vYmFja2VuZC1pbXBsLmpzJztcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZCBieSAvanMvc2NyaXB0cy91cGRhdGUtdmVyc2lvbi50c1xuLy8gRG8gbm90IG1vZGlmeSBmaWxlIGNvbnRlbnQgbWFudWFsbHkuXG5cbmV4cG9ydCBjb25zdCB2ZXJzaW9uID0gJzEuMzAuMCc7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEVudiB9IGZyb20gJy4vZW52LmpzJztcbmltcG9ydCB7IHZlcnNpb24gfSBmcm9tICcuL3ZlcnNpb24uanMnO1xuXG50eXBlIExvZ0xldmVsVHlwZSA9IEVudlsnbG9nTGV2ZWwnXTtcblxubGV0IGxvZ0xldmVsVmFsdWU6IFJlcXVpcmVkPExvZ0xldmVsVHlwZT4gPSAnd2FybmluZyc7XG5cbmV4cG9ydCBjb25zdCBlbnY6IEVudiA9IHtcbiAgd2FzbToge30sXG4gIHdlYmdsOiB7fSBhcyBFbnYuV2ViR0xGbGFncyxcbiAgd2ViZ3B1OiB7fSBhcyBFbnYuV2ViR3B1RmxhZ3MsXG4gIHZlcnNpb25zOiB7IGNvbW1vbjogdmVyc2lvbiB9LFxuXG4gIHNldCBsb2dMZXZlbCh2YWx1ZTogTG9nTGV2ZWxUeXBlKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycgfHwgWyd2ZXJib3NlJywgJ2luZm8nLCAnd2FybmluZycsICdlcnJvcicsICdmYXRhbCddLmluZGV4T2YodmFsdWUpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBsb2dnaW5nIGxldmVsOiAke3ZhbHVlfWApO1xuICAgIH1cbiAgICBsb2dMZXZlbFZhbHVlID0gdmFsdWU7XG4gIH0sXG4gIGdldCBsb2dMZXZlbCgpOiBSZXF1aXJlZDxMb2dMZXZlbFR5cGU+IHtcbiAgICByZXR1cm4gbG9nTGV2ZWxWYWx1ZTtcbiAgfSxcbn07XG5cbi8vIHNldCBwcm9wZXJ0eSAnbG9nTGV2ZWwnIHNvIHRoYXQgdGhleSBjYW4gYmUgY29ycmVjdGx5IHRyYW5zZmVycmVkIHRvIHdvcmtlciBieSBgcG9zdE1lc3NhZ2UoKWAuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZW52LCAnbG9nTGV2ZWwnLCB7IGVudW1lcmFibGU6IHRydWUgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiBhcyBlbnZJbXBsIH0gZnJvbSAnLi9lbnYtaW1wbC5qcyc7XG5pbXBvcnQgeyBUcnlHZXRHbG9iYWxUeXBlIH0gZnJvbSAnLi90eXBlLWhlbHBlci5qcyc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBFbnYge1xuICBleHBvcnQgdHlwZSBXYXNtUGF0aFByZWZpeCA9IHN0cmluZztcbiAgZXhwb3J0IGludGVyZmFjZSBXYXNtRmlsZVBhdGhzIHtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBvdmVycmlkZSBwYXRoIGZvciB0aGUgbWFpbiAud2FzbSBmaWxlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXRoIHNob3VsZCBiZSBhbiBhYnNvbHV0ZSBwYXRoLlxuICAgICAqXG4gICAgICogSWYgbm90IG1vZGlmaWVkLCB0aGUgZmlsZW5hbWUgb2YgdGhlIC53YXNtIGZpbGUgaXM6XG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC53YXNtYCBmb3IgZGVmYXVsdCBidWlsZFxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQuanNlcC53YXNtYCBmb3IgSlNFUCBidWlsZCAod2l0aCBXZWJHUFUgYW5kIFdlYk5OKVxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQuYXN5bmNpZnkud2FzbWAgZm9yIFdlYkdQVSBidWlsZCB3aXRoIEFzeW5jaWZ5ICh3aXRoIFdlYk5OKVxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQuanNwaS53YXNtYCBmb3IgV2ViR1BVIGJ1aWxkIHdpdGggSlNQSSBzdXBwb3J0ICh3aXRoIFdlYk5OKVxuICAgICAqL1xuICAgIHdhc20/OiBVUkwgfCBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgb3ZlcnJpZGUgcGF0aCBmb3IgdGhlIG1haW4gLm1qcyBmaWxlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXRoIHNob3VsZCBiZSBhbiBhYnNvbHV0ZSBwYXRoLlxuICAgICAqXG4gICAgICogSWYgbm90IG1vZGlmaWVkLCB0aGUgZmlsZW5hbWUgb2YgdGhlIC5tanMgZmlsZSBpczpcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLm1qc2AgZm9yIGRlZmF1bHQgYnVpbGRcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmpzZXAubWpzYCBmb3IgSlNFUCBidWlsZCAod2l0aCBXZWJHUFUgYW5kIFdlYk5OKVxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQuYXN5bmNpZnkubWpzYCBmb3IgV2ViR1BVIGJ1aWxkIHdpdGggQXN5bmNpZnkgKHdpdGggV2ViTk4pXG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc3BpLm1qc2AgZm9yIFdlYkdQVSBidWlsZCB3aXRoIEpTUEkgc3VwcG9ydCAod2l0aCBXZWJOTilcbiAgICAgKi9cbiAgICBtanM/OiBVUkwgfCBzdHJpbmc7XG4gIH1cbiAgZXhwb3J0IHR5cGUgV2FzbVByZWZpeE9yRmlsZVBhdGhzID0gV2FzbVBhdGhQcmVmaXggfCBXYXNtRmlsZVBhdGhzO1xuICBleHBvcnQgaW50ZXJmYWNlIFdlYkFzc2VtYmx5RmxhZ3Mge1xuICAgIC8qKlxuICAgICAqIHNldCBvciBnZXQgbnVtYmVyIG9mIHRocmVhZChzKS4gSWYgb21pdHRlZCBvciBzZXQgdG8gMCwgbnVtYmVyIG9mIHRocmVhZChzKSB3aWxsIGJlIGRldGVybWluZWQgYnkgc3lzdGVtLiBJZiBzZXRcbiAgICAgKiB0byAxLCBubyB3b3JrZXIgdGhyZWFkIHdpbGwgYmUgc3Bhd25lZC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSB3aGVuIFdlYkFzc2VtYmx5IG11bHRpdGhyZWFkIGZlYXR1cmUgaXMgYXZhaWxhYmxlIGluIGN1cnJlbnQgY29udGV4dC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYDBgXG4gICAgICovXG4gICAgbnVtVGhyZWFkcz86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIHNldCBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0byBlbmFibGUgU0lNRC5cbiAgICAgKlxuICAgICAqIE9OTlggUnVudGltZSB3aWxsIHBlcmZvcm0gZmVhdHVyZSBkZXRlY3Rpb24gYmFzZWQgb24gdGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkuIFNwZWNpZmljYWxseSwgd2hlbiB0aGUgdmFsdWUgaXNcbiAgICAgKiBzZXQgdG86XG4gICAgICogLSBgdW5kZWZpbmVkYCwgYHRydWVgIG9yIGBcImZpeGVkXCJgOiB3aWxsIGNoZWNrIGF2YWlsYWJpbGl0eSBvZiBGaXhlZC13aWR0aCBTSU1ELlxuICAgICAqIC0gYFwicmVsYXhlZFwiYDogd2lsbCBjaGVjayBhdmFpbGFiaWxpdHkgb2YgUmVsYXhlZCBTSU1ELlxuICAgICAqIC0gYGZhbHNlYDogd2lsbCBub3QgcGVyZm9ybSBTSU1EIGZlYXR1cmUgY2hlY2tpbmcuXG4gICAgICpcbiAgICAgKiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgZG9lcyBub3QgbWFrZSBPTk5YIFJ1bnRpbWUgdG8gc3dpdGNoIHRvIHRoZSBjb3JyZXNwb25kaW5nIHJ1bnRpbWUgYXV0b21hdGljYWxseS4gVXNlciBuZWVkXG4gICAgICogdG8gc2V0IGB3YXNtUGF0aHNgIG9yIGB3YXNtQmluYXJ5YCBwcm9wZXJ0eSB0byBsb2FkIHRoZSBjb3JyZXNwb25kaW5nIHJ1bnRpbWUuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgd2hlbiBXZWJBc3NlbWJseSBTSU1EIGZlYXR1cmUgaXMgYXZhaWxhYmxlIGluIGN1cnJlbnQgY29udGV4dC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYHRydWVgXG4gICAgICovXG4gICAgc2ltZD86IGJvb2xlYW4gfCAnZml4ZWQnIHwgJ3JlbGF4ZWQnO1xuXG4gICAgLyoqXG4gICAgICogc2V0IG9yIGdldCBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRvIGVuYWJsZSB0cmFjZS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWQgVXNlIGBlbnYudHJhY2VgIGluc3RlYWQuIElmIGBlbnYudHJhY2VgIGlzIHNldCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIGlnbm9yZWQuXG4gICAgICovXG4gICAgdHJhY2U/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCBhIG51bWJlciBzcGVjaWZ5aW5nIHRoZSB0aW1lb3V0IGZvciBpbml0aWFsaXphdGlvbiBvZiBXZWJBc3NlbWJseSBiYWNrZW5kLCBpbiBtaWxsaXNlY29uZHMuIEEgemVyb1xuICAgICAqIHZhbHVlIGluZGljYXRlcyBubyB0aW1lb3V0IGlzIHNldC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYDBgXG4gICAgICovXG4gICAgaW5pdFRpbWVvdXQ/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYSBjdXN0b20gVVJMIHByZWZpeCB0byB0aGUgLndhc20vLm1qcyBmaWxlcywgb3IgYW4gb2JqZWN0IG9mIG92ZXJyaWRlcyBmb3IgYm90aCAud2FzbS8ubWpzIGZpbGUuIFRoZSBvdmVycmlkZVxuICAgICAqIHBhdGggc2hvdWxkIGJlIGFuIGFic29sdXRlIHBhdGguXG4gICAgICovXG4gICAgd2FzbVBhdGhzPzogV2FzbVByZWZpeE9yRmlsZVBhdGhzO1xuXG4gICAgLyoqXG4gICAgICogU2V0IGEgY3VzdG9tIGJ1ZmZlciB3aGljaCBjb250YWlucyB0aGUgV2ViQXNzZW1ibHkgYmluYXJ5LiBJZiB0aGlzIHByb3BlcnR5IGlzIHNldCwgdGhlIGB3YXNtUGF0aHNgIHByb3BlcnR5IHdpbGxcbiAgICAgKiBiZSBpZ25vcmVkLlxuICAgICAqL1xuICAgIHdhc21CaW5hcnk/OiBBcnJheUJ1ZmZlckxpa2UgfCBVaW50OEFycmF5O1xuXG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHByb3h5IHRoZSBleGVjdXRpb24gb2YgbWFpbiB0aHJlYWQgdG8gYSB3b3JrZXIgdGhyZWFkLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICovXG4gICAgcHJveHk/OiBib29sZWFuO1xuICB9XG5cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHTEZsYWdzIHtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBXZWJHTCBDb250ZXh0IElEICh3ZWJnbCBvciB3ZWJnbDIpLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgJ3dlYmdsMidgXG4gICAgICovXG4gICAgY29udGV4dElkPzogJ3dlYmdsJyB8ICd3ZWJnbDInO1xuICAgIC8qKlxuICAgICAqIEdldCB0aGUgV2ViR0wgcmVuZGVyaW5nIGNvbnRleHQuXG4gICAgICovXG4gICAgcmVhZG9ubHkgY29udGV4dDogV2ViR0xSZW5kZXJpbmdDb250ZXh0O1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIG1heGltdW0gYmF0Y2ggc2l6ZSBmb3IgbWF0bXVsLiAwIG1lYW5zIHRvIGRpc2FibGUgYmF0Y2hpbmcuXG4gICAgICpcbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqL1xuICAgIG1hdG11bE1heEJhdGNoU2l6ZT86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSB0ZXh0dXJlIGNhY2hlIG1vZGUuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGAnZnVsbCdgXG4gICAgICovXG4gICAgdGV4dHVyZUNhY2hlTW9kZT86ICdpbml0aWFsaXplck9ubHknIHwgJ2Z1bGwnO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIHBhY2tlZCB0ZXh0dXJlIG1vZGVcbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgICAqL1xuICAgIHBhY2s/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgd2hldGhlciBlbmFibGUgYXN5bmMgZG93bmxvYWQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKi9cbiAgICBhc3luYz86IGJvb2xlYW47XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdwdVByb2ZpbGluZ0RhdGFWMVRlbnNvck1ldGFkYXRhIHtcbiAgICBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcbiAgICBkYXRhVHlwZTogc3RyaW5nO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR3B1UHJvZmlsaW5nRGF0YVYxIHtcbiAgICB2ZXJzaW9uOiAxO1xuICAgIGlucHV0c01ldGFkYXRhOiByZWFkb25seSBXZWJHcHVQcm9maWxpbmdEYXRhVjFUZW5zb3JNZXRhZGF0YVtdO1xuICAgIG91dHB1dHNNZXRhZGF0YTogcmVhZG9ubHkgV2ViR3B1UHJvZmlsaW5nRGF0YVYxVGVuc29yTWV0YWRhdGFbXTtcbiAgICBrZXJuZWxJZDogbnVtYmVyO1xuICAgIGtlcm5lbFR5cGU6IHN0cmluZztcbiAgICBrZXJuZWxOYW1lOiBzdHJpbmc7XG4gICAgcHJvZ3JhbU5hbWU6IHN0cmluZztcbiAgICBzdGFydFRpbWU6IG51bWJlcjtcbiAgICBlbmRUaW1lOiBudW1iZXI7XG4gIH1cblxuICBleHBvcnQgdHlwZSBXZWJHcHVQcm9maWxpbmdEYXRhID0gV2ViR3B1UHJvZmlsaW5nRGF0YVYxO1xuXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR3B1RmxhZ3Mge1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIHByb2ZpbGluZyBtb2RlLlxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWQgVXNlIGBlbnYud2ViZ3B1LnByb2ZpbGluZy5tb2RlYCBpbnN0ZWFkLiBJZiBgZW52LndlYmdwdS5wcm9maWxpbmcubW9kZWAgaXMgc2V0LCB0aGlzIHByb3BlcnR5IHdpbGwgYmVcbiAgICAgKiBpZ25vcmVkLlxuICAgICAqL1xuICAgIHByb2ZpbGluZ01vZGU/OiAnb2ZmJyB8ICdkZWZhdWx0JztcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwcm9maWxpbmcgY29uZmlndXJhdGlvbi5cbiAgICAgKi9cbiAgICBwcm9maWxpbmc6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2V0IG9yIGdldCB0aGUgcHJvZmlsaW5nIG1vZGUuXG4gICAgICAgKlxuICAgICAgICogQGRlZmF1bHRWYWx1ZSBgJ29mZidgXG4gICAgICAgKi9cbiAgICAgIG1vZGU/OiAnb2ZmJyB8ICdkZWZhdWx0JztcblxuICAgICAgLyoqXG4gICAgICAgKiBTZXQgb3IgZ2V0IGEgY2FsbGJhY2sgZnVuY3Rpb24gd2hlbiBhIHByb2ZpbGluZyBkYXRhIGlzIHJlY2VpdmVkLiBJZiBub3Qgc2V0LCB0aGUgcHJvZmlsaW5nIGRhdGEgd2lsbCBiZVxuICAgICAgICogcHJpbnRlZCB0byBjb25zb2xlLlxuICAgICAgICovXG4gICAgICBvbmRhdGE/OiAoZGF0YTogV2ViR3B1UHJvZmlsaW5nRGF0YSkgPT4gdm9pZDtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIHBvd2VyIHByZWZlcmVuY2UuXG4gICAgICpcbiAgICAgKiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgb25seSBoYXMgZWZmZWN0IGJlZm9yZSB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFRoZSB2YWx1ZSB3aWxsIGJlXG4gICAgICogdXNlZCBhcyBvcHRpb25zIGZvciBgbmF2aWdhdG9yLmdwdS5yZXF1ZXN0QWRhcHRlcigpYC5cbiAgICAgKlxuICAgICAqIFNlZSB7QGxpbmsgaHR0cHM6Ly9ncHV3ZWIuZ2l0aHViLmlvL2dwdXdlYi8jZGljdGRlZi1ncHVyZXF1ZXN0YWRhcHRlcm9wdGlvbnN9IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGB1bmRlZmluZWRgXG4gICAgICpcbiAgICAgKiBAZGVwcmVjYXRlZCBDcmVhdGUgeW91ciBvd24gR1BVQWRhcHRlciwgdXNlIGl0IHRvIGNyZWF0ZSBhIEdQVURldmljZSBpbnN0YW5jZSBhbmQgc2V0IHtAbGluayBkZXZpY2V9IHByb3BlcnR5IGlmXG4gICAgICogeW91IHdhbnQgdG8gdXNlIGEgc3BlY2lmaWMgcG93ZXIgcHJlZmVyZW5jZS5cbiAgICAgKi9cbiAgICBwb3dlclByZWZlcmVuY2U/OiAnbG93LXBvd2VyJyB8ICdoaWdoLXBlcmZvcm1hbmNlJztcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBmb3JjZSBmYWxsYmFjayBhZGFwdGVyIGZsYWcuXG4gICAgICpcbiAgICAgKiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgb25seSBoYXMgZWZmZWN0IGJlZm9yZSB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFRoZSB2YWx1ZSB3aWxsIGJlXG4gICAgICogdXNlZCBhcyBvcHRpb25zIGZvciBgbmF2aWdhdG9yLmdwdS5yZXF1ZXN0QWRhcHRlcigpYC5cbiAgICAgKlxuICAgICAqIFNlZSB7QGxpbmsgaHR0cHM6Ly9ncHV3ZWIuZ2l0aHViLmlvL2dwdXdlYi8jZGljdGRlZi1ncHVyZXF1ZXN0YWRhcHRlcm9wdGlvbnN9IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGB1bmRlZmluZWRgXG4gICAgICpcbiAgICAgKiBAZGVwcmVjYXRlZCBDcmVhdGUgeW91ciBvd24gR1BVQWRhcHRlciwgdXNlIGl0IHRvIGNyZWF0ZSBhIEdQVURldmljZSBpbnN0YW5jZSBhbmQgc2V0IHtAbGluayBkZXZpY2V9IHByb3BlcnR5IGlmXG4gICAgICogeW91IHdhbnQgdG8gdXNlIGEgc3BlY2lmaWMgZmFsbGJhY2sgb3B0aW9uLlxuICAgICAqL1xuICAgIGZvcmNlRmFsbGJhY2tBZGFwdGVyPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBhZGFwdGVyIGZvciBXZWJHUFUuXG4gICAgICpcbiAgICAgKiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgb25seSBoYXMgZWZmZWN0IGJlZm9yZSB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFRoZSB2YWx1ZSB3aWxsIGJlXG4gICAgICogdXNlZCBhcyB0aGUgR1BVIGFkYXB0ZXIgZm9yIHRoZSB1bmRlcmx5aW5nIFdlYkdQVSBiYWNrZW5kIHRvIGNyZWF0ZSBHUFUgZGV2aWNlLlxuICAgICAqXG4gICAgICogSWYgdGhpcyBwcm9wZXJ0eSBpcyBub3Qgc2V0LCBpdCB3aWxsIGJlIGF2YWlsYWJsZSB0byBnZXQgYWZ0ZXIgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGVcbiAgICAgKiB2YWx1ZSB3aWxsIGJlIHRoZSBHUFUgYWRhcHRlciB0aGF0IGNyZWF0ZWQgYnkgdGhlIHVuZGVybHlpbmcgV2ViR1BVIGJhY2tlbmQuXG4gICAgICpcbiAgICAgKiBXaGVuIHVzZSB3aXRoIFR5cGVTY3JpcHQsIHRoZSB0eXBlIG9mIHRoaXMgcHJvcGVydHkgaXMgYEdQVUFkYXB0ZXJgIGRlZmluZWQgaW4gXCJAd2ViZ3B1L3R5cGVzXCIuXG4gICAgICpcbiAgICAgKiBAZGVwcmVjYXRlZCBJdCBpcyBubyBsb25nZXIgcmVjb21tZW5kZWQgdG8gdXNlIHRoaXMgcHJvcGVydHkuIFRoZSBsYXRlc3QgV2ViR1BVIHNwZWMgYWRkcyBgR1BVRGV2aWNlLmFkYXB0ZXJJbmZvYFxuICAgICAqIChodHRwczovL3d3dy53My5vcmcvVFIvd2ViZ3B1LyNkb20tZ3B1ZGV2aWNlLWFkYXB0ZXJpbmZvKSwgd2hpY2ggYWxsb3dzIHRvIGdldCB0aGUgYWRhcHRlciBpbmZvcm1hdGlvbiBmcm9tIHRoZVxuICAgICAqIGRldmljZS4gV2hlbiBpdCdzIGF2YWlsYWJsZSwgdGhlcmUgaXMgbm8gbmVlZCB0byBzZXQvZ2V0IHRoZSB7QGxpbmsgYWRhcHRlcn0gcHJvcGVydHkuXG4gICAgICovXG4gICAgYWRhcHRlcjogVHJ5R2V0R2xvYmFsVHlwZTwnR1BVQWRhcHRlcic+O1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgdGhlIEdQVSBkZXZpY2UgZm9yIFdlYkdQVS5cbiAgICAgKlxuICAgICAqIFRoZXJlIGFyZSAzIHZhbGlkIHNjZW5hcmlvcyBvZiBhY2Nlc3NpbmcgdGhpcyBwcm9wZXJ0eTpcbiAgICAgKiAtIFNldCBhIHZhbHVlIGJlZm9yZSB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFRoZSB2YWx1ZSB3aWxsIGJlIHVzZWQgYnkgdGhlIFdlYkdQVSBiYWNrZW5kXG4gICAgICogdG8gcGVyZm9ybSBjYWxjdWxhdGlvbnMuIElmIHRoZSB2YWx1ZSBpcyBub3QgYSBgR1BVRGV2aWNlYCBvYmplY3QsIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duLlxuICAgICAqIC0gR2V0IHRoZSB2YWx1ZSBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGlzIHdpbGwgdHJ5IHRvIGNyZWF0ZSBhIG5ldyBHUFVEZXZpY2VcbiAgICAgKiBpbnN0YW5jZS4gUmV0dXJucyBhIGBQcm9taXNlYCB0aGF0IHJlc29sdmVzIHRvIGEgYEdQVURldmljZWAgb2JqZWN0LlxuICAgICAqIC0gR2V0IHRoZSB2YWx1ZSBhZnRlciB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFJldHVybnMgYSByZXNvbHZlZCBgUHJvbWlzZWAgdG8gdGhlXG4gICAgICogYEdQVURldmljZWAgb2JqZWN0IHVzZWQgYnkgdGhlIFdlYkdQVSBiYWNrZW5kLlxuICAgICAqL1xuICAgIGdldCBkZXZpY2UoKTogUHJvbWlzZTxUcnlHZXRHbG9iYWxUeXBlPCdHUFVEZXZpY2UnPj47XG4gICAgc2V0IGRldmljZSh2YWx1ZTogVHJ5R2V0R2xvYmFsVHlwZTwnR1BVRGV2aWNlJz4pO1xuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgd2hldGhlciB2YWxpZGF0ZSBpbnB1dCBjb250ZW50LlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICovXG4gICAgdmFsaWRhdGVJbnB1dENvbnRlbnQ/OiBib29sZWFuO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRW52IHtcbiAgLyoqXG4gICAqIHNldCB0aGUgc2V2ZXJpdHkgbGV2ZWwgZm9yIGxvZ2dpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0VmFsdWUgYCd3YXJuaW5nJ2BcbiAgICovXG4gIGxvZ0xldmVsPzogJ3ZlcmJvc2UnIHwgJ2luZm8nIHwgJ3dhcm5pbmcnIHwgJ2Vycm9yJyB8ICdmYXRhbCc7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlIHdoZXRoZXIgcnVuIGluIGRlYnVnIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgKi9cbiAgZGVidWc/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBzZXQgb3IgZ2V0IGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gZW5hYmxlIHRyYWNlLlxuICAgKlxuICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICovXG4gIHRyYWNlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogR2V0IHZlcnNpb24gb2YgdGhlIGN1cnJlbnQgcGFja2FnZS5cbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb25zOiB7XG4gICAgcmVhZG9ubHkgY29tbW9uOiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgd2ViPzogc3RyaW5nO1xuICAgIHJlYWRvbmx5IG5vZGU/OiBzdHJpbmc7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICAgIHJlYWRvbmx5ICdyZWFjdC1uYXRpdmUnPzogc3RyaW5nO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXByZXNlbnQgYSBzZXQgb2YgZmxhZ3MgZm9yIFdlYkFzc2VtYmx5XG4gICAqL1xuICByZWFkb25seSB3YXNtOiBFbnYuV2ViQXNzZW1ibHlGbGFncztcblxuICAvKipcbiAgICogUmVwcmVzZW50IGEgc2V0IG9mIGZsYWdzIGZvciBXZWJHTFxuICAgKi9cbiAgcmVhZG9ubHkgd2ViZ2w6IEVudi5XZWJHTEZsYWdzO1xuXG4gIC8qKlxuICAgKiBSZXByZXNlbnQgYSBzZXQgb2YgZmxhZ3MgZm9yIFdlYkdQVVxuICAgKi9cbiAgcmVhZG9ubHkgd2ViZ3B1OiBFbnYuV2ViR3B1RmxhZ3M7XG5cbiAgW25hbWU6IHN0cmluZ106IHVua25vd247XG59XG5cbi8qKlxuICogUmVwcmVzZW50IGEgc2V0IG9mIGZsYWdzIGFzIGEgZ2xvYmFsIHNpbmdsZXRvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IGVudjogRW52ID0gZW52SW1wbDtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yVG9EYXRhVXJsT3B0aW9ucywgVGVuc29yVG9JbWFnZURhdGFPcHRpb25zIH0gZnJvbSAnLi90ZW5zb3ItY29udmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLnRvRGF0YVVSTCgpXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JUb0RhdGFVUkwgPSAodGVuc29yOiBUZW5zb3IsIG9wdGlvbnM/OiBUZW5zb3JUb0RhdGFVcmxPcHRpb25zKTogc3RyaW5nID0+IHtcbiAgY29uc3QgY2FudmFzID0gdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpIDogbmV3IE9mZnNjcmVlbkNhbnZhcygxLCAxKTtcbiAgY2FudmFzLndpZHRoID0gdGVuc29yLmRpbXNbM107XG4gIGNhbnZhcy5oZWlnaHQgPSB0ZW5zb3IuZGltc1syXTtcbiAgY29uc3QgcGl4ZWxzMkRDb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoJzJkJykgYXNcbiAgICB8IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRFxuICAgIHwgT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEXG4gICAgfCBudWxsO1xuXG4gIGlmIChwaXhlbHMyRENvbnRleHQgIT0gbnVsbCkge1xuICAgIC8vIERlZmF1bHQgdmFsdWVzIGZvciBoZWlnaHQgYW5kIHdpZHRoICYgZm9ybWF0XG4gICAgbGV0IHdpZHRoOiBudW1iZXI7XG4gICAgbGV0IGhlaWdodDogbnVtYmVyO1xuICAgIGlmIChvcHRpb25zPy50ZW5zb3JMYXlvdXQgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnRlbnNvckxheW91dCA9PT0gJ05IV0MnKSB7XG4gICAgICB3aWR0aCA9IHRlbnNvci5kaW1zWzJdO1xuICAgICAgaGVpZ2h0ID0gdGVuc29yLmRpbXNbM107XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgbGF5b3V0IGlzIE5DV0hcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbM107XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1syXTtcbiAgICB9XG5cbiAgICBjb25zdCBpbnB1dGZvcm1hdCA9IG9wdGlvbnM/LmZvcm1hdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5mb3JtYXQgOiAnUkdCJztcblxuICAgIGNvbnN0IG5vcm0gPSBvcHRpb25zPy5ub3JtO1xuICAgIGxldCBub3JtTWVhbjogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgbGV0IG5vcm1CaWFzOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBpZiAobm9ybSA9PT0gdW5kZWZpbmVkIHx8IG5vcm0ubWVhbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBub3JtTWVhbiA9IFsyNTUsIDI1NSwgMjU1LCAyNTVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodHlwZW9mIG5vcm0ubWVhbiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vcm1NZWFuID0gW25vcm0ubWVhblswXSwgbm9ybS5tZWFuWzFdLCBub3JtLm1lYW5bMl0sIDBdO1xuICAgICAgICBpZiAobm9ybS5tZWFuWzNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBub3JtTWVhblszXSA9IG5vcm0ubWVhblszXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobm9ybSA9PT0gdW5kZWZpbmVkIHx8IG5vcm0uYmlhcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBub3JtQmlhcyA9IFswLCAwLCAwLCAwXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBub3JtLmJpYXMgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1CaWFzID0gW25vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhc107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtQmlhcyA9IFtub3JtLmJpYXNbMF0sIG5vcm0uYmlhc1sxXSwgbm9ybS5iaWFzWzJdLCAwXTtcbiAgICAgICAgaWYgKG5vcm0uYmlhc1szXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbm9ybUJpYXNbM10gPSBub3JtLmJpYXNbM107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzdHJpZGUgPSBoZWlnaHQgKiB3aWR0aDtcbiAgICAvLyBEZWZhdWx0IHBvaW50ZXIgYXNzaWdubWVudHNcbiAgICBsZXQgclRlbnNvclBvaW50ZXIgPSAwLFxuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUsXG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDIsXG4gICAgICBhVGVuc29yUG9pbnRlciA9IC0xO1xuXG4gICAgLy8gVXBkYXRpbmcgdGhlIHBvaW50ZXIgYXNzaWdubWVudHMgYmFzZWQgb24gdGhlIGlucHV0IGltYWdlIGZvcm1hdFxuICAgIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQkEnKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICAgIGFUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMztcbiAgICB9IGVsc2UgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkdCJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgfSBlbHNlIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JCRycpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGVpZ2h0OyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgd2lkdGg7IGorKykge1xuICAgICAgICBjb25zdCBSID0gKCh0ZW5zb3IuZGF0YVtyVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMF0pICogbm9ybU1lYW5bMF07IC8vIFIgdmFsdWVcbiAgICAgICAgY29uc3QgRyA9ICgodGVuc29yLmRhdGFbZ1RlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzFdKSAqIG5vcm1NZWFuWzFdOyAvLyBHIHZhbHVlXG4gICAgICAgIGNvbnN0IEIgPSAoKHRlbnNvci5kYXRhW2JUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1syXSkgKiBub3JtTWVhblsyXTsgLy8gQiB2YWx1ZVxuICAgICAgICBjb25zdCBBID0gYVRlbnNvclBvaW50ZXIgPT09IC0xID8gMjU1IDogKCh0ZW5zb3IuZGF0YVthVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbM10pICogbm9ybU1lYW5bM107IC8vIEEgdmFsdWVcblxuICAgICAgICBwaXhlbHMyRENvbnRleHQuZmlsbFN0eWxlID0gJ3JnYmEoJyArIFIgKyAnLCcgKyBHICsgJywnICsgQiArICcsJyArIEEgKyAnKSc7XG4gICAgICAgIHBpeGVsczJEQ29udGV4dC5maWxsUmVjdChqLCBpLCAxLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCd0b0RhdGFVUkwnIGluIGNhbnZhcykge1xuICAgICAgcmV0dXJuIGNhbnZhcy50b0RhdGFVUkwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0b0RhdGFVUkwgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgYWNjZXNzIGltYWdlIGRhdGEnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IudG9JbWFnZURhdGEoKVxuICovXG5leHBvcnQgY29uc3QgdGVuc29yVG9JbWFnZURhdGEgPSAodGVuc29yOiBUZW5zb3IsIG9wdGlvbnM/OiBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnMpOiBJbWFnZURhdGEgPT4ge1xuICBjb25zdCBwaXhlbHMyRENvbnRleHQgPVxuICAgIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKVxuICAgICAgOiAobmV3IE9mZnNjcmVlbkNhbnZhcygxLCAxKS5nZXRDb250ZXh0KCcyZCcpIGFzIE9mZnNjcmVlbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCk7XG4gIGxldCBpbWFnZTogSW1hZ2VEYXRhO1xuICBpZiAocGl4ZWxzMkRDb250ZXh0ICE9IG51bGwpIHtcbiAgICAvLyBEZWZhdWx0IHZhbHVlcyBmb3IgaGVpZ2h0IGFuZCB3aWR0aCAmIGZvcm1hdFxuICAgIGxldCB3aWR0aDogbnVtYmVyO1xuICAgIGxldCBoZWlnaHQ6IG51bWJlcjtcbiAgICBsZXQgY2hhbm5lbHM6IG51bWJlcjtcbiAgICBpZiAob3B0aW9ucz8udGVuc29yTGF5b3V0ICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy50ZW5zb3JMYXlvdXQgPT09ICdOSFdDJykge1xuICAgICAgd2lkdGggPSB0ZW5zb3IuZGltc1syXTtcbiAgICAgIGhlaWdodCA9IHRlbnNvci5kaW1zWzFdO1xuICAgICAgY2hhbm5lbHMgPSB0ZW5zb3IuZGltc1szXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRGVmYXVsdCBsYXlvdXQgaXMgTkNXSFxuICAgICAgd2lkdGggPSB0ZW5zb3IuZGltc1szXTtcbiAgICAgIGhlaWdodCA9IHRlbnNvci5kaW1zWzJdO1xuICAgICAgY2hhbm5lbHMgPSB0ZW5zb3IuZGltc1sxXTtcbiAgICB9XG4gICAgY29uc3QgaW5wdXRmb3JtYXQgPSBvcHRpb25zICE9PSB1bmRlZmluZWQgPyAob3B0aW9ucy5mb3JtYXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZm9ybWF0IDogJ1JHQicpIDogJ1JHQic7XG5cbiAgICBjb25zdCBub3JtID0gb3B0aW9ucz8ubm9ybTtcbiAgICBsZXQgbm9ybU1lYW46IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGxldCBub3JtQmlhczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgaWYgKG5vcm0gPT09IHVuZGVmaW5lZCB8fCBub3JtLm1lYW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgbm9ybU1lYW4gPSBbMjU1LCAyNTUsIDI1NSwgMjU1XTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBub3JtLm1lYW4gPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1NZWFuID0gW25vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbl07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW5bMF0sIG5vcm0ubWVhblsxXSwgbm9ybS5tZWFuWzJdLCAyNTVdO1xuICAgICAgICBpZiAobm9ybS5tZWFuWzNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBub3JtTWVhblszXSA9IG5vcm0ubWVhblszXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobm9ybSA9PT0gdW5kZWZpbmVkIHx8IG5vcm0uYmlhcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBub3JtQmlhcyA9IFswLCAwLCAwLCAwXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBub3JtLmJpYXMgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1CaWFzID0gW25vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhc107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtQmlhcyA9IFtub3JtLmJpYXNbMF0sIG5vcm0uYmlhc1sxXSwgbm9ybS5iaWFzWzJdLCAwXTtcbiAgICAgICAgaWYgKG5vcm0uYmlhc1szXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbm9ybUJpYXNbM10gPSBub3JtLmJpYXNbM107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzdHJpZGUgPSBoZWlnaHQgKiB3aWR0aDtcbiAgICBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoXG4gICAgICAgIChvcHRpb25zLmZvcm1hdCAhPT0gdW5kZWZpbmVkICYmIGNoYW5uZWxzID09PSA0ICYmIG9wdGlvbnMuZm9ybWF0ICE9PSAnUkdCQScpIHx8XG4gICAgICAgIChjaGFubmVscyA9PT0gMyAmJiBvcHRpb25zLmZvcm1hdCAhPT0gJ1JHQicgJiYgb3B0aW9ucy5mb3JtYXQgIT09ICdCR1InKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRlbnNvciBmb3JtYXQgZG9lc24ndCBtYXRjaCBpbnB1dCB0ZW5zb3IgZGltc1wiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBEZWZhdWx0IHBvaW50ZXIgYXNzaWdubWVudHNcbiAgICBjb25zdCBzdGVwID0gNDtcbiAgICBsZXQgckltYWdlUG9pbnRlciA9IDAsXG4gICAgICBnSW1hZ2VQb2ludGVyID0gMSxcbiAgICAgIGJJbWFnZVBvaW50ZXIgPSAyLFxuICAgICAgYUltYWdlUG9pbnRlciA9IDM7XG4gICAgbGV0IHJUZW5zb3JQb2ludGVyID0gMCxcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlLFxuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyLFxuICAgICAgYVRlbnNvclBvaW50ZXIgPSAtMTtcblxuICAgIC8vIFVwZGF0aW5nIHRoZSBwb2ludGVyIGFzc2lnbm1lbnRzIGJhc2VkIG9uIHRoZSBpbnB1dCBpbWFnZSBmb3JtYXRcbiAgICBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0JBJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgICBhVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDM7XG4gICAgfSBlbHNlIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQicpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgIH0gZWxzZSBpZiAoaW5wdXRmb3JtYXQgPT09ICdSQkcnKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICB9XG5cbiAgICBpbWFnZSA9IHBpeGVsczJEQ29udGV4dC5jcmVhdGVJbWFnZURhdGEod2lkdGgsIGhlaWdodCk7XG5cbiAgICBmb3IgKFxuICAgICAgbGV0IGkgPSAwO1xuICAgICAgaSA8IGhlaWdodCAqIHdpZHRoO1xuICAgICAgckltYWdlUG9pbnRlciArPSBzdGVwLCBnSW1hZ2VQb2ludGVyICs9IHN0ZXAsIGJJbWFnZVBvaW50ZXIgKz0gc3RlcCwgYUltYWdlUG9pbnRlciArPSBzdGVwLCBpKytcbiAgICApIHtcbiAgICAgIGltYWdlLmRhdGFbckltYWdlUG9pbnRlcl0gPSAoKHRlbnNvci5kYXRhW3JUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1swXSkgKiBub3JtTWVhblswXTsgLy8gUiB2YWx1ZVxuICAgICAgaW1hZ2UuZGF0YVtnSW1hZ2VQb2ludGVyXSA9ICgodGVuc29yLmRhdGFbZ1RlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzFdKSAqIG5vcm1NZWFuWzFdOyAvLyBHIHZhbHVlXG4gICAgICBpbWFnZS5kYXRhW2JJbWFnZVBvaW50ZXJdID0gKCh0ZW5zb3IuZGF0YVtiVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMl0pICogbm9ybU1lYW5bMl07IC8vIEIgdmFsdWVcbiAgICAgIGltYWdlLmRhdGFbYUltYWdlUG9pbnRlcl0gPVxuICAgICAgICBhVGVuc29yUG9pbnRlciA9PT0gLTEgPyAyNTUgOiAoKHRlbnNvci5kYXRhW2FUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1szXSkgKiBub3JtTWVhblszXTsgLy8gQSB2YWx1ZVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgYWNjZXNzIGltYWdlIGRhdGEnKTtcbiAgfVxuICByZXR1cm4gaW1hZ2U7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1xuICBPcHRpb25zRGltZW5zaW9ucyxcbiAgT3B0aW9uc0Zvcm1hdCxcbiAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzLFxuICBPcHRpb25zVGVuc29yRm9ybWF0LFxuICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zLFxuICBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zLFxuICBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnMsXG4gIFRlbnNvckZyb21VcmxPcHRpb25zLFxufSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLWltcGwuanMnO1xuaW1wb3J0IHsgVGVuc29yIGFzIFRlbnNvckludGVyZmFjZSB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuaW50ZXJmYWNlIEJ1ZmZlclRvVGVuc29yT3B0aW9uc1xuICBleHRlbmRzIE9wdGlvbnNEaW1lbnNpb25zLCBPcHRpb25zVGVuc29yTGF5b3V0LCBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMsIE9wdGlvbnNGb3JtYXQsIE9wdGlvbnNUZW5zb3JGb3JtYXQge31cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIGltYWdlIG9iamVjdFxuICpcbiAqIEBwYXJhbSBidWZmZXIgLSBFeHRyYWN0ZWQgaW1hZ2UgYnVmZmVyIGRhdGEgLSBhc3N1bWluZyBSR0JBIGZvcm1hdFxuICogQHBhcmFtIGltYWdlRm9ybWF0IC0gaW5wdXQgaW1hZ2UgY29uZmlndXJhdGlvbiAtIHJlcXVpcmVkIGNvbmZpZ3VyYXRpb25zIGhlaWdodCwgd2lkdGgsIGZvcm1hdFxuICogQHBhcmFtIHRlbnNvckZvcm1hdCAtIG91dHB1dCB0ZW5zb3IgY29uZmlndXJhdGlvbiAtIERlZmF1bHQgaXMgUkdCIGZvcm1hdFxuICovXG5leHBvcnQgY29uc3QgYnVmZmVyVG9UZW5zb3IgPSAoYnVmZmVyOiBVaW50OENsYW1wZWRBcnJheSB8IHVuZGVmaW5lZCwgb3B0aW9uczogQnVmZmVyVG9UZW5zb3JPcHRpb25zKTogVGVuc29yID0+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/ICFlbnYud2FzbS50cmFjZSA6ICFlbnYudHJhY2UpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgVFJBQ0VfRlVOQygnRU5EJywgZXh0cmFNc2cpO1xufTtcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRV9FVkVOVF9CRUdJTiA9IChleHRyYU1zZz86IHN0cmluZykgPT4ge1xuICBpZiAodHlwZW9mIGVudi50cmFjZSA9PT0gJ3VuZGVmaW5lZCcgPyAhZW52Lndhc20udHJhY2UgOiAhZW52LnRyYWNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gIGNvbnNvbGUudGltZShgT1JUOjoke2V4dHJhTXNnfWApO1xufTtcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRV9FVkVOVF9FTkQgPSAoZXh0cmFNc2c/OiBzdHJpbmcpID0+IHtcbiAgaWYgKHR5cGVvZiBlbnYudHJhY2UgPT09ICd1bmRlZmluZWQnID8gIWVudi53YXNtLnRyYWNlIDogIWVudi50cmFjZSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLnRpbWVFbmQoYE9SVDo6JHtleHRyYU1zZ31gKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IHJlc29sdmVCYWNrZW5kQW5kRXhlY3V0aW9uUHJvdmlkZXJzIH0gZnJvbSAnLi9iYWNrZW5kLWltcGwuanMnO1xuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL2JhY2tlbmQuanMnO1xuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiBhcyBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlIH0gZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5pbXBvcnQgeyBPbm54VmFsdWUgfSBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuaW1wb3J0IHsgVFJBQ0VfRlVOQ19CRUdJTiwgVFJBQ0VfRlVOQ19FTkQsIFRSQUNFX0VWRU5UX0JFR0lOLCBUUkFDRV9FVkVOVF9FTkQgfSBmcm9tICcuL3RyYWNlLmpzJztcblxudHlwZSBTZXNzaW9uT3B0aW9ucyA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuU2Vzc2lvbk9wdGlvbnM7XG50eXBlIFJ1bk9wdGlvbnMgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlJ1bk9wdGlvbnM7XG50eXBlIEZlZWRzVHlwZSA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuRmVlZHNUeXBlO1xudHlwZSBGZXRjaGVzVHlwZSA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuRmV0Y2hlc1R5cGU7XG50eXBlIFJldHVyblR5cGUgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlJldHVyblR5cGU7XG5cbmV4cG9ydCBjbGFzcyBJbmZlcmVuY2VTZXNzaW9uIGltcGxlbWVudHMgSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZSB7XG4gIHByaXZhdGUgY29uc3RydWN0b3IoaGFuZGxlcjogSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIpIHtcbiAgICB0aGlzLmhhbmRsZXIgPSBoYW5kbGVyO1xuICB9XG4gIHJ1bihmZWVkczogRmVlZHNUeXBlLCBvcHRpb25zPzogUnVuT3B0aW9ucyk6IFByb21pc2U8UmV0dXJuVHlwZT47XG4gIHJ1bihmZWVkczogRmVlZHNUeXBlLCBmZXRjaGVzOiBGZXRjaGVzVHlwZSwgb3B0aW9ucz86IFJ1bk9wdGlvbnMpOiBQcm9taXNlPFJldHVyblR5cGU+O1xuICBhc3luYyBydW4oZmVlZHM6IEZlZWRzVHlwZSwgYXJnMT86IEZldGNoZXNUeXBlIHwgUnVuT3B0aW9ucywgYXJnMj86IFJ1bk9wdGlvbnMpOiBQcm9taXNlPFJldHVyblR5cGU+IHtcbiAgICBUUkFDRV9GVU5DX0JFR0lOKCk7XG4gICAgVFJBQ0VfRVZFTlRfQkVHSU4oJ0luZmVyZW5jZVNlc3Npb24ucnVuJyk7XG4gICAgY29uc3QgZmV0Y2hlczogeyBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIHwgbnVsbCB9ID0ge307XG4gICAgbGV0IG9wdGlvbnM6IFJ1bk9wdGlvbnMgPSB7fTtcbiAgICAvLyBjaGVjayBpbnB1dHNcbiAgICBpZiAodHlwZW9mIGZlZWRzICE9PSAnb2JqZWN0JyB8fCBmZWVkcyA9PT0gbnVsbCB8fCBmZWVkcyBpbnN0YW5jZW9mIFRlbnNvciB8fCBBcnJheS5pc0FycmF5KGZlZWRzKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgXCInZmVlZHMnIG11c3QgYmUgYW4gb2JqZWN0IHRoYXQgdXNlIGlucHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbGV0IGlzRmV0Y2hlc0VtcHR5ID0gdHJ1ZTtcbiAgICAvLyBkZXRlcm1pbmUgd2hpY2ggb3ZlcnJpZGUgaXMgYmVpbmcgdXNlZFxuICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChhcmcxID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1VuZXhwZWN0ZWQgYXJndW1lbnRbMV06IGNhbm5vdCBiZSBudWxsLicpO1xuICAgICAgfVxuICAgICAgaWYgKGFyZzEgaW5zdGFuY2VvZiBUZW5zb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidmZXRjaGVzJyBjYW5ub3QgYmUgYSBUZW5zb3JcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZzEpKSB7XG4gICAgICAgIGlmIChhcmcxLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInZmV0Y2hlcycgY2Fubm90IGJlIGFuIGVtcHR5IGFycmF5LlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpc0ZldGNoZXNFbXB0eSA9IGZhbHNlO1xuICAgICAgICAvLyBvdXRwdXQgbmFtZXNcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIGFyZzEpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ2ZldGNoZXMnIG11c3QgYmUgYSBzdHJpbmcgYXJyYXkgb3IgYW4gb2JqZWN0LlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMub3V0cHV0TmFtZXMuaW5kZXhPZihuYW1lKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnZmV0Y2hlcycgY29udGFpbnMgaW52YWxpZCBvdXRwdXQgbmFtZTogJHtuYW1lfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZmV0Y2hlc1tuYW1lXSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGFyZzIgPT09ICdvYmplY3QnICYmIGFyZzIgIT09IG51bGwpIHtcbiAgICAgICAgICBvcHRpb25zID0gYXJnMjtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZGVjaWRlIHdoZXRoZXIgYXJnMSBpcyBmZXRjaGVzIG9yIG9wdGlvbnNcbiAgICAgICAgLy8gaWYgYW55IG91dHB1dCBuYW1lIGlzIHByZXNlbnQgYW5kIGl0cyB2YWx1ZSBpcyB2YWxpZCBPbm54VmFsdWUsIHdlIGNvbnNpZGVyIGl0IGZldGNoZXNcbiAgICAgICAgbGV0IGlzRmV0Y2hlcyA9IGZhbHNlO1xuICAgICAgICBjb25zdCBhcmcxS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGFyZzEpO1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdGhpcy5vdXRwdXROYW1lcykge1xuICAgICAgICAgIGlmIChhcmcxS2V5cy5pbmRleE9mKG5hbWUpICE9PSAtMSkge1xuICAgICAgICAgICAgY29uc3QgdiA9IChhcmcxIGFzIEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuTnVsbGFibGVPbm54VmFsdWVNYXBUeXBlKVtuYW1lXTtcbiAgICAgICAgICAgIGlmICh2ID09PSBudWxsIHx8IHYgaW5zdGFuY2VvZiBUZW5zb3IpIHtcbiAgICAgICAgICAgICAgaXNGZXRjaGVzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgaXNGZXRjaGVzRW1wdHkgPSBmYWxzZTtcbiAgICAgICAgICAgICAgZmV0Y2hlc1tuYW1lXSA9IHY7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzRmV0Y2hlcykge1xuICAgICAgICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ29iamVjdCcgJiYgYXJnMiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IGFyZzI7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcHRpb25zID0gYXJnMSBhcyBSdW5PcHRpb25zO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmV4cGVjdGVkIGFyZ3VtZW50WzFdOiBtdXN0IGJlICdmZXRjaGVzJyBvciAnb3B0aW9ucycuXCIpO1xuICAgIH1cblxuICAgIC8vIGNoZWNrIGlmIGFsbCBpbnB1dHMgYXJlIGluIGZlZWRcbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdGhpcy5pbnB1dE5hbWVzKSB7XG4gICAgICBpZiAodHlwZW9mIGZlZWRzW25hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0ICcke25hbWV9JyBpcyBtaXNzaW5nIGluICdmZWVkcycuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gaWYgbm8gZmV0Y2hlcyBpcyBzcGVjaWZpZWQsIHdlIHVzZSB0aGUgZnVsbCBvdXRwdXQgbmFtZXMgbGlzdFxuICAgIGlmIChpc0ZldGNoZXNFbXB0eSkge1xuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIHRoaXMub3V0cHV0TmFtZXMpIHtcbiAgICAgICAgZmV0Y2hlc1tuYW1lXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZmVlZHMsIGZldGNoZXMgYW5kIG9wdGlvbnMgYXJlIHByZXBhcmVkXG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5oYW5kbGVyLnJ1bihmZWVkcywgZmV0Y2hlcywgb3B0aW9ucyk7XG4gICAgY29uc3QgcmV0dXJuVmFsdWU6IHsgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB9ID0ge307XG4gICAgZm9yIChjb25zdCBrZXkgaW4gcmVzdWx0cykge1xuICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdHMsIGtleSkpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcmVzdWx0c1trZXldO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgVGVuc29yKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVba2V5XSA9IHJlc3VsdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtrZXldID0gbmV3IFRlbnNvcihyZXN1bHQudHlwZSwgcmVzdWx0LmRhdGEsIHJlc3VsdC5kaW1zKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBUUkFDRV9FVkVOVF9FTkQoJ0luZmVyZW5jZVNlc3Npb24ucnVuJyk7XG4gICAgVFJBQ0VfRlVOQ19FTkQoKTtcbiAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gIH1cblxuICBhc3luYyByZWxlYXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIuZGlzcG9zZSgpO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZShwYXRoOiBzdHJpbmcsIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT47XG4gIHN0YXRpYyBjcmVhdGUoYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT47XG4gIHN0YXRpYyBjcmVhdGUoXG4gICAgYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsXG4gICAgYnl0ZU9mZnNldDogbnVtYmVyLFxuICAgIGJ5dGVMZW5ndGg/OiBudW1iZXIsXG4gICAgb3B0aW9ucz86IFNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2U+O1xuICBzdGF0aWMgY3JlYXRlKGJ1ZmZlcjogVWludDhBcnJheSwgb3B0aW9ucz86IFNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPjtcbiAgc3RhdGljIGFzeW5jIGNyZWF0ZShcbiAgICBhcmcwOiBzdHJpbmcgfCBBcnJheUJ1ZmZlckxpa2UgfCBVaW50OEFycmF5LFxuICAgIGFyZzE/OiBTZXNzaW9uT3B0aW9ucyB8IG51bWJlcixcbiAgICBhcmcyPzogbnVtYmVyLFxuICAgIGFyZzM/OiBTZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPiB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTigpO1xuICAgIFRSQUNFX0VWRU5UX0JFR0lOKCdJbmZlcmVuY2VTZXNzaW9uLmNyZWF0ZScpO1xuICAgIC8vIGVpdGhlciBsb2FkIGZyb20gYSBmaWxlIG9yIGJ1ZmZlclxuICAgIGxldCBmaWxlUGF0aE9yVWludDhBcnJheTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgICBsZXQgb3B0aW9uczogU2Vzc2lvbk9wdGlvbnMgPSB7fTtcblxuICAgIGlmICh0eXBlb2YgYXJnMCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGZpbGVQYXRoT3JVaW50OEFycmF5ID0gYXJnMDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYXJnMCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIGZpbGVQYXRoT3JVaW50OEFycmF5ID0gYXJnMDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICBhcmcwIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHxcbiAgICAgICh0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIGFyZzAgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcilcbiAgICApIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IGFyZzA7XG4gICAgICBsZXQgYnl0ZU9mZnNldCA9IDA7XG4gICAgICBsZXQgYnl0ZUxlbmd0aCA9IGFyZzAuYnl0ZUxlbmd0aDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGJ5dGVPZmZzZXQgPSBhcmcxO1xuICAgICAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGJ5dGVPZmZzZXQpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInYnl0ZU9mZnNldCcgbXVzdCBiZSBhbiBpbnRlZ2VyLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYnl0ZU9mZnNldCA+PSBidWZmZXIuYnl0ZUxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnYnl0ZU9mZnNldCcgaXMgb3V0IG9mIHJhbmdlIFswLCAke2J1ZmZlci5ieXRlTGVuZ3RofSkuYCk7XG4gICAgICAgIH1cbiAgICAgICAgYnl0ZUxlbmd0aCA9IGFyZzAuYnl0ZUxlbmd0aCAtIGJ5dGVPZmZzZXQ7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBieXRlTGVuZ3RoID0gYXJnMjtcbiAgICAgICAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGJ5dGVMZW5ndGgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIidieXRlTGVuZ3RoJyBtdXN0IGJlIGFuIGludGVnZXIuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYnl0ZUxlbmd0aCA8PSAwIHx8IGJ5dGVPZmZzZXQgKyBieXRlTGVuZ3RoID4gYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnYnl0ZUxlbmd0aCcgaXMgb3V0IG9mIHJhbmdlICgwLCAke2J1ZmZlci5ieXRlTGVuZ3RoIC0gYnl0ZU9mZnNldH1dLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIGFyZzMgPT09ICdvYmplY3QnICYmIGFyZzMgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBhcmczO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidieXRlTGVuZ3RoJyBtdXN0IGJlIGEgbnVtYmVyLlwiKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidvcHRpb25zJyBtdXN0IGJlIGFuIG9iamVjdC5cIik7XG4gICAgICB9XG4gICAgICBmaWxlUGF0aE9yVWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmV4cGVjdGVkIGFyZ3VtZW50WzBdOiBtdXN0IGJlICdwYXRoJyBvciAnYnVmZmVyJy5cIik7XG4gICAgfVxuXG4gICAgLy8gcmVzb2x2ZSBiYWNrZW5kLCB1cGRhdGUgc2Vzc2lvbiBvcHRpb25zIHdpdGggdmFsaWRhdGVkIEVQcywgYW5kIGNyZWF0ZSBzZXNzaW9uIGhhbmRsZXJcbiAgICBjb25zdCBbYmFja2VuZCwgb3B0aW9uc1dpdGhWYWxpZGF0ZWRFUHNdID0gYXdhaXQgcmVzb2x2ZUJhY2tlbmRBbmRFeGVjdXRpb25Qcm92aWRlcnMob3B0aW9ucyk7XG4gICAgY29uc3QgaGFuZGxlciA9IGF3YWl0IGJhY2tlbmQuY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoZmlsZVBhdGhPclVpbnQ4QXJyYXksIG9wdGlvbnNXaXRoVmFsaWRhdGVkRVBzKTtcbiAgICBUUkFDRV9FVkVOVF9FTkQoJ0luZmVyZW5jZVNlc3Npb24uY3JlYXRlJyk7XG4gICAgVFJBQ0VfRlVOQ19FTkQoKTtcbiAgICByZXR1cm4gbmV3IEluZmVyZW5jZVNlc3Npb24oaGFuZGxlcik7XG4gIH1cblxuICBzdGFydFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLmhhbmRsZXIuc3RhcnRQcm9maWxpbmcoKTtcbiAgfVxuICBlbmRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5oYW5kbGVyLmVuZFByb2ZpbGluZygpO1xuICB9XG5cbiAgZ2V0IGlucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIuaW5wdXROYW1lcztcbiAgfVxuICBnZXQgb3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIub3V0cHV0TmFtZXM7XG4gIH1cblxuICBnZXQgaW5wdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5pbnB1dE1ldGFkYXRhO1xuICB9XG5cbiAgZ2V0IG91dHB1dE1ldGFkYXRhKCk6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuVmFsdWVNZXRhZGF0YVtdIHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVyLm91dHB1dE1ldGFkYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVyOiBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcjtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiBhcyBJbmZlcmVuY2VTZXNzaW9uSW1wbCB9IGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24taW1wbC5qcyc7XG5pbXBvcnQgeyBPbm54TW9kZWxPcHRpb25zIH0gZnJvbSAnLi9vbm54LW1vZGVsLmpzJztcbmltcG9ydCB7IE9ubnhWYWx1ZSwgT25ueFZhbHVlRGF0YUxvY2F0aW9uIH0gZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcbmltcG9ydCB0eXBlIHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuaW1wb3J0IHsgVHJ5R2V0R2xvYmFsVHlwZSB9IGZyb20gJy4vdHlwZS1oZWxwZXIuanMnO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlICovXG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgLy8gI3JlZ2lvbiBpbnB1dC9vdXRwdXQgdHlwZXNcblxuICB0eXBlIE9ubnhWYWx1ZU1hcFR5cGUgPSB7IHJlYWRvbmx5IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfTtcbiAgdHlwZSBOdWxsYWJsZU9ubnhWYWx1ZU1hcFR5cGUgPSB7IHJlYWRvbmx5IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfCBudWxsIH07XG5cbiAgLyoqXG4gICAqIEEgZmVlZHMgKG1vZGVsIGlucHV0cykgaXMgYW4gb2JqZWN0IHRoYXQgdXNlcyBpbnB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAqL1xuICB0eXBlIEZlZWRzVHlwZSA9IE9ubnhWYWx1ZU1hcFR5cGU7XG5cbiAgLyoqXG4gICAqIEEgZmV0Y2hlcyAobW9kZWwgb3V0cHV0cykgY291bGQgYmUgb25lIG9mIHRoZSBmb2xsb3dpbmc6XG4gICAqXG4gICAqIC0gT21pdHRlZC4gVXNlIG1vZGVsJ3Mgb3V0cHV0IG5hbWVzIGRlZmluaXRpb24uXG4gICAqIC0gQW4gYXJyYXkgb2Ygc3RyaW5nIGluZGljYXRpbmcgdGhlIG91dHB1dCBuYW1lcy5cbiAgICogLSBBbiBvYmplY3QgdGhhdCB1c2Ugb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBvciBudWxsIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcmVtYXJrc1xuICAgKiBkaWZmZXJlbnQgZnJvbSBpbnB1dCBhcmd1bWVudCwgaW4gb3V0cHV0LCBPbm54VmFsdWUgaXMgb3B0aW9uYWwuIElmIGFuIE9ubnhWYWx1ZSBpcyBwcmVzZW50IGl0IHdpbGwgYmVcbiAgICogdXNlZCBhcyBhIHByZS1hbGxvY2F0ZWQgdmFsdWUgYnkgdGhlIGluZmVyZW5jZSBlbmdpbmU7IGlmIG9taXR0ZWQsIGluZmVyZW5jZSBlbmdpbmUgd2lsbCBhbGxvY2F0ZSBidWZmZXJcbiAgICogaW50ZXJuYWxseS5cbiAgICovXG4gIHR5cGUgRmV0Y2hlc1R5cGUgPSByZWFkb25seSBzdHJpbmdbXSB8IE51bGxhYmxlT25ueFZhbHVlTWFwVHlwZTtcblxuICAvKipcbiAgICogQSBpbmZlcmVuY2luZyByZXR1cm4gdHlwZSBpcyBhbiBvYmplY3QgdGhhdCB1c2VzIG91dHB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAqL1xuICB0eXBlIFJldHVyblR5cGUgPSBPbm54VmFsdWVNYXBUeXBlO1xuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHNlc3Npb24gb3B0aW9uc1xuXG4gIC8qKlxuICAgKiBBIHNldCBvZiBjb25maWd1cmF0aW9ucyBmb3Igc2Vzc2lvbiBiZWhhdmlvci5cbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvbk9wdGlvbnMgZXh0ZW5kcyBPbm54TW9kZWxPcHRpb25zIHtcbiAgICAvKipcbiAgICAgKiBBbiBhcnJheSBvZiBleGVjdXRpb24gcHJvdmlkZXIgb3B0aW9ucy5cbiAgICAgKlxuICAgICAqIEFuIGV4ZWN1dGlvbiBwcm92aWRlciBvcHRpb24gY2FuIGJlIGEgc3RyaW5nIGluZGljYXRpbmcgdGhlIG5hbWUgb2YgdGhlIGV4ZWN1dGlvbiBwcm92aWRlcixcbiAgICAgKiBvciBhbiBvYmplY3Qgb2YgY29ycmVzcG9uZGluZyB0eXBlLlxuICAgICAqL1xuICAgIGV4ZWN1dGlvblByb3ZpZGVycz86IHJlYWRvbmx5IEV4ZWN1dGlvblByb3ZpZGVyQ29uZmlnW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaW50cmEgT1AgdGhyZWFkcyBudW1iZXIuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKS5cbiAgICAgKi9cbiAgICBpbnRyYU9wTnVtVGhyZWFkcz86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBpbnRlciBPUCB0aHJlYWRzIG51bWJlci5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIGludGVyT3BOdW1UaHJlYWRzPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGZyZWUgZGltZW5zaW9uIG92ZXJyaWRlLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGZyZWVEaW1lbnNpb25PdmVycmlkZXM/OiB7IHJlYWRvbmx5IFtkaW1lbnNpb25OYW1lOiBzdHJpbmddOiBudW1iZXIgfTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHRpbWl6YXRpb24gbGV2ZWwuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZ3JhcGhPcHRpbWl6YXRpb25MZXZlbD86ICdkaXNhYmxlZCcgfCAnYmFzaWMnIHwgJ2V4dGVuZGVkJyB8ICdsYXlvdXQnIHwgJ2FsbCc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIGVuYWJsZSBDUFUgbWVtb3J5IGFyZW5hLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGVuYWJsZUNwdU1lbUFyZW5hPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZW5hYmxlIG1lbW9yeSBwYXR0ZXJuLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGVuYWJsZU1lbVBhdHRlcm4/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogRXhlY3V0aW9uIG1vZGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZXhlY3V0aW9uTW9kZT86ICdzZXF1ZW50aWFsJyB8ICdwYXJhbGxlbCc7XG5cbiAgICAvKipcbiAgICAgKiBPcHRpbWl6ZWQgbW9kZWwgZmlsZSBwYXRoLlxuICAgICAqXG4gICAgICogSWYgdGhpcyBzZXR0aW5nIGlzIHNwZWNpZmllZCwgdGhlIG9wdGltaXplZCBtb2RlbCB3aWxsIGJlIGR1bXBlZC4gSW4gYnJvd3NlciwgYSBibG9iIHdpbGwgYmUgY3JlYXRlZFxuICAgICAqIHdpdGggYSBwb3AtdXAgd2luZG93LlxuICAgICAqL1xuICAgIG9wdGltaXplZE1vZGVsRmlsZVBhdGg/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIGVuYWJsZSBwcm9maWxpbmcuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYSBwbGFjZWhvbGRlciBmb3IgYSBmdXR1cmUgdXNlLlxuICAgICAqL1xuICAgIGVuYWJsZVByb2ZpbGluZz86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBGaWxlIHByZWZpeCBmb3IgcHJvZmlsaW5nLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGEgZnV0dXJlIHVzZS5cbiAgICAgKi9cbiAgICBwcm9maWxlRmlsZVByZWZpeD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIExvZyBJRC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBsb2dJZD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIExvZyBzZXZlcml0eSBsZXZlbC4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL2NvbW1vbi9sb2dnaW5nL3NldmVyaXR5LmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBsb2dTZXZlcml0eUxldmVsPzogMCB8IDEgfCAyIHwgMyB8IDQ7XG5cbiAgICAvKipcbiAgICAgKiBMb2cgdmVyYm9zaXR5IGxldmVsLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqL1xuICAgIGxvZ1ZlcmJvc2l0eUxldmVsPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBzdHJpbmcgYXMgYSBwcmVmZXJyZWQgZGF0YSBsb2NhdGlvbiBmb3IgYWxsIG91dHB1dHMsIG9yIGFuIG9iamVjdCB0aGF0IHVzZSBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgYVxuICAgICAqIHByZWZlcnJlZCBkYXRhIGxvY2F0aW9uIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIFdlYiBmb3IgV2ViR0wgYW5kIFdlYkdQVSBFUC5cbiAgICAgKi9cbiAgICBwcmVmZXJyZWRPdXRwdXRMb2NhdGlvbj86IE9ubnhWYWx1ZURhdGFMb2NhdGlvbiB8IHsgcmVhZG9ubHkgW291dHB1dE5hbWU6IHN0cmluZ106IE9ubnhWYWx1ZURhdGFMb2NhdGlvbiB9O1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBlbmFibGUgZ3JhcGggY2FwdHVyZS5cbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgV2ViIGZvciBXZWJHUFUgRVAuXG4gICAgICovXG4gICAgZW5hYmxlR3JhcGhDYXB0dXJlPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFN0b3JlIGNvbmZpZ3VyYXRpb25zIGZvciBhIHNlc3Npb24uIFNlZVxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueHJ1bnRpbWUvYmxvYi9tYWluL2luY2x1ZGUvb25ueHJ1bnRpbWUvY29yZS9zZXNzaW9uL1xuICAgICAqIG9ubnhydW50aW1lX3Nlc3Npb25fb3B0aW9uc19jb25maWdfa2V5cy5oXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZXh0cmE6IHtcbiAgICAgKiAgIHNlc3Npb246IHtcbiAgICAgKiAgICAgc2V0X2Rlbm9ybWFsX2FzX3plcm86IFwiMVwiLFxuICAgICAqICAgICBkaXNhYmxlX3ByZXBhY2tpbmc6IFwiMVwiXG4gICAgICogICB9LFxuICAgICAqICAgb3B0aW1pemF0aW9uOiB7XG4gICAgICogICAgIGVuYWJsZV9nZWx1X2FwcHJveGltYXRpb246IFwiMVwiXG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGV4dHJhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIH1cblxuICAvLyAjcmVnaW9uIGV4ZWN1dGlvbiBwcm92aWRlcnNcblxuICAvLyBDdXJyZW50bHksIHdlIGhhdmUgdGhlIGZvbGxvd2luZyBiYWNrZW5kcyB0byBzdXBwb3J0IGV4ZWN1dGlvbiBwcm92aWRlcnM6XG4gIC8vIEJhY2tlbmQgTm9kZS5qcyBiaW5kaW5nOiBzdXBwb3J0cyAnY3B1JywgJ2RtbCcgKHdpbjMyKSwgJ2NvcmVtbCcgKG1hY09TKSBhbmQgJ2N1ZGEnIChsaW51eCkuXG4gIC8vIEJhY2tlbmQgV2ViQXNzZW1ibHk6IHN1cHBvcnRzICdjcHUnLCAnd2FzbScsICd3ZWJncHUnIGFuZCAnd2Vibm4nLlxuICAvLyBCYWNrZW5kIE9OTlguanM6IHN1cHBvcnRzICd3ZWJnbCcuXG4gIC8vIEJhY2tlbmQgUmVhY3QgTmF0aXZlOiBzdXBwb3J0cyAnY3B1JywgJ3hubnBhY2snLCAnY29yZW1sJyAoaU9TKSwgJ25uYXBpJyAoQW5kcm9pZCkuXG4gIGludGVyZmFjZSBFeGVjdXRpb25Qcm92aWRlck9wdGlvbk1hcCB7XG4gICAgY29yZW1sOiBDb3JlTUxFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBjcHU6IENwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIGN1ZGE6IEN1ZGFFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBkbWw6IERtbEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIG5uYXBpOiBObmFwaUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHRlbnNvcnJ0OiBUZW5zb3JSdEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHdhc206IFdlYkFzc2VtYmx5RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgd2ViZ2w6IFdlYkdMRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgd2ViZ3B1OiBXZWJHcHVFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICB3ZWJubjogV2ViTk5FeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBxbm46IFFubkV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHhubnBhY2s6IFhubnBhY2tFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgfVxuXG4gIHR5cGUgRXhlY3V0aW9uUHJvdmlkZXJOYW1lID0ga2V5b2YgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25NYXA7XG4gIHR5cGUgRXhlY3V0aW9uUHJvdmlkZXJDb25maWcgPVxuICAgIHwgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25NYXBbRXhlY3V0aW9uUHJvdmlkZXJOYW1lXVxuICAgIHwgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25cbiAgICB8IEV4ZWN1dGlvblByb3ZpZGVyTmFtZVxuICAgIHwgc3RyaW5nO1xuXG4gIGV4cG9ydCBpbnRlcmZhY2UgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIENwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdjcHUnO1xuICAgIHVzZUFyZW5hPzogYm9vbGVhbjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIEN1ZGFFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnY3VkYSc7XG4gICAgZGV2aWNlSWQ/OiBudW1iZXI7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBEbWxFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnZG1sJztcbiAgICBkZXZpY2VJZD86IG51bWJlcjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFRlbnNvclJ0RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3RlbnNvcnJ0JztcbiAgICBkZXZpY2VJZD86IG51bWJlcjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkFzc2VtYmx5RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3dhc20nO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR0xFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnd2ViZ2wnO1xuICAgIC8vIFRPRE86IGFkZCBmbGFnc1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgWG5ucGFja0V4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd4bm5wYWNrJztcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd3ZWJncHUnO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgcHJlZmVycmVkIGxheW91dCB3aGVuIHJ1bm5pbmcgbGF5b3V0IHNlbnNpdGl2ZSBvcGVyYXRvcnMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAnTkNIVydcbiAgICAgKi9cbiAgICBwcmVmZXJyZWRMYXlvdXQ/OiAnTkNIVycgfCAnTkhXQyc7XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IGEgbGlzdCBvZiBub2RlIG5hbWVzIHRoYXQgc2hvdWxkIGJlIGV4ZWN1dGVkIG9uIENQVSBldmVuIHdoZW4gV2ViR1BVIEVQIGlzIHVzZWQuXG4gICAgICovXG4gICAgZm9yY2VDcHVOb2RlTmFtZXM/OiByZWFkb25seSBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIHZhbGlkYXRpb24gbW9kZSBmb3IgV2ViR1BVIGV4ZWN1dGlvbiBwcm92aWRlci5cbiAgICAgKiAtICdkaXNhYmxlZCc6IERpc2FibGUgYWxsIHZhbGlkYXRpb24uXG4gICAgICogV2hlbiB1c2VkIGluIE5vZGUuanMsIGRpc2FibGUgdmFsaWRhdGlvbiBtYXkgY2F1c2UgcHJvY2VzcyBjcmFzaCBpZiBXZWJHUFUgZXJyb3JzIG9jY3VyLiBCZSBjYXV0aW91cyB3aGVuIHVzaW5nXG4gICAgICogdGhpcyBtb2RlLlxuICAgICAqIFdoZW4gdXNlZCBpbiB3ZWIsIHRoaXMgbW9kZSBpcyBlcXVpdmFsZW50IHRvICd3Z3B1T25seScuXG4gICAgICogLSAnd2dwdU9ubHknOiBQZXJmb3JtIFdlYkdQVSBpbnRlcm5hbCB2YWxpZGF0aW9uIG9ubHkuXG4gICAgICogLSAnYmFzaWMnOiBQZXJmb3JtIGJhc2ljIHZhbGlkYXRpb24gaW5jbHVkaW5nIFdlYkdQVSBpbnRlcm5hbCB2YWxpZGF0aW9uLiBUaGlzIGlzIHRoZSBkZWZhdWx0IG1vZGUuXG4gICAgICogLSAnZnVsbCc6IFBlcmZvcm0gZnVsbCB2YWxpZGF0aW9uLiBUaGlzIG1vZGUgbWF5IGhhdmUgcGVyZm9ybWFuY2UgaW1wYWN0LiBVc2UgaXQgZm9yIGRlYnVnZ2luZyBwdXJwb3NlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgJ2Jhc2ljJ1xuICAgICAqL1xuICAgIHZhbGlkYXRpb25Nb2RlPzogJ2Rpc2FibGVkJyB8ICd3Z3B1T25seScgfCAnYmFzaWMnIHwgJ2Z1bGwnO1xuXG4gICAgLyoqXG4gICAgICogRW5hYmxlIHJvYnVzdCBidWZmZXIgYWNjZXNzIGZvciBhbiBPUlQtY3JlYXRlZCBEYXduIGRldmljZS4gVGhpcyBpcyBhIGdsb2JhbCwgZmlyc3QtZGV2aWNlLXdpbnMgb3B0aW9uLiBMYXRlclxuICAgICAqIGNvbmZsaWN0aW5nIHZhbHVlcyBhbmQgdmFsdWVzIHN1cHBsaWVkIHdpdGggYW4gZXh0ZXJuYWwgZGV2aWNlIGFyZSBpZ25vcmVkIHdpdGggYSB3YXJuaW5nLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlggUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nKS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IGB0cnVlYCBpbiBEZWJ1ZyBidWlsZHM7IGBmYWxzZWAgaW4gUmVsZWFzZSBhbmQgUmVsV2l0aERlYkluZm8gYnVpbGRzXG4gICAgICovXG4gICAgZW5hYmxlUm9idXN0bmVzcz86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBjYWNoZSBtb2RlIGZvciBzdG9yYWdlIGJ1ZmZlcnMuXG4gICAgICogLSAnZGlzYWJsZWQnOiBEaXNhYmxlIGJ1ZmZlciBjYWNoZS4gQnVmZmVycyBhcmUgZGVzdHJveWVkIHdoZW4gbm8gbG9uZ2VyIGluIHVzZS5cbiAgICAgKiAtICdsYXp5UmVsZWFzZSc6IEJ1ZmZlcnMgYXJlIHJlbGVhc2VkIGxhemlseSwgYXQgdGhlIGVuZCBvZiB0aGUgY3VycmVudCBydW4uXG4gICAgICogLSAnc2ltcGxlJzogUmVsZWFzZWQgYnVmZmVycyBhcmUgY2FjaGVkIGFuZCByZXVzZWQgb25seSBmb3IgcmVxdWVzdHMgb2YgdGhlIGV4YWN0IHNhbWUgc2l6ZS5cbiAgICAgKiAtICdidWNrZXQnOiBSZWxlYXNlZCBidWZmZXJzIGFyZSBjYWNoZWQgYW5kIHJldXNlZCB1c2luZyBwcmVkZWZpbmVkIHNpemUgYnVja2V0cy4gVGhpcyBpcyB0aGUgZGVmYXVsdCBtb2RlLlxuICAgICAqXG4gICAgICogRm9yIHN0YXRpYy1zaGFwZSBtb2RlbHMsICdzaW1wbGUnIG1heSByZWR1Y2UgR1BVIG1lbW9yeSB1c2FnZSwgYmVjYXVzZSBleGFjdC1zaXplIGJ1ZmZlcnMgYXJlIHJldXNlZCBhY3Jvc3NcbiAgICAgKiBydW5zIGluc3RlYWQgb2YgYWxsb2NhdGluZyBuZXcgYnVja2V0LXNpemVkIGJ1ZmZlcnMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAnYnVja2V0J1xuICAgICAqL1xuICAgIHN0b3JhZ2VCdWZmZXJDYWNoZU1vZGU/OiAnZGlzYWJsZWQnIHwgJ2xhenlSZWxlYXNlJyB8ICdzaW1wbGUnIHwgJ2J1Y2tldCc7XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBjYWNoZSBtb2RlIGZvciB1bmlmb3JtIGJ1ZmZlcnMuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIHN0b3JhZ2VCdWZmZXJDYWNoZU1vZGV9IGZvciBhIGRlc2NyaXB0aW9uIG9mIHRoZSBhdmFpbGFibGUgbW9kZXMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAnc2ltcGxlJ1xuICAgICAqL1xuICAgIHVuaWZvcm1CdWZmZXJDYWNoZU1vZGU/OiAnZGlzYWJsZWQnIHwgJ2xhenlSZWxlYXNlJyB8ICdzaW1wbGUnIHwgJ2J1Y2tldCc7XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBjYWNoZSBtb2RlIGZvciBxdWVyeSByZXNvbHZlIGJ1ZmZlcnMuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIHN0b3JhZ2VCdWZmZXJDYWNoZU1vZGV9IGZvciBhIGRlc2NyaXB0aW9uIG9mIHRoZSBhdmFpbGFibGUgbW9kZXMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAnZGlzYWJsZWQnXG4gICAgICovXG4gICAgcXVlcnlSZXNvbHZlQnVmZmVyQ2FjaGVNb2RlPzogJ2Rpc2FibGVkJyB8ICdsYXp5UmVsZWFzZScgfCAnc2ltcGxlJyB8ICdidWNrZXQnO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgY2FjaGUgbW9kZSBmb3IgYnVmZmVycyBub3QgY292ZXJlZCBieSB0aGUgb3RoZXIgYnVmZmVyIGNhY2hlIG1vZGUgb3B0aW9ucy5cbiAgICAgKlxuICAgICAqIFNlZSB7QGxpbmsgc3RvcmFnZUJ1ZmZlckNhY2hlTW9kZX0gZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhlIGF2YWlsYWJsZSBtb2Rlcy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0ICdkaXNhYmxlZCdcbiAgICAgKi9cbiAgICBkZWZhdWx0QnVmZmVyQ2FjaGVNb2RlPzogJ2Rpc2FibGVkJyB8ICdsYXp5UmVsZWFzZScgfCAnc2ltcGxlJyB8ICdidWNrZXQnO1xuXG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBhbiBvcHRpb25hbCBXZWJHUFUgZGV2aWNlIHRvIGJlIHVzZWQgYnkgdGhlIFdlYkdQVSBleGVjdXRpb24gcHJvdmlkZXIuXG4gICAgICovXG4gICAgZGV2aWNlPzogVHJ5R2V0R2xvYmFsVHlwZTwnR1BVRGV2aWNlJz47XG4gIH1cblxuICAvLyAjcmVnaW9uIFdlYk5OIG9wdGlvbnNcblxuICBpbnRlcmZhY2UgV2ViTk5FeGVjdXRpb25Qcm92aWRlck5hbWUgZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3dlYm5uJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIGEgc2V0IG9mIG9wdGlvbnMgZm9yIGNyZWF0aW5nIGEgV2ViTk4gTUxDb250ZXh0LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi93ZWJubi8jZGljdGRlZi1tbGNvbnRleHRvcHRpb25zXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFdlYk5OQ29udGV4dE9wdGlvbnMge1xuICAgIGRldmljZVR5cGU/OiAnY3B1JyB8ICdncHUnIHwgJ25wdSc7XG4gICAgbnVtVGhyZWFkcz86IG51bWJlcjtcbiAgICBwb3dlclByZWZlcmVuY2U/OiAnZGVmYXVsdCcgfCAnbG93LXBvd2VyJyB8ICdoaWdoLXBlcmZvcm1hbmNlJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIGEgc2V0IG9mIG9wdGlvbnMgZm9yIFdlYk5OIGV4ZWN1dGlvbiBwcm92aWRlciB3aXRob3V0IE1MQ29udGV4dC5cbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViTk5PcHRpb25zV2l0aG91dE1MQ29udGV4dCBleHRlbmRzIFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJOYW1lLCBXZWJOTkNvbnRleHRPcHRpb25zIHtcbiAgICBjb250ZXh0PzogbmV2ZXI7XG4gIH1cblxuICAvKipcbiAgICogUmVwcmVzZW50cyBhIHNldCBvZiBvcHRpb25zIGZvciBXZWJOTiBleGVjdXRpb24gcHJvdmlkZXIgd2l0aCBNTENvbnRleHQuXG4gICAqXG4gICAqIFdoZW4gTUxDb250ZXh0IGlzIHByb3ZpZGVkLCB0aGUgZGV2aWNlVHlwZSBpcyBhbHNvIHJlcXVpcmVkIHNvIHRoYXQgdGhlIFdlYk5OIEVQIGNhbiBkZXRlcm1pbmUgdGhlIHByZWZlcnJlZFxuICAgKiBjaGFubmVsIGxheW91dC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvd2Vibm4vI2RvbS1tbC1jcmVhdGVjb250ZXh0XG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFdlYk5OT3B0aW9uc1dpdGhNTENvbnRleHRcbiAgICBleHRlbmRzXG4gICAgICBXZWJOTkV4ZWN1dGlvblByb3ZpZGVyTmFtZSxcbiAgICAgIE9taXQ8V2ViTk5Db250ZXh0T3B0aW9ucywgJ2RldmljZVR5cGUnPixcbiAgICAgIFJlcXVpcmVkPFBpY2s8V2ViTk5Db250ZXh0T3B0aW9ucywgJ2RldmljZVR5cGUnPj4ge1xuICAgIGNvbnRleHQ6IFRyeUdldEdsb2JhbFR5cGU8J01MQ29udGV4dCc+O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgYSBzZXQgb2Ygb3B0aW9ucyBmb3IgV2ViTk4gZXhlY3V0aW9uIHByb3ZpZGVyIHdpdGggTUxDb250ZXh0IHdoaWNoIGlzIGNyZWF0ZWQgZnJvbSBHUFVEZXZpY2UuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSL3dlYm5uLyNkb20tbWwtY3JlYXRlY29udGV4dC1ncHVkZXZpY2VcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViTk5PcHRpb25zV2ViR3B1IGV4dGVuZHMgV2ViTk5FeGVjdXRpb25Qcm92aWRlck5hbWUge1xuICAgIGNvbnRleHQ6IFRyeUdldEdsb2JhbFR5cGU8J01MQ29udGV4dCc+O1xuICAgIGdwdURldmljZTogVHJ5R2V0R2xvYmFsVHlwZTwnR1BVRGV2aWNlJz47XG4gIH1cblxuICAvKipcbiAgICogT3B0aW9ucyBmb3IgV2ViTk4gZXhlY3V0aW9uIHByb3ZpZGVyLlxuICAgKi9cbiAgZXhwb3J0IHR5cGUgV2ViTk5FeGVjdXRpb25Qcm92aWRlck9wdGlvbiA9XG4gICAgfCBXZWJOTk9wdGlvbnNXaXRob3V0TUxDb250ZXh0XG4gICAgfCBXZWJOTk9wdGlvbnNXaXRoTUxDb250ZXh0XG4gICAgfCBXZWJOTk9wdGlvbnNXZWJHcHU7XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgUW5uRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3Fubic7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgUU5OIGJhY2tlbmQgdHlwZS4gRS5nLiwgJ2NwdScgb3IgJ2h0cCcuXG4gICAgICogTXV0dWFsbHkgZXhjbHVzaXZlIHdpdGggYGJhY2tlbmRQYXRoYC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0ICdodHAnXG4gICAgICovXG4gICAgYmFja2VuZFR5cGU/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBhIHBhdGggdG8gdGhlIFFOTiBiYWNrZW5kIGxpYnJhcnkuXG4gICAgICogTXV0dWFsbHkgZXhjbHVzaXZlIHdpdGggYGJhY2tlbmRUeXBlYC5cbiAgICAgKi9cbiAgICBiYWNrZW5kUGF0aD86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHdoZXRoZXIgdG8gZW5hYmxlIEhUUCBGUDE2IHByZWNpc2lvbi5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgKi9cbiAgICBlbmFibGVGcDE2UHJlY2lzaW9uPzogYm9vbGVhbjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIENvcmVNTEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdjb3JlbWwnO1xuICAgIC8qKlxuICAgICAqIFRoZSBiaXQgZmxhZ3MgZm9yIENvcmVNTCBleGVjdXRpb24gcHJvdmlkZXIuXG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKiBDT1JFTUxfRkxBR19VU0VfQ1BVX09OTFkgPSAweDAwMVxuICAgICAqIENPUkVNTF9GTEFHX0VOQUJMRV9PTl9TVUJHUkFQSCA9IDB4MDAyXG4gICAgICogQ09SRU1MX0ZMQUdfT05MWV9FTkFCTEVfREVWSUNFX1dJVEhfQU5FID0gMHgwMDRcbiAgICAgKiBDT1JFTUxfRkxBR19PTkxZX0FMTE9XX1NUQVRJQ19JTlBVVF9TSEFQRVMgPSAweDAwOFxuICAgICAqIENPUkVNTF9GTEFHX0NSRUFURV9NTFBST0dSQU0gPSAweDAxMFxuICAgICAqIENPUkVNTF9GTEFHX1VTRV9DUFVfQU5EX0dQVSA9IDB4MDIwXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBTZWUgaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL3Byb3ZpZGVycy9jb3JlbWwvY29yZW1sX3Byb3ZpZGVyX2ZhY3RvcnkuaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogVGhpcyBmbGFnIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcpLlxuICAgICAqL1xuICAgIGNvcmVNbEZsYWdzPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byB1c2UgQ1BVIG9ubHkgaW4gQ29yZU1MIEVQLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChyZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIHVzZUNQVU9ubHk/OiBib29sZWFuO1xuICAgIHVzZUNQVUFuZEdQVT86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB3aGV0aGVyIHRvIGVuYWJsZSBDb3JlTUwgRVAgb24gc3ViZ3JhcGguXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKHJlYWN0LW5hdGl2ZSkuXG4gICAgICovXG4gICAgZW5hYmxlT25TdWJncmFwaD86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB3aGV0aGVyIHRvIG9ubHkgZW5hYmxlIENvcmVNTCBFUCBmb3IgQXBwbGUgZGV2aWNlcyB3aXRoIEFORSAoQXBwbGUgTmV1cmFsIEVuZ2luZSkuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKHJlYWN0LW5hdGl2ZSkuXG4gICAgICovXG4gICAgb25seUVuYWJsZURldmljZVdpdGhBTkU/OiBib29sZWFuO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgTm5hcGlFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnbm5hcGknO1xuICAgIHVzZUZQMTY/OiBib29sZWFuO1xuICAgIHVzZU5DSFc/OiBib29sZWFuO1xuICAgIGNwdURpc2FibGVkPzogYm9vbGVhbjtcbiAgICBjcHVPbmx5PzogYm9vbGVhbjtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcnVuIG9wdGlvbnNcblxuICAvKipcbiAgICogQSBzZXQgb2YgY29uZmlndXJhdGlvbnMgZm9yIGluZmVyZW5jZSBydW4gYmVoYXZpb3JcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgUnVuT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogTG9nIHNldmVyaXR5IGxldmVsLiBTZWVcbiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhydW50aW1lL2Jsb2IvbWFpbi9pbmNsdWRlL29ubnhydW50aW1lL2NvcmUvY29tbW9uL2xvZ2dpbmcvc2V2ZXJpdHkuaFxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGxvZ1NldmVyaXR5TGV2ZWw/OiAwIHwgMSB8IDIgfCAzIHwgNDtcblxuICAgIC8qKlxuICAgICAqIExvZyB2ZXJib3NpdHkgbGV2ZWwuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICovXG4gICAgbG9nVmVyYm9zaXR5TGV2ZWw/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBUZXJtaW5hdGUgYWxsIGluY29tcGxldGUgT3J0UnVuIGNhbGxzIGFzIHNvb24gYXMgcG9zc2libGUgaWYgdHJ1ZVxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqL1xuICAgIHRlcm1pbmF0ZT86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBBIHRhZyBmb3IgdGhlIFJ1bigpIGNhbGxzIHVzaW5nIHRoaXNcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICB0YWc/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYSBzaW5nbGUgcnVuIGNvbmZpZ3VyYXRpb24gZW50cnkuIFNlZVxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueHJ1bnRpbWUvYmxvYi9tYWluL2luY2x1ZGUvb25ueHJ1bnRpbWUvY29yZS9zZXNzaW9uL1xuICAgICAqIG9ubnhydW50aW1lX3J1bl9vcHRpb25zX2NvbmZpZ19rZXlzLmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBXZWJBc3NlbWJseSBiYWNrZW5kLiBXaWxsIHN1cHBvcnQgTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUgbGF0ZXJcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGV4dHJhOiB7XG4gICAgICogICBtZW1vcnk6IHtcbiAgICAgKiAgICAgZW5hYmxlX21lbW9yeV9hcmVuYV9zaHJpbmthZ2U6IFwiMVwiLFxuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBleHRyYT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gdmFsdWUgbWV0YWRhdGFcblxuICAvKipcbiAgICogVGhlIGNvbW1vbiBwYXJ0IG9mIHRoZSB2YWx1ZSBtZXRhZGF0YSB0eXBlIGZvciBib3RoIHRlbnNvciBhbmQgbm9uLXRlbnNvciB2YWx1ZXMuXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFZhbHVlTWV0YWRhdGFCYXNlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgc3BlY2lmaWVkIGlucHV0IG9yIG91dHB1dC5cbiAgICAgKi9cbiAgICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIH1cblxuICAvKipcbiAgICogUmVwcmVzZW50cyB0aGUgbWV0YWRhdGEgb2YgYSBub24tdGVuc29yIHZhbHVlLlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBOb25UZW5zb3JWYWx1ZU1ldGFkYXRhIGV4dGVuZHMgVmFsdWVNZXRhZGF0YUJhc2Uge1xuICAgIC8qKlxuICAgICAqIEdldCBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGUgdmFsdWUgaXMgYSB0ZW5zb3IuXG4gICAgICovXG4gICAgcmVhZG9ubHkgaXNUZW5zb3I6IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIG1ldGFkYXRhIG9mIGEgdGVuc29yIHZhbHVlLlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBUZW5zb3JWYWx1ZU1ldGFkYXRhIGV4dGVuZHMgVmFsdWVNZXRhZGF0YUJhc2Uge1xuICAgIC8qKlxuICAgICAqIEdldCBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGUgdmFsdWUgaXMgYSB0ZW5zb3IuXG4gICAgICovXG4gICAgcmVhZG9ubHkgaXNUZW5zb3I6IHRydWU7XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICAgKi9cbiAgICByZWFkb25seSB0eXBlOiBUZW5zb3IuVHlwZTtcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHNoYXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgc2hhcGUgaXMgbm90IGRlZmluZWQsIHRoZSB2YWx1ZSB3aWxsIGFuIGVtcHR5IGFycmF5LiBPdGhlcndpc2UsIGl0IHdpbGwgYmUgYW4gYXJyYXkgcmVwcmVzZW50aW5nIHRoZSBzaGFwZVxuICAgICAqIG9mIHRoZSB0ZW5zb3IuIEVhY2ggZWxlbWVudCBpbiB0aGUgYXJyYXkgY2FuIGJlIGEgbnVtYmVyIG9yIGEgc3RyaW5nLiBJZiB0aGUgZWxlbWVudCBpcyBhIG51bWJlciwgaXQgcmVwcmVzZW50c1xuICAgICAqIHRoZSBjb3JyZXNwb25kaW5nIGRpbWVuc2lvbiBzaXplLiBJZiB0aGUgZWxlbWVudCBpcyBhIHN0cmluZywgaXQgcmVwcmVzZW50cyBhIHN5bWJvbGljIGRpbWVuc2lvbi5cbiAgICAgKi9cbiAgICByZWFkb25seSBzaGFwZTogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIG1ldGFkYXRhIG9mIGEgdmFsdWUuXG4gICAqL1xuICBleHBvcnQgdHlwZSBWYWx1ZU1ldGFkYXRhID0gTm9uVGVuc29yVmFsdWVNZXRhZGF0YSB8IFRlbnNvclZhbHVlTWV0YWRhdGE7XG5cbiAgLy8gI2VuZHJlZ2lvblxufVxuXG4vKipcbiAqIFJlcHJlc2VudCBhIHJ1bnRpbWUgaW5zdGFuY2Ugb2YgYW4gT05OWCBtb2RlbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgLy8gI3JlZ2lvbiBydW4oKVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIHRoZSBtb2RlbCBhc3luY2hyb25vdXNseSB3aXRoIHRoZSBnaXZlbiBmZWVkcyBhbmQgb3B0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIGZlZWRzIC0gUmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGVsIGlucHV0LiBTZWUgdHlwZSBkZXNjcmlwdGlvbiBvZiBgSW5mZXJlbmNlU2Vzc2lvbi5JbnB1dFR5cGVgIGZvciBkZXRhaWwuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwuIEEgc2V0IG9mIG9wdGlvbnMgdGhhdCBjb250cm9scyB0aGUgYmVoYXZpb3Igb2YgbW9kZWwgaW5mZXJlbmNlLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIG1hcCwgd2hpY2ggdXNlcyBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKi9cbiAgcnVuKGZlZWRzOiBJbmZlcmVuY2VTZXNzaW9uLkZlZWRzVHlwZSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbi5SZXR1cm5UeXBlPjtcblxuICAvKipcbiAgICogRXhlY3V0ZSB0aGUgbW9kZWwgYXN5bmNocm9ub3VzbHkgd2l0aCB0aGUgZ2l2ZW4gZmVlZHMsIGZldGNoZXMgYW5kIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmZWVkcyAtIFJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBpbnB1dC4gU2VlIHR5cGUgZGVzY3JpcHRpb24gb2YgYEluZmVyZW5jZVNlc3Npb24uSW5wdXRUeXBlYCBmb3IgZGV0YWlsLlxuICAgKiBAcGFyYW0gZmV0Y2hlcyAtIFJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBvdXRwdXQuIFNlZSB0eXBlIGRlc2NyaXB0aW9uIG9mIGBJbmZlcmVuY2VTZXNzaW9uLk91dHB1dFR5cGVgIGZvclxuICAgKiBkZXRhaWwuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwuIEEgc2V0IG9mIG9wdGlvbnMgdGhhdCBjb250cm9scyB0aGUgYmVoYXZpb3Igb2YgbW9kZWwgaW5mZXJlbmNlLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIG1hcCwgd2hpY2ggdXNlcyBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKi9cbiAgcnVuKFxuICAgIGZlZWRzOiBJbmZlcmVuY2VTZXNzaW9uLkZlZWRzVHlwZSxcbiAgICBmZXRjaGVzOiBJbmZlcmVuY2VTZXNzaW9uLkZldGNoZXNUeXBlLFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbi5SZXR1cm5UeXBlPjtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiByZWxlYXNlKClcblxuICAvKipcbiAgICogUmVsZWFzZSB0aGUgaW5mZXJlbmNlIHNlc3Npb24gYW5kIHRoZSB1bmRlcmx5aW5nIHJlc291cmNlcy5cbiAgICovXG4gIHJlbGVhc2UoKTogUHJvbWlzZTx2b2lkPjtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBwcm9maWxpbmdcblxuICAvKipcbiAgICogU3RhcnQgcHJvZmlsaW5nLlxuICAgKi9cbiAgc3RhcnRQcm9maWxpbmcoKTogdm9pZDtcblxuICAvKipcbiAgICogRW5kIHByb2ZpbGluZy5cbiAgICovXG4gIGVuZFByb2ZpbGluZygpOiB2b2lkO1xuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIG1ldGFkYXRhXG5cbiAgLyoqXG4gICAqIEdldCBpbnB1dCBuYW1lcyBvZiB0aGUgbG9hZGVkIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEdldCBvdXRwdXQgbmFtZXMgb2YgdGhlIGxvYWRlZCBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgICogR2V0IGlucHV0IG1ldGFkYXRhIG9mIHRoZSBsb2FkZWQgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSBpbnB1dE1ldGFkYXRhOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXTtcblxuICAvKipcbiAgICogR2V0IG91dHB1dCBtZXRhZGF0YSBvZiB0aGUgbG9hZGVkIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0TWV0YWRhdGE6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YVtdO1xuXG4gIC8vICNlbmRyZWdpb25cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbmZlcmVuY2VTZXNzaW9uRmFjdG9yeSB7XG4gIC8vICNyZWdpb24gY3JlYXRlKClcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uIGFuZCBsb2FkIG1vZGVsIGFzeW5jaHJvbm91c2x5IGZyb20gYW4gT05OWCBtb2RlbCBmaWxlLlxuICAgKlxuICAgKiBAcGFyYW0gdXJpIC0gVGhlIFVSSSBvciBmaWxlIHBhdGggb2YgdGhlIG1vZGVsIHRvIGxvYWQuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gc3BlY2lmeSBjb25maWd1cmF0aW9uIGZvciBjcmVhdGluZyBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gSW5mZXJlbmNlU2Vzc2lvbiBvYmplY3QuXG4gICAqL1xuICBjcmVhdGUodXJpOiBzdHJpbmcsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uPjtcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uIGFuZCBsb2FkIG1vZGVsIGFzeW5jaHJvbm91c2x5IGZyb20gYW4gYXJyYXkgYnVmZXIuXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBbiBBcnJheUJ1ZmZlciByZXByZXNlbnRhdGlvbiBvZiBhbiBPTk5YIG1vZGVsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbj47XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgbG9hZCBtb2RlbCBhc3luY2hyb25vdXNseSBmcm9tIHNlZ21lbnQgb2YgYW4gYXJyYXkgYnVmZXIuXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBbiBBcnJheUJ1ZmZlciByZXByZXNlbnRhdGlvbiBvZiBhbiBPTk5YIG1vZGVsLlxuICAgKiBAcGFyYW0gYnl0ZU9mZnNldCAtIFRoZSBiZWdpbm5pbmcgb2YgdGhlIHNwZWNpZmllZCBwb3J0aW9uIG9mIHRoZSBhcnJheSBidWZmZXIuXG4gICAqIEBwYXJhbSBieXRlTGVuZ3RoIC0gVGhlIGxlbmd0aCBpbiBieXRlcyBvZiB0aGUgYXJyYXkgYnVmZmVyLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKFxuICAgIGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLFxuICAgIGJ5dGVPZmZzZXQ6IG51bWJlcixcbiAgICBieXRlTGVuZ3RoPzogbnVtYmVyLFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24+O1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24gYW5kIGxvYWQgbW9kZWwgYXN5bmNocm9ub3VzbHkgZnJvbSBhIFVpbnQ4QXJyYXkuXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBIFVpbnQ4QXJyYXkgcmVwcmVzZW50YXRpb24gb2YgYW4gT05OWCBtb2RlbC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBzcGVjaWZ5IGNvbmZpZ3VyYXRpb24gZm9yIGNyZWF0aW5nIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBJbmZlcmVuY2VTZXNzaW9uIG9iamVjdC5cbiAgICovXG4gIGNyZWF0ZShidWZmZXI6IFVpbnQ4QXJyYXksIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uPjtcblxuICAvLyAjZW5kcmVnaW9uXG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmV4cG9ydCBjb25zdCBJbmZlcmVuY2VTZXNzaW9uOiBJbmZlcmVuY2VTZXNzaW9uRmFjdG9yeSA9IEluZmVyZW5jZVNlc3Npb25JbXBsO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBPcHRpb25zRm9ybWF0LCBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMsIE9wdGlvbnNUZW5zb3JMYXlvdXQgfSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JUb0RhdGFVcmxPcHRpb25zIGV4dGVuZHMgT3B0aW9uc1RlbnNvckxheW91dCwgT3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yVG9JbWFnZURhdGFPcHRpb25zIGV4dGVuZHMgT3B0aW9uc1RlbnNvckxheW91dCwgT3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udmVyc2lvblV0aWxzIHtcbiAgLyoqXG4gICAqIGNyZWF0ZXMgYSBEYXRhVVJMIGluc3RhbmNlIGZyb20gdGVuc29yXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyBhIERhdGFVUkwgaW5zdGFuY2UgZnJvbSB0aGUgdGVuc29yLlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGBmb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIEByZXR1cm5zIGEgRGF0YVVSTCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBpbWFnZSBjb252ZXJ0ZWQgZnJvbSB0ZW5zb3IgZGF0YVxuICAgKi9cbiAgdG9EYXRhVVJMKG9wdGlvbnM/OiBUZW5zb3JUb0RhdGFVcmxPcHRpb25zKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBjcmVhdGVzIGFuIEltYWdlRGF0YSBpbnN0YW5jZSBmcm9tIHRlbnNvclxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgYW4gSW1hZ2VEYXRhIGluc3RhbmNlIGZyb20gdGhlIHRlbnNvci5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgZm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiBAcmV0dXJucyBhbiBJbWFnZURhdGEgaW5zdGFuY2UgcmVwcmVzZW50aW5nIHRoZSBpbWFnZSBjb252ZXJ0ZWQgZnJvbSB0ZW5zb3IgZGF0YVxuICAgKi9cbiAgdG9JbWFnZURhdGEob3B0aW9ucz86IFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyk6IEltYWdlRGF0YTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yLCBUeXBlZFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuZXhwb3J0IHR5cGUgSW1hZ2VGb3JtYXQgPSAnUkdCJyB8ICdSR0JBJyB8ICdCR1InIHwgJ1JCRyc7XG5leHBvcnQgdHlwZSBJbWFnZVRlbnNvckxheW91dCA9ICdOSFdDJyB8ICdOQ0hXJztcblxuLy8gdGhlIGZvbGxvd2luZyByZWdpb24gY29udGFpbnMgdHlwZSBkZWZpbml0aW9ucyBmb3IgY29uc3RydWN0aW5nIHRlbnNvciBmcm9tIGEgc3BlY2lmaWMgbG9jYXRpb24uXG5cbi8vICNyZWdpb24gdHlwZXMgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgc3BlY2lmaWMgbG9jYXRpb25cblxuLyoqXG4gKiByZXByZXNlbnQgY29tbW9uIHByb3BlcnRpZXMgb2YgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBzcGVjaWZpYyBsb2NhdGlvbi5cbiAqL1xuaW50ZXJmYWNlIENvbW1vbkNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiBleHRlbmRzIFBpY2s8VGVuc29yLCAnZGltcyc+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLlxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogVDtcbn1cblxuLyoqXG4gKiByZXByZXNlbnQgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBHUFUgcmVzb3VyY2UuXG4gKi9cbmludGVyZmFjZSBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLlR5cGU+IHtcbiAgLyoqXG4gICAqIGFuIG9wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGRvd25sb2FkIGRhdGEgZnJvbSBHUFUgdG8gQ1BVLlxuICAgKlxuICAgKiBJZiBub3QgcHJvdmlkZWQsIHRoZSB0ZW5zb3IgdHJlYXQgdGhlIEdQVSBkYXRhIGFzIGV4dGVybmFsIHJlc291cmNlLlxuICAgKi9cbiAgZG93bmxvYWQ/KCk6IFByb21pc2U8VGVuc29yLkRhdGFUeXBlTWFwW1RdPjtcblxuICAvKipcbiAgICogYW4gb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSB0ZW5zb3IgaXMgZGlzcG9zZWQuXG4gICAqXG4gICAqIElmIG5vdCBwcm92aWRlZCwgdGhlIHRlbnNvciB0cmVhdCB0aGUgR1BVIGRhdGEgYXMgZXh0ZXJuYWwgcmVzb3VyY2UuXG4gICAqL1xuICBkaXNwb3NlPygpOiB2b2lkO1xufVxuXG4vKipcbiAqIHJlcHJlc2VudCB0aGUgcGFyYW1ldGVyIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIHBpbm5lZCBDUFUgYnVmZmVyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFxuICBUIGV4dGVuZHMgVGVuc29yLkNwdVBpbm5lZERhdGFUeXBlcyA9IFRlbnNvci5DcHVQaW5uZWREYXRhVHlwZXMsXG4+IGV4dGVuZHMgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICdjcHUtcGlubmVkJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnY3B1LXBpbm5lZCc7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBDUFUgcGlubmVkIGJ1ZmZlciB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICovXG4gIHJlYWRvbmx5IGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUXTtcbn1cblxuLyoqXG4gKiByZXByZXNlbnQgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBXZWJHTCB0ZXh0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLlRleHR1cmVEYXRhVHlwZXMgPSBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcz5cbiAgZXh0ZW5kcyBDb21tb25Db25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4sIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICd0ZXh0dXJlJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAndGV4dHVyZSc7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBXZWJHTCB0ZXh0dXJlIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgdGV4dHVyZTogVGVuc29yLlRleHR1cmVUeXBlO1xufVxuXG4vKipcbiAqIHJlcHJlc2VudCB0aGUgcGFyYW1ldGVyIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIFdlYkdQVSBidWZmZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VCBleHRlbmRzIFRlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXMgPSBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzPlxuICBleHRlbmRzIENvbW1vbkNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiwgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEgdG8gYmUgJ2dwdS1idWZmZXInLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9jYXRpb246ICdncHUtYnVmZmVyJztcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIFdlYkdQVSBidWZmZXIgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqL1xuICByZWFkb25seSBncHVCdWZmZXI6IFRlbnNvci5HcHVCdWZmZXJUeXBlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1MVGVuc29yQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQgZXh0ZW5kcyBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXMgPSBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXM+XG4gIGV4dGVuZHMgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+LCBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YSB0byBiZSAnbWwtdGVuc29yJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnbWwtdGVuc29yJztcblxuICAvKipcbiAgICogU3BlY2lmeSB0aGUgV2ViTk4gTUxUZW5zb3IgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqL1xuICByZWFkb25seSBtbFRlbnNvcjogVGVuc29yLk1MVGVuc29yVHlwZTtcbn1cblxuLy8gI2VuZHJlZ2lvblxuXG4vLyB0aGUgZm9sbG93aW5nIHJlZ2lvbiBjb250YWlucyB0eXBlIGRlZmluaXRpb25zIG9mIGVhY2ggaW5kaXZpZHVhbCBvcHRpb25zLlxuLy8gdGhlIHRlbnNvciBmYWN0b3J5IGZ1bmN0aW9ucyB1c2UgYSBjb21wb3NpdGlvbiBvZiB0aG9zZSBvcHRpb25zIGFzIHRoZSBwYXJhbWV0ZXIgdHlwZS5cblxuLy8gI3JlZ2lvbiBPcHRpb25zIGZpZWxkc1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNGb3JtYXQge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBmb3JtYXQgcmVwcmVzZW50ZWQgaW4gUkdCQSBjb2xvciBzcGFjZS5cbiAgICovXG4gIGZvcm1hdD86IEltYWdlRm9ybWF0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNUZW5zb3JGb3JtYXQge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBmb3JtYXQgb2YgdGhlIHRlbnNvci5cbiAgICpcbiAgICogTk9URTogdGhpcyBpcyBkaWZmZXJlbnQgZnJvbSBvcHRpb24gJ2Zvcm1hdCcuIFdoaWxlIG9wdGlvbiAnZm9ybWF0JyByZXByZXNlbnRzIHRoZSBvcmlnaW5hbCBpbWFnZSwgJ3RlbnNvckZvcm1hdCdcbiAgICogcmVwcmVzZW50cyB0aGUgdGFyZ2V0IGZvcm1hdCBvZiB0aGUgdGVuc29yLiBBIHRyYW5zcG9zZSB3aWxsIGJlIHBlcmZvcm1lZCBpZiB0aGV5IGFyZSBkaWZmZXJlbnQuXG4gICAqL1xuICB0ZW5zb3JGb3JtYXQ/OiBJbWFnZUZvcm1hdDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zVGVuc29yRGF0YVR5cGUge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIGRhdGFUeXBlPzogJ2Zsb2F0MzInIHwgJ3VpbnQ4Jztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zVGVuc29yTGF5b3V0IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgdGVuc29yIGxheW91dCB3aGVuIHJlcHJlc2VudGluZyBkYXRhIG9mIG9uZSBvciBtb3JlIGltYWdlKHMpLlxuICAgKi9cbiAgdGVuc29yTGF5b3V0PzogSW1hZ2VUZW5zb3JMYXlvdXQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc0RpbWVuc2lvbnMge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBoZWlnaHQgaW4gcGl4ZWxcbiAgICovXG4gIGhlaWdodD86IG51bWJlcjtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgaW1hZ2Ugd2lkdGggaW4gcGl4ZWxcbiAgICovXG4gIHdpZHRoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zIHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgcmVzaXplZCBoZWlnaHQuIElmIG9taXR0ZWQsIG9yaWdpbmFsIGhlaWdodCB3aWxsIGJlIHVzZWQuXG4gICAqL1xuICByZXNpemVkSGVpZ2h0PzogbnVtYmVyO1xuICAvKipcbiAgICogRGVzY3JpYmVzIHJlc2l6ZWQgd2lkdGggLSBjYW4gYmUgYWNjZXNzZWQgdmlhIHRlbnNvciBkaW1lbnNpb25zIGFzIHdlbGxcbiAgICovXG4gIHJlc2l6ZWRXaWR0aD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge1xuICAvKipcbiAgICogRGVzY3JpYmVzIG5vcm1hbGl6YXRpb24gcGFyYW1ldGVycyB3aGVuIHByZXByb2Nlc3NpbmcgdGhlIGltYWdlIGFzIG1vZGVsIGlucHV0LlxuICAgKlxuICAgKiBEYXRhIGVsZW1lbnQgYXJlIHJhbmdlZCBmcm9tIDAgdG8gMjU1LlxuICAgKi9cbiAgbm9ybT86IHtcbiAgICAvKipcbiAgICAgKiBUaGUgJ2JpYXMnIHZhbHVlIGZvciBpbWFnZSBub3JtYWxpemF0aW9uLlxuICAgICAqIC0gSWYgb21pdHRlZCwgdXNlIGRlZmF1bHQgdmFsdWUgMC5cbiAgICAgKiAtIElmIGl0J3MgYSBzaW5nbGUgbnVtYmVyLCBhcHBseSB0byBlYWNoIGNoYW5uZWxcbiAgICAgKiAtIElmIGl0J3MgYW4gYXJyYXkgb2YgMyBvciA0IG51bWJlcnMsIGFwcGx5IGVsZW1lbnQtd2lzZS4gTnVtYmVyIG9mIGVsZW1lbnRzIG5lZWQgdG8gbWF0Y2ggdGhlIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAqIGZvciB0aGUgY29ycmVzcG9uZGluZyBpbWFnZSBmb3JtYXRcbiAgICAgKi9cbiAgICBiaWFzPzogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgLyoqXG4gICAgICogVGhlICdtZWFuJyB2YWx1ZSBmb3IgaW1hZ2Ugbm9ybWFsaXphdGlvbi5cbiAgICAgKiAtIElmIG9taXR0ZWQsIHVzZSBkZWZhdWx0IHZhbHVlIDI1NS5cbiAgICAgKiAtIElmIGl0J3MgYSBzaW5nbGUgbnVtYmVyLCBhcHBseSB0byBlYWNoIGNoYW5uZWxcbiAgICAgKiAtIElmIGl0J3MgYW4gYXJyYXkgb2YgMyBvciA0IG51bWJlcnMsIGFwcGx5IGVsZW1lbnQtd2lzZS4gTnVtYmVyIG9mIGVsZW1lbnRzIG5lZWQgdG8gbWF0Y2ggdGhlIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAqIGZvciB0aGUgY29ycmVzcG9uZGluZyBpbWFnZSBmb3JtYXRcbiAgICAgKi9cbiAgICBtZWFuPzogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIH07XG59XG5cbi8vICNlbmRyZWdpb25cblxuLy8gI3JlZ2lvbiBPcHRpb25zIGNvbXBvc2l0aW9uXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnNcbiAgZXh0ZW5kc1xuICAgIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUltYWdlRWxlbWVudE9wdGlvbnNcbiAgZXh0ZW5kc1xuICAgIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbVVybE9wdGlvbnNcbiAgZXh0ZW5kc1xuICAgIE9wdGlvbnNEaW1lbnNpb25zLFxuICAgIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9uc1xuICBleHRlbmRzXG4gICAgT3B0aW9uUmVzaXplZERpbWVuc2lvbnMsXG4gICAgT3B0aW9uc1RlbnNvckZvcm1hdCxcbiAgICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICAgIE9wdGlvbnNUZW5zb3JEYXRhVHlwZSxcbiAgICBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnM8VCBleHRlbmRzIFRlbnNvci5UZXh0dXJlRGF0YVR5cGVzPlxuICBleHRlbmRzIFJlcXVpcmVkPE9wdGlvbnNEaW1lbnNpb25zPiwgT3B0aW9uc0Zvcm1hdCwgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4gLyogVE9ETzogYWRkIG1vcmUgKi8ge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9uczxUIGV4dGVuZHMgVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlcz5cbiAgZXh0ZW5kcyBQaWNrPFRlbnNvciwgJ2RpbXMnPiwgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIGRhdGFUeXBlPzogVDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zPFQgZXh0ZW5kcyBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXM+XG4gIGV4dGVuZHMgUGljazxUZW5zb3IsICdkaW1zJz4sIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICBkYXRhVHlwZT86IFQ7XG59XG5cbi8vICNlbmRyZWdpb25cblxuLyoqXG4gKiB0eXBlIFRlbnNvckZhY3RvcnkgZGVmaW5lcyB0aGUgZmFjdG9yeSBmdW5jdGlvbnMgb2YgJ1RlbnNvcicgdG8gY3JlYXRlIHRlbnNvciBpbnN0YW5jZXMgZnJvbSBleGlzdGluZyBkYXRhIG9yXG4gKiByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRmFjdG9yeSB7XG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhbiBJbWFnZURhdGEgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSBpbWFnZURhdGEgLSB0aGUgSW1hZ2VEYXRhIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIEltYWdlRGF0YS5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgdGVuc29yRm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiAtIGBkYXRhVHlwZWA6IGAnZmxvYXQzMidgXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbUltYWdlKFxuICAgIGltYWdlRGF0YTogSW1hZ2VEYXRhLFxuICAgIG9wdGlvbnM/OiBUZW5zb3JGcm9tSW1hZ2VEYXRhT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhIEhUTUxJbWFnZUVsZW1lbnQgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSBpbWFnZUVsZW1lbnQgLSB0aGUgSFRNTEltYWdlRWxlbWVudCBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBIVE1MSW1hZ2VFbGVtZW50LlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGB0ZW5zb3JGb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIC0gYGRhdGFUeXBlYDogYCdmbG9hdDMyJ2BcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tSW1hZ2UoXG4gICAgaW1hZ2VFbGVtZW50OiBIVE1MSW1hZ2VFbGVtZW50LFxuICAgIG9wdGlvbnM/OiBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9ucyxcbiAgKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBVUkxcbiAgICpcbiAgICogQHBhcmFtIHVybFNvdXJjZSAtIGEgc3RyaW5nIGFzIGEgVVJMIHRvIHRoZSBpbWFnZSBvciBhIGRhdGEgVVJMIGNvbnRhaW5pbmcgdGhlIGltYWdlIGRhdGEuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBVUkwuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZSh1cmxTb3VyY2U6IHN0cmluZywgb3B0aW9ucz86IFRlbnNvckZyb21VcmxPcHRpb25zKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhbiBJbWFnZUJpdG1hcCBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIGJpdG1hcCAtIHRoZSBJbWFnZUJpdG1hcCBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBVUkwuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZShcbiAgICBiaXRtYXA6IEltYWdlQml0bWFwLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnMsXG4gICk6IFByb21pc2U8VHlwZWRUZW5zb3I8J2Zsb2F0MzInPiB8IFR5cGVkVGVuc29yPCd1aW50OCc+PjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJHTCB0ZXh0dXJlXG4gICAqXG4gICAqIEBwYXJhbSB0ZXh0dXJlIC0gdGhlIFdlYkdMVGV4dHVyZSBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBXZWJHTCB0ZXh0dXJlLlxuICAgKlxuICAgKiBUaGUgb3B0aW9ucyBpbmNsdWRlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICAgKiAtIGB3aWR0aGA6IHRoZSB3aWR0aCBvZiB0aGUgdGV4dHVyZS4gUmVxdWlyZWQuXG4gICAqIC0gYGhlaWdodGA6IHRoZSBoZWlnaHQgb2YgdGhlIHRleHR1cmUuIFJlcXVpcmVkLlxuICAgKiAtIGBmb3JtYXRgOiB0aGUgZm9ybWF0IG9mIHRoZSB0ZXh0dXJlLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ1JHQkEnLlxuICAgKiAtIGBkb3dubG9hZGA6IGFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGRvd25sb2FkIHRoZSB0ZW5zb3IgZGF0YSBmcm9tIEdQVSB0byBDUFUuIElmIG9taXR0ZWQsIHRoZSBHUFUgZGF0YVxuICAgKiB3aWxsIG5vdCBiZSBhYmxlIHRvIGRvd25sb2FkLiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IGEgR1BVIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3RcbiAgICogbmVlZCB0byBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqIC0gYGRpc3Bvc2VgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkaXNwb3NlIHRoZSB0ZW5zb3IgZGF0YSBvbiBHUFUuIElmIG9taXR0ZWQsIHRoZSBHUFUgZGF0YSB3aWxsIG5vdCBiZSBkaXNwb3NlZC5cbiAgICogVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSBhIEdQVSBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0IG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21UZXh0dXJlPFQgZXh0ZW5kcyBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcyA9ICdmbG9hdDMyJz4oXG4gICAgdGV4dHVyZTogVGVuc29yLlRleHR1cmVUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21UZXh0dXJlT3B0aW9uczxUPixcbiAgKTogVHlwZWRUZW5zb3I8J2Zsb2F0MzInPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJHUFUgYnVmZmVyXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSB0aGUgR1BVQnVmZmVyIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIFdlYkdQVSBidWZmZXIuXG4gICAqXG4gICAqIFRoZSBvcHRpb25zIGluY2x1ZGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAqIC0gYGRhdGFUeXBlYDogdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ2Zsb2F0MzInLlxuICAgKiAtIGBkaW1zYDogdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBSZXF1aXJlZC5cbiAgICogLSBgZG93bmxvYWRgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkb3dubG9hZCB0aGUgdGVuc29yIGRhdGEgZnJvbSBHUFUgdG8gQ1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGFcbiAgICogd2lsbCBub3QgYmUgYWJsZSB0byBkb3dubG9hZC4gVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSBhIEdQVSBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0XG4gICAqIG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKiAtIGBkaXNwb3NlYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdGVuc29yIGRhdGEgb24gR1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGEgd2lsbCBub3QgYmUgZGlzcG9zZWQuXG4gICAqIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgYSBHUFUgYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLiBVc2VycyBkb24ndCBuZWVkIHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMgYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tR3B1QnVmZmVyPFQgZXh0ZW5kcyBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzPihcbiAgICBidWZmZXI6IFRlbnNvci5HcHVCdWZmZXJUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQ+LFxuICApOiBUeXBlZFRlbnNvcjxUPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJOTiBNTFRlbnNvclxuICAgKlxuICAgKiBAcGFyYW0gdGVuc29yIC0gdGhlIE1MVGVuc29yIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIGEgV2ViTk4gTUxUZW5zb3IuXG4gICAqXG4gICAqIFRoZSBvcHRpb25zIGluY2x1ZGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAqIC0gYGRhdGFUeXBlYDogdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ2Zsb2F0MzInLlxuICAgKiAtIGBkaW1zYDogdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBSZXF1aXJlZC5cbiAgICogLSBgZG93bmxvYWRgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkb3dubG9hZCB0aGUgdGVuc29yIGRhdGEgZnJvbSB0aGUgTUxUZW5zb3IgdG8gQ1BVLiBJZiBvbWl0dGVkLCB0aGUgTUxUZW5zb3JcbiAgICogZGF0YSB3aWxsIG5vdCBiZSBhYmxlIHRvIGRvd25sb2FkLiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IHRoZSBXZWJOTiBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuXG4gICAqIFVzZXJzIGRvbid0IG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKiAtIGBkaXNwb3NlYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdGVuc29yIGRhdGEgb24gdGhlIFdlYk5OIE1MVGVuc29yLiBJZiBvbWl0dGVkLCB0aGUgTUxUZW5zb3Igd2lsbFxuICAgKiBub3QgYmUgZGlzcG9zZWQuIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgdGhlIFdlYk5OIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3QgbmVlZCB0b1xuICAgKiBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqXG4gICAqIEByZXR1cm5zIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbU1MVGVuc29yPFQgZXh0ZW5kcyBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXM+KFxuICAgIHRlbnNvcjogVGVuc29yLk1MVGVuc29yVHlwZSxcbiAgICBvcHRpb25zOiBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zPFQ+LFxuICApOiBUeXBlZFRlbnNvcjxUPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBwcmUtYWxsb2NhdGVkIGJ1ZmZlci4gVGhlIGJ1ZmZlciB3aWxsIGJlIHVzZWQgYXMgYSBwaW5uZWQgYnVmZmVyLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIHRoZSB0ZW5zb3IgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gYSBUeXBlZEFycmF5IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUuXG4gICAqIEBwYXJhbSBkaW1zIC0gc3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21QaW5uZWRCdWZmZXI8VCBleHRlbmRzIEV4Y2x1ZGU8VGVuc29yLlR5cGUsICdzdHJpbmcnPj4oXG4gICAgdHlwZTogVCxcbiAgICBidWZmZXI6IFRlbnNvci5EYXRhVHlwZU1hcFtUXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFR5cGVkVGVuc29yPFQ+O1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKipcbiAqIEEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyBhIGZpbGUncyBVUkwgb3IgcGF0aC5cbiAqXG4gKiBQYXRoIGlzIHZhaWxhYmxlIG9ubHkgaW4gb25ueHJ1bnRpbWUtbm9kZSBvciBvbm54cnVudGltZS13ZWIgcnVubmluZyBpbiBOb2RlLmpzLlxuICovXG5leHBvcnQgdHlwZSBGaWxlVXJsT3JQYXRoID0gc3RyaW5nO1xuXG4vKipcbiAqIEEgQmxvYiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgZmlsZS5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZUJsb2IgPSBCbG9iO1xuXG4vKipcbiAqIEEgVWludDhBcnJheSwgQXJyYXlCdWZmZXIgb3IgU2hhcmVkQXJyYXlCdWZmZXIgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhIGZpbGUgY29udGVudC5cbiAqXG4gKiBXaGVuIGl0IGlzIGFuIEFycmF5QnVmZmVyIG9yIFNoYXJlZEFycmF5QnVmZmVyLCB0aGUgd2hvbGUgYnVmZmVyIGlzIGFzc3VtZWQgdG8gYmUgdGhlIGZpbGUgY29udGVudC5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZURhdGEgPSBVaW50OEFycmF5IHwgQXJyYXlCdWZmZXJMaWtlO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBmaWxlIHRoYXQgY2FuIGJlIGxvYWRlZCBieSB0aGUgT05OWCBSdW50aW1lIEphdmFTY3JpcHQgQVBJLlxuICovXG5leHBvcnQgdHlwZSBGaWxlVHlwZSA9IEZpbGVVcmxPclBhdGggfCBGaWxlQmxvYiB8IEZpbGVEYXRhO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gZXh0ZXJuYWwgZGF0YSBmaWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVybmFsRGF0YUZpbGVEZXNjcmlwdGlvbiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBleHRlcm5hbCBkYXRhIGZpbGUuXG4gICAqL1xuICBkYXRhOiBGaWxlVHlwZTtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGZpbGUgcGF0aC5cbiAgICovXG4gIHBhdGg6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIGV4dGVybmFsIGRhdGEgZmlsZS5cbiAqXG4gKiBXaGVuIHVzaW5nIGEgc3RyaW5nLCBpdCBzaG91bGQgYmUgYSBmaWxlIFVSTCBvciBwYXRoIHRoYXQgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHRoZSBtb2RlbCBmaWxlLlxuICovXG5leHBvcnQgdHlwZSBFeHRlcm5hbERhdGFGaWxlVHlwZSA9IEV4dGVybmFsRGF0YUZpbGVEZXNjcmlwdGlvbiB8IEZpbGVVcmxPclBhdGg7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgbW9kZWwgbG9hZGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPbm54TW9kZWxPcHRpb25zIHtcbiAgLyoqXG4gICAqIFNwZWNpZnlpbmcgYSBsaXN0IG9mIGZpbGVzIHRoYXQgcmVwcmVzZW50cyB0aGUgZXh0ZXJuYWwgZGF0YS5cbiAgICovXG4gIGV4dGVybmFsRGF0YT86IHJlYWRvbmx5IEV4dGVybmFsRGF0YUZpbGVUeXBlW107XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuZXhwb3J0IHR5cGUgTm9uVGVuc29yVHlwZSA9IG5ldmVyO1xuXG4vKipcbiAqIFR5cGUgT25ueFZhbHVlIFJlcHJlc2VudHMgYm90aCB0ZW5zb3JzIGFuZCBub24tdGVuc29ycyB2YWx1ZSBmb3IgbW9kZWwncyBpbnB1dHMvb3V0cHV0cy5cbiAqXG4gKiBOT1RFOiBjdXJyZW50bHkgbm90IHN1cHBvcnQgbm9uLXRlbnNvclxuICovXG5leHBvcnQgdHlwZSBPbm54VmFsdWUgPSBUZW5zb3IgfCBOb25UZW5zb3JUeXBlO1xuXG4vKipcbiAqIFR5cGUgT25ueFZhbHVlRGF0YUxvY2F0aW9uIHJlcHJlc2VudHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIG9mIGFuIE9ubnhWYWx1ZS5cbiAqL1xuZXhwb3J0IHR5cGUgT25ueFZhbHVlRGF0YUxvY2F0aW9uID0gVGVuc29yLkRhdGFMb2NhdGlvbjtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLyoqXG4gKiAjIE9OTlggUnVudGltZSBKYXZhU2NyaXB0IEFQSVxuICpcbiAqIE9OTlggUnVudGltZSBKYXZhU2NyaXB0IEFQSSBpcyBhIHVuaWZpZWQgQVBJIGZvciBhbGwgSmF2YVNjcmlwdCB1c2FnZXMsIGluY2x1ZGluZyB0aGUgZm9sbG93aW5nIE5QTSBwYWNrYWdlczpcbiAqXG4gKiAtIFtvbm54cnVudGltZS1ub2RlXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9vbm54cnVudGltZS1ub2RlKVxuICogLSBbb25ueHJ1bnRpbWUtd2ViXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9vbm54cnVudGltZS13ZWIpXG4gKiAtIFtvbm54cnVudGltZS1yZWFjdC1uYXRpdmVdKGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL29ubnhydW50aW1lLXJlYWN0LW5hdGl2ZSlcbiAqXG4gKiBTZWUgYWxzbzpcbiAqIC0gW0dldCBTdGFydGVkXShodHRwczovL29ubnhydW50aW1lLmFpL2RvY3MvZ2V0LXN0YXJ0ZWQvd2l0aC1qYXZhc2NyaXB0LylcbiAqIC0gW0luZmVyZW5jZSBleGFtcGxlc10oaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS1pbmZlcmVuY2UtZXhhbXBsZXMvdHJlZS9tYWluL2pzKVxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vYmFja2VuZC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2Vudi5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuc29yLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24uanMnO1xuZXhwb3J0ICogZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3RyYWNlLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vb25ueC1tb2RlbC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBFbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL2JhY2tlbmRzL3dlYmdsL3dlYmdsLWNvbnRleHQnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgTG9nZ2VyIHtcbiAgZXhwb3J0IGludGVyZmFjZSBTZXZlcml0eVR5cGVNYXAge1xuICAgIHZlcmJvc2U6ICd2JztcbiAgICBpbmZvOiAnaSc7XG4gICAgd2FybmluZzogJ3cnO1xuICAgIGVycm9yOiAnZSc7XG4gICAgZmF0YWw6ICdmJztcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIFNldmVyaXR5ID0ga2V5b2YgU2V2ZXJpdHlUeXBlTWFwO1xuXG4gIGV4cG9ydCB0eXBlIFByb3ZpZGVyID0gJ25vbmUnIHwgJ2NvbnNvbGUnO1xuXG4gIC8qKlxuICAgKiBMb2dnaW5nIGNvbmZpZyB0aGF0IHVzZWQgdG8gY29udHJvbCB0aGUgYmVoYXZpb3Igb2YgbG9nZ2VyXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgbG9nZ2luZyBwcm92aWRlci4gJ2NvbnNvbGUnIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBwcm92aWRlcj86IFByb3ZpZGVyO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIG1pbmltYWwgbG9nZ2VyIHNldmVyaXR5LiAnd2FybmluZycgYnkgZGVmYXVsdFxuICAgICAqL1xuICAgIG1pbmltYWxTZXZlcml0eT86IExvZ2dlci5TZXZlcml0eTtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIG91dHB1dCBkYXRlIHRpbWUgaW4gbG9nLiB0cnVlIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBsb2dEYXRlVGltZT86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0byBvdXRwdXQgc291cmNlIGluZm9ybWF0aW9uIChOb3QgeWV0IHN1cHBvcnRlZCkuIGZhbHNlIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBsb2dTb3VyY2VMb2NhdGlvbj86IGJvb2xlYW47XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIENhdGVnb3JpemVkTG9nZ2VyIHtcbiAgICB2ZXJib3NlKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gICAgaW5mbyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIHdhcm5pbmcoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICBlcnJvcihjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmVcbmV4cG9ydCBpbnRlcmZhY2UgTG9nZ2VyIHtcbiAgKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXI7XG5cbiAgdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB2ZXJib3NlKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGluZm8oY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgaW5mbyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIHdhcm5pbmcoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXJyb3IoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZmF0YWwoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZmF0YWwoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcblxuICAvKipcbiAgICogUmVzZXQgdGhlIGxvZ2dlciBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0gY29uZmlnIHNwZWNpZnkgYW4gb3B0aW9uYWwgZGVmYXVsdCBjb25maWdcbiAgICovXG4gIHJlc2V0KGNvbmZpZz86IExvZ2dlci5Db25maWcpOiB2b2lkO1xuICAvKipcbiAgICogU2V0IHRoZSBsb2dnZXIncyBiZWhhdmlvciBvbiB0aGUgZ2l2ZW4gY2F0ZWdvcnlcbiAgICogQHBhcmFtIGNhdGVnb3J5IHNwZWNpZnkgYSBjYXRlZ29yeSBzdHJpbmcuIElmICcqJyBpcyBzcGVjaWZpZWQsIGFsbCBwcmV2aW91cyBjb25maWd1cmF0aW9uIHdpbGwgYmUgb3ZlcndyaXR0ZW4uIElmXG4gICAqICcnIGlzIHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgYmVoYXZpb3Igd2lsbCBiZSB1cGRhdGVkLlxuICAgKiBAcGFyYW0gY29uZmlnIHRoZSBjb25maWcgb2JqZWN0IHRvIGluZGljYXRlIHRoZSBsb2dnZXIncyBiZWhhdmlvclxuICAgKi9cbiAgc2V0KGNhdGVnb3J5OiBzdHJpbmcsIGNvbmZpZzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3IgZnJvbSBvcnQtY29tbW9uIGVudlxuICAgKiBAcGFyYW0gZW52IHRoZSBlbnYgdXNlZCB0byBzZXQgbG9nZ2VyLiBDdXJyZW50bHkgb25seSBzZXR0aW5nIGxvZ2xldmVsIGlzIHN1cHBvcnRlZCB0aHJvdWdoIEVudi5cbiAgICovXG4gIHNldFdpdGhFbnYoZW52OiBFbnYpOiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nLCBjYXRlZ29yeT86IHN0cmluZyk6IHZvaWQ7XG59XG5jbGFzcyBOb09wTG9nZ2VyUHJvdmlkZXIgaW1wbGVtZW50cyBMb2dnZXJQcm92aWRlciB7XG4gIGxvZyhfc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgX2NvbnRlbnQ6IHN0cmluZywgX2NhdGVnb3J5Pzogc3RyaW5nKSB7XG4gICAgLy8gZG8gbm90aGluZ1xuICB9XG59XG5jbGFzcyBDb25zb2xlTG9nZ2VyUHJvdmlkZXIgaW1wbGVtZW50cyBMb2dnZXJQcm92aWRlciB7XG4gIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcsIGNhdGVnb3J5Pzogc3RyaW5nKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLmxvZyhgJHt0aGlzLmNvbG9yKHNldmVyaXR5KX0gJHtjYXRlZ29yeSA/ICdcXHgxYlszNW0nICsgY2F0ZWdvcnkgKyAnXFx4MWJbMG0gJyA6ICcnfSR7Y29udGVudH1gKTtcbiAgfVxuXG4gIHByaXZhdGUgY29sb3Ioc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSkge1xuICAgIHN3aXRjaCAoc2V2ZXJpdHkpIHtcbiAgICAgIGNhc2UgJ3ZlcmJvc2UnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzM0OzQwbXZcXHgxYlswbSc7XG4gICAgICBjYXNlICdpbmZvJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszMm1pXFx4MWJbMG0nO1xuICAgICAgY2FzZSAnd2FybmluZyc6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzA7NDNtd1xceDFiWzBtJztcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszMTs0MG1lXFx4MWJbMG0nO1xuICAgICAgY2FzZSAnZmF0YWwnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzEwMW1mXFx4MWJbMG0nO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBzZXZlcml0eTogJHtzZXZlcml0eX1gKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgU0VWRVJJVFlfVkFMVUUgPSB7XG4gIHZlcmJvc2U6IDEwMDAsXG4gIGluZm86IDIwMDAsXG4gIHdhcm5pbmc6IDQwMDAsXG4gIGVycm9yOiA1MDAwLFxuICBmYXRhbDogNjAwMCxcbn07XG5cbmNvbnN0IExPR0dFUl9QUk9WSURFUl9NQVA6IHsgcmVhZG9ubHkgW3Byb3ZpZGVyOiBzdHJpbmddOiBSZWFkb25seTxMb2dnZXJQcm92aWRlcj4gfSA9IHtcbiAgWydub25lJ106IG5ldyBOb09wTG9nZ2VyUHJvdmlkZXIoKSxcbiAgWydjb25zb2xlJ106IG5ldyBDb25zb2xlTG9nZ2VyUHJvdmlkZXIoKSxcbn07XG5jb25zdCBMT0dHRVJfREVGQVVMVF9DT05GSUcgPSB7XG4gIHByb3ZpZGVyOiAnY29uc29sZScsXG4gIG1pbmltYWxTZXZlcml0eTogJ3dhcm5pbmcnLFxuICBsb2dEYXRlVGltZTogdHJ1ZSxcbiAgbG9nU291cmNlTG9jYXRpb246IGZhbHNlLFxufTtcbmxldCBMT0dHRVJfQ09ORklHX01BUDogeyBbY2F0ZWdvcnk6IHN0cmluZ106IFJlYWRvbmx5PFJlcXVpcmVkPExvZ2dlci5Db25maWc+PiB9ID0ge1xuICBbJyddOiBMT0dHRVJfREVGQVVMVF9DT05GSUcgYXMgUmVxdWlyZWQ8TG9nZ2VyLkNvbmZpZz4sXG59O1xuXG5mdW5jdGlvbiBsb2coY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlcjtcbmZ1bmN0aW9uIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuZnVuY3Rpb24gbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG5mdW5jdGlvbiBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgYXJnMTogc3RyaW5nLCBhcmcyPzogc3RyaW5nKTogdm9pZDtcbmZ1bmN0aW9uIGxvZyhcbiAgYXJnMDogc3RyaW5nIHwgTG9nZ2VyLlNldmVyaXR5LFxuICBhcmcxPzogc3RyaW5nLFxuICBhcmcyPzogc3RyaW5nIHwgbnVtYmVyLFxuICBhcmczPzogbnVtYmVyLFxuKTogTG9nZ2VyLkNhdGVnb3JpemVkTG9nZ2VyIHwgdm9pZCB7XG4gIGlmIChhcmcxID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlcjtcbiAgICByZXR1cm4gY3JlYXRlQ2F0ZWdvcml6ZWRMb2dnZXIoYXJnMCk7XG4gIH0gZWxzZSBpZiAoYXJnMiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjb250ZW50KTtcbiAgICBsb2dJbnRlcm5hbChhcmcwIGFzIExvZ2dlci5TZXZlcml0eSwgYXJnMSwgMSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgPT09ICdudW1iZXInICYmIGFyZzMgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGxvZyhzZXZlcml0eSwgY29udGVudCwgc3RhY2spXG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzEsIGFyZzIpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyID09PSAnc3RyaW5nJyAmJiBhcmczID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coc2V2ZXJpdHksIGNhdGVnb3J5LCBjb250ZW50KVxuICAgIGxvZ0ludGVybmFsKGFyZzAgYXMgTG9nZ2VyLlNldmVyaXR5LCBhcmcyLCAxLCBhcmcxKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIGFyZzMgPT09ICdudW1iZXInKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjYXRlZ29yeSwgY29udGVudCwgc3RhY2spXG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzIsIGFyZzMsIGFyZzEpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2lucHV0IGlzIHZhbGlkJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2F0ZWdvcml6ZWRMb2dnZXIoY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlciB7XG4gIHJldHVybiB7XG4gICAgdmVyYm9zZTogbG9nLnZlcmJvc2UuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgaW5mbzogbG9nLmluZm8uYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgd2FybmluZzogbG9nLndhcm5pbmcuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgZXJyb3I6IGxvZy5lcnJvci5iaW5kKG51bGwsIGNhdGVnb3J5KSxcbiAgICBmYXRhbDogbG9nLmZhdGFsLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICB9O1xufVxuXG4vLyBOT1RFOiBhcmd1bWVudCAnY2F0ZWdvcnknIGlzIHB1dCB0aGUgbGFzdCBwYXJhbWV0ZXIgYmVjYXVzZSB0eXBlc2NyaXB0XG4vLyBkb2Vzbid0IGFsbG93IG9wdGlvbmFsIGFyZ3VtZW50IHB1dCBpbiBmcm9udCBvZiByZXF1aXJlZCBhcmd1bWVudC4gVGhpc1xuLy8gb3JkZXIgaXMgZGlmZmVyZW50IGZyb20gYSB1c3VhbCBsb2dnaW5nIEFQSS5cbmZ1bmN0aW9uIGxvZ0ludGVybmFsKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNvbnRlbnQ6IHN0cmluZywgX3N0YWNrOiBudW1iZXIsIGNhdGVnb3J5Pzogc3RyaW5nKSB7XG4gIGNvbnN0IGNvbmZpZyA9IExPR0dFUl9DT05GSUdfTUFQW2NhdGVnb3J5IHx8ICcnXSB8fCBMT0dHRVJfQ09ORklHX01BUFsnJ107XG4gIGlmIChTRVZFUklUWV9WQUxVRVtzZXZlcml0eV0gPCBTRVZFUklUWV9WQUxVRVtjb25maWcubWluaW1hbFNldmVyaXR5XSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChjb25maWcubG9nRGF0ZVRpbWUpIHtcbiAgICBjb250ZW50ID0gYCR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfXwke2NvbnRlbnR9YDtcbiAgfVxuXG4gIGlmIChjb25maWcubG9nU291cmNlTG9jYXRpb24pIHtcbiAgICAvLyBUT0RPOiBjYWxjdWxhdGUgc291cmNlIGxvY2F0aW9uIGZyb20gJ3N0YWNrJ1xuICB9XG5cbiAgTE9HR0VSX1BST1ZJREVSX01BUFtjb25maWcucHJvdmlkZXJdLmxvZyhzZXZlcml0eSwgY29udGVudCwgY2F0ZWdvcnkpO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5hbWVzcGFjZVxubmFtZXNwYWNlIGxvZyB7XG4gIGV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygndmVyYm9zZScsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBpbmZvKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBpbmZvKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBpbmZvKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnaW5mbycsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB3YXJuaW5nKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB3YXJuaW5nKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnd2FybmluZycsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBlcnJvcihjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gZXJyb3IoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGVycm9yKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnZXJyb3InLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gZmF0YWwoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGZhdGFsKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBmYXRhbChhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ2ZhdGFsJywgYXJnMCwgYXJnMSk7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gcmVzZXQoY29uZmlnPzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQge1xuICAgIExPR0dFUl9DT05GSUdfTUFQID0ge307XG4gICAgc2V0KCcnLCBjb25maWcgfHwge30pO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBzZXQoY2F0ZWdvcnk6IHN0cmluZywgY29uZmlnOiBMb2dnZXIuQ29uZmlnKTogdm9pZCB7XG4gICAgaWYgKGNhdGVnb3J5ID09PSAnKicpIHtcbiAgICAgIHJlc2V0KGNvbmZpZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHByZXZpb3VzQ29uZmlnID0gTE9HR0VSX0NPTkZJR19NQVBbY2F0ZWdvcnldIHx8IExPR0dFUl9ERUZBVUxUX0NPTkZJRztcbiAgICAgIExPR0dFUl9DT05GSUdfTUFQW2NhdGVnb3J5XSA9IHtcbiAgICAgICAgcHJvdmlkZXI6IGNvbmZpZy5wcm92aWRlciB8fCBwcmV2aW91c0NvbmZpZy5wcm92aWRlcixcbiAgICAgICAgbWluaW1hbFNldmVyaXR5OiBjb25maWcubWluaW1hbFNldmVyaXR5IHx8IHByZXZpb3VzQ29uZmlnLm1pbmltYWxTZXZlcml0eSxcbiAgICAgICAgbG9nRGF0ZVRpbWU6IGNvbmZpZy5sb2dEYXRlVGltZSA9PT0gdW5kZWZpbmVkID8gcHJldmlvdXNDb25maWcubG9nRGF0ZVRpbWUgOiBjb25maWcubG9nRGF0ZVRpbWUsXG4gICAgICAgIGxvZ1NvdXJjZUxvY2F0aW9uOlxuICAgICAgICAgIGNvbmZpZy5sb2dTb3VyY2VMb2NhdGlvbiA9PT0gdW5kZWZpbmVkID8gcHJldmlvdXNDb25maWcubG9nU291cmNlTG9jYXRpb24gOiBjb25maWcubG9nU291cmNlTG9jYXRpb24sXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFRPRE86IHdlIHdhbnQgdG8gc3VwcG9ydCB3aWxkY2FyZCBvciByZWdleD9cbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBzZXRXaXRoRW52KGVudjogRW52KTogdm9pZCB7XG4gICAgY29uc3QgY29uZmlnOiBMb2dnZXIuQ29uZmlnID0ge307XG4gICAgaWYgKGVudi5sb2dMZXZlbCkge1xuICAgICAgY29uZmlnLm1pbmltYWxTZXZlcml0eSA9IGVudi5sb2dMZXZlbCBhcyBMb2dnZXIuU2V2ZXJpdHk7XG4gICAgfVxuICAgIHNldCgnJywgY29uZmlnKTtcbiAgfVxufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZSwgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgY29uc3QgTG9nZ2VyOiBMb2dnZXIgPSBsb2c7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBQcm9maWxlciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnIHtcbiAgICBtYXhOdW1iZXJFdmVudHM/OiBudW1iZXI7XG4gICAgZmx1c2hCYXRjaFNpemU/OiBudW1iZXI7XG4gICAgZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgRXZlbnRDYXRlZ29yeSA9ICdzZXNzaW9uJyB8ICdub2RlJyB8ICdvcCcgfCAnYmFja2VuZCc7XG5cbiAgZXhwb3J0IGludGVyZmFjZSBFdmVudCB7XG4gICAgZW5kKCk6IHZvaWQgfCBQcm9taXNlPHZvaWQ+O1xuICB9XG59XG4vLyBUT0RPXG4vLyBjbGFzcyBXZWJHTEV2ZW50IGltcGxlbWVudHMgUHJvZmlsZXIuRXZlbnQge31cblxuY2xhc3MgRXZlbnQgaW1wbGVtZW50cyBQcm9maWxlci5FdmVudCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSxcbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nLFxuICAgIHB1YmxpYyBzdGFydFRpbWU6IG51bWJlcixcbiAgICBwcml2YXRlIGVuZENhbGxiYWNrOiAoZTogRXZlbnQpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+LFxuICAgIHB1YmxpYyB0aW1lcj86IFdlYkdMUXVlcnksXG4gICAgcHVibGljIGN0eD86IFdlYkdMQ29udGV4dCxcbiAgKSB7fVxuXG4gIGFzeW5jIGVuZCgpIHtcbiAgICByZXR1cm4gdGhpcy5lbmRDYWxsYmFjayh0aGlzKTtcbiAgfVxuXG4gIGFzeW5jIGNoZWNrVGltZXIoKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBpZiAodGhpcy5jdHggPT09IHVuZGVmaW5lZCB8fCB0aGlzLnRpbWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gd2ViZ2wgdGltZXIgZm91bmQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jdHguZW5kVGltZXIoKTtcbiAgICAgIHJldHVybiB0aGlzLmN0eC53YWl0Rm9yUXVlcnlBbmRHZXRUaW1lKHRoaXMudGltZXIpO1xuICAgIH1cbiAgfVxufVxuXG5jbGFzcyBFdmVudFJlY29yZCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSxcbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nLFxuICAgIHB1YmxpYyBzdGFydFRpbWU6IG51bWJlcixcbiAgICBwdWJsaWMgZW5kVGltZTogbnVtYmVyLFxuICApIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBQcm9maWxlciB7XG4gIHN0YXRpYyBjcmVhdGUoY29uZmlnPzogUHJvZmlsZXIuQ29uZmlnKTogUHJvZmlsZXIge1xuICAgIGlmIChjb25maWcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIG5ldyB0aGlzKCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgdGhpcyhjb25maWcubWF4TnVtYmVyRXZlbnRzLCBjb25maWcuZmx1c2hCYXRjaFNpemUsIGNvbmZpZy5mbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihtYXhOdW1iZXJFdmVudHM/OiBudW1iZXIsIGZsdXNoQmF0Y2hTaXplPzogbnVtYmVyLCBmbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHM/OiBudW1iZXIpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2U7XG4gICAgdGhpcy5fbWF4TnVtYmVyRXZlbnRzID0gbWF4TnVtYmVyRXZlbnRzID09PSB1bmRlZmluZWQgPyAxMDAwMCA6IG1heE51bWJlckV2ZW50cztcbiAgICB0aGlzLl9mbHVzaEJhdGNoU2l6ZSA9IGZsdXNoQmF0Y2hTaXplID09PSB1bmRlZmluZWQgPyAxMCA6IGZsdXNoQmF0Y2hTaXplO1xuICAgIHRoaXMuX2ZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcyA9IGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcyA9PT0gdW5kZWZpbmVkID8gNTAwMCA6IGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcztcbiAgfVxuXG4gIC8vIHN0YXJ0IHByb2ZpbGluZ1xuICBzdGFydCgpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gdHJ1ZTtcbiAgICB0aGlzLl90aW1pbmdFdmVudHMgPSBbXTtcbiAgICB0aGlzLl9mbHVzaFRpbWUgPSBub3coKTtcbiAgICB0aGlzLl9mbHVzaFBvaW50ZXIgPSAwO1xuICB9XG5cbiAgLy8gc3RvcCBwcm9maWxpbmdcbiAgc3RvcCgpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2U7XG4gICAgZm9yICg7IHRoaXMuX2ZsdXNoUG9pbnRlciA8IHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGg7IHRoaXMuX2ZsdXNoUG9pbnRlcisrKSB7XG4gICAgICB0aGlzLmxvZ09uZUV2ZW50KHRoaXMuX3RpbWluZ0V2ZW50c1t0aGlzLl9mbHVzaFBvaW50ZXJdKTtcbiAgICB9XG4gIH1cblxuICAvLyBjcmVhdGUgYW4gZXZlbnQgc2NvcGUgZm9yIHRoZSBzcGVjaWZpYyBmdW5jdGlvblxuICBldmVudDxUPihjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSwgbmFtZTogc3RyaW5nLCBmdW5jOiAoKSA9PiBULCBjdHg/OiBXZWJHTENvbnRleHQpOiBUO1xuICBldmVudDxUPihjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSwgbmFtZTogc3RyaW5nLCBmdW5jOiAoKSA9PiBQcm9taXNlPFQ+LCBjdHg/OiBXZWJHTENvbnRleHQpOiBQcm9taXNlPFQ+O1xuXG4gIGV2ZW50PFQ+KFxuICAgIGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBmdW5jOiAoKSA9PiBUIHwgUHJvbWlzZTxUPixcbiAgICBjdHg/OiBXZWJHTENvbnRleHQsXG4gICk6IFQgfCBQcm9taXNlPFQ+IHtcbiAgICBjb25zdCBldmVudCA9IHRoaXMuX3N0YXJ0ZWQgPyB0aGlzLmJlZ2luKGNhdGVnb3J5LCBuYW1lLCBjdHgpIDogdW5kZWZpbmVkO1xuICAgIGxldCBpc1Byb21pc2UgPSBmYWxzZTtcblxuICAgIGNvbnN0IHJlcyA9IGZ1bmMoKTtcblxuICAgIC8vIHdlIGNvbnNpZGVyIGEgdGhlbi1hYmxlIG9iamVjdCBpcyBhIHByb21pc2VcbiAgICBpZiAocmVzICYmIHR5cGVvZiAocmVzIGFzIFByb21pc2U8VD4pLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlzUHJvbWlzZSA9IHRydWU7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2U8VD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAocmVzIGFzIFByb21pc2U8VD4pLnRoZW4oXG4gICAgICAgICAgYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAvLyBmdWxmaWxsZWRcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICBhd2FpdCBldmVudC5lbmQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgYXN5bmMgKHJlYXNvbikgPT4ge1xuICAgICAgICAgICAgLy8gcmVqZWN0ZWRcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICBhd2FpdCBldmVudC5lbmQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlamVjdChyZWFzb24pO1xuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKCFpc1Byb21pc2UgJiYgZXZlbnQpIHtcbiAgICAgIGNvbnN0IGV2ZW50UmVzID0gZXZlbnQuZW5kKCk7XG4gICAgICBpZiAoZXZlbnRSZXMgJiYgdHlwZW9mIGV2ZW50UmVzLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBldmVudFJlcy50aGVuKFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAvLyBmdWxmaWxsZWRcbiAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChyZWFzb24pID0+IHtcbiAgICAgICAgICAgICAgLy8gcmVqZWN0ZWRcbiAgICAgICAgICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgLy8gYmVnaW4gYW4gZXZlbnRcbiAgYmVnaW4oY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIG5hbWU6IHN0cmluZywgY3R4PzogV2ViR0xDb250ZXh0KTogRXZlbnQge1xuICAgIGlmICghdGhpcy5fc3RhcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdwcm9maWxlciBpcyBub3Qgc3RhcnRlZCB5ZXQnKTtcbiAgICB9XG4gICAgaWYgKGN0eCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBzdGFydFRpbWUgPSBub3coKTtcbiAgICAgIHRoaXMuZmx1c2goc3RhcnRUaW1lKTtcbiAgICAgIHJldHVybiBuZXcgRXZlbnQoY2F0ZWdvcnksIG5hbWUsIHN0YXJ0VGltZSwgKGUpID0+IHRoaXMuZW5kU3luYyhlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRpbWVyOiBXZWJHTFF1ZXJ5ID0gY3R4LmJlZ2luVGltZXIoKTtcbiAgICAgIHJldHVybiBuZXcgRXZlbnQoY2F0ZWdvcnksIG5hbWUsIDAsIGFzeW5jIChlKSA9PiB0aGlzLmVuZChlKSwgdGltZXIsIGN0eCk7XG4gICAgfVxuICB9XG5cbiAgLy8gZW5kIHRoZSBzcGVjaWZpYyBldmVudFxuICBwcml2YXRlIGFzeW5jIGVuZChldmVudDogRXZlbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBlbmRUaW1lOiBudW1iZXIgPSBhd2FpdCBldmVudC5jaGVja1RpbWVyKCk7XG4gICAgaWYgKHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGggPCB0aGlzLl9tYXhOdW1iZXJFdmVudHMpIHtcbiAgICAgIHRoaXMuX3RpbWluZ0V2ZW50cy5wdXNoKG5ldyBFdmVudFJlY29yZChldmVudC5jYXRlZ29yeSwgZXZlbnQubmFtZSwgZXZlbnQuc3RhcnRUaW1lLCBlbmRUaW1lKSk7XG4gICAgICB0aGlzLmZsdXNoKGVuZFRpbWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZW5kU3luYyhldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBlbmRUaW1lOiBudW1iZXIgPSBub3coKTtcbiAgICBpZiAodGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aCA8IHRoaXMuX21heE51bWJlckV2ZW50cykge1xuICAgICAgdGhpcy5fdGltaW5nRXZlbnRzLnB1c2gobmV3IEV2ZW50UmVjb3JkKGV2ZW50LmNhdGVnb3J5LCBldmVudC5uYW1lLCBldmVudC5zdGFydFRpbWUsIGVuZFRpbWUpKTtcbiAgICAgIHRoaXMuZmx1c2goZW5kVGltZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBsb2dPbmVFdmVudChldmVudDogRXZlbnRSZWNvcmQpIHtcbiAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgIGBQcm9maWxlci4ke2V2ZW50LmNhdGVnb3J5fWAsXG4gICAgICBgJHsoZXZlbnQuZW5kVGltZSAtIGV2ZW50LnN0YXJ0VGltZSkudG9GaXhlZCgyKX1tcyBvbiBldmVudCAnJHtldmVudC5uYW1lfScgYXQgJHtldmVudC5lbmRUaW1lLnRvRml4ZWQoMil9YCxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBmbHVzaChjdXJyZW50VGltZTogbnVtYmVyKSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aCAtIHRoaXMuX2ZsdXNoUG9pbnRlciA+PSB0aGlzLl9mbHVzaEJhdGNoU2l6ZSB8fFxuICAgICAgY3VycmVudFRpbWUgLSB0aGlzLl9mbHVzaFRpbWUgPj0gdGhpcy5fZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzXG4gICAgKSB7XG4gICAgICAvLyBzaG91bGQgZmx1c2ggd2hlbiBlaXRoZXIgYmF0Y2ggc2l6ZSBhY2N1bXVsYXRlZCBvciBpbnRlcnZhbCBlbGVwc2VkXG5cbiAgICAgIGZvciAoXG4gICAgICAgIGNvbnN0IHByZXZpb3VzUG9pbnRlciA9IHRoaXMuX2ZsdXNoUG9pbnRlcjtcbiAgICAgICAgdGhpcy5fZmx1c2hQb2ludGVyIDwgcHJldmlvdXNQb2ludGVyICsgdGhpcy5fZmx1c2hCYXRjaFNpemUgJiYgdGhpcy5fZmx1c2hQb2ludGVyIDwgdGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5fZmx1c2hQb2ludGVyKytcbiAgICAgICkge1xuICAgICAgICB0aGlzLmxvZ09uZUV2ZW50KHRoaXMuX3RpbWluZ0V2ZW50c1t0aGlzLl9mbHVzaFBvaW50ZXJdKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fZmx1c2hUaW1lID0gbm93KCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHN0YXJ0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXJ0ZWQ7XG4gIH1cbiAgcHJpdmF0ZSBfc3RhcnRlZCA9IGZhbHNlO1xuICBwcml2YXRlIF90aW1pbmdFdmVudHM6IEV2ZW50UmVjb3JkW107XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbWF4TnVtYmVyRXZlbnRzOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZmx1c2hCYXRjaFNpemU6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBfZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSBfZmx1c2hUaW1lOiBudW1iZXI7XG4gIHByaXZhdGUgX2ZsdXNoUG9pbnRlciA9IDA7XG59XG5cbi8qKlxuICogcmV0dXJucyBhIG51bWJlciB0byByZXByZXNlbnQgdGhlIGN1cnJlbnQgdGltZXN0YW1wIGluIGEgcmVzb2x1dGlvbiBhcyBoaWdoIGFzIHBvc3NpYmxlLlxuICovXG5leHBvcnQgY29uc3Qgbm93ID0gdHlwZW9mIHBlcmZvcm1hbmNlICE9PSAndW5kZWZpbmVkJyAmJiBwZXJmb3JtYW5jZS5ub3cgPyAoKSA9PiBwZXJmb3JtYW5jZS5ub3coKSA6IERhdGUubm93O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4vb3BlcmF0b3JzJztcblxuZXhwb3J0IGludGVyZmFjZSBPcFNldCB7XG4gIGRvbWFpbjogc3RyaW5nO1xuICB2ZXJzaW9uOiBudW1iZXI7XG59XG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgT3BTZXQge1xuICAvKipcbiAgICogRG9tYWluIG9mIGFuIG9wc2V0LCBpdCBjYW4gYmUgYW4gZW1wdHkgc3RyaW5nKGRlZmF1bHQgdmFsdWUsIHJlcHJlc2VudCBmb3IgYWkub25ueCksIG9yICdhaS5vbm54Lm1sJ1xuICAgKi9cbiAgdHlwZSBEb21haW4gPSAnJyB8ICdhaS5vbm54Lm1sJyB8ICdjb20ubWljcm9zb2Z0JztcbiAgLyoqXG4gICAqIEEgcmVzb2x2ZSBydWxlIGNvbnNpc3RzIG9mIDQgb3IgNSBpdGVtczogb3BUeXBlLCBvcFNldERvbWFpbiwgdmVyc2lvblNlbGVjdG9yLCBvcGVyYXRvckltcGxlbWVudGF0aW9uIGFuZFxuICAgKiBvcGVyYXRvckluaXRpYWxpemF0aW9uIChvcHRpb25hbClcbiAgICovXG4gIHR5cGUgUmVzb2x2ZVJ1bGUgPVxuICAgIHwgW3N0cmluZywgRG9tYWluLCBzdHJpbmcsIE9wZXJhdG9ySW1wbGVtZW50YXRpb248R3JhcGguTm9kZT5dXG4gICAgfCBbc3RyaW5nLCBEb21haW4sIHN0cmluZywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjx1bmtub3duPiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbjx1bmtub3duPl07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlT3BlcmF0b3Iobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBydWxlczogcmVhZG9ubHkgT3BTZXQuUmVzb2x2ZVJ1bGVbXSkge1xuICBmb3IgKGNvbnN0IHJ1bGUgb2YgcnVsZXMpIHtcbiAgICBjb25zdCBvcFR5cGUgPSBydWxlWzBdO1xuICAgIGNvbnN0IGRvbWFpbiA9IHJ1bGVbMV07XG4gICAgY29uc3QgdmVyc2lvblNlbGVjdG9yID0gcnVsZVsyXTtcbiAgICBjb25zdCBvcEltcGwgPSBydWxlWzNdO1xuICAgIGNvbnN0IG9wSW5pdCA9IHJ1bGVbNF07XG5cbiAgICBpZiAobm9kZS5vcFR5cGUgPT09IG9wVHlwZSkge1xuICAgICAgLy8gb3BlcmF0b3IgdHlwZSBtYXRjaGVzXG4gICAgICBmb3IgKGNvbnN0IG9wc2V0IG9mIG9wc2V0cykge1xuICAgICAgICAvLyBvcHNldCAnJyBhbmQgJ2FpLm9ubngnIGFyZSBjb25zaWRlcmVkIHRoZSBzYW1lLlxuICAgICAgICBpZiAob3BzZXQuZG9tYWluID09PSBkb21haW4gfHwgKG9wc2V0LmRvbWFpbiA9PT0gJ2FpLm9ubngnICYmIGRvbWFpbiA9PT0gJycpKSB7XG4gICAgICAgICAgLy8gb3BzZXQgZG9tYWluIGZvdW5kXG4gICAgICAgICAgaWYgKG1hdGNoU2VsZWN0b3Iob3BzZXQudmVyc2lvbiwgdmVyc2lvblNlbGVjdG9yKSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgb3BJbXBsLCBvcEluaXQgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgIGBjYW5ub3QgcmVzb2x2ZSBvcGVyYXRvciAnJHtub2RlLm9wVHlwZX0nIHdpdGggb3BzZXRzOiAke29wc2V0c1xuICAgICAgLm1hcCgoc2V0KSA9PiBgJHtzZXQuZG9tYWluIHx8ICdhaS5vbm54J30gdiR7c2V0LnZlcnNpb259YClcbiAgICAgIC5qb2luKCcsICcpfWAsXG4gICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoU2VsZWN0b3IodmVyc2lvbjogbnVtYmVyLCBzZWxlY3Rvcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChzZWxlY3Rvci5lbmRzV2l0aCgnKycpKSB7XG4gICAgLy8gbWluaW11bSB2ZXJzaW9uIG1hdGNoICgnNysnIGV4cGVjdHMgdmVyc2lvbj49NylcbiAgICBjb25zdCByYW5nZVN0YXJ0ID0gTnVtYmVyLnBhcnNlSW50KHNlbGVjdG9yLnN1YnN0cmluZygwLCBzZWxlY3Rvci5sZW5ndGggLSAxKSwgMTApO1xuICAgIHJldHVybiAhaXNOYU4ocmFuZ2VTdGFydCkgJiYgcmFuZ2VTdGFydCA8PSB2ZXJzaW9uO1xuICB9IGVsc2UgaWYgKHNlbGVjdG9yLnNwbGl0KCctJykubGVuZ3RoID09PSAyKSB7XG4gICAgLy8gcmFuZ2UgbWF0Y2ggKCc2LTgnIGV4cGVjdHMgNjw9dmVyc2lvbjw9OClcbiAgICBjb25zdCBwYWlyID0gc2VsZWN0b3Iuc3BsaXQoJy0nKTtcbiAgICBjb25zdCByYW5nZVN0YXJ0ID0gTnVtYmVyLnBhcnNlSW50KHBhaXJbMF0sIDEwKTtcbiAgICBjb25zdCByYW5nZUVuZCA9IE51bWJlci5wYXJzZUludChwYWlyWzFdLCAxMCk7XG4gICAgcmV0dXJuICFpc05hTihyYW5nZVN0YXJ0KSAmJiAhaXNOYU4ocmFuZ2VFbmQpICYmIHJhbmdlU3RhcnQgPD0gdmVyc2lvbiAmJiB2ZXJzaW9uIDw9IHJhbmdlRW5kO1xuICB9IGVsc2Uge1xuICAgIC8vIGV4YWN0IG1hdGNoICgnNycgZXhwZWN0cyB2ZXJzaW9uPT09NylcbiAgICByZXR1cm4gTnVtYmVyLnBhcnNlSW50KHNlbGVjdG9yLCAxMCkgPT09IHZlcnNpb247XG4gIH1cbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcclxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcclxudmFyIEd1aWQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBHdWlkKGd1aWQpIHtcclxuICAgICAgICBpZiAoIWd1aWQpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXJndW1lbnQ7IGB2YWx1ZWAgaGFzIG5vIHZhbHVlLlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IEd1aWQuRU1QVFk7XHJcbiAgICAgICAgaWYgKGd1aWQgJiYgR3VpZC5pc0d1aWQoZ3VpZCkpIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IGd1aWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgR3VpZC5pc0d1aWQgPSBmdW5jdGlvbiAoZ3VpZCkge1xyXG4gICAgICAgIHZhciB2YWx1ZSA9IGd1aWQudG9TdHJpbmcoKTtcclxuICAgICAgICByZXR1cm4gZ3VpZCAmJiAoZ3VpZCBpbnN0YW5jZW9mIEd1aWQgfHwgR3VpZC52YWxpZGF0b3IudGVzdCh2YWx1ZSkpO1xyXG4gICAgfTtcclxuICAgIEd1aWQuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgR3VpZChbR3VpZC5nZW4oMiksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDMpXS5qb2luKFwiLVwiKSk7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5jcmVhdGVFbXB0eSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEd1aWQoXCJlbXB0eWd1aWRcIik7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5wYXJzZSA9IGZ1bmN0aW9uIChndWlkKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBHdWlkKGd1aWQpO1xyXG4gICAgfTtcclxuICAgIEd1aWQucmF3ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBbR3VpZC5nZW4oMiksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDMpXS5qb2luKFwiLVwiKTtcclxuICAgIH07XHJcbiAgICBHdWlkLmdlbiA9IGZ1bmN0aW9uIChjb3VudCkge1xyXG4gICAgICAgIHZhciBvdXQgPSBcIlwiO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xyXG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYml0d2lzZVxyXG4gICAgICAgICAgICBvdXQgKz0gKCgoMSArIE1hdGgucmFuZG9tKCkpICogMHgxMDAwMCkgfCAwKS50b1N0cmluZygxNikuc3Vic3RyaW5nKDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb3V0O1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgICAgIC8vIENvbXBhcmluZyBzdHJpbmcgYHZhbHVlYCBhZ2FpbnN0IHByb3ZpZGVkIGBndWlkYCB3aWxsIGF1dG8tY2FsbFxyXG4gICAgICAgIC8vIHRvU3RyaW5nIG9uIGBndWlkYCBmb3IgY29tcGFyaXNvblxyXG4gICAgICAgIHJldHVybiBHdWlkLmlzR3VpZChvdGhlcikgJiYgdGhpcy52YWx1ZSA9PT0gb3RoZXIudG9TdHJpbmcoKTtcclxuICAgIH07XHJcbiAgICBHdWlkLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlID09PSBHdWlkLkVNUFRZO1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZVxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgR3VpZC52YWxpZGF0b3IgPSBuZXcgUmVnRXhwKFwiXlthLXowLTldezh9LVthLXowLTldezR9LVthLXowLTldezR9LVthLXowLTldezR9LVthLXowLTldezEyfSRcIiwgXCJpXCIpO1xyXG4gICAgR3VpZC5FTVBUWSA9IFwiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCI7XHJcbiAgICByZXR1cm4gR3VpZDtcclxufSgpKTtcclxuZXhwb3J0cy5HdWlkID0gR3VpZDtcclxuIiwgIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDA5IFRoZSBDbG9zdXJlIExpYnJhcnkgQXV0aG9yc1xuICogQ29weXJpZ2h0IDIwMjAgRGFuaWVsIFdpcnR6IC8gVGhlIGxvbmcuanMgQXV0aG9ycy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuXG4vLyBXZWJBc3NlbWJseSBvcHRpbWl6YXRpb25zIHRvIGRvIG5hdGl2ZSBpNjQgbXVsdGlwbGljYXRpb24gYW5kIGRpdmlkZVxudmFyIHdhc20gPSBudWxsO1xudHJ5IHtcbiAgd2FzbSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZShcbiAgICBuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKFxuICAgICAgbmV3IFVpbnQ4QXJyYXkoW1xuICAgICAgICAvLyBcXDBhc21cbiAgICAgICAgMCwgOTcsIDExNSwgMTA5LFxuICAgICAgICAvLyB2ZXJzaW9uIDFcbiAgICAgICAgMSwgMCwgMCwgMCxcblxuICAgICAgICAvLyBzZWN0aW9uIFwidHlwZVwiXG4gICAgICAgIDEsIDEzLCAyLFxuICAgICAgICAvLyAwLCAoKSA9PiBpMzJcbiAgICAgICAgOTYsIDAsIDEsIDEyNyxcbiAgICAgICAgLy8gMSwgKGkzMiwgaTMyLCBpMzIsIGkzMikgPT4gaTMyXG4gICAgICAgIDk2LCA0LCAxMjcsIDEyNywgMTI3LCAxMjcsIDEsIDEyNyxcblxuICAgICAgICAvLyBzZWN0aW9uIFwiZnVuY3Rpb25cIlxuICAgICAgICAzLCA3LCA2LFxuICAgICAgICAvLyAwLCB0eXBlIDBcbiAgICAgICAgMCxcbiAgICAgICAgLy8gMSwgdHlwZSAxXG4gICAgICAgIDEsXG4gICAgICAgIC8vIDIsIHR5cGUgMVxuICAgICAgICAxLFxuICAgICAgICAvLyAzLCB0eXBlIDFcbiAgICAgICAgMSxcbiAgICAgICAgLy8gNCwgdHlwZSAxXG4gICAgICAgIDEsXG4gICAgICAgIC8vIDUsIHR5cGUgMVxuICAgICAgICAxLFxuXG4gICAgICAgIC8vIHNlY3Rpb24gXCJnbG9iYWxcIlxuICAgICAgICA2LCA2LCAxLFxuICAgICAgICAvLyAwLCBcImhpZ2hcIiwgbXV0YWJsZSBpMzJcbiAgICAgICAgMTI3LCAxLCA2NSwgMCwgMTEsXG5cbiAgICAgICAgLy8gc2VjdGlvbiBcImV4cG9ydFwiXG4gICAgICAgIDcsIDUwLCA2LFxuICAgICAgICAvLyAwLCBcIm11bFwiXG4gICAgICAgIDMsIDEwOSwgMTE3LCAxMDgsIDAsIDEsXG4gICAgICAgIC8vIDEsIFwiZGl2X3NcIlxuICAgICAgICA1LCAxMDAsIDEwNSwgMTE4LCA5NSwgMTE1LCAwLCAyLFxuICAgICAgICAvLyAyLCBcImRpdl91XCJcbiAgICAgICAgNSwgMTAwLCAxMDUsIDExOCwgOTUsIDExNywgMCwgMyxcbiAgICAgICAgLy8gMywgXCJyZW1fc1wiXG4gICAgICAgIDUsIDExNCwgMTAxLCAxMDksIDk1LCAxMTUsIDAsIDQsXG4gICAgICAgIC8vIDQsIFwicmVtX3VcIlxuICAgICAgICA1LCAxMTQsIDEwMSwgMTA5LCA5NSwgMTE3LCAwLCA1LFxuICAgICAgICAvLyA1LCBcImdldF9oaWdoXCJcbiAgICAgICAgOCwgMTAzLCAxMDEsIDExNiwgOTUsIDEwNCwgMTA1LCAxMDMsIDEwNCwgMCwgMCxcblxuICAgICAgICAvLyBzZWN0aW9uIFwiY29kZVwiXG4gICAgICAgIDEwLCAxOTEsIDEsIDYsXG4gICAgICAgIC8vIDAsIFwiZ2V0X2hpZ2hcIlxuICAgICAgICA0LCAwLCAzNSwgMCwgMTEsXG4gICAgICAgIC8vIDEsIFwibXVsXCJcbiAgICAgICAgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsXG4gICAgICAgIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI2LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LFxuICAgICAgICAxNjcsIDExLFxuICAgICAgICAvLyAyLCBcImRpdl9zXCJcbiAgICAgICAgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsXG4gICAgICAgIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI3LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LFxuICAgICAgICAxNjcsIDExLFxuICAgICAgICAvLyAzLCBcImRpdl91XCJcbiAgICAgICAgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsXG4gICAgICAgIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI4LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LFxuICAgICAgICAxNjcsIDExLFxuICAgICAgICAvLyA0LCBcInJlbV9zXCJcbiAgICAgICAgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsXG4gICAgICAgIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI5LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LFxuICAgICAgICAxNjcsIDExLFxuICAgICAgICAvLyA1LCBcInJlbV91XCJcbiAgICAgICAgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsXG4gICAgICAgIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTMwLCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LFxuICAgICAgICAxNjcsIDExLFxuICAgICAgXSksXG4gICAgKSxcbiAgICB7fSxcbiAgKS5leHBvcnRzO1xufSBjYXRjaCB7XG4gIC8vIG5vIHdhc20gc3VwcG9ydCA6KFxufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyLCBnaXZlbiBpdHMgbG93IGFuZCBoaWdoIDMyIGJpdCB2YWx1ZXMgYXMgKnNpZ25lZCogaW50ZWdlcnMuXG4gKiAgU2VlIHRoZSBmcm9tKiBmdW5jdGlvbnMgYmVsb3cgZm9yIG1vcmUgY29udmVuaWVudCB3YXlzIG9mIGNvbnN0cnVjdGluZyBMb25ncy5cbiAqIEBleHBvcnRzIExvbmdcbiAqIEBjbGFzcyBBIExvbmcgY2xhc3MgZm9yIHJlcHJlc2VudGluZyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIgdmFsdWUuXG4gKiBAcGFyYW0ge251bWJlcn0gbG93IFRoZSBsb3cgKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2ggVGhlIGhpZ2ggKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIExvbmcobG93LCBoaWdoLCB1bnNpZ25lZCkge1xuICAvKipcbiAgICogVGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgdGhpcy5sb3cgPSBsb3cgfCAwO1xuXG4gIC8qKlxuICAgKiBUaGUgaGlnaCAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgdGhpcy5oaWdoID0gaGlnaCB8IDA7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIHRoaXMudW5zaWduZWQgPSAhIXVuc2lnbmVkO1xufVxuXG4vLyBUaGUgaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gb2YgYSBsb25nIGlzIHRoZSB0d28gZ2l2ZW4gc2lnbmVkLCAzMi1iaXQgdmFsdWVzLlxuLy8gV2UgdXNlIDMyLWJpdCBwaWVjZXMgYmVjYXVzZSB0aGVzZSBhcmUgdGhlIHNpemUgb2YgaW50ZWdlcnMgb24gd2hpY2hcbi8vIEphdmFzY3JpcHQgcGVyZm9ybXMgYml0LW9wZXJhdGlvbnMuICBGb3Igb3BlcmF0aW9ucyBsaWtlIGFkZGl0aW9uIGFuZFxuLy8gbXVsdGlwbGljYXRpb24sIHdlIHNwbGl0IGVhY2ggbnVtYmVyIGludG8gMTYgYml0IHBpZWNlcywgd2hpY2ggY2FuIGVhc2lseSBiZVxuLy8gbXVsdGlwbGllZCB3aXRoaW4gSmF2YXNjcmlwdCdzIGZsb2F0aW5nLXBvaW50IHJlcHJlc2VudGF0aW9uIHdpdGhvdXQgb3ZlcmZsb3dcbi8vIG9yIGNoYW5nZSBpbiBzaWduLlxuLy9cbi8vIEluIHRoZSBhbGdvcml0aG1zIGJlbG93LCB3ZSBmcmVxdWVudGx5IHJlZHVjZSB0aGUgbmVnYXRpdmUgY2FzZSB0byB0aGVcbi8vIHBvc2l0aXZlIGNhc2UgYnkgbmVnYXRpbmcgdGhlIGlucHV0KHMpIGFuZCB0aGVuIHBvc3QtcHJvY2Vzc2luZyB0aGUgcmVzdWx0LlxuLy8gTm90ZSB0aGF0IHdlIG11c3QgQUxXQVlTIGNoZWNrIHNwZWNpYWxseSB3aGV0aGVyIHRob3NlIHZhbHVlcyBhcmUgTUlOX1ZBTFVFXG4vLyAoLTJeNjMpIGJlY2F1c2UgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUUgKHNpbmNlIDJeNjMgY2Fubm90IGJlIHJlcHJlc2VudGVkIGFzXG4vLyBhIHBvc2l0aXZlIG51bWJlciwgaXQgb3ZlcmZsb3dzIGJhY2sgaW50byBhIG5lZ2F0aXZlKS4gIE5vdCBoYW5kbGluZyB0aGlzXG4vLyBjYXNlIHdvdWxkIG9mdGVuIHJlc3VsdCBpbiBpbmZpbml0ZSByZWN1cnNpb24uXG4vL1xuLy8gQ29tbW9uIGNvbnN0YW50IHZhbHVlcyBaRVJPLCBPTkUsIE5FR19PTkUsIGV0Yy4gYXJlIGRlZmluZWQgYmVsb3cgdGhlIGZyb20qXG4vLyBtZXRob2RzIG9uIHdoaWNoIHRoZXkgZGVwZW5kLlxuXG4vKipcbiAqIEFuIGluZGljYXRvciB1c2VkIHRvIHJlbGlhYmx5IGRldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBMb25nIG9yIG5vdC5cbiAqIEB0eXBlIHtib29sZWFufVxuICogQGNvbnN0XG4gKiBAcHJpdmF0ZVxuICovXG5Mb25nLnByb3RvdHlwZS5fX2lzTG9uZ19fO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoTG9uZy5wcm90b3R5cGUsIFwiX19pc0xvbmdfX1wiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqIEBpbm5lclxuICovXG5mdW5jdGlvbiBpc0xvbmcob2JqKSB7XG4gIHJldHVybiAob2JqICYmIG9ialtcIl9faXNMb25nX19cIl0pID09PSB0cnVlO1xufVxuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHsqfSB2YWx1ZSBudW1iZXJcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gY3R6MzIodmFsdWUpIHtcbiAgdmFyIGMgPSBNYXRoLmNsejMyKHZhbHVlICYgLXZhbHVlKTtcbiAgcmV0dXJuIHZhbHVlID8gMzEgLSBjIDogYztcbn1cblxuLyoqXG4gKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhIExvbmcuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7Kn0gb2JqIE9iamVjdFxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmcuaXNMb25nID0gaXNMb25nO1xuXG4vKipcbiAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIGludGVnZXIgdmFsdWVzLlxuICogQHR5cGUgeyFPYmplY3R9XG4gKiBAaW5uZXJcbiAqL1xudmFyIElOVF9DQUNIRSA9IHt9O1xuXG4vKipcbiAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLlxuICogQHR5cGUgeyFPYmplY3R9XG4gKiBAaW5uZXJcbiAqL1xudmFyIFVJTlRfQ0FDSEUgPSB7fTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbUludCh2YWx1ZSwgdW5zaWduZWQpIHtcbiAgdmFyIG9iaiwgY2FjaGVkT2JqLCBjYWNoZTtcbiAgaWYgKHVuc2lnbmVkKSB7XG4gICAgdmFsdWUgPj4+PSAwO1xuICAgIGlmICgoY2FjaGUgPSAwIDw9IHZhbHVlICYmIHZhbHVlIDwgMjU2KSkge1xuICAgICAgY2FjaGVkT2JqID0gVUlOVF9DQUNIRVt2YWx1ZV07XG4gICAgICBpZiAoY2FjaGVkT2JqKSByZXR1cm4gY2FjaGVkT2JqO1xuICAgIH1cbiAgICBvYmogPSBmcm9tQml0cyh2YWx1ZSwgMCwgdHJ1ZSk7XG4gICAgaWYgKGNhY2hlKSBVSU5UX0NBQ0hFW3ZhbHVlXSA9IG9iajtcbiAgICByZXR1cm4gb2JqO1xuICB9IGVsc2Uge1xuICAgIHZhbHVlIHw9IDA7XG4gICAgaWYgKChjYWNoZSA9IC0xMjggPD0gdmFsdWUgJiYgdmFsdWUgPCAxMjgpKSB7XG4gICAgICBjYWNoZWRPYmogPSBJTlRfQ0FDSEVbdmFsdWVdO1xuICAgICAgaWYgKGNhY2hlZE9iaikgcmV0dXJuIGNhY2hlZE9iajtcbiAgICB9XG4gICAgb2JqID0gZnJvbUJpdHModmFsdWUsIHZhbHVlIDwgMCA/IC0xIDogMCwgZmFsc2UpO1xuICAgIGlmIChjYWNoZSkgSU5UX0NBQ0hFW3ZhbHVlXSA9IG9iajtcbiAgICByZXR1cm4gb2JqO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiAzMiBiaXQgaW50ZWdlciB2YWx1ZS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSAzMiBiaXQgaW50ZWdlciBpbiBxdWVzdGlvblxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbUludCA9IGZyb21JbnQ7XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGZyb21OdW1iZXIodmFsdWUsIHVuc2lnbmVkKSB7XG4gIGlmIChpc05hTih2YWx1ZSkpIHJldHVybiB1bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgaWYgKHVuc2lnbmVkKSB7XG4gICAgaWYgKHZhbHVlIDwgMCkgcmV0dXJuIFVaRVJPO1xuICAgIGlmICh2YWx1ZSA+PSBUV09fUFdSXzY0X0RCTCkgcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRTtcbiAgfSBlbHNlIHtcbiAgICBpZiAodmFsdWUgPD0gLVRXT19QV1JfNjNfREJMKSByZXR1cm4gTUlOX1ZBTFVFO1xuICAgIGlmICh2YWx1ZSArIDEgPj0gVFdPX1BXUl82M19EQkwpIHJldHVybiBNQVhfVkFMVUU7XG4gIH1cbiAgaWYgKHZhbHVlIDwgMCkgcmV0dXJuIGZyb21OdW1iZXIoLXZhbHVlLCB1bnNpZ25lZCkubmVnKCk7XG4gIHJldHVybiBmcm9tQml0cyhcbiAgICB2YWx1ZSAlIFRXT19QV1JfMzJfREJMIHwgMCxcbiAgICAodmFsdWUgLyBUV09fUFdSXzMyX0RCTCkgfCAwLFxuICAgIHVuc2lnbmVkLFxuICApO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gdmFsdWUsIHByb3ZpZGVkIHRoYXQgaXQgaXMgYSBmaW5pdGUgbnVtYmVyLiBPdGhlcndpc2UsIHplcm8gaXMgcmV0dXJuZWQuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgbnVtYmVyIGluIHF1ZXN0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tTnVtYmVyID0gZnJvbU51bWJlcjtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gbG93Qml0c1xuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGZyb21CaXRzKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCkge1xuICByZXR1cm4gbmV3IExvbmcobG93Qml0cywgaGlnaEJpdHMsIHVuc2lnbmVkKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIDY0IGJpdCBpbnRlZ2VyIHRoYXQgY29tZXMgYnkgY29uY2F0ZW5hdGluZyB0aGUgZ2l2ZW4gbG93IGFuZCBoaWdoIGJpdHMuIEVhY2ggaXNcbiAqICBhc3N1bWVkIHRvIHVzZSAzMiBiaXRzLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gbG93Qml0cyBUaGUgbG93IDMyIGJpdHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoQml0cyBUaGUgaGlnaCAzMiBiaXRzXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tQml0cyA9IGZyb21CaXRzO1xuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGJhc2VcbiAqIEBwYXJhbSB7bnVtYmVyfSBleHBvbmVudFxuICogQHJldHVybnMge251bWJlcn1cbiAqIEBpbm5lclxuICovXG52YXIgcG93X2RibCA9IE1hdGgucG93OyAvLyBVc2VkIDQgdGltZXMgKDQqOCB0byAxNSs0KVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7KGJvb2xlYW58bnVtYmVyKT19IHVuc2lnbmVkXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4XG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbVN0cmluZyhzdHIsIHVuc2lnbmVkLCByYWRpeCkge1xuICBpZiAoc3RyLmxlbmd0aCA9PT0gMCkgdGhyb3cgRXJyb3IoXCJlbXB0eSBzdHJpbmdcIik7XG4gIGlmICh0eXBlb2YgdW5zaWduZWQgPT09IFwibnVtYmVyXCIpIHtcbiAgICAvLyBGb3IgZ29vZy5tYXRoLmxvbmcgY29tcGF0aWJpbGl0eVxuICAgIHJhZGl4ID0gdW5zaWduZWQ7XG4gICAgdW5zaWduZWQgPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICB1bnNpZ25lZCA9ICEhdW5zaWduZWQ7XG4gIH1cbiAgaWYgKFxuICAgIHN0ciA9PT0gXCJOYU5cIiB8fFxuICAgIHN0ciA9PT0gXCJJbmZpbml0eVwiIHx8XG4gICAgc3RyID09PSBcIitJbmZpbml0eVwiIHx8XG4gICAgc3RyID09PSBcIi1JbmZpbml0eVwiXG4gIClcbiAgICByZXR1cm4gdW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gIHJhZGl4ID0gcmFkaXggfHwgMTA7XG4gIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeCkgdGhyb3cgUmFuZ2VFcnJvcihcInJhZGl4XCIpO1xuXG4gIHZhciBwO1xuICBpZiAoKHAgPSBzdHIuaW5kZXhPZihcIi1cIikpID4gMCkgdGhyb3cgRXJyb3IoXCJpbnRlcmlvciBoeXBoZW5cIik7XG4gIGVsc2UgaWYgKHAgPT09IDApIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyhzdHIuc3Vic3RyaW5nKDEpLCB1bnNpZ25lZCwgcmFkaXgpLm5lZygpO1xuICB9XG5cbiAgLy8gRG8gc2V2ZXJhbCAoOCkgZGlnaXRzIGVhY2ggdGltZSB0aHJvdWdoIHRoZSBsb29wLCBzbyBhcyB0b1xuICAvLyBtaW5pbWl6ZSB0aGUgY2FsbHMgdG8gdGhlIHZlcnkgZXhwZW5zaXZlIGVtdWxhdGVkIGRpdi5cbiAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgOCkpO1xuXG4gIHZhciByZXN1bHQgPSBaRVJPO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkgKz0gOCkge1xuICAgIHZhciBzaXplID0gTWF0aC5taW4oOCwgc3RyLmxlbmd0aCAtIGkpLFxuICAgICAgdmFsdWUgPSBwYXJzZUludChzdHIuc3Vic3RyaW5nKGksIGkgKyBzaXplKSwgcmFkaXgpO1xuICAgIGlmIChzaXplIDwgOCkge1xuICAgICAgdmFyIHBvd2VyID0gZnJvbU51bWJlcihwb3dfZGJsKHJhZGl4LCBzaXplKSk7XG4gICAgICByZXN1bHQgPSByZXN1bHQubXVsKHBvd2VyKS5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQubXVsKHJhZGl4VG9Qb3dlcik7XG4gICAgICByZXN1bHQgPSByZXN1bHQuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcbiAgICB9XG4gIH1cbiAgcmVzdWx0LnVuc2lnbmVkID0gdW5zaWduZWQ7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIHN0cmluZywgd3JpdHRlbiB1c2luZyB0aGUgc3BlY2lmaWVkIHJhZGl4LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBMb25nXG4gKiBAcGFyYW0geyhib29sZWFufG51bWJlcik9fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFRoZSByYWRpeCBpbiB3aGljaCB0aGUgdGV4dCBpcyB3cml0dGVuICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcbiAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21TdHJpbmcgPSBmcm9tU3RyaW5nO1xuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfCF7bG93OiBudW1iZXIsIGhpZ2g6IG51bWJlciwgdW5zaWduZWQ6IGJvb2xlYW59fSB2YWxcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbVZhbHVlKHZhbCwgdW5zaWduZWQpIHtcbiAgaWYgKHR5cGVvZiB2YWwgPT09IFwibnVtYmVyXCIpIHJldHVybiBmcm9tTnVtYmVyKHZhbCwgdW5zaWduZWQpO1xuICBpZiAodHlwZW9mIHZhbCA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIGZyb21TdHJpbmcodmFsLCB1bnNpZ25lZCk7XG4gIC8vIFRocm93cyBmb3Igbm9uLW9iamVjdHMsIGNvbnZlcnRzIG5vbi1pbnN0YW5jZW9mIExvbmc6XG4gIHJldHVybiBmcm9tQml0cyhcbiAgICB2YWwubG93LFxuICAgIHZhbC5oaWdoLFxuICAgIHR5cGVvZiB1bnNpZ25lZCA9PT0gXCJib29sZWFuXCIgPyB1bnNpZ25lZCA6IHZhbC51bnNpZ25lZCxcbiAgKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIHZhbHVlIHRvIGEgTG9uZyB1c2luZyB0aGUgYXBwcm9wcmlhdGUgZnJvbSogZnVuY3Rpb24gZm9yIGl0cyB0eXBlLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfCF7bG93OiBudW1iZXIsIGhpZ2g6IG51bWJlciwgdW5zaWduZWQ6IGJvb2xlYW59fSB2YWwgVmFsdWVcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqL1xuTG9uZy5mcm9tVmFsdWUgPSBmcm9tVmFsdWU7XG5cbi8vIE5PVEU6IHRoZSBjb21waWxlciBzaG91bGQgaW5saW5lIHRoZXNlIGNvbnN0YW50IHZhbHVlcyBiZWxvdyBhbmQgdGhlbiByZW1vdmUgdGhlc2UgdmFyaWFibGVzLCBzbyB0aGVyZSBzaG91bGQgYmVcbi8vIG5vIHJ1bnRpbWUgcGVuYWx0eSBmb3IgdGhlc2UuXG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzE2X0RCTCA9IDEgPDwgMTY7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzI0X0RCTCA9IDEgPDwgMjQ7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzMyX0RCTCA9IFRXT19QV1JfMTZfREJMICogVFdPX1BXUl8xNl9EQkw7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzY0X0RCTCA9IFRXT19QV1JfMzJfREJMICogVFdPX1BXUl8zMl9EQkw7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzYzX0RCTCA9IFRXT19QV1JfNjRfREJMIC8gMjtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl8yNCA9IGZyb21JbnQoVFdPX1BXUl8yNF9EQkwpO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgWkVSTyA9IGZyb21JbnQoMCk7XG5cbi8qKlxuICogU2lnbmVkIHplcm8uXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuWkVSTyA9IFpFUk87XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBVWkVSTyA9IGZyb21JbnQoMCwgdHJ1ZSk7XG5cbi8qKlxuICogVW5zaWduZWQgemVyby5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5VWkVSTyA9IFVaRVJPO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgT05FID0gZnJvbUludCgxKTtcblxuLyoqXG4gKiBTaWduZWQgb25lLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk9ORSA9IE9ORTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIFVPTkUgPSBmcm9tSW50KDEsIHRydWUpO1xuXG4vKipcbiAqIFVuc2lnbmVkIG9uZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5VT05FID0gVU9ORTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE5FR19PTkUgPSBmcm9tSW50KC0xKTtcblxuLyoqXG4gKiBTaWduZWQgbmVnYXRpdmUgb25lLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk5FR19PTkUgPSBORUdfT05FO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgTUFYX1ZBTFVFID0gZnJvbUJpdHMoMHhmZmZmZmZmZiB8IDAsIDB4N2ZmZmZmZmYgfCAwLCBmYWxzZSk7XG5cbi8qKlxuICogTWF4aW11bSBzaWduZWQgdmFsdWUuXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuTUFYX1ZBTFVFID0gTUFYX1ZBTFVFO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgTUFYX1VOU0lHTkVEX1ZBTFVFID0gZnJvbUJpdHMoMHhmZmZmZmZmZiB8IDAsIDB4ZmZmZmZmZmYgfCAwLCB0cnVlKTtcblxuLyoqXG4gKiBNYXhpbXVtIHVuc2lnbmVkIHZhbHVlLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk1BWF9VTlNJR05FRF9WQUxVRSA9IE1BWF9VTlNJR05FRF9WQUxVRTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE1JTl9WQUxVRSA9IGZyb21CaXRzKDAsIDB4ODAwMDAwMDAgfCAwLCBmYWxzZSk7XG5cbi8qKlxuICogTWluaW11bSBzaWduZWQgdmFsdWUuXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuTUlOX1ZBTFVFID0gTUlOX1ZBTFVFO1xuXG4vKipcbiAqIEBhbGlhcyBMb25nLnByb3RvdHlwZVxuICogQGlubmVyXG4gKi9cbnZhciBMb25nUHJvdG90eXBlID0gTG9uZy5wcm90b3R5cGU7XG5cbi8qKlxuICogQ29udmVydHMgdGhlIExvbmcgdG8gYSAzMiBiaXQgaW50ZWdlciwgYXNzdW1pbmcgaXQgaXMgYSAzMiBiaXQgaW50ZWdlci5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUudG9JbnQgPSBmdW5jdGlvbiB0b0ludCgpIHtcbiAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyB0aGlzLmxvdyA+Pj4gMCA6IHRoaXMubG93O1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBhIHRoZSBuZWFyZXN0IGZsb2F0aW5nLXBvaW50IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgdmFsdWUgKGRvdWJsZSwgNTMgYml0IG1hbnRpc3NhKS5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUudG9OdW1iZXIgPSBmdW5jdGlvbiB0b051bWJlcigpIHtcbiAgaWYgKHRoaXMudW5zaWduZWQpXG4gICAgcmV0dXJuICh0aGlzLmhpZ2ggPj4+IDApICogVFdPX1BXUl8zMl9EQkwgKyAodGhpcy5sb3cgPj4+IDApO1xuICByZXR1cm4gdGhpcy5oaWdoICogVFdPX1BXUl8zMl9EQkwgKyAodGhpcy5sb3cgPj4+IDApO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBhIHN0cmluZyB3cml0dGVuIGluIHRoZSBzcGVjaWZpZWQgcmFkaXguXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFJhZGl4ICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKiBAb3ZlcnJpZGVcbiAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGByYWRpeGAgaXMgb3V0IG9mIHJhbmdlXG4gKi9cbkxvbmdQcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhyYWRpeCkge1xuICByYWRpeCA9IHJhZGl4IHx8IDEwO1xuICBpZiAocmFkaXggPCAyIHx8IDM2IDwgcmFkaXgpIHRocm93IFJhbmdlRXJyb3IoXCJyYWRpeFwiKTtcbiAgaWYgKHRoaXMuaXNaZXJvKCkpIHJldHVybiBcIjBcIjtcbiAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XG4gICAgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXG4gICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSkge1xuICAgICAgLy8gV2UgbmVlZCB0byBjaGFuZ2UgdGhlIExvbmcgdmFsdWUgYmVmb3JlIGl0IGNhbiBiZSBuZWdhdGVkLCBzbyB3ZSByZW1vdmVcbiAgICAgIC8vIHRoZSBib3R0b20tbW9zdCBkaWdpdCBpbiB0aGlzIGJhc2UgYW5kIHRoZW4gcmVjdXJzZSB0byBkbyB0aGUgcmVzdC5cbiAgICAgIHZhciByYWRpeExvbmcgPSBmcm9tTnVtYmVyKHJhZGl4KSxcbiAgICAgICAgZGl2ID0gdGhpcy5kaXYocmFkaXhMb25nKSxcbiAgICAgICAgcmVtMSA9IGRpdi5tdWwocmFkaXhMb25nKS5zdWIodGhpcyk7XG4gICAgICByZXR1cm4gZGl2LnRvU3RyaW5nKHJhZGl4KSArIHJlbTEudG9JbnQoKS50b1N0cmluZyhyYWRpeCk7XG4gICAgfSBlbHNlIHJldHVybiBcIi1cIiArIHRoaXMubmVnKCkudG9TdHJpbmcocmFkaXgpO1xuICB9XG5cbiAgLy8gRG8gc2V2ZXJhbCAoNikgZGlnaXRzIGVhY2ggdGltZSB0aHJvdWdoIHRoZSBsb29wLCBzbyBhcyB0b1xuICAvLyBtaW5pbWl6ZSB0aGUgY2FsbHMgdG8gdGhlIHZlcnkgZXhwZW5zaXZlIGVtdWxhdGVkIGRpdi5cbiAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgNiksIHRoaXMudW5zaWduZWQpLFxuICAgIHJlbSA9IHRoaXM7XG4gIHZhciByZXN1bHQgPSBcIlwiO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHZhciByZW1EaXYgPSByZW0uZGl2KHJhZGl4VG9Qb3dlciksXG4gICAgICBpbnR2YWwgPSByZW0uc3ViKHJlbURpdi5tdWwocmFkaXhUb1Bvd2VyKSkudG9JbnQoKSA+Pj4gMCxcbiAgICAgIGRpZ2l0cyA9IGludHZhbC50b1N0cmluZyhyYWRpeCk7XG4gICAgcmVtID0gcmVtRGl2O1xuICAgIGlmIChyZW0uaXNaZXJvKCkpIHJldHVybiBkaWdpdHMgKyByZXN1bHQ7XG4gICAgZWxzZSB7XG4gICAgICB3aGlsZSAoZGlnaXRzLmxlbmd0aCA8IDYpIGRpZ2l0cyA9IFwiMFwiICsgZGlnaXRzO1xuICAgICAgcmVzdWx0ID0gXCJcIiArIGRpZ2l0cyArIHJlc3VsdDtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogR2V0cyB0aGUgaGlnaCAzMiBiaXRzIGFzIGEgc2lnbmVkIGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgaGlnaCBiaXRzXG4gKi9cbkxvbmdQcm90b3R5cGUuZ2V0SGlnaEJpdHMgPSBmdW5jdGlvbiBnZXRIaWdoQml0cygpIHtcbiAgcmV0dXJuIHRoaXMuaGlnaDtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgaGlnaCAzMiBiaXRzIGFzIGFuIHVuc2lnbmVkIGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBoaWdoIGJpdHNcbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0SGlnaEJpdHNVbnNpZ25lZCgpIHtcbiAgcmV0dXJuIHRoaXMuaGlnaCA+Pj4gMDtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFNpZ25lZCBsb3cgYml0c1xuICovXG5Mb25nUHJvdG90eXBlLmdldExvd0JpdHMgPSBmdW5jdGlvbiBnZXRMb3dCaXRzKCkge1xuICByZXR1cm4gdGhpcy5sb3c7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIGxvdyAzMiBiaXRzIGFzIGFuIHVuc2lnbmVkIGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBsb3cgYml0c1xuICovXG5Mb25nUHJvdG90eXBlLmdldExvd0JpdHNVbnNpZ25lZCA9IGZ1bmN0aW9uIGdldExvd0JpdHNVbnNpZ25lZCgpIHtcbiAgcmV0dXJuIHRoaXMubG93ID4+PiAwO1xufTtcblxuLyoqXG4gKiBHZXRzIHRoZSBudW1iZXIgb2YgYml0cyBuZWVkZWQgdG8gcmVwcmVzZW50IHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGlzIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmdldE51bUJpdHNBYnMgPSBmdW5jdGlvbiBnZXROdW1CaXRzQWJzKCkge1xuICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpXG4gICAgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXG4gICAgcmV0dXJuIHRoaXMuZXEoTUlOX1ZBTFVFKSA/IDY0IDogdGhpcy5uZWcoKS5nZXROdW1CaXRzQWJzKCk7XG4gIHZhciB2YWwgPSB0aGlzLmhpZ2ggIT0gMCA/IHRoaXMuaGlnaCA6IHRoaXMubG93O1xuICBmb3IgKHZhciBiaXQgPSAzMTsgYml0ID4gMDsgYml0LS0pIGlmICgodmFsICYgKDEgPDwgYml0KSkgIT0gMCkgYnJlYWs7XG4gIHJldHVybiB0aGlzLmhpZ2ggIT0gMCA/IGJpdCArIDMzIDogYml0ICsgMTtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nIGNhbiBiZSBzYWZlbHkgcmVwcmVzZW50ZWQgYXMgYSBKYXZhU2NyaXB0IG51bWJlci5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmlzU2FmZUludGVnZXIgPSBmdW5jdGlvbiBpc1NhZmVJbnRlZ2VyKCkge1xuICAvLyAyXjUzLTEgaXMgdGhlIG1heGltdW0gc2FmZSB2YWx1ZVxuICB2YXIgdG9wMTFCaXRzID0gdGhpcy5oaWdoID4+IDIxO1xuICAvLyBbMCwgMl41My0xXVxuICBpZiAoIXRvcDExQml0cykgcmV0dXJuIHRydWU7XG4gIC8vID4gMl41My0xXG4gIGlmICh0aGlzLnVuc2lnbmVkKSByZXR1cm4gZmFsc2U7XG4gIC8vIFstMl41MywgLTFdIGV4Y2VwdCAtMl41M1xuICByZXR1cm4gdG9wMTFCaXRzID09PSAtMSAmJiAhKHRoaXMubG93ID09PSAwICYmIHRoaXMuaGlnaCA9PT0gLTB4MjAwMDAwKTtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHplcm8uXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5pc1plcm8gPSBmdW5jdGlvbiBpc1plcm8oKSB7XG4gIHJldHVybiB0aGlzLmhpZ2ggPT09IDAgJiYgdGhpcy5sb3cgPT09IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB6ZXJvLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2lzWmVyb30uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5lcXogPSBMb25nUHJvdG90eXBlLmlzWmVybztcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBuZWdhdGl2ZS5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmlzTmVnYXRpdmUgPSBmdW5jdGlvbiBpc05lZ2F0aXZlKCkge1xuICByZXR1cm4gIXRoaXMudW5zaWduZWQgJiYgdGhpcy5oaWdoIDwgMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgcG9zaXRpdmUgb3IgemVyby5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmlzUG9zaXRpdmUgPSBmdW5jdGlvbiBpc1Bvc2l0aXZlKCkge1xuICByZXR1cm4gdGhpcy51bnNpZ25lZCB8fCB0aGlzLmhpZ2ggPj0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgb2RkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuaXNPZGQgPSBmdW5jdGlvbiBpc09kZCgpIHtcbiAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAxO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBldmVuLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuaXNFdmVuID0gZnVuY3Rpb24gaXNFdmVuKCkge1xuICByZXR1cm4gKHRoaXMubG93ICYgMSkgPT09IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSkgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICBpZiAoXG4gICAgdGhpcy51bnNpZ25lZCAhPT0gb3RoZXIudW5zaWduZWQgJiZcbiAgICB0aGlzLmhpZ2ggPj4+IDMxID09PSAxICYmXG4gICAgb3RoZXIuaGlnaCA+Pj4gMzEgPT09IDFcbiAgKVxuICAgIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRoaXMuaGlnaCA9PT0gb3RoZXIuaGlnaCAmJiB0aGlzLmxvdyA9PT0gb3RoZXIubG93O1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2VxdWFsc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5lcSA9IExvbmdQcm90b3R5cGUuZXF1YWxzO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubm90RXF1YWxzID0gZnVuY3Rpb24gbm90RXF1YWxzKG90aGVyKSB7XG4gIHJldHVybiAhdGhpcy5lcSgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI25vdEVxdWFsc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5uZXEgPSBMb25nUHJvdG90eXBlLm5vdEVxdWFscztcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI25vdEVxdWFsc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5uZSA9IExvbmdQcm90b3R5cGUubm90RXF1YWxzO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubGVzc1RoYW4gPSBmdW5jdGlvbiBsZXNzVGhhbihvdGhlcikge1xuICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPCAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFufS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmx0ID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbjtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbCA9IGZ1bmN0aW9uIGxlc3NUaGFuT3JFcXVhbChvdGhlcikge1xuICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPD0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbk9yRXF1YWx9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubHRlID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWw7XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbk9yRXF1YWx9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubGUgPSBMb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbDtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuID0gZnVuY3Rpb24gZ3JlYXRlclRoYW4ob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID4gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbn0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ndCA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW47XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBncmVhdGVyVGhhbk9yRXF1YWwob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID49IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW5PckVxdWFsfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmd0ZSA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW5PckVxdWFsfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmdlID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWw7XG5cbi8qKlxuICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxuICogIGlmIHRoZSBnaXZlbiBvbmUgaXMgZ3JlYXRlclxuICovXG5Mb25nUHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSkgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICBpZiAodGhpcy5lcShvdGhlcikpIHJldHVybiAwO1xuICB2YXIgdGhpc05lZyA9IHRoaXMuaXNOZWdhdGl2ZSgpLFxuICAgIG90aGVyTmVnID0gb3RoZXIuaXNOZWdhdGl2ZSgpO1xuICBpZiAodGhpc05lZyAmJiAhb3RoZXJOZWcpIHJldHVybiAtMTtcbiAgaWYgKCF0aGlzTmVnICYmIG90aGVyTmVnKSByZXR1cm4gMTtcbiAgLy8gQXQgdGhpcyBwb2ludCB0aGUgc2lnbiBiaXRzIGFyZSB0aGUgc2FtZVxuICBpZiAoIXRoaXMudW5zaWduZWQpIHJldHVybiB0aGlzLnN1YihvdGhlcikuaXNOZWdhdGl2ZSgpID8gLTEgOiAxO1xuICAvLyBCb3RoIGFyZSBwb3NpdGl2ZSBpZiBhdCBsZWFzdCBvbmUgaXMgdW5zaWduZWRcbiAgcmV0dXJuIG90aGVyLmhpZ2ggPj4+IDAgPiB0aGlzLmhpZ2ggPj4+IDAgfHxcbiAgICAob3RoZXIuaGlnaCA9PT0gdGhpcy5oaWdoICYmIG90aGVyLmxvdyA+Pj4gMCA+IHRoaXMubG93ID4+PiAwKVxuICAgID8gLTFcbiAgICA6IDE7XG59O1xuXG4vKipcbiAqIENvbXBhcmVzIHRoaXMgTG9uZydzIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2NvbXBhcmV9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxuICogIGlmIHRoZSBnaXZlbiBvbmUgaXMgZ3JlYXRlclxuICovXG5Mb25nUHJvdG90eXBlLmNvbXAgPSBMb25nUHJvdG90eXBlLmNvbXBhcmU7XG5cbi8qKlxuICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUubmVnYXRlID0gZnVuY3Rpb24gbmVnYXRlKCkge1xuICBpZiAoIXRoaXMudW5zaWduZWQgJiYgdGhpcy5lcShNSU5fVkFMVUUpKSByZXR1cm4gTUlOX1ZBTFVFO1xuICByZXR1cm4gdGhpcy5ub3QoKS5hZGQoT05FKTtcbn07XG5cbi8qKlxuICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNuZWdhdGV9LlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7IUxvbmd9IE5lZ2F0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLm5lZyA9IExvbmdQcm90b3R5cGUubmVnYXRlO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHN1bSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBhZGRlbmQgQWRkZW5kXG4gKiBAcmV0dXJucyB7IUxvbmd9IFN1bVxuICovXG5Mb25nUHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChhZGRlbmQpIHtcbiAgaWYgKCFpc0xvbmcoYWRkZW5kKSkgYWRkZW5kID0gZnJvbVZhbHVlKGFkZGVuZCk7XG5cbiAgLy8gRGl2aWRlIGVhY2ggbnVtYmVyIGludG8gNCBjaHVua3Mgb2YgMTYgYml0cywgYW5kIHRoZW4gc3VtIHRoZSBjaHVua3MuXG5cbiAgdmFyIGE0OCA9IHRoaXMuaGlnaCA+Pj4gMTY7XG4gIHZhciBhMzIgPSB0aGlzLmhpZ2ggJiAweGZmZmY7XG4gIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XG4gIHZhciBhMDAgPSB0aGlzLmxvdyAmIDB4ZmZmZjtcblxuICB2YXIgYjQ4ID0gYWRkZW5kLmhpZ2ggPj4+IDE2O1xuICB2YXIgYjMyID0gYWRkZW5kLmhpZ2ggJiAweGZmZmY7XG4gIHZhciBiMTYgPSBhZGRlbmQubG93ID4+PiAxNjtcbiAgdmFyIGIwMCA9IGFkZGVuZC5sb3cgJiAweGZmZmY7XG5cbiAgdmFyIGM0OCA9IDAsXG4gICAgYzMyID0gMCxcbiAgICBjMTYgPSAwLFxuICAgIGMwMCA9IDA7XG4gIGMwMCArPSBhMDAgKyBiMDA7XG4gIGMxNiArPSBjMDAgPj4+IDE2O1xuICBjMDAgJj0gMHhmZmZmO1xuICBjMTYgKz0gYTE2ICsgYjE2O1xuICBjMzIgKz0gYzE2ID4+PiAxNjtcbiAgYzE2ICY9IDB4ZmZmZjtcbiAgYzMyICs9IGEzMiArIGIzMjtcbiAgYzQ4ICs9IGMzMiA+Pj4gMTY7XG4gIGMzMiAmPSAweGZmZmY7XG4gIGM0OCArPSBhNDggKyBiNDg7XG4gIGM0OCAmPSAweGZmZmY7XG4gIHJldHVybiBmcm9tQml0cygoYzE2IDw8IDE2KSB8IGMwMCwgKGM0OCA8PCAxNikgfCBjMzIsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxuICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXG4gKi9cbkxvbmdQcm90b3R5cGUuc3VidHJhY3QgPSBmdW5jdGlvbiBzdWJ0cmFjdChzdWJ0cmFoZW5kKSB7XG4gIGlmICghaXNMb25nKHN1YnRyYWhlbmQpKSBzdWJ0cmFoZW5kID0gZnJvbVZhbHVlKHN1YnRyYWhlbmQpO1xuICByZXR1cm4gdGhpcy5hZGQoc3VidHJhaGVuZC5uZWcoKSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2Ugb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3N1YnRyYWN0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gc3VidHJhaGVuZCBTdWJ0cmFoZW5kXG4gKiBAcmV0dXJucyB7IUxvbmd9IERpZmZlcmVuY2VcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zdWIgPSBMb25nUHJvdG90eXBlLnN1YnRyYWN0O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gbXVsdGlwbGllciBNdWx0aXBsaWVyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFByb2R1Y3RcbiAqL1xuTG9uZ1Byb3RvdHlwZS5tdWx0aXBseSA9IGZ1bmN0aW9uIG11bHRpcGx5KG11bHRpcGxpZXIpIHtcbiAgaWYgKHRoaXMuaXNaZXJvKCkpIHJldHVybiB0aGlzO1xuICBpZiAoIWlzTG9uZyhtdWx0aXBsaWVyKSkgbXVsdGlwbGllciA9IGZyb21WYWx1ZShtdWx0aXBsaWVyKTtcblxuICAvLyB1c2Ugd2FzbSBzdXBwb3J0IGlmIHByZXNlbnRcbiAgaWYgKHdhc20pIHtcbiAgICB2YXIgbG93ID0gd2FzbVtcIm11bFwiXSh0aGlzLmxvdywgdGhpcy5oaWdoLCBtdWx0aXBsaWVyLmxvdywgbXVsdGlwbGllci5oaWdoKTtcbiAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtW1wiZ2V0X2hpZ2hcIl0oKSwgdGhpcy51bnNpZ25lZCk7XG4gIH1cblxuICBpZiAobXVsdGlwbGllci5pc1plcm8oKSkgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHJldHVybiBtdWx0aXBsaWVyLmlzT2RkKCkgPyBNSU5fVkFMVUUgOiBaRVJPO1xuICBpZiAobXVsdGlwbGllci5lcShNSU5fVkFMVUUpKSByZXR1cm4gdGhpcy5pc09kZCgpID8gTUlOX1ZBTFVFIDogWkVSTztcblxuICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHtcbiAgICBpZiAobXVsdGlwbGllci5pc05lZ2F0aXZlKCkpIHJldHVybiB0aGlzLm5lZygpLm11bChtdWx0aXBsaWVyLm5lZygpKTtcbiAgICBlbHNlIHJldHVybiB0aGlzLm5lZygpLm11bChtdWx0aXBsaWVyKS5uZWcoKTtcbiAgfSBlbHNlIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSkgcmV0dXJuIHRoaXMubXVsKG11bHRpcGxpZXIubmVnKCkpLm5lZygpO1xuXG4gIC8vIElmIGJvdGggbG9uZ3MgYXJlIHNtYWxsLCB1c2UgZmxvYXQgbXVsdGlwbGljYXRpb25cbiAgaWYgKHRoaXMubHQoVFdPX1BXUl8yNCkgJiYgbXVsdGlwbGllci5sdChUV09fUFdSXzI0KSlcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLnRvTnVtYmVyKCkgKiBtdWx0aXBsaWVyLnRvTnVtYmVyKCksIHRoaXMudW5zaWduZWQpO1xuXG4gIC8vIERpdmlkZSBlYWNoIGxvbmcgaW50byA0IGNodW5rcyBvZiAxNiBiaXRzLCBhbmQgdGhlbiBhZGQgdXAgNHg0IHByb2R1Y3RzLlxuICAvLyBXZSBjYW4gc2tpcCBwcm9kdWN0cyB0aGF0IHdvdWxkIG92ZXJmbG93LlxuXG4gIHZhciBhNDggPSB0aGlzLmhpZ2ggPj4+IDE2O1xuICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhmZmZmO1xuICB2YXIgYTE2ID0gdGhpcy5sb3cgPj4+IDE2O1xuICB2YXIgYTAwID0gdGhpcy5sb3cgJiAweGZmZmY7XG5cbiAgdmFyIGI0OCA9IG11bHRpcGxpZXIuaGlnaCA+Pj4gMTY7XG4gIHZhciBiMzIgPSBtdWx0aXBsaWVyLmhpZ2ggJiAweGZmZmY7XG4gIHZhciBiMTYgPSBtdWx0aXBsaWVyLmxvdyA+Pj4gMTY7XG4gIHZhciBiMDAgPSBtdWx0aXBsaWVyLmxvdyAmIDB4ZmZmZjtcblxuICB2YXIgYzQ4ID0gMCxcbiAgICBjMzIgPSAwLFxuICAgIGMxNiA9IDAsXG4gICAgYzAwID0gMDtcbiAgYzAwICs9IGEwMCAqIGIwMDtcbiAgYzE2ICs9IGMwMCA+Pj4gMTY7XG4gIGMwMCAmPSAweGZmZmY7XG4gIGMxNiArPSBhMTYgKiBiMDA7XG4gIGMzMiArPSBjMTYgPj4+IDE2O1xuICBjMTYgJj0gMHhmZmZmO1xuICBjMTYgKz0gYTAwICogYjE2O1xuICBjMzIgKz0gYzE2ID4+PiAxNjtcbiAgYzE2ICY9IDB4ZmZmZjtcbiAgYzMyICs9IGEzMiAqIGIwMDtcbiAgYzQ4ICs9IGMzMiA+Pj4gMTY7XG4gIGMzMiAmPSAweGZmZmY7XG4gIGMzMiArPSBhMTYgKiBiMTY7XG4gIGM0OCArPSBjMzIgPj4+IDE2O1xuICBjMzIgJj0gMHhmZmZmO1xuICBjMzIgKz0gYTAwICogYjMyO1xuICBjNDggKz0gYzMyID4+PiAxNjtcbiAgYzMyICY9IDB4ZmZmZjtcbiAgYzQ4ICs9IGE0OCAqIGIwMCArIGEzMiAqIGIxNiArIGExNiAqIGIzMiArIGEwMCAqIGI0ODtcbiAgYzQ4ICY9IDB4ZmZmZjtcbiAgcmV0dXJuIGZyb21CaXRzKChjMTYgPDwgMTYpIHwgYzAwLCAoYzQ4IDw8IDE2KSB8IGMzMiwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI211bHRpcGx5fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gbXVsdGlwbGllciBNdWx0aXBsaWVyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFByb2R1Y3RcbiAqL1xuTG9uZ1Byb3RvdHlwZS5tdWwgPSBMb25nUHJvdG90eXBlLm11bHRpcGx5O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhlIHJlc3VsdCBpcyBzaWduZWQgaWYgdGhpcyBMb25nIGlzIHNpZ25lZCBvclxuICogIHVuc2lnbmVkIGlmIHRoaXMgTG9uZyBpcyB1bnNpZ25lZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBRdW90aWVudFxuICovXG5Mb25nUHJvdG90eXBlLmRpdmlkZSA9IGZ1bmN0aW9uIGRpdmlkZShkaXZpc29yKSB7XG4gIGlmICghaXNMb25nKGRpdmlzb3IpKSBkaXZpc29yID0gZnJvbVZhbHVlKGRpdmlzb3IpO1xuICBpZiAoZGl2aXNvci5pc1plcm8oKSkgdGhyb3cgRXJyb3IoXCJkaXZpc2lvbiBieSB6ZXJvXCIpO1xuXG4gIC8vIHVzZSB3YXNtIHN1cHBvcnQgaWYgcHJlc2VudFxuICBpZiAod2FzbSkge1xuICAgIC8vIGd1YXJkIGFnYWluc3Qgc2lnbmVkIGRpdmlzaW9uIG92ZXJmbG93OiB0aGUgbGFyZ2VzdFxuICAgIC8vIG5lZ2F0aXZlIG51bWJlciAvIC0xIHdvdWxkIGJlIDEgbGFyZ2VyIHRoYW4gdGhlIGxhcmdlc3RcbiAgICAvLyBwb3NpdGl2ZSBudW1iZXIsIGR1ZSB0byB0d28ncyBjb21wbGVtZW50LlxuICAgIGlmIChcbiAgICAgICF0aGlzLnVuc2lnbmVkICYmXG4gICAgICB0aGlzLmhpZ2ggPT09IC0weDgwMDAwMDAwICYmXG4gICAgICBkaXZpc29yLmxvdyA9PT0gLTEgJiZcbiAgICAgIGRpdmlzb3IuaGlnaCA9PT0gLTFcbiAgICApIHtcbiAgICAgIC8vIGJlIGNvbnNpc3RlbnQgd2l0aCBub24td2FzbSBjb2RlIHBhdGhcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB2YXIgbG93ID0gKHRoaXMudW5zaWduZWQgPyB3YXNtW1wiZGl2X3VcIl0gOiB3YXNtW1wiZGl2X3NcIl0pKFxuICAgICAgdGhpcy5sb3csXG4gICAgICB0aGlzLmhpZ2gsXG4gICAgICBkaXZpc29yLmxvdyxcbiAgICAgIGRpdmlzb3IuaGlnaCxcbiAgICApO1xuICAgIHJldHVybiBmcm9tQml0cyhsb3csIHdhc21bXCJnZXRfaGlnaFwiXSgpLCB0aGlzLnVuc2lnbmVkKTtcbiAgfVxuXG4gIGlmICh0aGlzLmlzWmVybygpKSByZXR1cm4gdGhpcy51bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgdmFyIGFwcHJveCwgcmVtLCByZXM7XG4gIGlmICghdGhpcy51bnNpZ25lZCkge1xuICAgIC8vIFRoaXMgc2VjdGlvbiBpcyBvbmx5IHJlbGV2YW50IGZvciBzaWduZWQgbG9uZ3MgYW5kIGlzIGRlcml2ZWQgZnJvbSB0aGVcbiAgICAvLyBjbG9zdXJlIGxpYnJhcnkgYXMgYSB3aG9sZS5cbiAgICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKSB7XG4gICAgICBpZiAoZGl2aXNvci5lcShPTkUpIHx8IGRpdmlzb3IuZXEoTkVHX09ORSkpXG4gICAgICAgIHJldHVybiBNSU5fVkFMVUU7IC8vIHJlY2FsbCB0aGF0IC1NSU5fVkFMVUUgPT0gTUlOX1ZBTFVFXG4gICAgICBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpIHJldHVybiBPTkU7XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgd2UgaGF2ZSB8b3RoZXJ8ID49IDIsIHNvIHx0aGlzL290aGVyfCA8IHxNSU5fVkFMVUV8LlxuICAgICAgICB2YXIgaGFsZlRoaXMgPSB0aGlzLnNocigxKTtcbiAgICAgICAgYXBwcm94ID0gaGFsZlRoaXMuZGl2KGRpdmlzb3IpLnNobCgxKTtcbiAgICAgICAgaWYgKGFwcHJveC5lcShaRVJPKSkge1xuICAgICAgICAgIHJldHVybiBkaXZpc29yLmlzTmVnYXRpdmUoKSA/IE9ORSA6IE5FR19PTkU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVtID0gdGhpcy5zdWIoZGl2aXNvci5tdWwoYXBwcm94KSk7XG4gICAgICAgICAgcmVzID0gYXBwcm94LmFkZChyZW0uZGl2KGRpdmlzb3IpKTtcbiAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xuICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xuICAgICAgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKSByZXR1cm4gdGhpcy5uZWcoKS5kaXYoZGl2aXNvci5uZWcoKSk7XG4gICAgICByZXR1cm4gdGhpcy5uZWcoKS5kaXYoZGl2aXNvcikubmVnKCk7XG4gICAgfSBlbHNlIGlmIChkaXZpc29yLmlzTmVnYXRpdmUoKSkgcmV0dXJuIHRoaXMuZGl2KGRpdmlzb3IubmVnKCkpLm5lZygpO1xuICAgIHJlcyA9IFpFUk87XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhlIGFsZ29yaXRobSBiZWxvdyBoYXMgbm90IGJlZW4gbWFkZSBmb3IgdW5zaWduZWQgbG9uZ3MuIEl0J3MgdGhlcmVmb3JlXG4gICAgLy8gcmVxdWlyZWQgdG8gdGFrZSBzcGVjaWFsIGNhcmUgb2YgdGhlIE1TQiBwcmlvciB0byBydW5uaW5nIGl0LlxuICAgIGlmICghZGl2aXNvci51bnNpZ25lZCkgZGl2aXNvciA9IGRpdmlzb3IudG9VbnNpZ25lZCgpO1xuICAgIGlmIChkaXZpc29yLmd0KHRoaXMpKSByZXR1cm4gVVpFUk87XG4gICAgaWYgKGRpdmlzb3IuZ3QodGhpcy5zaHJ1KDEpKSlcbiAgICAgIC8vIDE1ID4+PiAxID0gNyA7IHdpdGggZGl2aXNvciA9IDggOyB0cnVlXG4gICAgICByZXR1cm4gVU9ORTtcbiAgICByZXMgPSBVWkVSTztcbiAgfVxuXG4gIC8vIFJlcGVhdCB0aGUgZm9sbG93aW5nIHVudGlsIHRoZSByZW1haW5kZXIgaXMgbGVzcyB0aGFuIG90aGVyOiAgZmluZCBhXG4gIC8vIGZsb2F0aW5nLXBvaW50IHRoYXQgYXBwcm94aW1hdGVzIHJlbWFpbmRlciAvIG90aGVyICpmcm9tIGJlbG93KiwgYWRkIHRoaXNcbiAgLy8gaW50byB0aGUgcmVzdWx0LCBhbmQgc3VidHJhY3QgaXQgZnJvbSB0aGUgcmVtYWluZGVyLiAgSXQgaXMgY3JpdGljYWwgdGhhdFxuICAvLyB0aGUgYXBwcm94aW1hdGUgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSByZWFsIHZhbHVlIHNvIHRoYXQgdGhlXG4gIC8vIHJlbWFpbmRlciBuZXZlciBiZWNvbWVzIG5lZ2F0aXZlLlxuICByZW0gPSB0aGlzO1xuICB3aGlsZSAocmVtLmd0ZShkaXZpc29yKSkge1xuICAgIC8vIEFwcHJveGltYXRlIHRoZSByZXN1bHQgb2YgZGl2aXNpb24uIFRoaXMgbWF5IGJlIGEgbGl0dGxlIGdyZWF0ZXIgb3JcbiAgICAvLyBzbWFsbGVyIHRoYW4gdGhlIGFjdHVhbCB2YWx1ZS5cbiAgICBhcHByb3ggPSBNYXRoLm1heCgxLCBNYXRoLmZsb29yKHJlbS50b051bWJlcigpIC8gZGl2aXNvci50b051bWJlcigpKSk7XG5cbiAgICAvLyBXZSB3aWxsIHR3ZWFrIHRoZSBhcHByb3hpbWF0ZSByZXN1bHQgYnkgY2hhbmdpbmcgaXQgaW4gdGhlIDQ4LXRoIGRpZ2l0IG9yXG4gICAgLy8gdGhlIHNtYWxsZXN0IG5vbi1mcmFjdGlvbmFsIGRpZ2l0LCB3aGljaGV2ZXIgaXMgbGFyZ2VyLlxuICAgIHZhciBsb2cyID0gTWF0aC5jZWlsKE1hdGgubG9nKGFwcHJveCkgLyBNYXRoLkxOMiksXG4gICAgICBkZWx0YSA9IGxvZzIgPD0gNDggPyAxIDogcG93X2RibCgyLCBsb2cyIC0gNDgpLFxuICAgICAgLy8gRGVjcmVhc2UgdGhlIGFwcHJveGltYXRpb24gdW50aWwgaXQgaXMgc21hbGxlciB0aGFuIHRoZSByZW1haW5kZXIuICBOb3RlXG4gICAgICAvLyB0aGF0IGlmIGl0IGlzIHRvbyBsYXJnZSwgdGhlIHByb2R1Y3Qgb3ZlcmZsb3dzIGFuZCBpcyBuZWdhdGl2ZS5cbiAgICAgIGFwcHJveFJlcyA9IGZyb21OdW1iZXIoYXBwcm94KSxcbiAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XG4gICAgd2hpbGUgKGFwcHJveFJlbS5pc05lZ2F0aXZlKCkgfHwgYXBwcm94UmVtLmd0KHJlbSkpIHtcbiAgICAgIGFwcHJveCAtPSBkZWx0YTtcbiAgICAgIGFwcHJveFJlcyA9IGZyb21OdW1iZXIoYXBwcm94LCB0aGlzLnVuc2lnbmVkKTtcbiAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XG4gICAgfVxuXG4gICAgLy8gV2Uga25vdyB0aGUgYW5zd2VyIGNhbid0IGJlIHplcm8uLi4gYW5kIGFjdHVhbGx5LCB6ZXJvIHdvdWxkIGNhdXNlXG4gICAgLy8gaW5maW5pdGUgcmVjdXJzaW9uIHNpbmNlIHdlIHdvdWxkIG1ha2Ugbm8gcHJvZ3Jlc3MuXG4gICAgaWYgKGFwcHJveFJlcy5pc1plcm8oKSkgYXBwcm94UmVzID0gT05FO1xuXG4gICAgcmVzID0gcmVzLmFkZChhcHByb3hSZXMpO1xuICAgIHJlbSA9IHJlbS5zdWIoYXBwcm94UmVtKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBkaXZpZGVkIGJ5IHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZGl2aWRlfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XG4gKi9cbkxvbmdQcm90b3R5cGUuZGl2ID0gTG9uZ1Byb3RvdHlwZS5kaXZpZGU7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcbiAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXG4gKi9cbkxvbmdQcm90b3R5cGUubW9kdWxvID0gZnVuY3Rpb24gbW9kdWxvKGRpdmlzb3IpIHtcbiAgaWYgKCFpc0xvbmcoZGl2aXNvcikpIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XG5cbiAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XG4gIGlmICh3YXNtKSB7XG4gICAgdmFyIGxvdyA9ICh0aGlzLnVuc2lnbmVkID8gd2FzbVtcInJlbV91XCJdIDogd2FzbVtcInJlbV9zXCJdKShcbiAgICAgIHRoaXMubG93LFxuICAgICAgdGhpcy5oaWdoLFxuICAgICAgZGl2aXNvci5sb3csXG4gICAgICBkaXZpc29yLmhpZ2gsXG4gICAgKTtcbiAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtW1wiZ2V0X2hpZ2hcIl0oKSwgdGhpcy51bnNpZ25lZCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5zdWIodGhpcy5kaXYoZGl2aXNvcikubXVsKGRpdmlzb3IpKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbW9kdWxvfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxuICovXG5Mb25nUHJvdG90eXBlLm1vZCA9IExvbmdQcm90b3R5cGUubW9kdWxvO1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIG1vZHVsbyB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI21vZHVsb30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcbiAqL1xuTG9uZ1Byb3RvdHlwZS5yZW0gPSBMb25nUHJvdG90eXBlLm1vZHVsbztcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIE5PVCBvZiB0aGlzIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmdQcm90b3R5cGUubm90ID0gZnVuY3Rpb24gbm90KCkge1xuICByZXR1cm4gZnJvbUJpdHMofnRoaXMubG93LCB+dGhpcy5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBjb3VudCBsZWFkaW5nIHplcm9zIG9mIHRoaXMgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshbnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmNvdW50TGVhZGluZ1plcm9zID0gZnVuY3Rpb24gY291bnRMZWFkaW5nWmVyb3MoKSB7XG4gIHJldHVybiB0aGlzLmhpZ2ggPyBNYXRoLmNsejMyKHRoaXMuaGlnaCkgOiBNYXRoLmNsejMyKHRoaXMubG93KSArIDMyO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IGxlYWRpbmcgemVyb3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY291bnRMZWFkaW5nWmVyb3N9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfVxuICogQHJldHVybnMgeyFudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUuY2x6ID0gTG9uZ1Byb3RvdHlwZS5jb3VudExlYWRpbmdaZXJvcztcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IHRyYWlsaW5nIHplcm9zIG9mIHRoaXMgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshbnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmNvdW50VHJhaWxpbmdaZXJvcyA9IGZ1bmN0aW9uIGNvdW50VHJhaWxpbmdaZXJvcygpIHtcbiAgcmV0dXJuIHRoaXMubG93ID8gY3R6MzIodGhpcy5sb3cpIDogY3R6MzIodGhpcy5oaWdoKSArIDMyO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IHRyYWlsaW5nIHplcm9zLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2NvdW50VHJhaWxpbmdaZXJvc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IW51bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5jdHogPSBMb25nUHJvdG90eXBlLmNvdW50VHJhaWxpbmdaZXJvcztcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIEFORCBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmdQcm90b3R5cGUuYW5kID0gZnVuY3Rpb24gYW5kKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSkgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgJiBvdGhlci5sb3csIHRoaXMuaGlnaCAmIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIE9SIG9mIHRoaXMgTG9uZyBhbmQgdGhlIHNwZWNpZmllZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqL1xuTG9uZ1Byb3RvdHlwZS5vciA9IGZ1bmN0aW9uIG9yKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSkgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgfCBvdGhlci5sb3csIHRoaXMuaGlnaCB8IG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIFhPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBnaXZlbiBvbmUuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmdQcm90b3R5cGUueG9yID0gZnVuY3Rpb24geG9yKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSkgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgXiBvdGhlci5sb3csIHRoaXMuaGlnaCBeIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgc2hpZnRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hpZnRMZWZ0ID0gZnVuY3Rpb24gc2hpZnRMZWZ0KG51bUJpdHMpIHtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gIGVsc2UgaWYgKG51bUJpdHMgPCAzMilcbiAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICB0aGlzLmxvdyA8PCBudW1CaXRzLFxuICAgICAgKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gKDMyIC0gbnVtQml0cykpLFxuICAgICAgdGhpcy51bnNpZ25lZCxcbiAgICApO1xuICBlbHNlIHJldHVybiBmcm9tQml0cygwLCB0aGlzLmxvdyA8PCAobnVtQml0cyAtIDMyKSwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRMZWZ0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hsID0gTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQ7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0ID0gZnVuY3Rpb24gc2hpZnRSaWdodChudW1CaXRzKSB7XG4gIGlmIChpc0xvbmcobnVtQml0cykpIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XG4gIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApIHJldHVybiB0aGlzO1xuICBlbHNlIGlmIChudW1CaXRzIDwgMzIpXG4gICAgcmV0dXJuIGZyb21CaXRzKFxuICAgICAgKHRoaXMubG93ID4+PiBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPDwgKDMyIC0gbnVtQml0cykpLFxuICAgICAgdGhpcy5oaWdoID4+IG51bUJpdHMsXG4gICAgICB0aGlzLnVuc2lnbmVkLFxuICAgICk7XG4gIGVsc2VcbiAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICB0aGlzLmhpZ2ggPj4gKG51bUJpdHMgLSAzMiksXG4gICAgICB0aGlzLmhpZ2ggPj0gMCA/IDAgOiAtMSxcbiAgICAgIHRoaXMudW5zaWduZWQsXG4gICAgKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNociA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQgPSBmdW5jdGlvbiBzaGlmdFJpZ2h0VW5zaWduZWQobnVtQml0cykge1xuICBpZiAoaXNMb25nKG51bUJpdHMpKSBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xuICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKSByZXR1cm4gdGhpcztcbiAgaWYgKG51bUJpdHMgPCAzMilcbiAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICAodGhpcy5sb3cgPj4+IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA8PCAoMzIgLSBudW1CaXRzKSksXG4gICAgICB0aGlzLmhpZ2ggPj4+IG51bUJpdHMsXG4gICAgICB0aGlzLnVuc2lnbmVkLFxuICAgICk7XG4gIGlmIChudW1CaXRzID09PSAzMikgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCwgMCwgdGhpcy51bnNpZ25lZCk7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2ggPj4+IChudW1CaXRzIC0gMzIpLCAwLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGxvZ2ljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0UmlnaHRVbnNpZ25lZH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNocnUgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hyX3UgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgcm90YXRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gUm90YXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUucm90YXRlTGVmdCA9IGZ1bmN0aW9uIHJvdGF0ZUxlZnQobnVtQml0cykge1xuICB2YXIgYjtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gIGlmIChudW1CaXRzID09PSAzMikgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCwgdGhpcy5sb3csIHRoaXMudW5zaWduZWQpO1xuICBpZiAobnVtQml0cyA8IDMyKSB7XG4gICAgYiA9IDMyIC0gbnVtQml0cztcbiAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICAodGhpcy5sb3cgPDwgbnVtQml0cykgfCAodGhpcy5oaWdoID4+PiBiKSxcbiAgICAgICh0aGlzLmhpZ2ggPDwgbnVtQml0cykgfCAodGhpcy5sb3cgPj4+IGIpLFxuICAgICAgdGhpcy51bnNpZ25lZCxcbiAgICApO1xuICB9XG4gIG51bUJpdHMgLT0gMzI7XG4gIGIgPSAzMiAtIG51bUJpdHM7XG4gIHJldHVybiBmcm9tQml0cyhcbiAgICAodGhpcy5oaWdoIDw8IG51bUJpdHMpIHwgKHRoaXMubG93ID4+PiBiKSxcbiAgICAodGhpcy5sb3cgPDwgbnVtQml0cykgfCAodGhpcy5oaWdoID4+PiBiKSxcbiAgICB0aGlzLnVuc2lnbmVkLFxuICApO1xufTtcbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHJvdGF0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNyb3RhdGVMZWZ0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gUm90YXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUucm90bCA9IExvbmdQcm90b3R5cGUucm90YXRlTGVmdDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgcm90YXRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJvdGF0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnJvdGF0ZVJpZ2h0ID0gZnVuY3Rpb24gcm90YXRlUmlnaHQobnVtQml0cykge1xuICB2YXIgYjtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gIGlmIChudW1CaXRzID09PSAzMikgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCwgdGhpcy5sb3csIHRoaXMudW5zaWduZWQpO1xuICBpZiAobnVtQml0cyA8IDMyKSB7XG4gICAgYiA9IDMyIC0gbnVtQml0cztcbiAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICAodGhpcy5oaWdoIDw8IGIpIHwgKHRoaXMubG93ID4+PiBudW1CaXRzKSxcbiAgICAgICh0aGlzLmxvdyA8PCBiKSB8ICh0aGlzLmhpZ2ggPj4+IG51bUJpdHMpLFxuICAgICAgdGhpcy51bnNpZ25lZCxcbiAgICApO1xuICB9XG4gIG51bUJpdHMgLT0gMzI7XG4gIGIgPSAzMiAtIG51bUJpdHM7XG4gIHJldHVybiBmcm9tQml0cyhcbiAgICAodGhpcy5sb3cgPDwgYikgfCAodGhpcy5oaWdoID4+PiBudW1CaXRzKSxcbiAgICAodGhpcy5oaWdoIDw8IGIpIHwgKHRoaXMubG93ID4+PiBudW1CaXRzKSxcbiAgICB0aGlzLnVuc2lnbmVkLFxuICApO1xufTtcbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHJvdGF0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjcm90YXRlUmlnaHR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBSb3RhdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5yb3RyID0gTG9uZ1Byb3RvdHlwZS5yb3RhdGVSaWdodDtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gc2lnbmVkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnRvU2lnbmVkID0gZnVuY3Rpb24gdG9TaWduZWQoKSB7XG4gIGlmICghdGhpcy51bnNpZ25lZCkgcmV0dXJuIHRoaXM7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdywgdGhpcy5oaWdoLCBmYWxzZSk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byB1bnNpZ25lZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshTG9uZ30gVW5zaWduZWQgbG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnRvVW5zaWduZWQgPSBmdW5jdGlvbiB0b1Vuc2lnbmVkKCkge1xuICBpZiAodGhpcy51bnNpZ25lZCkgcmV0dXJuIHRoaXM7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdywgdGhpcy5oaWdoLCB0cnVlKTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxuICogQHBhcmFtIHtib29sZWFuPX0gbGUgV2hldGhlciBsaXR0bGUgb3IgYmlnIGVuZGlhbiwgZGVmYXVsdHMgdG8gYmlnIGVuZGlhblxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQnl0ZSByZXByZXNlbnRhdGlvblxuICovXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXMgPSBmdW5jdGlvbiB0b0J5dGVzKGxlKSB7XG4gIHJldHVybiBsZSA/IHRoaXMudG9CeXRlc0xFKCkgOiB0aGlzLnRvQnl0ZXNCRSgpO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGxpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshQXJyYXkuPG51bWJlcj59IExpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvblxuICovXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXNMRSA9IGZ1bmN0aW9uIHRvQnl0ZXNMRSgpIHtcbiAgdmFyIGhpID0gdGhpcy5oaWdoLFxuICAgIGxvID0gdGhpcy5sb3c7XG4gIHJldHVybiBbXG4gICAgbG8gJiAweGZmLFxuICAgIChsbyA+Pj4gOCkgJiAweGZmLFxuICAgIChsbyA+Pj4gMTYpICYgMHhmZixcbiAgICBsbyA+Pj4gMjQsXG4gICAgaGkgJiAweGZmLFxuICAgIChoaSA+Pj4gOCkgJiAweGZmLFxuICAgIChoaSA+Pj4gMTYpICYgMHhmZixcbiAgICBoaSA+Pj4gMjQsXG4gIF07XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgYmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXG4gKi9cbkxvbmdQcm90b3R5cGUudG9CeXRlc0JFID0gZnVuY3Rpb24gdG9CeXRlc0JFKCkge1xuICB2YXIgaGkgPSB0aGlzLmhpZ2gsXG4gICAgbG8gPSB0aGlzLmxvdztcbiAgcmV0dXJuIFtcbiAgICBoaSA+Pj4gMjQsXG4gICAgKGhpID4+PiAxNikgJiAweGZmLFxuICAgIChoaSA+Pj4gOCkgJiAweGZmLFxuICAgIGhpICYgMHhmZixcbiAgICBsbyA+Pj4gMjQsXG4gICAgKGxvID4+PiAxNikgJiAweGZmLFxuICAgIChsbyA+Pj4gOCkgJiAweGZmLFxuICAgIGxvICYgMHhmZixcbiAgXTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBCeXRlIHJlcHJlc2VudGF0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBsZSBXaGV0aGVyIGxpdHRsZSBvciBiaWcgZW5kaWFuLCBkZWZhdWx0cyB0byBiaWcgZW5kaWFuXG4gKiBAcmV0dXJucyB7TG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21CeXRlcyA9IGZ1bmN0aW9uIGZyb21CeXRlcyhieXRlcywgdW5zaWduZWQsIGxlKSB7XG4gIHJldHVybiBsZVxuICAgID8gTG9uZy5mcm9tQnl0ZXNMRShieXRlcywgdW5zaWduZWQpXG4gICAgOiBMb25nLmZyb21CeXRlc0JFKGJ5dGVzLCB1bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBMb25nIGZyb20gaXRzIGxpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEByZXR1cm5zIHtMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbUJ5dGVzTEUgPSBmdW5jdGlvbiBmcm9tQnl0ZXNMRShieXRlcywgdW5zaWduZWQpIHtcbiAgcmV0dXJuIG5ldyBMb25nKFxuICAgIGJ5dGVzWzBdIHwgKGJ5dGVzWzFdIDw8IDgpIHwgKGJ5dGVzWzJdIDw8IDE2KSB8IChieXRlc1szXSA8PCAyNCksXG4gICAgYnl0ZXNbNF0gfCAoYnl0ZXNbNV0gPDwgOCkgfCAoYnl0ZXNbNl0gPDwgMTYpIHwgKGJ5dGVzWzddIDw8IDI0KSxcbiAgICB1bnNpZ25lZCxcbiAgKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgYmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxuICogQHBhcmFtIHshQXJyYXkuPG51bWJlcj59IGJ5dGVzIEJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvblxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tQnl0ZXNCRSA9IGZ1bmN0aW9uIGZyb21CeXRlc0JFKGJ5dGVzLCB1bnNpZ25lZCkge1xuICByZXR1cm4gbmV3IExvbmcoXG4gICAgKGJ5dGVzWzRdIDw8IDI0KSB8IChieXRlc1s1XSA8PCAxNikgfCAoYnl0ZXNbNl0gPDwgOCkgfCBieXRlc1s3XSxcbiAgICAoYnl0ZXNbMF0gPDwgMjQpIHwgKGJ5dGVzWzFdIDw8IDE2KSB8IChieXRlc1syXSA8PCA4KSB8IGJ5dGVzWzNdLFxuICAgIHVuc2lnbmVkLFxuICApO1xufTtcblxuLy8gU3VwcG9ydCBjb252ZXJzaW9uIHRvL2Zyb20gQmlnSW50IHdoZXJlIGF2YWlsYWJsZVxuaWYgKHR5cGVvZiBCaWdJbnQgPT09IFwiZnVuY3Rpb25cIikge1xuICAvKipcbiAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiBiaWcgaW50ZWdlci5cbiAgICogQGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgYmlnIGludGVnZXIgdmFsdWVcbiAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICAgKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAgICovXG4gIExvbmcuZnJvbUJpZ0ludCA9IGZ1bmN0aW9uIGZyb21CaWdJbnQodmFsdWUsIHVuc2lnbmVkKSB7XG4gICAgdmFyIGxvd0JpdHMgPSBOdW1iZXIoQmlnSW50LmFzSW50TigzMiwgdmFsdWUpKTtcbiAgICB2YXIgaGlnaEJpdHMgPSBOdW1iZXIoQmlnSW50LmFzSW50TigzMiwgdmFsdWUgPj4gQmlnSW50KDMyKSkpO1xuICAgIHJldHVybiBmcm9tQml0cyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpO1xuICB9O1xuXG4gIC8vIE92ZXJyaWRlXG4gIExvbmcuZnJvbVZhbHVlID0gZnVuY3Rpb24gZnJvbVZhbHVlV2l0aEJpZ0ludCh2YWx1ZSwgdW5zaWduZWQpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcImJpZ2ludFwiKSByZXR1cm4gTG9uZy5mcm9tQmlnSW50KHZhbHVlLCB1bnNpZ25lZCk7XG4gICAgcmV0dXJuIGZyb21WYWx1ZSh2YWx1ZSwgdW5zaWduZWQpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBpdHMgYmlnIGludGVnZXIgcmVwcmVzZW50YXRpb24uXG4gICAqIEB0aGlzIHshTG9uZ31cbiAgICogQHJldHVybnMge2JpZ2ludH1cbiAgICovXG4gIExvbmdQcm90b3R5cGUudG9CaWdJbnQgPSBmdW5jdGlvbiB0b0JpZ0ludCgpIHtcbiAgICB2YXIgbG93QmlnSW50ID0gQmlnSW50KHRoaXMubG93ID4+PiAwKTtcbiAgICB2YXIgaGlnaEJpZ0ludCA9IEJpZ0ludCh0aGlzLnVuc2lnbmVkID8gdGhpcy5oaWdoID4+PiAwIDogdGhpcy5oaWdoKTtcbiAgICByZXR1cm4gKGhpZ2hCaWdJbnQgPDwgQmlnSW50KDMyKSkgfCBsb3dCaWdJbnQ7XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IExvbmc7XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5leHBvcnQgZW51bSBBcmdUeXBlIHtcbiAgSU5QVVQgPSAwLFxuICBPVVRQVVQgPSAxLFxufVxuIiwgIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5TSVpFX1BSRUZJWF9MRU5HVEggPSBleHBvcnRzLkZJTEVfSURFTlRJRklFUl9MRU5HVEggPSBleHBvcnRzLlNJWkVPRl9JTlQgPSBleHBvcnRzLlNJWkVPRl9TSE9SVCA9IHZvaWQgMDtcbmV4cG9ydHMuU0laRU9GX1NIT1JUID0gMjtcbmV4cG9ydHMuU0laRU9GX0lOVCA9IDQ7XG5leHBvcnRzLkZJTEVfSURFTlRJRklFUl9MRU5HVEggPSA0O1xuZXhwb3J0cy5TSVpFX1BSRUZJWF9MRU5HVEggPSA0O1xuIiwgIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5pc0xpdHRsZUVuZGlhbiA9IGV4cG9ydHMuZmxvYXQ2NCA9IGV4cG9ydHMuZmxvYXQzMiA9IGV4cG9ydHMuaW50MzIgPSB2b2lkIDA7XG5leHBvcnRzLmludDMyID0gbmV3IEludDMyQXJyYXkoMik7XG5leHBvcnRzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KGV4cG9ydHMuaW50MzIuYnVmZmVyKTtcbmV4cG9ydHMuZmxvYXQ2NCA9IG5ldyBGbG9hdDY0QXJyYXkoZXhwb3J0cy5pbnQzMi5idWZmZXIpO1xuZXhwb3J0cy5pc0xpdHRsZUVuZGlhbiA9IG5ldyBVaW50MTZBcnJheShuZXcgVWludDhBcnJheShbMSwgMF0pLmJ1ZmZlcilbMF0gPT09IDE7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkVuY29kaW5nID0gdm9pZCAwO1xudmFyIEVuY29kaW5nO1xuKGZ1bmN0aW9uIChFbmNvZGluZykge1xuICAgIEVuY29kaW5nW0VuY29kaW5nW1wiVVRGOF9CWVRFU1wiXSA9IDFdID0gXCJVVEY4X0JZVEVTXCI7XG4gICAgRW5jb2RpbmdbRW5jb2RpbmdbXCJVVEYxNl9TVFJJTkdcIl0gPSAyXSA9IFwiVVRGMTZfU1RSSU5HXCI7XG59KShFbmNvZGluZyB8fCAoZXhwb3J0cy5FbmNvZGluZyA9IEVuY29kaW5nID0ge30pKTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQnl0ZUJ1ZmZlciA9IHZvaWQgMDtcbmNvbnN0IGNvbnN0YW50c19qc18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzLmpzXCIpO1xuY29uc3QgZW5jb2RpbmdfanNfMSA9IHJlcXVpcmUoXCIuL2VuY29kaW5nLmpzXCIpO1xuY29uc3QgdXRpbHNfanNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xuY2xhc3MgQnl0ZUJ1ZmZlciB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IEJ5dGVCdWZmZXIgd2l0aCBhIGdpdmVuIGFycmF5IG9mIGJ5dGVzIChgVWludDhBcnJheWApXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoYnl0ZXNfKSB7XG4gICAgICAgIHRoaXMuYnl0ZXNfID0gYnl0ZXNfO1xuICAgICAgICB0aGlzLnBvc2l0aW9uXyA9IDA7XG4gICAgICAgIHRoaXMudGV4dF9kZWNvZGVyXyA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW5kIGFsbG9jYXRlIGEgbmV3IEJ5dGVCdWZmZXIgd2l0aCBhIGdpdmVuIHNpemUuXG4gICAgICovXG4gICAgc3RhdGljIGFsbG9jYXRlKGJ5dGVfc2l6ZSkge1xuICAgICAgICByZXR1cm4gbmV3IEJ5dGVCdWZmZXIobmV3IFVpbnQ4QXJyYXkoYnl0ZV9zaXplKSk7XG4gICAgfVxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLnBvc2l0aW9uXyA9IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdW5kZXJseWluZyBgVWludDhBcnJheWAuXG4gICAgICovXG4gICAgYnl0ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ5dGVzXztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBidWZmZXIncyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBwb3NpdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb25fO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGJ1ZmZlcidzIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uKHBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMucG9zaXRpb25fID0gcG9zaXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYnVmZmVyJ3MgY2FwYWNpdHkuXG4gICAgICovXG4gICAgY2FwYWNpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ5dGVzXy5sZW5ndGg7XG4gICAgfVxuICAgIHJlYWRJbnQ4KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gKHRoaXMucmVhZFVpbnQ4KG9mZnNldCkgPDwgMjQpID4+IDI0O1xuICAgIH1cbiAgICByZWFkVWludDgob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ5dGVzX1tvZmZzZXRdO1xuICAgIH1cbiAgICByZWFkSW50MTYob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiAodGhpcy5yZWFkVWludDE2KG9mZnNldCkgPDwgMTYpID4+IDE2O1xuICAgIH1cbiAgICByZWFkVWludDE2KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ieXRlc19bb2Zmc2V0XSB8ICh0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA8PCA4KTtcbiAgICB9XG4gICAgcmVhZEludDMyKG9mZnNldCkge1xuICAgICAgICByZXR1cm4gKHRoaXMuYnl0ZXNfW29mZnNldF0gfFxuICAgICAgICAgICAgKHRoaXMuYnl0ZXNfW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICAgICAgICh0aGlzLmJ5dGVzX1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICAgICAgICAgKHRoaXMuYnl0ZXNfW29mZnNldCArIDNdIDw8IDI0KSk7XG4gICAgfVxuICAgIHJlYWRVaW50MzIob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRJbnQzMihvZmZzZXQpID4+PiAwO1xuICAgIH1cbiAgICByZWFkSW50NjQob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBCaWdJbnQuYXNJbnROKDY0LCBCaWdJbnQodGhpcy5yZWFkVWludDMyKG9mZnNldCkpICtcbiAgICAgICAgICAgIChCaWdJbnQodGhpcy5yZWFkVWludDMyKG9mZnNldCArIDQpKSA8PCBCaWdJbnQoMzIpKSk7XG4gICAgfVxuICAgIHJlYWRVaW50NjQob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBCaWdJbnQuYXNVaW50Tig2NCwgQmlnSW50KHRoaXMucmVhZFVpbnQzMihvZmZzZXQpKSArXG4gICAgICAgICAgICAoQmlnSW50KHRoaXMucmVhZFVpbnQzMihvZmZzZXQgKyA0KSkgPDwgQmlnSW50KDMyKSkpO1xuICAgIH1cbiAgICByZWFkRmxvYXQzMihvZmZzZXQpIHtcbiAgICAgICAgdXRpbHNfanNfMS5pbnQzMlswXSA9IHRoaXMucmVhZEludDMyKG9mZnNldCk7XG4gICAgICAgIHJldHVybiB1dGlsc19qc18xLmZsb2F0MzJbMF07XG4gICAgfVxuICAgIHJlYWRGbG9hdDY0KG9mZnNldCkge1xuICAgICAgICB1dGlsc19qc18xLmludDMyW3V0aWxzX2pzXzEuaXNMaXR0bGVFbmRpYW4gPyAwIDogMV0gPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgICAgICB1dGlsc19qc18xLmludDMyW3V0aWxzX2pzXzEuaXNMaXR0bGVFbmRpYW4gPyAxIDogMF0gPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQgKyA0KTtcbiAgICAgICAgcmV0dXJuIHV0aWxzX2pzXzEuZmxvYXQ2NFswXTtcbiAgICB9XG4gICAgd3JpdGVJbnQ4KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICAgIH1cbiAgICB3cml0ZVVpbnQ4KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICAgIH1cbiAgICB3cml0ZUludDE2KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA9IHZhbHVlID4+IDg7XG4gICAgfVxuICAgIHdyaXRlVWludDE2KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA9IHZhbHVlID4+IDg7XG4gICAgfVxuICAgIHdyaXRlSW50MzIob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMl0gPSB2YWx1ZSA+PiAxNjtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgM10gPSB2YWx1ZSA+PiAyNDtcbiAgICB9XG4gICAgd3JpdGVVaW50MzIob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMl0gPSB2YWx1ZSA+PiAxNjtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgM10gPSB2YWx1ZSA+PiAyNDtcbiAgICB9XG4gICAgd3JpdGVJbnQ2NChvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMud3JpdGVJbnQzMihvZmZzZXQsIE51bWJlcihCaWdJbnQuYXNJbnROKDMyLCB2YWx1ZSkpKTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCArIDQsIE51bWJlcihCaWdJbnQuYXNJbnROKDMyLCB2YWx1ZSA+PiBCaWdJbnQoMzIpKSkpO1xuICAgIH1cbiAgICB3cml0ZVVpbnQ2NChvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMud3JpdGVVaW50MzIob2Zmc2V0LCBOdW1iZXIoQmlnSW50LmFzVWludE4oMzIsIHZhbHVlKSkpO1xuICAgICAgICB0aGlzLndyaXRlVWludDMyKG9mZnNldCArIDQsIE51bWJlcihCaWdJbnQuYXNVaW50TigzMiwgdmFsdWUgPj4gQmlnSW50KDMyKSkpKTtcbiAgICB9XG4gICAgd3JpdGVGbG9hdDMyKG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdXRpbHNfanNfMS5mbG9hdDMyWzBdID0gdmFsdWU7XG4gICAgICAgIHRoaXMud3JpdGVJbnQzMihvZmZzZXQsIHV0aWxzX2pzXzEuaW50MzJbMF0pO1xuICAgIH1cbiAgICB3cml0ZUZsb2F0NjQob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB1dGlsc19qc18xLmZsb2F0NjRbMF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCwgdXRpbHNfanNfMS5pbnQzMlt1dGlsc19qc18xLmlzTGl0dGxlRW5kaWFuID8gMCA6IDFdKTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCArIDQsIHV0aWxzX2pzXzEuaW50MzJbdXRpbHNfanNfMS5pc0xpdHRsZUVuZGlhbiA/IDEgOiAwXSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZmlsZSBpZGVudGlmaWVyLiAgIEJlaGF2aW9yIGlzIHVuZGVmaW5lZCBmb3IgRmxhdEJ1ZmZlcnMgd2hvc2VcbiAgICAgKiBzY2hlbWEgZG9lcyBub3QgaW5jbHVkZSBhIGZpbGVfaWRlbnRpZmllciAobGlrZWx5IHBvaW50cyBhdCBwYWRkaW5nIG9yIHRoZVxuICAgICAqIHN0YXJ0IG9mIGEgdGhlIHJvb3QgdnRhYmxlKS5cbiAgICAgKi9cbiAgICBnZXRCdWZmZXJJZGVudGlmaWVyKCkge1xuICAgICAgICBpZiAodGhpcy5ieXRlc18ubGVuZ3RoIDxcbiAgICAgICAgICAgIHRoaXMucG9zaXRpb25fICsgY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVCArIGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IEJ5dGVCdWZmZXIgaXMgdG9vIHNob3J0IHRvIGNvbnRhaW4gYW4gaWRlbnRpZmllci4nKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzdWx0ID0gJyc7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSDsgaSsrKSB7XG4gICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnJlYWRJbnQ4KHRoaXMucG9zaXRpb25fICsgY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVCArIGkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMb29rIHVwIGEgZmllbGQgaW4gdGhlIHZ0YWJsZSwgcmV0dXJuIGFuIG9mZnNldCBpbnRvIHRoZSBvYmplY3QsIG9yIDAgaWYgdGhlXG4gICAgICogZmllbGQgaXMgbm90IHByZXNlbnQuXG4gICAgICovXG4gICAgX19vZmZzZXQoYmJfcG9zLCB2dGFibGVfb2Zmc2V0KSB7XG4gICAgICAgIGNvbnN0IHZ0YWJsZSA9IGJiX3BvcyAtIHRoaXMucmVhZEludDMyKGJiX3Bvcyk7XG4gICAgICAgIHJldHVybiB2dGFibGVfb2Zmc2V0IDwgdGhpcy5yZWFkSW50MTYodnRhYmxlKVxuICAgICAgICAgICAgPyB0aGlzLnJlYWRJbnQxNih2dGFibGUgKyB2dGFibGVfb2Zmc2V0KVxuICAgICAgICAgICAgOiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIGFueSBUYWJsZS1kZXJpdmVkIHR5cGUgdG8gcG9pbnQgdG8gdGhlIHVuaW9uIGF0IHRoZSBnaXZlbiBvZmZzZXQuXG4gICAgICovXG4gICAgX191bmlvbih0LCBvZmZzZXQpIHtcbiAgICAgICAgdC5iYl9wb3MgPSBvZmZzZXQgKyB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgICAgICB0LmJiID0gdGhpcztcbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIEphdmFTY3JpcHQgc3RyaW5nIGZyb20gVVRGLTggZGF0YSBzdG9yZWQgaW5zaWRlIHRoZSBGbGF0QnVmZmVyLlxuICAgICAqIFRoaXMgYWxsb2NhdGVzIGEgbmV3IHN0cmluZyBhbmQgY29udmVydHMgdG8gd2lkZSBjaGFycyB1cG9uIGVhY2ggYWNjZXNzLlxuICAgICAqXG4gICAgICogVG8gYXZvaWQgdGhlIGNvbnZlcnNpb24gdG8gc3RyaW5nLCBwYXNzIEVuY29kaW5nLlVURjhfQllURVMgYXMgdGhlXG4gICAgICogXCJvcHRpb25hbEVuY29kaW5nXCIgYXJndW1lbnQuIFRoaXMgaXMgdXNlZnVsIGZvciBhdm9pZGluZyBjb252ZXJzaW9uIHdoZW5cbiAgICAgKiB0aGUgZGF0YSB3aWxsIGp1c3QgYmUgcGFja2FnZWQgYmFjayB1cCBpbiBhbm90aGVyIEZsYXRCdWZmZXIgbGF0ZXIgb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb2Zmc2V0XG4gICAgICogQHBhcmFtIG9wdF9lbmNvZGluZyBEZWZhdWx0cyB0byBVVEYxNl9TVFJJTkdcbiAgICAgKi9cbiAgICBfX3N0cmluZyhvZmZzZXQsIG9wdF9lbmNvZGluZykge1xuICAgICAgICBvZmZzZXQgKz0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQ7XG4gICAgICAgIGNvbnN0IHV0ZjhieXRlcyA9IHRoaXMuYnl0ZXNfLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgbGVuZ3RoKTtcbiAgICAgICAgaWYgKG9wdF9lbmNvZGluZyA9PT0gZW5jb2RpbmdfanNfMS5FbmNvZGluZy5VVEY4X0JZVEVTKVxuICAgICAgICAgICAgcmV0dXJuIHV0ZjhieXRlcztcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGV4dF9kZWNvZGVyXy5kZWNvZGUodXRmOGJ5dGVzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIHVuaW9ucyB0aGF0IGNhbiBjb250YWluIHN0cmluZyBhcyBpdHMgbWVtYmVyLCBpZiBhIFRhYmxlLWRlcml2ZWQgdHlwZSB0aGVuIGluaXRpYWxpemUgaXQsXG4gICAgICogaWYgYSBzdHJpbmcgdGhlbiByZXR1cm4gYSBuZXcgb25lXG4gICAgICpcbiAgICAgKiBXQVJOSU5HOiBzdHJpbmdzIGFyZSBpbW11dGFibGUgaW4gSlMgc28gd2UgY2FuJ3QgY2hhbmdlIHRoZSBzdHJpbmcgdGhhdCB0aGUgdXNlciBnYXZlIHVzLCB0aGlzXG4gICAgICogbWFrZXMgdGhlIGJlaGF2aW91ciBvZiBfX3VuaW9uX3dpdGhfc3RyaW5nIGRpZmZlcmVudCBjb21wYXJlZCB0byBfX3VuaW9uXG4gICAgICovXG4gICAgX191bmlvbl93aXRoX3N0cmluZyhvLCBvZmZzZXQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX19zdHJpbmcob2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fX3VuaW9uKG8sIG9mZnNldCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlIHRoZSByZWxhdGl2ZSBvZmZzZXQgc3RvcmVkIGF0IFwib2Zmc2V0XCJcbiAgICAgKi9cbiAgICBfX2luZGlyZWN0KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzdGFydCBvZiBkYXRhIG9mIGEgdmVjdG9yIHdob3NlIG9mZnNldCBpcyBzdG9yZWQgYXQgXCJvZmZzZXRcIiBpbiB0aGlzIG9iamVjdC5cbiAgICAgKi9cbiAgICBfX3ZlY3RvcihvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCkgKyBjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5UOyAvLyBkYXRhIHN0YXJ0cyBhZnRlciB0aGUgbGVuZ3RoXG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgbGVuZ3RoIG9mIGEgdmVjdG9yIHdob3NlIG9mZnNldCBpcyBzdG9yZWQgYXQgXCJvZmZzZXRcIiBpbiB0aGlzIG9iamVjdC5cbiAgICAgKi9cbiAgICBfX3ZlY3Rvcl9sZW4ob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRJbnQzMihvZmZzZXQgKyB0aGlzLnJlYWRJbnQzMihvZmZzZXQpKTtcbiAgICB9XG4gICAgX19oYXNfaWRlbnRpZmllcihpZGVudCkge1xuICAgICAgICBpZiAoaWRlbnQubGVuZ3RoICE9IGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IGZpbGUgaWRlbnRpZmllciBtdXN0IGJlIGxlbmd0aCAnICsgY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChpZGVudC5jaGFyQ29kZUF0KGkpICE9IHRoaXMucmVhZEludDgodGhpcy5wb3NpdGlvbigpICsgY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVCArIGkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIGhlbHBlciBmdW5jdGlvbiBmb3IgZ2VuZXJhdGluZyBsaXN0IGZvciBvYmogYXBpXG4gICAgICovXG4gICAgY3JlYXRlU2NhbGFyTGlzdChsaXN0QWNjZXNzb3IsIGxpc3RMZW5ndGgpIHtcbiAgICAgICAgY29uc3QgcmV0ID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdExlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBjb25zdCB2YWwgPSBsaXN0QWNjZXNzb3IoaSk7XG4gICAgICAgICAgICBpZiAodmFsICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0LnB1c2godmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIGhlbHBlciBmdW5jdGlvbiBmb3IgZ2VuZXJhdGluZyBsaXN0IGZvciBvYmogYXBpXG4gICAgICogQHBhcmFtIGxpc3RBY2Nlc3NvciBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgYW4gaW5kZXggYW5kIHJldHVybiBkYXRhIGF0IHRoYXQgaW5kZXhcbiAgICAgKiBAcGFyYW0gbGlzdExlbmd0aCBsaXN0TGVuZ3RoXG4gICAgICogQHBhcmFtIHJlcyByZXN1bHQgbGlzdFxuICAgICAqL1xuICAgIGNyZWF0ZU9iakxpc3QobGlzdEFjY2Vzc29yLCBsaXN0TGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHJldCA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RMZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgY29uc3QgdmFsID0gbGlzdEFjY2Vzc29yKGkpO1xuICAgICAgICAgICAgaWYgKHZhbCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldC5wdXNoKHZhbC51bnBhY2soKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG59XG5leHBvcnRzLkJ5dGVCdWZmZXIgPSBCeXRlQnVmZmVyO1xuIiwgIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CdWlsZGVyID0gdm9pZCAwO1xuY29uc3QgYnl0ZV9idWZmZXJfanNfMSA9IHJlcXVpcmUoXCIuL2J5dGUtYnVmZmVyLmpzXCIpO1xuY29uc3QgY29uc3RhbnRzX2pzXzEgPSByZXF1aXJlKFwiLi9jb25zdGFudHMuanNcIik7XG5jbGFzcyBCdWlsZGVyIHtcbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBGbGF0QnVmZmVyQnVpbGRlci5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRfaW5pdGlhbF9zaXplKSB7XG4gICAgICAgIC8qKiBNaW5pbXVtIGFsaWdubWVudCBlbmNvdW50ZXJlZCBzbyBmYXIuICovXG4gICAgICAgIHRoaXMubWluYWxpZ24gPSAxO1xuICAgICAgICAvKiogVGhlIHZ0YWJsZSBmb3IgdGhlIGN1cnJlbnQgdGFibGUuICovXG4gICAgICAgIHRoaXMudnRhYmxlID0gbnVsbDtcbiAgICAgICAgLyoqIFRoZSBhbW91bnQgb2YgZmllbGRzIHdlJ3JlIGFjdHVhbGx5IHVzaW5nLiAqL1xuICAgICAgICB0aGlzLnZ0YWJsZV9pbl91c2UgPSAwO1xuICAgICAgICAvKiogV2hldGhlciB3ZSBhcmUgY3VycmVudGx5IHNlcmlhbGl6aW5nIGEgdGFibGUuICovXG4gICAgICAgIHRoaXMuaXNOZXN0ZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqIFN0YXJ0aW5nIG9mZnNldCBvZiB0aGUgY3VycmVudCBzdHJ1Y3QvdGFibGUuICovXG4gICAgICAgIHRoaXMub2JqZWN0X3N0YXJ0ID0gMDtcbiAgICAgICAgLyoqIExpc3Qgb2Ygb2Zmc2V0cyBvZiBhbGwgdnRhYmxlcy4gKi9cbiAgICAgICAgdGhpcy52dGFibGVzID0gW107XG4gICAgICAgIC8qKiBGb3IgdGhlIGN1cnJlbnQgdmVjdG9yIGJlaW5nIGJ1aWx0LiAqL1xuICAgICAgICB0aGlzLnZlY3Rvcl9udW1fZWxlbXMgPSAwO1xuICAgICAgICAvKiogRmFsc2Ugb21pdHMgZGVmYXVsdCB2YWx1ZXMgZnJvbSB0aGUgc2VyaWFsaXplZCBkYXRhICovXG4gICAgICAgIHRoaXMuZm9yY2VfZGVmYXVsdHMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zdHJpbmdfbWFwcyA9IG51bGw7XG4gICAgICAgIHRoaXMudGV4dF9lbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG4gICAgICAgIGxldCBpbml0aWFsX3NpemU7XG4gICAgICAgIGlmICghb3B0X2luaXRpYWxfc2l6ZSkge1xuICAgICAgICAgICAgaW5pdGlhbF9zaXplID0gMTAyNDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGluaXRpYWxfc2l6ZSA9IG9wdF9pbml0aWFsX3NpemU7XG4gICAgICAgIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB0eXBlIHtCeXRlQnVmZmVyfVxuICAgICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5iYiA9IGJ5dGVfYnVmZmVyX2pzXzEuQnl0ZUJ1ZmZlci5hbGxvY2F0ZShpbml0aWFsX3NpemUpO1xuICAgICAgICB0aGlzLnNwYWNlID0gaW5pdGlhbF9zaXplO1xuICAgIH1cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5iYi5jbGVhcigpO1xuICAgICAgICB0aGlzLnNwYWNlID0gdGhpcy5iYi5jYXBhY2l0eSgpO1xuICAgICAgICB0aGlzLm1pbmFsaWduID0gMTtcbiAgICAgICAgdGhpcy52dGFibGUgPSBudWxsO1xuICAgICAgICB0aGlzLnZ0YWJsZV9pbl91c2UgPSAwO1xuICAgICAgICB0aGlzLmlzTmVzdGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMub2JqZWN0X3N0YXJ0ID0gMDtcbiAgICAgICAgdGhpcy52dGFibGVzID0gW107XG4gICAgICAgIHRoaXMudmVjdG9yX251bV9lbGVtcyA9IDA7XG4gICAgICAgIHRoaXMuZm9yY2VfZGVmYXVsdHMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zdHJpbmdfbWFwcyA9IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluIG9yZGVyIHRvIHNhdmUgc3BhY2UsIGZpZWxkcyB0aGF0IGFyZSBzZXQgdG8gdGhlaXIgZGVmYXVsdCB2YWx1ZVxuICAgICAqIGRvbid0IGdldCBzZXJpYWxpemVkIGludG8gdGhlIGJ1ZmZlci4gRm9yY2luZyBkZWZhdWx0cyBwcm92aWRlcyBhXG4gICAgICogd2F5IHRvIG1hbnVhbGx5IGRpc2FibGUgdGhpcyBvcHRpbWl6YXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZm9yY2VEZWZhdWx0cyB0cnVlIGFsd2F5cyBzZXJpYWxpemVzIGRlZmF1bHQgdmFsdWVzXG4gICAgICovXG4gICAgZm9yY2VEZWZhdWx0cyhmb3JjZURlZmF1bHRzKSB7XG4gICAgICAgIHRoaXMuZm9yY2VfZGVmYXVsdHMgPSBmb3JjZURlZmF1bHRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIEJ5dGVCdWZmZXIgcmVwcmVzZW50aW5nIHRoZSBGbGF0QnVmZmVyLiBPbmx5IGNhbGwgdGhpcyBhZnRlciB5b3UndmVcbiAgICAgKiBjYWxsZWQgZmluaXNoKCkuIFRoZSBhY3R1YWwgZGF0YSBzdGFydHMgYXQgdGhlIEJ5dGVCdWZmZXIncyBjdXJyZW50IHBvc2l0aW9uLFxuICAgICAqIG5vdCBuZWNlc3NhcmlseSBhdCAwLlxuICAgICAqL1xuICAgIGRhdGFCdWZmZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGJ5dGVzIHJlcHJlc2VudGluZyB0aGUgRmxhdEJ1ZmZlci4gT25seSBjYWxsIHRoaXMgYWZ0ZXIgeW91J3ZlXG4gICAgICogY2FsbGVkIGZpbmlzaCgpLlxuICAgICAqL1xuICAgIGFzVWludDhBcnJheSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmJcbiAgICAgICAgICAgIC5ieXRlcygpXG4gICAgICAgICAgICAuc3ViYXJyYXkodGhpcy5iYi5wb3NpdGlvbigpLCB0aGlzLmJiLnBvc2l0aW9uKCkgKyB0aGlzLm9mZnNldCgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJlcGFyZSB0byB3cml0ZSBhbiBlbGVtZW50IG9mIGBzaXplYCBhZnRlciBgYWRkaXRpb25hbF9ieXRlc2AgaGF2ZSBiZWVuXG4gICAgICogd3JpdHRlbiwgZS5nLiBpZiB5b3Ugd3JpdGUgYSBzdHJpbmcsIHlvdSBuZWVkIHRvIGFsaWduIHN1Y2ggdGhlIGludCBsZW5ndGhcbiAgICAgKiBmaWVsZCBpcyBhbGlnbmVkIHRvIDQgYnl0ZXMsIGFuZCB0aGUgc3RyaW5nIGRhdGEgZm9sbG93cyBpdCBkaXJlY3RseS4gSWYgYWxsXG4gICAgICogeW91IG5lZWQgdG8gZG8gaXMgYWxpZ25tZW50LCBgYWRkaXRpb25hbF9ieXRlc2Agd2lsbCBiZSAwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNpemUgVGhpcyBpcyB0aGUgb2YgdGhlIG5ldyBlbGVtZW50IHRvIHdyaXRlXG4gICAgICogQHBhcmFtIGFkZGl0aW9uYWxfYnl0ZXMgVGhlIHBhZGRpbmcgc2l6ZVxuICAgICAqL1xuICAgIHByZXAoc2l6ZSwgYWRkaXRpb25hbF9ieXRlcykge1xuICAgICAgICAvLyBUcmFjayB0aGUgYmlnZ2VzdCB0aGluZyB3ZSd2ZSBldmVyIGFsaWduZWQgdG8uXG4gICAgICAgIGlmIChzaXplID4gdGhpcy5taW5hbGlnbikge1xuICAgICAgICAgICAgdGhpcy5taW5hbGlnbiA9IHNpemU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmluZCB0aGUgYW1vdW50IG9mIGFsaWdubWVudCBuZWVkZWQgc3VjaCB0aGF0IGBzaXplYCBpcyBwcm9wZXJseVxuICAgICAgICAvLyBhbGlnbmVkIGFmdGVyIGBhZGRpdGlvbmFsX2J5dGVzYFxuICAgICAgICBjb25zdCBhbGlnbl9zaXplID0gKH4odGhpcy5iYi5jYXBhY2l0eSgpIC0gdGhpcy5zcGFjZSArIGFkZGl0aW9uYWxfYnl0ZXMpICsgMSkgJiAoc2l6ZSAtIDEpO1xuICAgICAgICAvLyBSZWFsbG9jYXRlIHRoZSBidWZmZXIgaWYgbmVlZGVkLlxuICAgICAgICB3aGlsZSAodGhpcy5zcGFjZSA8IGFsaWduX3NpemUgKyBzaXplICsgYWRkaXRpb25hbF9ieXRlcykge1xuICAgICAgICAgICAgY29uc3Qgb2xkX2J1Zl9zaXplID0gdGhpcy5iYi5jYXBhY2l0eSgpO1xuICAgICAgICAgICAgdGhpcy5iYiA9IEJ1aWxkZXIuZ3Jvd0J5dGVCdWZmZXIodGhpcy5iYik7XG4gICAgICAgICAgICB0aGlzLnNwYWNlICs9IHRoaXMuYmIuY2FwYWNpdHkoKSAtIG9sZF9idWZfc2l6ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBhZChhbGlnbl9zaXplKTtcbiAgICB9XG4gICAgcGFkKGJ5dGVfc2l6ZSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ5dGVfc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLmJiLndyaXRlSW50OCgtLXRoaXMuc3BhY2UsIDApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHdyaXRlSW50OCh2YWx1ZSkge1xuICAgICAgICB0aGlzLmJiLndyaXRlSW50OCgodGhpcy5zcGFjZSAtPSAxKSwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUludDE2KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVJbnQxNigodGhpcy5zcGFjZSAtPSAyKSwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUludDMyKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVJbnQzMigodGhpcy5zcGFjZSAtPSA0KSwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUludDY0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVJbnQ2NCgodGhpcy5zcGFjZSAtPSA4KSwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUZsb2F0MzIodmFsdWUpIHtcbiAgICAgICAgdGhpcy5iYi53cml0ZUZsb2F0MzIoKHRoaXMuc3BhY2UgLT0gNCksIHZhbHVlKTtcbiAgICB9XG4gICAgd3JpdGVGbG9hdDY0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVGbG9hdDY0KCh0aGlzLnNwYWNlIC09IDgpLCB2YWx1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhbiBgaW50OGAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgaW50OGAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkSW50OCh2YWx1ZSkge1xuICAgICAgICB0aGlzLnByZXAoMSwgMCk7XG4gICAgICAgIHRoaXMud3JpdGVJbnQ4KHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGBpbnQxNmAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgaW50MTZgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEludDE2KHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCgyLCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUludDE2KHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGBpbnQzMmAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgaW50MzJgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEludDMyKHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCg0LCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGBpbnQ2NGAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgaW50NjRgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEludDY0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCg4LCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUludDY0KHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgYGZsb2F0MzJgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYGZsb2F0MzJgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEZsb2F0MzIodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDQsIDApO1xuICAgICAgICB0aGlzLndyaXRlRmxvYXQzMih2YWx1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIGBmbG9hdDY0YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBmbG9hdDY0YCB0byBhZGQgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBhZGRGbG9hdDY0KHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCg4LCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUZsb2F0NjQodmFsdWUpO1xuICAgIH1cbiAgICBhZGRGaWVsZEludDgodm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkSW50OCh2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRJbnQxNih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnQxNih2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRJbnQzMih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnQzMih2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRJbnQ2NCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9PSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkSW50NjQodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZEZpZWxkRmxvYXQzMih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRGbG9hdDMyKHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZEZsb2F0NjQodm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkRmxvYXQ2NCh2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRPZmZzZXQodm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkT2Zmc2V0KHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdHJ1Y3RzIGFyZSBzdG9yZWQgaW5saW5lLCBzbyBub3RoaW5nIGFkZGl0aW9uYWwgaXMgYmVpbmcgYWRkZWQuIGBkYCBpcyBhbHdheXMgMC5cbiAgICAgKi9cbiAgICBhZGRGaWVsZFN0cnVjdCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMubmVzdGVkKHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdHJ1Y3R1cmVzIGFyZSBhbHdheXMgc3RvcmVkIGlubGluZSwgdGhleSBuZWVkIHRvIGJlIGNyZWF0ZWQgcmlnaHRcbiAgICAgKiB3aGVyZSB0aGV5J3JlIHVzZWQuICBZb3UnbGwgZ2V0IHRoaXMgYXNzZXJ0aW9uIGZhaWx1cmUgaWYgeW91XG4gICAgICogY3JlYXRlZCBpdCBlbHNld2hlcmUuXG4gICAgICovXG4gICAgbmVzdGVkKG9iaikge1xuICAgICAgICBpZiAob2JqICE9IHRoaXMub2Zmc2V0KCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZsYXRCdWZmZXJzOiBzdHJ1Y3QgbXVzdCBiZSBzZXJpYWxpemVkIGlubGluZS4nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTaG91bGQgbm90IGJlIGNyZWF0aW5nIGFueSBvdGhlciBvYmplY3QsIHN0cmluZyBvciB2ZWN0b3JcbiAgICAgKiB3aGlsZSBhbiBvYmplY3QgaXMgYmVpbmcgY29uc3RydWN0ZWRcbiAgICAgKi9cbiAgICBub3ROZXN0ZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzTmVzdGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGbGF0QnVmZmVyczogb2JqZWN0IHNlcmlhbGl6YXRpb24gbXVzdCBub3QgYmUgbmVzdGVkLicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgY3VycmVudCB2dGFibGUgYXQgYHZvZmZzZXRgIHRvIHRoZSBjdXJyZW50IGxvY2F0aW9uIGluIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgc2xvdCh2b2Zmc2V0KSB7XG4gICAgICAgIGlmICh0aGlzLnZ0YWJsZSAhPT0gbnVsbClcbiAgICAgICAgICAgIHRoaXMudnRhYmxlW3ZvZmZzZXRdID0gdGhpcy5vZmZzZXQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHJldHVybnMgT2Zmc2V0IHJlbGF0aXZlIHRvIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBvZmZzZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJiLmNhcGFjaXR5KCkgLSB0aGlzLnNwYWNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb3VibGVzIHRoZSBzaXplIG9mIHRoZSBiYWNraW5nIEJ5dGVCdWZmZXIgYW5kIGNvcGllcyB0aGUgb2xkIGRhdGEgdG93YXJkc1xuICAgICAqIHRoZSBlbmQgb2YgdGhlIG5ldyBidWZmZXIgKHNpbmNlIHdlIGJ1aWxkIHRoZSBidWZmZXIgYmFja3dhcmRzKS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBiYiBUaGUgY3VycmVudCBidWZmZXIgd2l0aCB0aGUgZXhpc3RpbmcgZGF0YVxuICAgICAqIEByZXR1cm5zIEEgbmV3IGJ5dGUgYnVmZmVyIHdpdGggdGhlIG9sZCBkYXRhIGNvcGllZFxuICAgICAqIHRvIGl0LiBUaGUgZGF0YSBpcyBsb2NhdGVkIGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlci5cbiAgICAgKlxuICAgICAqIHVpbnQ4QXJyYXkuc2V0KCkgZm9ybWFsbHkgdGFrZXMge0FycmF5PG51bWJlcj58QXJyYXlCdWZmZXJWaWV3fSwgc28gdG8gcGFzc1xuICAgICAqIGl0IGEgdWludDhBcnJheSB3ZSBuZWVkIHRvIHN1cHByZXNzIHRoZSB0eXBlIGNoZWNrOlxuICAgICAqIEBzdXBwcmVzcyB7Y2hlY2tUeXBlc31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ3Jvd0J5dGVCdWZmZXIoYmIpIHtcbiAgICAgICAgY29uc3Qgb2xkX2J1Zl9zaXplID0gYmIuY2FwYWNpdHkoKTtcbiAgICAgICAgLy8gRW5zdXJlIHdlIGRvbid0IGdyb3cgYmV5b25kIHdoYXQgZml0cyBpbiBhbiBpbnQuXG4gICAgICAgIGlmIChvbGRfYnVmX3NpemUgJiAweGMwMDAwMDAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXRCdWZmZXJzOiBjYW5ub3QgZ3JvdyBidWZmZXIgYmV5b25kIDIgZ2lnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5ld19idWZfc2l6ZSA9IG9sZF9idWZfc2l6ZSA8PCAxO1xuICAgICAgICBjb25zdCBuYmIgPSBieXRlX2J1ZmZlcl9qc18xLkJ5dGVCdWZmZXIuYWxsb2NhdGUobmV3X2J1Zl9zaXplKTtcbiAgICAgICAgbmJiLnNldFBvc2l0aW9uKG5ld19idWZfc2l6ZSAtIG9sZF9idWZfc2l6ZSk7XG4gICAgICAgIG5iYi5ieXRlcygpLnNldChiYi5ieXRlcygpLCBuZXdfYnVmX3NpemUgLSBvbGRfYnVmX3NpemUpO1xuICAgICAgICByZXR1cm4gbmJiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIG9uIG9mZnNldCwgcmVsYXRpdmUgdG8gd2hlcmUgaXQgd2lsbCBiZSB3cml0dGVuLlxuICAgICAqXG4gICAgICogQHBhcmFtIG9mZnNldCBUaGUgb2Zmc2V0IHRvIGFkZC5cbiAgICAgKi9cbiAgICBhZGRPZmZzZXQob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMucHJlcChjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5ULCAwKTsgLy8gRW5zdXJlIGFsaWdubWVudCBpcyBhbHJlYWR5IGRvbmUuXG4gICAgICAgIHRoaXMud3JpdGVJbnQzMih0aGlzLm9mZnNldCgpIC0gb2Zmc2V0ICsgY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IGVuY29kaW5nIGEgbmV3IG9iamVjdCBpbiB0aGUgYnVmZmVyLiAgVXNlcnMgd2lsbCBub3QgdXN1YWxseSBuZWVkIHRvXG4gICAgICogY2FsbCB0aGlzIGRpcmVjdGx5LiBUaGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIgd2lsbCBnZW5lcmF0ZSBoZWxwZXIgbWV0aG9kc1xuICAgICAqIHRoYXQgY2FsbCB0aGlzIG1ldGhvZCBpbnRlcm5hbGx5LlxuICAgICAqL1xuICAgIHN0YXJ0T2JqZWN0KG51bWZpZWxkcykge1xuICAgICAgICB0aGlzLm5vdE5lc3RlZCgpO1xuICAgICAgICBpZiAodGhpcy52dGFibGUgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy52dGFibGUgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZ0YWJsZV9pbl91c2UgPSBudW1maWVsZHM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtZmllbGRzOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMudnRhYmxlW2ldID0gMDsgLy8gVGhpcyB3aWxsIHB1c2ggYWRkaXRpb25hbCBlbGVtZW50cyBhcyBuZWVkZWRcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzTmVzdGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5vYmplY3Rfc3RhcnQgPSB0aGlzLm9mZnNldCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5pc2ggb2ZmIHdyaXRpbmcgdGhlIG9iamVjdCB0aGF0IGlzIHVuZGVyIGNvbnN0cnVjdGlvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBvZmZzZXQgdG8gdGhlIG9iamVjdCBpbnNpZGUgYGRhdGFCdWZmZXJgXG4gICAgICovXG4gICAgZW5kT2JqZWN0KCkge1xuICAgICAgICBpZiAodGhpcy52dGFibGUgPT0gbnVsbCB8fCAhdGhpcy5pc05lc3RlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogZW5kT2JqZWN0IGNhbGxlZCB3aXRob3V0IHN0YXJ0T2JqZWN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hZGRJbnQzMigwKTtcbiAgICAgICAgY29uc3QgdnRhYmxlbG9jID0gdGhpcy5vZmZzZXQoKTtcbiAgICAgICAgLy8gVHJpbSB0cmFpbGluZyB6ZXJvZXMuXG4gICAgICAgIGxldCBpID0gdGhpcy52dGFibGVfaW5fdXNlIC0gMTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVtcHR5XG4gICAgICAgIGZvciAoOyBpID49IDAgJiYgdGhpcy52dGFibGVbaV0gPT0gMDsgaS0tKSB7IH1cbiAgICAgICAgY29uc3QgdHJpbW1lZF9zaXplID0gaSArIDE7XG4gICAgICAgIC8vIFdyaXRlIG91dCB0aGUgY3VycmVudCB2dGFibGUuXG4gICAgICAgIGZvciAoOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgLy8gT2Zmc2V0IHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgdGFibGUuXG4gICAgICAgICAgICB0aGlzLmFkZEludDE2KHRoaXMudnRhYmxlW2ldICE9IDAgPyB2dGFibGVsb2MgLSB0aGlzLnZ0YWJsZVtpXSA6IDApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0YW5kYXJkX2ZpZWxkcyA9IDI7IC8vIFRoZSBmaWVsZHMgYmVsb3c6XG4gICAgICAgIHRoaXMuYWRkSW50MTYodnRhYmxlbG9jIC0gdGhpcy5vYmplY3Rfc3RhcnQpO1xuICAgICAgICBjb25zdCBsZW4gPSAodHJpbW1lZF9zaXplICsgc3RhbmRhcmRfZmllbGRzKSAqIGNvbnN0YW50c19qc18xLlNJWkVPRl9TSE9SVDtcbiAgICAgICAgdGhpcy5hZGRJbnQxNihsZW4pO1xuICAgICAgICAvLyBTZWFyY2ggZm9yIGFuIGV4aXN0aW5nIHZ0YWJsZSB0aGF0IG1hdGNoZXMgdGhlIGN1cnJlbnQgb25lLlxuICAgICAgICBsZXQgZXhpc3RpbmdfdnRhYmxlID0gMDtcbiAgICAgICAgY29uc3QgdnQxID0gdGhpcy5zcGFjZTtcbiAgICAgICAgb3V0ZXJfbG9vcDogZm9yIChpID0gMDsgaSA8IHRoaXMudnRhYmxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgdnQyID0gdGhpcy5iYi5jYXBhY2l0eSgpIC0gdGhpcy52dGFibGVzW2ldO1xuICAgICAgICAgICAgaWYgKGxlbiA9PSB0aGlzLmJiLnJlYWRJbnQxNih2dDIpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IGNvbnN0YW50c19qc18xLlNJWkVPRl9TSE9SVDsgaiA8IGxlbjsgaiArPSBjb25zdGFudHNfanNfMS5TSVpFT0ZfU0hPUlQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuYmIucmVhZEludDE2KHZ0MSArIGopICE9IHRoaXMuYmIucmVhZEludDE2KHZ0MiArIGopKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcl9sb29wO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGV4aXN0aW5nX3Z0YWJsZSA9IHRoaXMudnRhYmxlc1tpXTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhpc3RpbmdfdnRhYmxlKSB7XG4gICAgICAgICAgICAvLyBGb3VuZCBhIG1hdGNoOlxuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBjdXJyZW50IHZ0YWJsZS5cbiAgICAgICAgICAgIHRoaXMuc3BhY2UgPSB0aGlzLmJiLmNhcGFjaXR5KCkgLSB2dGFibGVsb2M7XG4gICAgICAgICAgICAvLyBQb2ludCB0YWJsZSB0byBleGlzdGluZyB2dGFibGUuXG4gICAgICAgICAgICB0aGlzLmJiLndyaXRlSW50MzIodGhpcy5zcGFjZSwgZXhpc3RpbmdfdnRhYmxlIC0gdnRhYmxlbG9jKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIE5vIG1hdGNoOlxuICAgICAgICAgICAgLy8gQWRkIHRoZSBsb2NhdGlvbiBvZiB0aGUgY3VycmVudCB2dGFibGUgdG8gdGhlIGxpc3Qgb2YgdnRhYmxlcy5cbiAgICAgICAgICAgIHRoaXMudnRhYmxlcy5wdXNoKHRoaXMub2Zmc2V0KCkpO1xuICAgICAgICAgICAgLy8gUG9pbnQgdGFibGUgdG8gY3VycmVudCB2dGFibGUuXG4gICAgICAgICAgICB0aGlzLmJiLndyaXRlSW50MzIodGhpcy5iYi5jYXBhY2l0eSgpIC0gdnRhYmxlbG9jLCB0aGlzLm9mZnNldCgpIC0gdnRhYmxlbG9jKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzTmVzdGVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiB2dGFibGVsb2M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmFsaXplIGEgYnVmZmVyLCBwb2l0aW5nIHRvIHRoZSBnaXZlbiBgcm9vdF90YWJsZWAuXG4gICAgICovXG4gICAgZmluaXNoKHJvb3RfdGFibGUsIG9wdF9maWxlX2lkZW50aWZpZXIsIG9wdF9zaXplX3ByZWZpeCkge1xuICAgICAgICBjb25zdCBzaXplX3ByZWZpeCA9IG9wdF9zaXplX3ByZWZpeCA/IGNvbnN0YW50c19qc18xLlNJWkVfUFJFRklYX0xFTkdUSCA6IDA7XG4gICAgICAgIGlmIChvcHRfZmlsZV9pZGVudGlmaWVyKSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlX2lkZW50aWZpZXIgPSBvcHRfZmlsZV9pZGVudGlmaWVyO1xuICAgICAgICAgICAgdGhpcy5wcmVwKHRoaXMubWluYWxpZ24sIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgKyBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIICsgc2l6ZV9wcmVmaXgpO1xuICAgICAgICAgICAgaWYgKGZpbGVfaWRlbnRpZmllci5sZW5ndGggIT0gY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZsYXRCdWZmZXJzOiBmaWxlIGlkZW50aWZpZXIgbXVzdCBiZSBsZW5ndGggJyArXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgIHRoaXMud3JpdGVJbnQ4KGZpbGVfaWRlbnRpZmllci5jaGFyQ29kZUF0KGkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByZXAodGhpcy5taW5hbGlnbiwgY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVCArIHNpemVfcHJlZml4KTtcbiAgICAgICAgdGhpcy5hZGRPZmZzZXQocm9vdF90YWJsZSk7XG4gICAgICAgIGlmIChzaXplX3ByZWZpeCkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnQzMih0aGlzLmJiLmNhcGFjaXR5KCkgLSB0aGlzLnNwYWNlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmJiLnNldFBvc2l0aW9uKHRoaXMuc3BhY2UpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5hbGl6ZSBhIHNpemUgcHJlZml4ZWQgYnVmZmVyLCBwb2ludGluZyB0byB0aGUgZ2l2ZW4gYHJvb3RfdGFibGVgLlxuICAgICAqL1xuICAgIGZpbmlzaFNpemVQcmVmaXhlZChyb290X3RhYmxlLCBvcHRfZmlsZV9pZGVudGlmaWVyKSB7XG4gICAgICAgIHRoaXMuZmluaXNoKHJvb3RfdGFibGUsIG9wdF9maWxlX2lkZW50aWZpZXIsIHRydWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGNoZWNrcyBhIHJlcXVpcmVkIGZpZWxkIGhhcyBiZWVuIHNldCBpbiBhIGdpdmVuIHRhYmxlIHRoYXQgaGFzXG4gICAgICoganVzdCBiZWVuIGNvbnN0cnVjdGVkLlxuICAgICAqL1xuICAgIHJlcXVpcmVkRmllbGQodGFibGUsIGZpZWxkKSB7XG4gICAgICAgIGNvbnN0IHRhYmxlX3N0YXJ0ID0gdGhpcy5iYi5jYXBhY2l0eSgpIC0gdGFibGU7XG4gICAgICAgIGNvbnN0IHZ0YWJsZV9zdGFydCA9IHRhYmxlX3N0YXJ0IC0gdGhpcy5iYi5yZWFkSW50MzIodGFibGVfc3RhcnQpO1xuICAgICAgICBjb25zdCBvayA9IGZpZWxkIDwgdGhpcy5iYi5yZWFkSW50MTYodnRhYmxlX3N0YXJ0KSAmJlxuICAgICAgICAgICAgdGhpcy5iYi5yZWFkSW50MTYodnRhYmxlX3N0YXJ0ICsgZmllbGQpICE9IDA7XG4gICAgICAgIC8vIElmIHRoaXMgZmFpbHMsIHRoZSBjYWxsZXIgd2lsbCBzaG93IHdoYXQgZmllbGQgbmVlZHMgdG8gYmUgc2V0LlxuICAgICAgICBpZiAoIW9rKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGbGF0QnVmZmVyczogZmllbGQgJyArIGZpZWxkICsgJyBtdXN0IGJlIHNldCcpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IGEgbmV3IGFycmF5L3ZlY3RvciBvZiBvYmplY3RzLiAgVXNlcnMgdXN1YWxseSB3aWxsIG5vdCBjYWxsXG4gICAgICogdGhpcyBkaXJlY3RseS4gVGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyIHdpbGwgY3JlYXRlIGEgc3RhcnQvZW5kXG4gICAgICogbWV0aG9kIGZvciB2ZWN0b3IgdHlwZXMgaW4gZ2VuZXJhdGVkIGNvZGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZWxlbV9zaXplIFRoZSBzaXplIG9mIGVhY2ggZWxlbWVudCBpbiB0aGUgYXJyYXlcbiAgICAgKiBAcGFyYW0gbnVtX2VsZW1zIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGFycmF5XG4gICAgICogQHBhcmFtIGFsaWdubWVudCBUaGUgYWxpZ25tZW50IG9mIHRoZSBhcnJheVxuICAgICAqL1xuICAgIHN0YXJ0VmVjdG9yKGVsZW1fc2l6ZSwgbnVtX2VsZW1zLCBhbGlnbm1lbnQpIHtcbiAgICAgICAgdGhpcy5ub3ROZXN0ZWQoKTtcbiAgICAgICAgdGhpcy52ZWN0b3JfbnVtX2VsZW1zID0gbnVtX2VsZW1zO1xuICAgICAgICB0aGlzLnByZXAoY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVCwgZWxlbV9zaXplICogbnVtX2VsZW1zKTtcbiAgICAgICAgdGhpcy5wcmVwKGFsaWdubWVudCwgZWxlbV9zaXplICogbnVtX2VsZW1zKTsgLy8gSnVzdCBpbiBjYXNlIGFsaWdubWVudCA+IGludC5cbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluaXNoIG9mZiB0aGUgY3JlYXRpb24gb2YgYW4gYXJyYXkgYW5kIGFsbCBpdHMgZWxlbWVudHMuIFRoZSBhcnJheSBtdXN0IGJlXG4gICAgICogY3JlYXRlZCB3aXRoIGBzdGFydFZlY3RvcmAuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgb2Zmc2V0IGF0IHdoaWNoIHRoZSBuZXdseSBjcmVhdGVkIGFycmF5XG4gICAgICogc3RhcnRzLlxuICAgICAqL1xuICAgIGVuZFZlY3RvcigpIHtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKHRoaXMudmVjdG9yX251bV9lbGVtcyk7XG4gICAgICAgIHJldHVybiB0aGlzLm9mZnNldCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFbmNvZGUgdGhlIHN0cmluZyBgc2AgaW4gdGhlIGJ1ZmZlciB1c2luZyBVVEYtOC4gSWYgdGhlIHN0cmluZyBwYXNzZWQgaGFzXG4gICAgICogYWxyZWFkeSBiZWVuIHNlZW4sIHdlIHJldHVybiB0aGUgb2Zmc2V0IG9mIHRoZSBhbHJlYWR5IHdyaXR0ZW4gc3RyaW5nXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcyBUaGUgc3RyaW5nIHRvIGVuY29kZVxuICAgICAqIEByZXR1cm4gVGhlIG9mZnNldCBpbiB0aGUgYnVmZmVyIHdoZXJlIHRoZSBlbmNvZGVkIHN0cmluZyBzdGFydHNcbiAgICAgKi9cbiAgICBjcmVhdGVTaGFyZWRTdHJpbmcocykge1xuICAgICAgICBpZiAoIXMpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5zdHJpbmdfbWFwcykge1xuICAgICAgICAgICAgdGhpcy5zdHJpbmdfbWFwcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zdHJpbmdfbWFwcy5oYXMocykpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0cmluZ19tYXBzLmdldChzKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmNyZWF0ZVN0cmluZyhzKTtcbiAgICAgICAgdGhpcy5zdHJpbmdfbWFwcy5zZXQocywgb2Zmc2V0KTtcbiAgICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRW5jb2RlIHRoZSBzdHJpbmcgYHNgIGluIHRoZSBidWZmZXIgdXNpbmcgVVRGLTguIElmIGEgVWludDhBcnJheSBpcyBwYXNzZWRcbiAgICAgKiBpbnN0ZWFkIG9mIGEgc3RyaW5nLCBpdCBpcyBhc3N1bWVkIHRvIGNvbnRhaW4gdmFsaWQgVVRGLTggZW5jb2RlZCBkYXRhLlxuICAgICAqXG4gICAgICogQHBhcmFtIHMgVGhlIHN0cmluZyB0byBlbmNvZGVcbiAgICAgKiBAcmV0dXJuIFRoZSBvZmZzZXQgaW4gdGhlIGJ1ZmZlciB3aGVyZSB0aGUgZW5jb2RlZCBzdHJpbmcgc3RhcnRzXG4gICAgICovXG4gICAgY3JlYXRlU3RyaW5nKHMpIHtcbiAgICAgICAgaWYgKHMgPT09IG51bGwgfHwgcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgdXRmODtcbiAgICAgICAgaWYgKHMgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICB1dGY4ID0gcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHV0ZjggPSB0aGlzLnRleHRfZW5jb2Rlci5lbmNvZGUocyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hZGRJbnQ4KDApO1xuICAgICAgICB0aGlzLnN0YXJ0VmVjdG9yKDEsIHV0ZjgubGVuZ3RoLCAxKTtcbiAgICAgICAgdGhpcy5iYi5zZXRQb3NpdGlvbigodGhpcy5zcGFjZSAtPSB1dGY4Lmxlbmd0aCkpO1xuICAgICAgICB0aGlzLmJiLmJ5dGVzKCkuc2V0KHV0ZjgsIHRoaXMuc3BhY2UpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbmRWZWN0b3IoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgYnl0ZSB2ZWN0b3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdiBUaGUgYnl0ZXMgdG8gYWRkXG4gICAgICogQHJldHVybnMgVGhlIG9mZnNldCBpbiB0aGUgYnVmZmVyIHdoZXJlIHRoZSBieXRlIHZlY3RvciBzdGFydHNcbiAgICAgKi9cbiAgICBjcmVhdGVCeXRlVmVjdG9yKHYpIHtcbiAgICAgICAgaWYgKHYgPT09IG51bGwgfHwgdiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXJ0VmVjdG9yKDEsIHYubGVuZ3RoLCAxKTtcbiAgICAgICAgdGhpcy5iYi5zZXRQb3NpdGlvbigodGhpcy5zcGFjZSAtPSB2Lmxlbmd0aCkpO1xuICAgICAgICB0aGlzLmJiLmJ5dGVzKCkuc2V0KHYsIHRoaXMuc3BhY2UpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbmRWZWN0b3IoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gcGFjayBhbiBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIG9mZnNldCBvZiBvYmpcbiAgICAgKi9cbiAgICBjcmVhdGVPYmplY3RPZmZzZXQob2JqKSB7XG4gICAgICAgIGlmIChvYmogPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU3RyaW5nKG9iaik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqLnBhY2sodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gcGFjayBhIGxpc3Qgb2Ygb2JqZWN0XG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBsaXN0IG9mIG9mZnNldHMgb2YgZWFjaCBub24gbnVsbCBvYmplY3RcbiAgICAgKi9cbiAgICBjcmVhdGVPYmplY3RPZmZzZXRMaXN0KGxpc3QpIHtcbiAgICAgICAgY29uc3QgcmV0ID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgY29uc3QgdmFsID0gbGlzdFtpXTtcbiAgICAgICAgICAgIGlmICh2YWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXQucHVzaCh0aGlzLmNyZWF0ZU9iamVjdE9mZnNldCh2YWwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZsYXRCdWZmZXJzOiBBcmd1bWVudCBmb3IgY3JlYXRlT2JqZWN0T2Zmc2V0TGlzdCBjYW5ub3QgY29udGFpbiBudWxsLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIGNyZWF0ZVN0cnVjdE9mZnNldExpc3QobGlzdCwgc3RhcnRGdW5jKSB7XG4gICAgICAgIHN0YXJ0RnVuYyh0aGlzLCBsaXN0Lmxlbmd0aCk7XG4gICAgICAgIHRoaXMuY3JlYXRlT2JqZWN0T2Zmc2V0TGlzdChsaXN0LnNsaWNlKCkucmV2ZXJzZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5kVmVjdG9yKCk7XG4gICAgfVxufVxuZXhwb3J0cy5CdWlsZGVyID0gQnVpbGRlcjtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuRW5jb2RpbmcgPSBleHBvcnRzLkJ5dGVCdWZmZXIgPSBleHBvcnRzLkJ1aWxkZXIgPSBleHBvcnRzLmlzTGl0dGxlRW5kaWFuID0gZXhwb3J0cy5pbnQzMiA9IGV4cG9ydHMuZmxvYXQ2NCA9IGV4cG9ydHMuZmxvYXQzMiA9IGV4cG9ydHMuU0laRV9QUkVGSVhfTEVOR1RIID0gZXhwb3J0cy5TSVpFT0ZfU0hPUlQgPSBleHBvcnRzLlNJWkVPRl9JTlQgPSBleHBvcnRzLkZJTEVfSURFTlRJRklFUl9MRU5HVEggPSB2b2lkIDA7XG52YXIgY29uc3RhbnRzX2pzXzEgPSByZXF1aXJlKFwiLi9jb25zdGFudHMuanNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJGSUxFX0lERU5USUZJRVJfTEVOR1RIXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU0laRU9GX0lOVFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlNJWkVPRl9TSE9SVFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RhbnRzX2pzXzEuU0laRU9GX1NIT1JUOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU0laRV9QUkVGSVhfTEVOR1RIXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdGFudHNfanNfMS5TSVpFX1BSRUZJWF9MRU5HVEg7IH0gfSk7XG52YXIgdXRpbHNfanNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZmxvYXQzMlwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdXRpbHNfanNfMS5mbG9hdDMyOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZmxvYXQ2NFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdXRpbHNfanNfMS5mbG9hdDY0OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiaW50MzJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHV0aWxzX2pzXzEuaW50MzI7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpc0xpdHRsZUVuZGlhblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdXRpbHNfanNfMS5pc0xpdHRsZUVuZGlhbjsgfSB9KTtcbnZhciBidWlsZGVyX2pzXzEgPSByZXF1aXJlKFwiLi9idWlsZGVyLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQnVpbGRlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYnVpbGRlcl9qc18xLkJ1aWxkZXI7IH0gfSk7XG52YXIgYnl0ZV9idWZmZXJfanNfMSA9IHJlcXVpcmUoXCIuL2J5dGUtYnVmZmVyLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQnl0ZUJ1ZmZlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYnl0ZV9idWZmZXJfanNfMS5CeXRlQnVmZmVyOyB9IH0pO1xudmFyIGVuY29kaW5nX2pzXzEgPSByZXF1aXJlKFwiLi9lbmNvZGluZy5qc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkVuY29kaW5nXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBlbmNvZGluZ19qc18xLkVuY29kaW5nOyB9IH0pO1xuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBBcmdUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIEFyZ1R5cGVBbmRJbmRleCB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogQXJnVHlwZUFuZEluZGV4IHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0FyZ1R5cGVBbmRJbmRleChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogQXJnVHlwZUFuZEluZGV4KTogQXJnVHlwZUFuZEluZGV4IHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgQXJnVHlwZUFuZEluZGV4KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzQXJnVHlwZUFuZEluZGV4KGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBBcmdUeXBlQW5kSW5kZXgpOiBBcmdUeXBlQW5kSW5kZXgge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBBcmdUeXBlQW5kSW5kZXgoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGFyZ1R5cGUoKTogQXJnVHlwZSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50OCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBBcmdUeXBlLklOUFVUO1xuICB9XG5cbiAgaW5kZXgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEFyZ1R5cGVBbmRJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRBcmdUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGFyZ1R5cGU6IEFyZ1R5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50OCgwLCBhcmdUeXBlLCBBcmdUeXBlLklOUFVUKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbmRleDogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDEsIGluZGV4LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRBcmdUeXBlQW5kSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUFyZ1R5cGVBbmRJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBhcmdUeXBlOiBBcmdUeXBlLCBpbmRleDogbnVtYmVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBBcmdUeXBlQW5kSW5kZXguc3RhcnRBcmdUeXBlQW5kSW5kZXgoYnVpbGRlcik7XG4gICAgQXJnVHlwZUFuZEluZGV4LmFkZEFyZ1R5cGUoYnVpbGRlciwgYXJnVHlwZSk7XG4gICAgQXJnVHlwZUFuZEluZGV4LmFkZEluZGV4KGJ1aWxkZXIsIGluZGV4KTtcbiAgICByZXR1cm4gQXJnVHlwZUFuZEluZGV4LmVuZEFyZ1R5cGVBbmRJbmRleChidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuZXhwb3J0IGVudW0gQXR0cmlidXRlVHlwZSB7XG4gIFVOREVGSU5FRCA9IDAsXG4gIEZMT0FUID0gMSxcbiAgSU5UID0gMixcbiAgU1RSSU5HID0gMyxcbiAgVEVOU09SID0gNCxcbiAgR1JBUEggPSA1LFxuICBGTE9BVFMgPSA2LFxuICBJTlRTID0gNyxcbiAgU1RSSU5HUyA9IDgsXG4gIFRFTlNPUlMgPSA5LFxuICBHUkFQSFMgPSAxMCxcbiAgU1BBUlNFX1RFTlNPUiA9IDExLFxuICBTUEFSU0VfVEVOU09SUyA9IDEyLFxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuZXhwb3J0IGVudW0gTm9kZVR5cGUge1xuICBQcmltaXRpdmUgPSAwLFxuICBGdXNlZCA9IDEsXG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IEF0dHJpYnV0ZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9hdHRyaWJ1dGUuanMnO1xuaW1wb3J0IHsgTm9kZVR5cGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvbm9kZS10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIE5vZGUge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IE5vZGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzTm9kZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTm9kZSk6IE5vZGUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzTm9kZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTm9kZSk6IE5vZGUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBuYW1lKCk6IHN0cmluZyB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGRvY1N0cmluZygpOiBzdHJpbmcgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgZG9tYWluKCk6IHN0cmluZyB8IG51bGw7XG4gIGRvbWFpbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBkb21haW4ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBzaW5jZVZlcnNpb24oKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGluZGV4KCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgb3BUeXBlKCk6IHN0cmluZyB8IG51bGw7XG4gIG9wVHlwZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBvcFR5cGUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdHlwZSgpOiBOb2RlVHlwZSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IE5vZGVUeXBlLlByaW1pdGl2ZTtcbiAgfVxuXG4gIGV4ZWN1dGlvblByb3ZpZGVyVHlwZSgpOiBzdHJpbmcgfCBudWxsO1xuICBleGVjdXRpb25Qcm92aWRlclR5cGUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZXhlY3V0aW9uUHJvdmlkZXJUeXBlKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGlucHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICBpbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5O1xuICBpbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGlucHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgb3V0cHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICBvdXRwdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgb3V0cHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgb3V0cHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgYXR0cmlidXRlcyhpbmRleDogbnVtYmVyLCBvYmo/OiBBdHRyaWJ1dGUpOiBBdHRyaWJ1dGUgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgQXR0cmlidXRlKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGF0dHJpYnV0ZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGlucHV0QXJnQ291bnRzKGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSA6IDA7XG4gIH1cblxuICBpbnB1dEFyZ0NvdW50c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgaW5wdXRBcmdDb3VudHNBcnJheSgpOiBJbnQzMkFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IG5ldyBJbnQzMkFycmF5KFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnVmZmVyLFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBpbXBsaWNpdElucHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICBpbXBsaWNpdElucHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIGltcGxpY2l0SW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBpbXBsaWNpdElucHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0Tm9kZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb21haW4oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIGRvbWFpbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkU2luY2VWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNpbmNlVmVyc2lvbjogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDMsIHNpbmNlVmVyc2lvbiwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5kZXg6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMig0LCBpbmRleCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkT3BUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9wVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBvcFR5cGVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdHlwZTogTm9kZVR5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoNiwgdHlwZSwgTm9kZVR5cGUuUHJpbWl0aXZlKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRFeGVjdXRpb25Qcm92aWRlclR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZXhlY3V0aW9uUHJvdmlkZXJUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDcsIGV4ZWN1dGlvblByb3ZpZGVyVHlwZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5wdXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg4LCBpbnB1dHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUlucHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbnB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE91dHB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3V0cHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg5LCBvdXRwdXRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPdXRwdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE91dHB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEF0dHJpYnV0ZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgYXR0cmlidXRlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMCwgYXR0cmlidXRlc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlQXR0cmlidXRlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRBdHRyaWJ1dGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJbnB1dEFyZ0NvdW50cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnB1dEFyZ0NvdW50c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMSwgaW5wdXRBcmdDb3VudHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUlucHV0QXJnQ291bnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdIHwgSW50MzJBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldDtcbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFRoaXMgVWludDhBcnJheSBvdmVybG9hZCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIGZ1dHVyZS5cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVJbnB1dEFyZ0NvdW50c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBudW1iZXJbXSB8IFVpbnQ4QXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQ7XG4gIHN0YXRpYyBjcmVhdGVJbnB1dEFyZ0NvdW50c1ZlY3RvcihcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGRhdGE6IG51bWJlcltdIHwgSW50MzJBcnJheSB8IFVpbnQ4QXJyYXksXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkSW50MzIoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydElucHV0QXJnQ291bnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJbXBsaWNpdElucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbXBsaWNpdElucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMiwgaW1wbGljaXRJbnB1dHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUltcGxpY2l0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEltcGxpY2l0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmROb2RlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVOb2RlKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGRvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGRvbWFpbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHNpbmNlVmVyc2lvbjogbnVtYmVyLFxuICAgIGluZGV4OiBudW1iZXIsXG4gICAgb3BUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgdHlwZTogTm9kZVR5cGUsXG4gICAgZXhlY3V0aW9uUHJvdmlkZXJUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgaW5wdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgb3V0cHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGF0dHJpYnV0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBpbnB1dEFyZ0NvdW50c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGltcGxpY2l0SW5wdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgTm9kZS5zdGFydE5vZGUoYnVpbGRlcik7XG4gICAgTm9kZS5hZGROYW1lKGJ1aWxkZXIsIG5hbWVPZmZzZXQpO1xuICAgIE5vZGUuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgTm9kZS5hZGREb21haW4oYnVpbGRlciwgZG9tYWluT2Zmc2V0KTtcbiAgICBOb2RlLmFkZFNpbmNlVmVyc2lvbihidWlsZGVyLCBzaW5jZVZlcnNpb24pO1xuICAgIE5vZGUuYWRkSW5kZXgoYnVpbGRlciwgaW5kZXgpO1xuICAgIE5vZGUuYWRkT3BUeXBlKGJ1aWxkZXIsIG9wVHlwZU9mZnNldCk7XG4gICAgTm9kZS5hZGRUeXBlKGJ1aWxkZXIsIHR5cGUpO1xuICAgIE5vZGUuYWRkRXhlY3V0aW9uUHJvdmlkZXJUeXBlKGJ1aWxkZXIsIGV4ZWN1dGlvblByb3ZpZGVyVHlwZU9mZnNldCk7XG4gICAgTm9kZS5hZGRJbnB1dHMoYnVpbGRlciwgaW5wdXRzT2Zmc2V0KTtcbiAgICBOb2RlLmFkZE91dHB1dHMoYnVpbGRlciwgb3V0cHV0c09mZnNldCk7XG4gICAgTm9kZS5hZGRBdHRyaWJ1dGVzKGJ1aWxkZXIsIGF0dHJpYnV0ZXNPZmZzZXQpO1xuICAgIE5vZGUuYWRkSW5wdXRBcmdDb3VudHMoYnVpbGRlciwgaW5wdXRBcmdDb3VudHNPZmZzZXQpO1xuICAgIE5vZGUuYWRkSW1wbGljaXRJbnB1dHMoYnVpbGRlciwgaW1wbGljaXRJbnB1dHNPZmZzZXQpO1xuICAgIHJldHVybiBOb2RlLmVuZE5vZGUoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuZXhwb3J0IGNsYXNzIEVkZ2VFbmQge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IEVkZ2VFbmQge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBub2RlSW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiX3Bvcyk7XG4gIH1cblxuICBzcmNBcmdJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyA0KTtcbiAgfVxuXG4gIGRzdEFyZ0luZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIDgpO1xuICB9XG5cbiAgc3RhdGljIHNpemVPZigpOiBudW1iZXIge1xuICAgIHJldHVybiAxMjtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVFZGdlRW5kKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbm9kZV9pbmRleDogbnVtYmVyLFxuICAgIHNyY19hcmdfaW5kZXg6IG51bWJlcixcbiAgICBkc3RfYXJnX2luZGV4OiBudW1iZXIsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5wcmVwKDQsIDEyKTtcbiAgICBidWlsZGVyLndyaXRlSW50MzIoZHN0X2FyZ19pbmRleCk7XG4gICAgYnVpbGRlci53cml0ZUludDMyKHNyY19hcmdfaW5kZXgpO1xuICAgIGJ1aWxkZXIud3JpdGVJbnQzMihub2RlX2luZGV4KTtcbiAgICByZXR1cm4gYnVpbGRlci5vZmZzZXQoKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBFZGdlRW5kIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2VkZ2UtZW5kLmpzJztcblxuZXhwb3J0IGNsYXNzIE5vZGVFZGdlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBOb2RlRWRnZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNOb2RlRWRnZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTm9kZUVkZ2UpOiBOb2RlRWRnZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE5vZGVFZGdlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzTm9kZUVkZ2UoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE5vZGVFZGdlKTogTm9kZUVkZ2Uge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlRWRnZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgbm9kZUluZGV4KCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBpbnB1dEVkZ2VzKGluZGV4OiBudW1iZXIsIG9iaj86IEVkZ2VFbmQpOiBFZGdlRW5kIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgRWRnZUVuZCgpKS5fX2luaXQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiAxMiwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBpbnB1dEVkZ2VzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG91dHB1dEVkZ2VzKGluZGV4OiBudW1iZXIsIG9iaj86IEVkZ2VFbmQpOiBFZGdlRW5kIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgRWRnZUVuZCgpKS5fX2luaXQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiAxMiwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBvdXRwdXRFZGdlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnROb2RlRWRnZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROb2RlSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGV4OiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMCwgbm9kZUluZGV4LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJbnB1dEVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlucHV0RWRnZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgaW5wdXRFZGdlc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbnB1dEVkZ2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDEyLCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkT3V0cHV0RWRnZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3V0cHV0RWRnZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgb3V0cHV0RWRnZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0T3V0cHV0RWRnZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoMTIsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmROb2RlRWRnZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlTm9kZUVkZ2UoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBub2RlSW5kZXg6IG51bWJlcixcbiAgICBpbnB1dEVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgb3V0cHV0RWRnZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBOb2RlRWRnZS5zdGFydE5vZGVFZGdlKGJ1aWxkZXIpO1xuICAgIE5vZGVFZGdlLmFkZE5vZGVJbmRleChidWlsZGVyLCBub2RlSW5kZXgpO1xuICAgIE5vZGVFZGdlLmFkZElucHV0RWRnZXMoYnVpbGRlciwgaW5wdXRFZGdlc09mZnNldCk7XG4gICAgTm9kZUVkZ2UuYWRkT3V0cHV0RWRnZXMoYnVpbGRlciwgb3V0cHV0RWRnZXNPZmZzZXQpO1xuICAgIHJldHVybiBOb2RlRWRnZS5lbmROb2RlRWRnZShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG4vKipcbiAqIG5vZGVzIHRvIGNvbnNpZGVyIGZvciBhIHJ1bnRpbWUgb3B0aW1pemF0aW9uXG4gKiBzZWUgY29ycmVzcG9uZGluZyB0eXBlIGluIG9ubnhydW50aW1lL2NvcmUvZ3JhcGgvcnVudGltZV9vcHRpbWl6YXRpb25fcmVjb3JkLmhcbiAqL1xuZXhwb3J0IGNsYXNzIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzTm9kZXNUb09wdGltaXplSW5kaWNlcyhcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzLFxuICApOiBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgTm9kZXNUb09wdGltaXplSW5kaWNlcygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc05vZGVzVG9PcHRpbWl6ZUluZGljZXMoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogTm9kZXNUb09wdGltaXplSW5kaWNlcyxcbiAgKTogTm9kZXNUb09wdGltaXplSW5kaWNlcyB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIG5vZGVJbmRpY2VzKGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSA6IDA7XG4gIH1cblxuICBub2RlSW5kaWNlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBub2RlSW5kaWNlc0FycmF5KCk6IFVpbnQzMkFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gbmV3IFVpbnQzMkFycmF5KFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnVmZmVyLFxuICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBudW1JbnB1dHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG51bU91dHB1dHMoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGhhc1ZhcmlhZGljSW5wdXQoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gISF0aGlzLmJiIS5yZWFkSW50OCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBmYWxzZTtcbiAgfVxuXG4gIGhhc1ZhcmlhZGljT3V0cHV0KCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgcmV0dXJuIG9mZnNldCA/ICEhdGhpcy5iYiEucmVhZEludDgodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogZmFsc2U7XG4gIH1cblxuICBudW1WYXJpYWRpY0lucHV0cygpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG51bVZhcmlhZGljT3V0cHV0cygpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoNyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTm9kZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgbm9kZUluZGljZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdIHwgVWludDMyQXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQ7XG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBUaGlzIFVpbnQ4QXJyYXkgb3ZlcmxvYWQgd2lsbCBiZSByZW1vdmVkIGluIHRoZSBmdXR1cmUuXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlTm9kZUluZGljZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW10gfCBVaW50OEFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuICBzdGF0aWMgY3JlYXRlTm9kZUluZGljZXNWZWN0b3IoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBkYXRhOiBudW1iZXJbXSB8IFVpbnQzMkFycmF5IHwgVWludDhBcnJheSxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRJbnQzMihkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0Tm9kZUluZGljZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE51bUlucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1JbnB1dHM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigxLCBudW1JbnB1dHMsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE51bU91dHB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtT3V0cHV0czogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDIsIG51bU91dHB1dHMsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEhhc1ZhcmlhZGljSW5wdXQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaGFzVmFyaWFkaWNJbnB1dDogYm9vbGVhbikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ4KDMsICtoYXNWYXJpYWRpY0lucHV0LCArZmFsc2UpO1xuICB9XG5cbiAgc3RhdGljIGFkZEhhc1ZhcmlhZGljT3V0cHV0KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGhhc1ZhcmlhZGljT3V0cHV0OiBib29sZWFuKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDgoNCwgK2hhc1ZhcmlhZGljT3V0cHV0LCArZmFsc2UpO1xuICB9XG5cbiAgc3RhdGljIGFkZE51bVZhcmlhZGljSW5wdXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bVZhcmlhZGljSW5wdXRzOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoNSwgbnVtVmFyaWFkaWNJbnB1dHMsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE51bVZhcmlhZGljT3V0cHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1WYXJpYWRpY091dHB1dHM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMig2LCBudW1WYXJpYWRpY091dHB1dHMsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVzVG9PcHRpbWl6ZUluZGljZXMoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBub2RlSW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIG51bUlucHV0czogbnVtYmVyLFxuICAgIG51bU91dHB1dHM6IG51bWJlcixcbiAgICBoYXNWYXJpYWRpY0lucHV0OiBib29sZWFuLFxuICAgIGhhc1ZhcmlhZGljT3V0cHV0OiBib29sZWFuLFxuICAgIG51bVZhcmlhZGljSW5wdXRzOiBudW1iZXIsXG4gICAgbnVtVmFyaWFkaWNPdXRwdXRzOiBudW1iZXIsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgTm9kZXNUb09wdGltaXplSW5kaWNlcy5zdGFydE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoYnVpbGRlcik7XG4gICAgTm9kZXNUb09wdGltaXplSW5kaWNlcy5hZGROb2RlSW5kaWNlcyhidWlsZGVyLCBub2RlSW5kaWNlc09mZnNldCk7XG4gICAgTm9kZXNUb09wdGltaXplSW5kaWNlcy5hZGROdW1JbnB1dHMoYnVpbGRlciwgbnVtSW5wdXRzKTtcbiAgICBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzLmFkZE51bU91dHB1dHMoYnVpbGRlciwgbnVtT3V0cHV0cyk7XG4gICAgTm9kZXNUb09wdGltaXplSW5kaWNlcy5hZGRIYXNWYXJpYWRpY0lucHV0KGJ1aWxkZXIsIGhhc1ZhcmlhZGljSW5wdXQpO1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuYWRkSGFzVmFyaWFkaWNPdXRwdXQoYnVpbGRlciwgaGFzVmFyaWFkaWNPdXRwdXQpO1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuYWRkTnVtVmFyaWFkaWNJbnB1dHMoYnVpbGRlciwgbnVtVmFyaWFkaWNJbnB1dHMpO1xuICAgIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuYWRkTnVtVmFyaWFkaWNPdXRwdXRzKGJ1aWxkZXIsIG51bVZhcmlhZGljT3V0cHV0cyk7XG4gICAgcmV0dXJuIE5vZGVzVG9PcHRpbWl6ZUluZGljZXMuZW5kTm9kZXNUb09wdGltaXplSW5kaWNlcyhidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL25vZGVzLXRvLW9wdGltaXplLWluZGljZXMuanMnO1xuXG4vKipcbiAqIGEgc2luZ2xlIHJ1bnRpbWUgb3B0aW1pemF0aW9uXG4gKiBzZWUgY29ycmVzcG9uZGluZyB0eXBlIGluIG9ubnhydW50aW1lL2NvcmUvZ3JhcGgvcnVudGltZV9vcHRpbWl6YXRpb25fcmVjb3JkLmhcbiAqL1xuZXhwb3J0IGNsYXNzIFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzUnVudGltZU9wdGltaXphdGlvblJlY29yZChcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkLFxuICApOiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgUnVudGltZU9wdGltaXphdGlvblJlY29yZCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1J1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogUnVudGltZU9wdGltaXphdGlvblJlY29yZCxcbiAgKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZCB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGFjdGlvbklkKCk6IHN0cmluZyB8IG51bGw7XG4gIGFjdGlvbklkKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGFjdGlvbklkKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgbm9kZXNUb09wdGltaXplSW5kaWNlcyhvYmo/OiBOb2Rlc1RvT3B0aW1pemVJbmRpY2VzKTogTm9kZXNUb09wdGltaXplSW5kaWNlcyB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHByb2R1Y2VkT3BJZHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgcHJvZHVjZWRPcElkcyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIHByb2R1Y2VkT3BJZHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHByb2R1Y2VkT3BJZHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkQWN0aW9uSWQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgYWN0aW9uSWRPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgYWN0aW9uSWRPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE5vZGVzVG9PcHRpbWl6ZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZXNUb09wdGltaXplSW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBub2Rlc1RvT3B0aW1pemVJbmRpY2VzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRQcm9kdWNlZE9wSWRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHByb2R1Y2VkT3BJZHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMywgcHJvZHVjZWRPcElkc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlUHJvZHVjZWRPcElkc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRQcm9kdWNlZE9wSWRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9uLXJlY29yZC5qcyc7XG5cbmV4cG9ydCBjbGFzcyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5LFxuICApOiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkoKSkuX19pbml0KFxuICAgICAgYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSxcbiAgICAgIGJiLFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSxcbiAgKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KCkpLl9faW5pdChcbiAgICAgIGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksXG4gICAgICBiYixcbiAgICApO1xuICB9XG5cbiAgb3B0aW1pemVyTmFtZSgpOiBzdHJpbmcgfCBudWxsO1xuICBvcHRpbWl6ZXJOYW1lKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIG9wdGltaXplck5hbWUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBydW50aW1lT3B0aW1pemF0aW9uUmVjb3JkcyhpbmRleDogbnVtYmVyLCBvYmo/OiBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQoKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgcnVudGltZU9wdGltaXphdGlvblJlY29yZHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0UnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICB9XG5cbiAgc3RhdGljIGFkZE9wdGltaXplck5hbWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3B0aW1pemVyTmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBvcHRpbWl6ZXJOYW1lT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkcyhcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIHJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgcnVudGltZU9wdGltaXphdGlvblJlY29yZHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzVmVjdG9yKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10sXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3Jkc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgYnVpbGRlci5yZXF1aXJlZEZpZWxkKG9mZnNldCwgNCk7IC8vIG9wdGltaXplcl9uYW1lXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBvcHRpbWl6ZXJOYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgcnVudGltZU9wdGltaXphdGlvblJlY29yZHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkuc3RhcnRSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkoYnVpbGRlcik7XG4gICAgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5LmFkZE9wdGltaXplck5hbWUoYnVpbGRlciwgb3B0aW1pemVyTmFtZU9mZnNldCk7XG4gICAgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5LmFkZFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzKGJ1aWxkZXIsIHJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRzT2Zmc2V0KTtcbiAgICByZXR1cm4gUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5LmVuZFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkQ29udGFpbmVyRW50cnkgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLWNvbnRhaW5lci1lbnRyeS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBSdW50aW1lT3B0aW1pemF0aW9ucyB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogUnVudGltZU9wdGltaXphdGlvbnMge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzUnVudGltZU9wdGltaXphdGlvbnMoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25zKTogUnVudGltZU9wdGltaXphdGlvbnMge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBSdW50aW1lT3B0aW1pemF0aW9ucygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1J1bnRpbWVPcHRpbWl6YXRpb25zKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25zLFxuICApOiBSdW50aW1lT3B0aW1pemF0aW9ucyB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFJ1bnRpbWVPcHRpbWl6YXRpb25zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICAvKipcbiAgICogbWFwcGluZyBmcm9tIG9wdGltaXplciBuYW1lIHRvIFtSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkXVxuICAgKi9cbiAgcmVjb3JkcyhcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIG9iaj86IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmRDb250YWluZXJFbnRyeSxcbiAgKTogUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5KCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHJlY29yZHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0UnVudGltZU9wdGltaXphdGlvbnMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMSk7XG4gIH1cblxuICBzdGF0aWMgYWRkUmVjb3JkcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCByZWNvcmRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIHJlY29yZHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVJlY29yZHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0UmVjb3Jkc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kUnVudGltZU9wdGltaXphdGlvbnMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVJ1bnRpbWVPcHRpbWl6YXRpb25zKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgcmVjb3Jkc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIFJ1bnRpbWVPcHRpbWl6YXRpb25zLnN0YXJ0UnVudGltZU9wdGltaXphdGlvbnMoYnVpbGRlcik7XG4gICAgUnVudGltZU9wdGltaXphdGlvbnMuYWRkUmVjb3JkcyhidWlsZGVyLCByZWNvcmRzT2Zmc2V0KTtcbiAgICByZXR1cm4gUnVudGltZU9wdGltaXphdGlvbnMuZW5kUnVudGltZU9wdGltaXphdGlvbnMoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmV4cG9ydCBlbnVtIFRlbnNvckRhdGFUeXBlIHtcbiAgVU5ERUZJTkVEID0gMCxcbiAgRkxPQVQgPSAxLFxuICBVSU5UOCA9IDIsXG4gIElOVDggPSAzLFxuICBVSU5UMTYgPSA0LFxuICBJTlQxNiA9IDUsXG4gIElOVDMyID0gNixcbiAgSU5UNjQgPSA3LFxuICBTVFJJTkcgPSA4LFxuICBCT09MID0gOSxcbiAgRkxPQVQxNiA9IDEwLFxuICBET1VCTEUgPSAxMSxcbiAgVUlOVDMyID0gMTIsXG4gIFVJTlQ2NCA9IDEzLFxuICBDT01QTEVYNjQgPSAxNCxcbiAgQ09NUExFWDEyOCA9IDE1LFxuICBCRkxPQVQxNiA9IDE2LFxuICBGTE9BVDhFNE0zRk4gPSAxNyxcbiAgRkxPQVQ4RTRNM0ZOVVogPSAxOCxcbiAgRkxPQVQ4RTVNMiA9IDE5LFxuICBGTE9BVDhFNU0yRk5VWiA9IDIwLFxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBUZW5zb3JEYXRhVHlwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90ZW5zb3ItZGF0YS10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIFRlbnNvciB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogVGVuc29yIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1RlbnNvcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVGVuc29yKTogVGVuc29yIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgVGVuc29yKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzVGVuc29yKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUZW5zb3IpOiBUZW5zb3Ige1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBUZW5zb3IoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIG5hbWUoKTogc3RyaW5nIHwgbnVsbDtcbiAgbmFtZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBuYW1lKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgZG9jU3RyaW5nKCk6IHN0cmluZyB8IG51bGw7XG4gIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBkaW1zKGluZGV4OiBudW1iZXIpOiBiaWdpbnQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDgpIDogQmlnSW50KDApO1xuICB9XG5cbiAgZGltc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBkYXRhVHlwZSgpOiBUZW5zb3JEYXRhVHlwZSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IFRlbnNvckRhdGFUeXBlLlVOREVGSU5FRDtcbiAgfVxuXG4gIHJhd0RhdGEoaW5kZXg6IG51bWJlcik6IG51bWJlciB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50OCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCkgOiAwO1xuICB9XG5cbiAgcmF3RGF0YUxlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgcmF3RGF0YUFycmF5KCk6IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gbmV3IFVpbnQ4QXJyYXkoXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5idWZmZXIsXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5ieXRlT2Zmc2V0ICsgdGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICAgIHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHN0cmluZ0RhdGEoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgc3RyaW5nRGF0YShpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIHN0cmluZ0RhdGEoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHN0cmluZ0RhdGFMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGV4dGVybmFsRGF0YU9mZnNldCgpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBCaWdJbnQoJy0xJyk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRUZW5zb3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoNyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREaW1zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZGltc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGltc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBiaWdpbnRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig4LCBkYXRhLmxlbmd0aCwgOCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkSW50NjQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgbnVtRWxlbXMsIDgpO1xuICB9XG5cbiAgc3RhdGljIGFkZERhdGFUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGFUeXBlOiBUZW5zb3JEYXRhVHlwZSkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigzLCBkYXRhVHlwZSwgVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRSYXdEYXRhKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHJhd0RhdGFPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNCwgcmF3RGF0YU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlUmF3RGF0YVZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBudW1iZXJbXSB8IFVpbnQ4QXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoMSwgZGF0YS5sZW5ndGgsIDEpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEludDgoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFJhd0RhdGFWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoMSwgbnVtRWxlbXMsIDEpO1xuICB9XG5cbiAgc3RhdGljIGFkZFN0cmluZ0RhdGEoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc3RyaW5nRGF0YU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBzdHJpbmdEYXRhT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVTdHJpbmdEYXRhVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFN0cmluZ0RhdGFWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEV4dGVybmFsRGF0YU9mZnNldChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBleHRlcm5hbERhdGFPZmZzZXQ6IGJpZ2ludCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCg2LCBleHRlcm5hbERhdGFPZmZzZXQsIEJpZ0ludCgnLTEnKSk7XG4gIH1cblxuICBzdGF0aWMgZW5kVGVuc29yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVUZW5zb3IoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgZGltc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGRhdGFUeXBlOiBUZW5zb3JEYXRhVHlwZSxcbiAgICByYXdEYXRhT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgc3RyaW5nRGF0YU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIGV4dGVybmFsRGF0YU9mZnNldDogYmlnaW50LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIFRlbnNvci5zdGFydFRlbnNvcihidWlsZGVyKTtcbiAgICBUZW5zb3IuYWRkTmFtZShidWlsZGVyLCBuYW1lT2Zmc2V0KTtcbiAgICBUZW5zb3IuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgVGVuc29yLmFkZERpbXMoYnVpbGRlciwgZGltc09mZnNldCk7XG4gICAgVGVuc29yLmFkZERhdGFUeXBlKGJ1aWxkZXIsIGRhdGFUeXBlKTtcbiAgICBUZW5zb3IuYWRkUmF3RGF0YShidWlsZGVyLCByYXdEYXRhT2Zmc2V0KTtcbiAgICBUZW5zb3IuYWRkU3RyaW5nRGF0YShidWlsZGVyLCBzdHJpbmdEYXRhT2Zmc2V0KTtcbiAgICBUZW5zb3IuYWRkRXh0ZXJuYWxEYXRhT2Zmc2V0KGJ1aWxkZXIsIGV4dGVybmFsRGF0YU9mZnNldCk7XG4gICAgcmV0dXJuIFRlbnNvci5lbmRUZW5zb3IoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3RlbnNvci5qcyc7XG5cbmV4cG9ydCBjbGFzcyBTcGFyc2VUZW5zb3Ige1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFNwYXJzZVRlbnNvciB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNTcGFyc2VUZW5zb3IoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNwYXJzZVRlbnNvcik6IFNwYXJzZVRlbnNvciB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFNwYXJzZVRlbnNvcigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1NwYXJzZVRlbnNvcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU3BhcnNlVGVuc29yKTogU3BhcnNlVGVuc29yIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU3BhcnNlVGVuc29yKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICB2YWx1ZXMob2JqPzogVGVuc29yKTogVGVuc29yIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUZW5zb3IoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgaW5kaWNlcyhvYmo/OiBUZW5zb3IpOiBUZW5zb3IgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBkaW1zKGluZGV4OiBudW1iZXIpOiBiaWdpbnQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDgpIDogQmlnSW50KDApO1xuICB9XG5cbiAgZGltc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRTcGFyc2VUZW5zb3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkVmFsdWVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHZhbHVlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCB2YWx1ZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZEluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBpbmRpY2VzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREaW1zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZGltc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGltc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBiaWdpbnRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig4LCBkYXRhLmxlbmd0aCwgOCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkSW50NjQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgbnVtRWxlbXMsIDgpO1xuICB9XG5cbiAgc3RhdGljIGVuZFNwYXJzZVRlbnNvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgVGVuc29yRGF0YVR5cGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdGVuc29yLWRhdGEtdHlwZS5qcyc7XG5pbXBvcnQgeyBUeXBlSW5mbyB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90eXBlLWluZm8uanMnO1xuXG5leHBvcnQgY2xhc3MgTWFwVHlwZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogTWFwVHlwZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNNYXBUeXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBNYXBUeXBlKTogTWFwVHlwZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE1hcFR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNNYXBUeXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBNYXBUeXBlKTogTWFwVHlwZSB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE1hcFR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGtleVR5cGUoKTogVGVuc29yRGF0YVR5cGUge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IFRlbnNvckRhdGFUeXBlLlVOREVGSU5FRDtcbiAgfVxuXG4gIHZhbHVlVHlwZShvYmo/OiBUeXBlSW5mbyk6IFR5cGVJbmZvIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUeXBlSW5mbygpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRNYXBUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICB9XG5cbiAgc3RhdGljIGFkZEtleVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwga2V5VHlwZTogVGVuc29yRGF0YVR5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMCwga2V5VHlwZSwgVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRWYWx1ZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIHZhbHVlVHlwZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kTWFwVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgVHlwZUluZm8gfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdHlwZS1pbmZvLmpzJztcblxuZXhwb3J0IGNsYXNzIFNlcXVlbmNlVHlwZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogU2VxdWVuY2VUeXBlIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1NlcXVlbmNlVHlwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU2VxdWVuY2VUeXBlKTogU2VxdWVuY2VUeXBlIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2VxdWVuY2VUeXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzU2VxdWVuY2VUeXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTZXF1ZW5jZVR5cGUpOiBTZXF1ZW5jZVR5cGUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBTZXF1ZW5jZVR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGVsZW1UeXBlKG9iaj86IFR5cGVJbmZvKTogVHlwZUluZm8gfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IFR5cGVJbmZvKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFNlcXVlbmNlVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRFbGVtVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBlbGVtVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBlbGVtVHlwZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kU2VxdWVuY2VUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVTZXF1ZW5jZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZWxlbVR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgU2VxdWVuY2VUeXBlLnN0YXJ0U2VxdWVuY2VUeXBlKGJ1aWxkZXIpO1xuICAgIFNlcXVlbmNlVHlwZS5hZGRFbGVtVHlwZShidWlsZGVyLCBlbGVtVHlwZU9mZnNldCk7XG4gICAgcmV0dXJuIFNlcXVlbmNlVHlwZS5lbmRTZXF1ZW5jZVR5cGUoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmV4cG9ydCBlbnVtIERpbWVuc2lvblZhbHVlVHlwZSB7XG4gIFVOS05PV04gPSAwLFxuICBWQUxVRSA9IDEsXG4gIFBBUkFNID0gMixcbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgRGltZW5zaW9uVmFsdWVUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2RpbWVuc2lvbi12YWx1ZS10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIERpbWVuc2lvblZhbHVlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEaW1lbnNpb25WYWx1ZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNEaW1lbnNpb25WYWx1ZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogRGltZW5zaW9uVmFsdWUpOiBEaW1lbnNpb25WYWx1ZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERpbWVuc2lvblZhbHVlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzRGltZW5zaW9uVmFsdWUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvblZhbHVlKTogRGltZW5zaW9uVmFsdWUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEaW1lbnNpb25WYWx1ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgZGltVHlwZSgpOiBEaW1lbnNpb25WYWx1ZVR5cGUge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDgodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogRGltZW5zaW9uVmFsdWVUeXBlLlVOS05PV047XG4gIH1cblxuICBkaW1WYWx1ZSgpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgZGltUGFyYW0oKTogc3RyaW5nIHwgbnVsbDtcbiAgZGltUGFyYW0ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZGltUGFyYW0ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREaW1lbnNpb25WYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREaW1UeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbVR5cGU6IERpbWVuc2lvblZhbHVlVHlwZSkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ4KDAsIGRpbVR5cGUsIERpbWVuc2lvblZhbHVlVHlwZS5VTktOT1dOKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREaW1WYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1WYWx1ZTogYmlnaW50KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDEsIGRpbVZhbHVlLCBCaWdJbnQoJzAnKSk7XG4gIH1cblxuICBzdGF0aWMgYWRkRGltUGFyYW0oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltUGFyYW1PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZGltUGFyYW1PZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZERpbWVuc2lvblZhbHVlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVEaW1lbnNpb25WYWx1ZShcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGRpbVR5cGU6IERpbWVuc2lvblZhbHVlVHlwZSxcbiAgICBkaW1WYWx1ZTogYmlnaW50LFxuICAgIGRpbVBhcmFtT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgRGltZW5zaW9uVmFsdWUuc3RhcnREaW1lbnNpb25WYWx1ZShidWlsZGVyKTtcbiAgICBEaW1lbnNpb25WYWx1ZS5hZGREaW1UeXBlKGJ1aWxkZXIsIGRpbVR5cGUpO1xuICAgIERpbWVuc2lvblZhbHVlLmFkZERpbVZhbHVlKGJ1aWxkZXIsIGRpbVZhbHVlKTtcbiAgICBEaW1lbnNpb25WYWx1ZS5hZGREaW1QYXJhbShidWlsZGVyLCBkaW1QYXJhbU9mZnNldCk7XG4gICAgcmV0dXJuIERpbWVuc2lvblZhbHVlLmVuZERpbWVuc2lvblZhbHVlKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IERpbWVuc2lvblZhbHVlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2RpbWVuc2lvbi12YWx1ZS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBEaW1lbnNpb24ge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IERpbWVuc2lvbiB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNEaW1lbnNpb24oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvbik6IERpbWVuc2lvbiB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERpbWVuc2lvbigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0RpbWVuc2lvbihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogRGltZW5zaW9uKTogRGltZW5zaW9uIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGltZW5zaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICB2YWx1ZShvYmo/OiBEaW1lbnNpb25WYWx1ZSk6IERpbWVuc2lvblZhbHVlIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBEaW1lbnNpb25WYWx1ZSgpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBkZW5vdGF0aW9uKCk6IHN0cmluZyB8IG51bGw7XG4gIGRlbm90YXRpb24ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZGVub3RhdGlvbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERpbWVuc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRWYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCB2YWx1ZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkRGVub3RhdGlvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkZW5vdGF0aW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGRlbm90YXRpb25PZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZERpbWVuc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGltZW5zaW9uKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBkZW5vdGF0aW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgRGltZW5zaW9uLnN0YXJ0RGltZW5zaW9uKGJ1aWxkZXIpO1xuICAgIERpbWVuc2lvbi5hZGRWYWx1ZShidWlsZGVyLCB2YWx1ZU9mZnNldCk7XG4gICAgRGltZW5zaW9uLmFkZERlbm90YXRpb24oYnVpbGRlciwgZGVub3RhdGlvbk9mZnNldCk7XG4gICAgcmV0dXJuIERpbWVuc2lvbi5lbmREaW1lbnNpb24oYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgRGltZW5zaW9uIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2RpbWVuc2lvbi5qcyc7XG5cbmV4cG9ydCBjbGFzcyBTaGFwZSB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogU2hhcGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzU2hhcGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNoYXBlKTogU2hhcGUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1NoYXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTaGFwZSk6IFNoYXBlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2hhcGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGRpbShpbmRleDogbnVtYmVyLCBvYmo/OiBEaW1lbnNpb24pOiBEaW1lbnNpb24gfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBEaW1lbnNpb24oKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgZGltTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFNoYXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDEpO1xuICB9XG5cbiAgc3RhdGljIGFkZERpbShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgZGltT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVEaW1WZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0RGltVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIFNoYXBlLnN0YXJ0U2hhcGUoYnVpbGRlcik7XG4gICAgU2hhcGUuYWRkRGltKGJ1aWxkZXIsIGRpbU9mZnNldCk7XG4gICAgcmV0dXJuIFNoYXBlLmVuZFNoYXBlKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IFNoYXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3NoYXBlLmpzJztcbmltcG9ydCB7IFRlbnNvckRhdGFUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3RlbnNvci1kYXRhLXR5cGUuanMnO1xuXG5leHBvcnQgY2xhc3MgVGVuc29yVHlwZUFuZFNoYXBlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzVGVuc29yVHlwZUFuZFNoYXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUZW5zb3JUeXBlQW5kU2hhcGUpOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBUZW5zb3JUeXBlQW5kU2hhcGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNUZW5zb3JUeXBlQW5kU2hhcGUoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogVGVuc29yVHlwZUFuZFNoYXBlLFxuICApOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBUZW5zb3JUeXBlQW5kU2hhcGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGVsZW1UeXBlKCk6IFRlbnNvckRhdGFUeXBlIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBUZW5zb3JEYXRhVHlwZS5VTkRFRklORUQ7XG4gIH1cblxuICBzaGFwZShvYmo/OiBTaGFwZSk6IFNoYXBlIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBTaGFwZSgpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRUZW5zb3JUeXBlQW5kU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkRWxlbVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZWxlbVR5cGU6IFRlbnNvckRhdGFUeXBlKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDAsIGVsZW1UeXBlLCBUZW5zb3JEYXRhVHlwZS5VTkRFRklORUQpO1xuICB9XG5cbiAgc3RhdGljIGFkZFNoYXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNoYXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIHNoYXBlT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRUZW5zb3JUeXBlQW5kU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgeyBNYXBUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL21hcC10eXBlLmpzJztcbmltcG9ydCB7IFNlcXVlbmNlVHlwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9zZXF1ZW5jZS10eXBlLmpzJztcbmltcG9ydCB7IFRlbnNvclR5cGVBbmRTaGFwZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90ZW5zb3ItdHlwZS1hbmQtc2hhcGUuanMnO1xuXG5leHBvcnQgZW51bSBUeXBlSW5mb1ZhbHVlIHtcbiAgTk9ORSA9IDAsXG4gIHRlbnNvcl90eXBlID0gMSxcbiAgc2VxdWVuY2VfdHlwZSA9IDIsXG4gIG1hcF90eXBlID0gMyxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVuaW9uVG9UeXBlSW5mb1ZhbHVlKFxuICB0eXBlOiBUeXBlSW5mb1ZhbHVlLFxuICBhY2Nlc3NvcjogKG9iajogTWFwVHlwZSB8IFNlcXVlbmNlVHlwZSB8IFRlbnNvclR5cGVBbmRTaGFwZSkgPT4gTWFwVHlwZSB8IFNlcXVlbmNlVHlwZSB8IFRlbnNvclR5cGVBbmRTaGFwZSB8IG51bGwsXG4pOiBNYXBUeXBlIHwgU2VxdWVuY2VUeXBlIHwgVGVuc29yVHlwZUFuZFNoYXBlIHwgbnVsbCB7XG4gIHN3aXRjaCAoVHlwZUluZm9WYWx1ZVt0eXBlXSkge1xuICAgIGNhc2UgJ05PTkUnOlxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgY2FzZSAndGVuc29yX3R5cGUnOlxuICAgICAgcmV0dXJuIGFjY2Vzc29yKG5ldyBUZW5zb3JUeXBlQW5kU2hhcGUoKSkhIGFzIFRlbnNvclR5cGVBbmRTaGFwZTtcbiAgICBjYXNlICdzZXF1ZW5jZV90eXBlJzpcbiAgICAgIHJldHVybiBhY2Nlc3NvcihuZXcgU2VxdWVuY2VUeXBlKCkpISBhcyBTZXF1ZW5jZVR5cGU7XG4gICAgY2FzZSAnbWFwX3R5cGUnOlxuICAgICAgcmV0dXJuIGFjY2Vzc29yKG5ldyBNYXBUeXBlKCkpISBhcyBNYXBUeXBlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdW5pb25MaXN0VG9UeXBlSW5mb1ZhbHVlKFxuICB0eXBlOiBUeXBlSW5mb1ZhbHVlLFxuICBhY2Nlc3NvcjogKFxuICAgIGluZGV4OiBudW1iZXIsXG4gICAgb2JqOiBNYXBUeXBlIHwgU2VxdWVuY2VUeXBlIHwgVGVuc29yVHlwZUFuZFNoYXBlLFxuICApID0+IE1hcFR5cGUgfCBTZXF1ZW5jZVR5cGUgfCBUZW5zb3JUeXBlQW5kU2hhcGUgfCBudWxsLFxuICBpbmRleDogbnVtYmVyLFxuKTogTWFwVHlwZSB8IFNlcXVlbmNlVHlwZSB8IFRlbnNvclR5cGVBbmRTaGFwZSB8IG51bGwge1xuICBzd2l0Y2ggKFR5cGVJbmZvVmFsdWVbdHlwZV0pIHtcbiAgICBjYXNlICdOT05FJzpcbiAgICAgIHJldHVybiBudWxsO1xuICAgIGNhc2UgJ3RlbnNvcl90eXBlJzpcbiAgICAgIHJldHVybiBhY2Nlc3NvcihpbmRleCwgbmV3IFRlbnNvclR5cGVBbmRTaGFwZSgpKSEgYXMgVGVuc29yVHlwZUFuZFNoYXBlO1xuICAgIGNhc2UgJ3NlcXVlbmNlX3R5cGUnOlxuICAgICAgcmV0dXJuIGFjY2Vzc29yKGluZGV4LCBuZXcgU2VxdWVuY2VUeXBlKCkpISBhcyBTZXF1ZW5jZVR5cGU7XG4gICAgY2FzZSAnbWFwX3R5cGUnOlxuICAgICAgcmV0dXJuIGFjY2Vzc29yKGluZGV4LCBuZXcgTWFwVHlwZSgpKSEgYXMgTWFwVHlwZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgVHlwZUluZm9WYWx1ZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy90eXBlLWluZm8tdmFsdWUuanMnO1xuXG5leHBvcnQgY2xhc3MgVHlwZUluZm8ge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFR5cGVJbmZvIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1R5cGVJbmZvKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUeXBlSW5mbyk6IFR5cGVJbmZvIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgVHlwZUluZm8oKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNUeXBlSW5mbyhiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVHlwZUluZm8pOiBUeXBlSW5mbyB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFR5cGVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBkZW5vdGF0aW9uKCk6IHN0cmluZyB8IG51bGw7XG4gIGRlbm90YXRpb24ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZGVub3RhdGlvbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHZhbHVlVHlwZSgpOiBUeXBlSW5mb1ZhbHVlIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50OCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBUeXBlSW5mb1ZhbHVlLk5PTkU7XG4gIH1cblxuICB2YWx1ZShvYmo6IGFueSk6IGFueSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX191bmlvbihvYmosIHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRUeXBlSW5mbyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREZW5vdGF0aW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRlbm90YXRpb25PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgZGVub3RhdGlvbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVmFsdWVUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHZhbHVlVHlwZTogVHlwZUluZm9WYWx1ZSkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ4KDEsIHZhbHVlVHlwZSwgVHlwZUluZm9WYWx1ZS5OT05FKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRWYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgyLCB2YWx1ZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kVHlwZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVR5cGVJbmZvKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgZGVub3RhdGlvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHZhbHVlVHlwZTogVHlwZUluZm9WYWx1ZSxcbiAgICB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIFR5cGVJbmZvLnN0YXJ0VHlwZUluZm8oYnVpbGRlcik7XG4gICAgVHlwZUluZm8uYWRkRGVub3RhdGlvbihidWlsZGVyLCBkZW5vdGF0aW9uT2Zmc2V0KTtcbiAgICBUeXBlSW5mby5hZGRWYWx1ZVR5cGUoYnVpbGRlciwgdmFsdWVUeXBlKTtcbiAgICBUeXBlSW5mby5hZGRWYWx1ZShidWlsZGVyLCB2YWx1ZU9mZnNldCk7XG4gICAgcmV0dXJuIFR5cGVJbmZvLmVuZFR5cGVJbmZvKGJ1aWxkZXIpO1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IFR5cGVJbmZvIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3R5cGUtaW5mby5qcyc7XG5cbmV4cG9ydCBjbGFzcyBWYWx1ZUluZm8ge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFZhbHVlSW5mbyB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNWYWx1ZUluZm8oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFZhbHVlSW5mbyk6IFZhbHVlSW5mbyB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IFZhbHVlSW5mbygpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1ZhbHVlSW5mbyhiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVmFsdWVJbmZvKTogVmFsdWVJbmZvIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgVmFsdWVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBuYW1lKCk6IHN0cmluZyB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGRvY1N0cmluZygpOiBzdHJpbmcgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdHlwZShvYmo/OiBUeXBlSW5mbyk6IFR5cGVJbmZvIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUeXBlSW5mbygpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRWYWx1ZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgdHlwZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kVmFsdWVJbmZvKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL25vZGUuanMnO1xuaW1wb3J0IHsgTm9kZUVkZ2UgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvbm9kZS1lZGdlLmpzJztcbmltcG9ydCB7IFJ1bnRpbWVPcHRpbWl6YXRpb25zIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9ucy5qcyc7XG5pbXBvcnQgeyBTcGFyc2VUZW5zb3IgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvc3BhcnNlLXRlbnNvci5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvdGVuc29yLmpzJztcbmltcG9ydCB7IFZhbHVlSW5mbyB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy92YWx1ZS1pbmZvLmpzJztcblxuZXhwb3J0IGNsYXNzIEdyYXBoIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBHcmFwaCB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNHcmFwaChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogR3JhcGgpOiBHcmFwaCB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IEdyYXBoKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzR3JhcGgoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEdyYXBoKTogR3JhcGgge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBHcmFwaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgaW5pdGlhbGl6ZXJzKGluZGV4OiBudW1iZXIsIG9iaj86IFRlbnNvcik6IFRlbnNvciB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGluaXRpYWxpemVyc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBub2RlQXJncyhpbmRleDogbnVtYmVyLCBvYmo/OiBWYWx1ZUluZm8pOiBWYWx1ZUluZm8gfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBWYWx1ZUluZm8oKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgbm9kZUFyZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbm9kZXMoaW5kZXg6IG51bWJlciwgb2JqPzogTm9kZSk6IE5vZGUgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgbm9kZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbWF4Tm9kZUluZGV4KCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbm9kZUVkZ2VzKGluZGV4OiBudW1iZXIsIG9iaj86IE5vZGVFZGdlKTogTm9kZUVkZ2UgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgTm9kZUVkZ2UoKSkuX19pbml0KFxuICAgICAgICAgIHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSxcbiAgICAgICAgICB0aGlzLmJiISxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgbm9kZUVkZ2VzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBpbnB1dHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICBpbnB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIG91dHB1dHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgb3V0cHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXk7XG4gIG91dHB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIG91dHB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHNwYXJzZUluaXRpYWxpemVycyhpbmRleDogbnVtYmVyLCBvYmo/OiBTcGFyc2VUZW5zb3IpOiBTcGFyc2VUZW5zb3IgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTgpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgU3BhcnNlVGVuc29yKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHNwYXJzZUluaXRpYWxpemVyc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgcnVudGltZU9wdGltaXphdGlvbnMob2JqPzogUnVudGltZU9wdGltaXphdGlvbnMpOiBSdW50aW1lT3B0aW1pemF0aW9ucyB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBSdW50aW1lT3B0aW1pemF0aW9ucygpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0R3JhcGgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoOSk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5pdGlhbGl6ZXJzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBpbml0aWFsaXplcnNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluaXRpYWxpemVyc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbml0aWFsaXplcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE5vZGVBcmdzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVBcmdzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIG5vZGVBcmdzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVOb2RlQXJnc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnROb2RlQXJnc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkTm9kZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgbm9kZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE5vZGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRNYXhOb2RlSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbWF4Tm9kZUluZGV4OiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMywgbWF4Tm9kZUluZGV4LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROb2RlRWRnZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDQsIG5vZGVFZGdlc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlTm9kZUVkZ2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE5vZGVFZGdlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW5wdXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBpbnB1dHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUlucHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbnB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE91dHB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3V0cHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg2LCBvdXRwdXRzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPdXRwdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE91dHB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZFNwYXJzZUluaXRpYWxpemVycyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzcGFyc2VJbml0aWFsaXplcnNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNywgc3BhcnNlSW5pdGlhbGl6ZXJzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVTcGFyc2VJbml0aWFsaXplcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0U3BhcnNlSW5pdGlhbGl6ZXJzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRSdW50aW1lT3B0aW1pemF0aW9ucyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBydW50aW1lT3B0aW1pemF0aW9uc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg4LCBydW50aW1lT3B0aW1pemF0aW9uc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kR3JhcGgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG59XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IEF0dHJpYnV0ZVR5cGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvYXR0cmlidXRlLXR5cGUuanMnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvZ3JhcGguanMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL3RlbnNvci5qcyc7XG5cbmV4cG9ydCBjbGFzcyBBdHRyaWJ1dGUge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IEF0dHJpYnV0ZSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNBdHRyaWJ1dGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEF0dHJpYnV0ZSk6IEF0dHJpYnV0ZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IEF0dHJpYnV0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0F0dHJpYnV0ZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogQXR0cmlidXRlKTogQXR0cmlidXRlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgQXR0cmlidXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBuYW1lKCk6IHN0cmluZyB8IG51bGw7XG4gIG5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGRvY1N0cmluZygpOiBzdHJpbmcgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdHlwZSgpOiBBdHRyaWJ1dGVUeXBlIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiBBdHRyaWJ1dGVUeXBlLlVOREVGSU5FRDtcbiAgfVxuXG4gIGYoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkRmxvYXQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwLjA7XG4gIH1cblxuICBpKCk6IGJpZ2ludCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgcygpOiBzdHJpbmcgfCBudWxsO1xuICBzKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIHMob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdChvYmo/OiBUZW5zb3IpOiBUZW5zb3IgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBUZW5zb3IoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgZyhvYmo/OiBHcmFwaCk6IEdyYXBoIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE4KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgR3JhcGgoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOiBudWxsO1xuICB9XG5cbiAgZmxvYXRzKGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkRmxvYXQzMih0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpIDogMDtcbiAgfVxuXG4gIGZsb2F0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgZmxvYXRzQXJyYXkoKTogRmxvYXQzMkFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IG5ldyBGbG9hdDMyQXJyYXkoXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5idWZmZXIsXG4gICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5ieXRlT2Zmc2V0ICsgdGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICAgIHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGludHMoaW5kZXg6IG51bWJlcik6IGJpZ2ludCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDgpIDogQmlnSW50KDApO1xuICB9XG5cbiAgaW50c0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RyaW5ncyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICBzdHJpbmdzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgc3RyaW5ncyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgc3RyaW5nc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgdGVuc29ycyhpbmRleDogbnVtYmVyLCBvYmo/OiBUZW5zb3IpOiBUZW5zb3IgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgVGVuc29yKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgdGVuc29yc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgZ3JhcGhzKGluZGV4OiBudW1iZXIsIG9iaj86IEdyYXBoKTogR3JhcGggfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjgpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgR3JhcGgoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBncmFwaHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEF0dHJpYnV0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxMyk7XG4gIH1cblxuICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHR5cGU6IEF0dHJpYnV0ZVR5cGUpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMiwgdHlwZSwgQXR0cmlidXRlVHlwZS5VTkRFRklORUQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEYoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZjogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEZsb2F0MzIoMywgZiwgMC4wKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRJKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGk6IGJpZ2ludCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCg0LCBpLCBCaWdJbnQoJzAnKSk7XG4gIH1cblxuICBzdGF0aWMgYWRkUyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDUsIHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg2LCB0T2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRHKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNywgZ09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkRmxvYXRzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGZsb2F0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg4LCBmbG9hdHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUZsb2F0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBudW1iZXJbXSB8IEZsb2F0MzJBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldDtcbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFRoaXMgVWludDhBcnJheSBvdmVybG9hZCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIGZ1dHVyZS5cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVGbG9hdHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW10gfCBVaW50OEFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuICBzdGF0aWMgY3JlYXRlRmxvYXRzVmVjdG9yKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgZGF0YTogbnVtYmVyW10gfCBGbG9hdDMyQXJyYXkgfCBVaW50OEFycmF5LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEZsb2F0MzIoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEZsb2F0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSW50cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDksIGludHNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUludHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogYmlnaW50W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEludDY0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIG51bUVsZW1zLCA4KTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRTdHJpbmdzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHN0cmluZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMTAsIHN0cmluZ3NPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVN0cmluZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0U3RyaW5nc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVGVuc29ycyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB0ZW5zb3JzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDExLCB0ZW5zb3JzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVUZW5zb3JzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFRlbnNvcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEdyYXBocyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBncmFwaHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMTIsIGdyYXBoc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlR3JhcGhzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEdyYXBoc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kQXR0cmlidXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG4vKipcbiAqIGRlcHJlY2F0ZWQ6IG5vIGxvbmdlciB1c2luZyBrZXJuZWwgZGVmIGhhc2hlc1xuICovXG5leHBvcnQgY2xhc3MgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3Mge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyxcbiAgKTogRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyxcbiAgKTogRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBub2RlSW5kaWNlcyhpbmRleDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCkgOiAwO1xuICB9XG5cbiAgbm9kZUluZGljZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgbm9kZUluZGljZXNBcnJheSgpOiBVaW50MzJBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IG5ldyBVaW50MzJBcnJheShcbiAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ1ZmZlcixcbiAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ5dGVPZmZzZXQgKyB0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgICAgdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAga2VybmVsRGVmSGFzaGVzKGluZGV4OiBudW1iZXIpOiBiaWdpbnQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50NjQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA4KSA6IEJpZ0ludCgwKTtcbiAgfVxuXG4gIGtlcm5lbERlZkhhc2hlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gIH1cblxuICBzdGF0aWMgYWRkTm9kZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgbm9kZUluZGljZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdIHwgVWludDMyQXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQ7XG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBUaGlzIFVpbnQ4QXJyYXkgb3ZlcmxvYWQgd2lsbCBiZSByZW1vdmVkIGluIHRoZSBmdXR1cmUuXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlTm9kZUluZGljZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW10gfCBVaW50OEFycmF5KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuICBzdGF0aWMgY3JlYXRlTm9kZUluZGljZXNWZWN0b3IoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBkYXRhOiBudW1iZXJbXSB8IFVpbnQzMkFycmF5IHwgVWludDhBcnJheSxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRJbnQzMihkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0Tm9kZUluZGljZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZEtlcm5lbERlZkhhc2hlcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXJuZWxEZWZIYXNoZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwga2VybmVsRGVmSGFzaGVzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVLZXJuZWxEZWZIYXNoZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogYmlnaW50W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZEludDY0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRLZXJuZWxEZWZIYXNoZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgbnVtRWxlbXMsIDgpO1xuICB9XG5cbiAgc3RhdGljIGVuZERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbm9kZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICBrZXJuZWxEZWZIYXNoZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3Muc3RhcnREZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcik7XG4gICAgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zLmFkZE5vZGVJbmRpY2VzKGJ1aWxkZXIsIG5vZGVJbmRpY2VzT2Zmc2V0KTtcbiAgICBEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MuYWRkS2VybmVsRGVmSGFzaGVzKGJ1aWxkZXIsIGtlcm5lbERlZkhhc2hlc09mZnNldCk7XG4gICAgcmV0dXJuIERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcy5lbmREZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuLyoqXG4gKiBkZXByZWNhdGVkOiBubyBsb25nZXIgdXNpbmcga2VybmVsIGRlZiBoYXNoZXNcbiAqL1xuZXhwb3J0IGNsYXNzIERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaChcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCxcbiAgKTogRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2gge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0RlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoLFxuICApOiBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBub2RlSW5kZXgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIGtlcm5lbERlZkhhc2goKTogYmlnaW50IHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50NjQodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogQmlnSW50KCcwJyk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnREZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGROb2RlSW5kZXgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGV4OiBudW1iZXIpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMCwgbm9kZUluZGV4LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRLZXJuZWxEZWZIYXNoKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbERlZkhhc2g6IGJpZ2ludCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCgxLCBrZXJuZWxEZWZIYXNoLCBCaWdJbnQoJzAnKSk7XG4gIH1cblxuICBzdGF0aWMgZW5kRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2goYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZURlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgbm9kZUluZGV4OiBudW1iZXIsXG4gICAga2VybmVsRGVmSGFzaDogYmlnaW50LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIERlcHJlY2F0ZWROb2RlSW5kZXhBbmRLZXJuZWxEZWZIYXNoLnN0YXJ0RGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2goYnVpbGRlcik7XG4gICAgRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2guYWRkTm9kZUluZGV4KGJ1aWxkZXIsIG5vZGVJbmRleCk7XG4gICAgRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2guYWRkS2VybmVsRGVmSGFzaChidWlsZGVyLCBrZXJuZWxEZWZIYXNoKTtcbiAgICByZXR1cm4gRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2guZW5kRGVwcmVjYXRlZE5vZGVJbmRleEFuZEtlcm5lbERlZkhhc2goYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9kZXByZWNhdGVkLXNlc3Npb24tc3RhdGUuanMnO1xuXG4vKipcbiAqIGRlcHJlY2F0ZWQ6IG5vIGxvbmdlciB1c2luZyBrZXJuZWwgZGVmIGhhc2hlc1xuICovXG5leHBvcnQgY2xhc3MgRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSxcbiAgKTogRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSxcbiAgKTogRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBncmFwaElkKCk6IHN0cmluZyB8IG51bGw7XG4gIGdyYXBoSWQob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZ3JhcGhJZChvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHNlc3Npb25TdGF0ZShvYmo/OiBEZXByZWNhdGVkU2Vzc2lvblN0YXRlKTogRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUoKSkuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRHcmFwaElkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGdyYXBoSWRPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgZ3JhcGhJZE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkU2Vzc2lvblN0YXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNlc3Npb25TdGF0ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBzZXNzaW9uU3RhdGVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIGJ1aWxkZXIucmVxdWlyZWRGaWVsZChvZmZzZXQsIDQpOyAvLyBncmFwaF9pZFxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgRGVwcmVjYXRlZEtlcm5lbENyZWF0ZUluZm9zIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQta2VybmVsLWNyZWF0ZS1pbmZvcy5qcyc7XG5pbXBvcnQgeyBEZXByZWNhdGVkU3ViR3JhcGhTZXNzaW9uU3RhdGUgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvZGVwcmVjYXRlZC1zdWItZ3JhcGgtc2Vzc2lvbi1zdGF0ZS5qcyc7XG5cbi8qKlxuICogZGVwcmVjYXRlZDogbm8gbG9uZ2VyIHVzaW5nIGtlcm5lbCBkZWYgaGFzaGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXByZWNhdGVkU2Vzc2lvblN0YXRlIHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEZXByZWNhdGVkU2Vzc2lvblN0YXRlIHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0RlcHJlY2F0ZWRTZXNzaW9uU3RhdGUoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSxcbiAgKTogRGVwcmVjYXRlZFNlc3Npb25TdGF0ZSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNEZXByZWNhdGVkU2Vzc2lvblN0YXRlKFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUsXG4gICk6IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBEZXByZWNhdGVkU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBrZXJuZWxzKG9iaj86IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyk6IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcygpKS5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgc3ViR3JhcGhTZXNzaW9uU3RhdGVzKGluZGV4OiBudW1iZXIsIG9iaj86IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSk6IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IERlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBzdWJHcmFwaFNlc3Npb25TdGF0ZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0RGVwcmVjYXRlZFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRLZXJuZWxzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwga2VybmVsc09mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkU3ViR3JhcGhTZXNzaW9uU3RhdGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHN1YkdyYXBoU2Vzc2lvblN0YXRlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVN1YkdyYXBoU2Vzc2lvblN0YXRlc1ZlY3RvcihcbiAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLFxuICAgIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdLFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0U3ViR3JhcGhTZXNzaW9uU3RhdGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmREZXByZWNhdGVkU2Vzc2lvblN0YXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVEZXByZWNhdGVkU2Vzc2lvblN0YXRlKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAga2VybmVsc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgIHN1YkdyYXBoU2Vzc2lvblN0YXRlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUuc3RhcnREZXByZWNhdGVkU2Vzc2lvblN0YXRlKGJ1aWxkZXIpO1xuICAgIERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUuYWRkS2VybmVscyhidWlsZGVyLCBrZXJuZWxzT2Zmc2V0KTtcbiAgICBEZXByZWNhdGVkU2Vzc2lvblN0YXRlLmFkZFN1YkdyYXBoU2Vzc2lvblN0YXRlcyhidWlsZGVyLCBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQpO1xuICAgIHJldHVybiBEZXByZWNhdGVkU2Vzc2lvblN0YXRlLmVuZERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgQXJnVHlwZUFuZEluZGV4IH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLWFuZC1pbmRleC5qcyc7XG5cbmV4cG9ydCBjbGFzcyBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0tlcm5lbFR5cGVTdHJBcmdzRW50cnkoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSxcbiAgKTogS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IEtlcm5lbFR5cGVTdHJBcmdzRW50cnksXG4gICk6IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBrZXJuZWxUeXBlU3RyKCk6IHN0cmluZyB8IG51bGw7XG4gIGtlcm5lbFR5cGVTdHIob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAga2VybmVsVHlwZVN0cihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGFyZ3MoaW5kZXg6IG51bWJlciwgb2JqPzogQXJnVHlwZUFuZEluZGV4KTogQXJnVHlwZUFuZEluZGV4IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgQXJnVHlwZUFuZEluZGV4KCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIGFyZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0S2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRLZXJuZWxUeXBlU3RyKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbFR5cGVTdHJPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwga2VybmVsVHlwZVN0ck9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkQXJncyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBhcmdzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGFyZ3NPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUFyZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldISk7XG4gICAgfVxuICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0QXJnc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgZW5kS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIGJ1aWxkZXIucmVxdWlyZWRGaWVsZChvZmZzZXQsIDQpOyAvLyBrZXJuZWxfdHlwZV9zdHJcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUtlcm5lbFR5cGVTdHJBcmdzRW50cnkoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBrZXJuZWxUeXBlU3RyT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgYXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuc3RhcnRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KGJ1aWxkZXIpO1xuICAgIEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuYWRkS2VybmVsVHlwZVN0cihidWlsZGVyLCBrZXJuZWxUeXBlU3RyT2Zmc2V0KTtcbiAgICBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LmFkZEFyZ3MoYnVpbGRlciwgYXJnc09mZnNldCk7XG4gICAgcmV0dXJuIEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuZW5kS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2tlcm5lbC10eXBlLXN0ci1hcmdzLWVudHJ5LmpzJztcblxuZXhwb3J0IGNsYXNzIE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHtcbiAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgYmJfcG9zID0gMDtcbiAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSxcbiAgKTogT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc09wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KFxuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICAgIG9iaj86IE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LFxuICApOiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBvcElkKCk6IHN0cmluZyB8IG51bGw7XG4gIG9wSWQob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgb3BJZChvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIGtlcm5lbFR5cGVTdHJBcmdzKGluZGV4OiBudW1iZXIsIG9iaj86IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkpOiBLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBrZXJuZWxUeXBlU3RyQXJnc0xlbmd0aCgpOiBudW1iZXIge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRPcElkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9wSWRPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgb3BJZE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkS2VybmVsVHlwZVN0ckFyZ3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwga2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwga2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUtlcm5lbFR5cGVTdHJBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydEtlcm5lbFR5cGVTdHJBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgfVxuXG4gIHN0YXRpYyBlbmRPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIGJ1aWxkZXIucmVxdWlyZWRGaWVsZChvZmZzZXQsIDQpOyAvLyBvcF9pZFxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBvcElkT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAga2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeS5zdGFydE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KGJ1aWxkZXIpO1xuICAgIE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5LmFkZE9wSWQoYnVpbGRlciwgb3BJZE9mZnNldCk7XG4gICAgT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkuYWRkS2VybmVsVHlwZVN0ckFyZ3MoYnVpbGRlciwga2VybmVsVHlwZVN0ckFyZ3NPZmZzZXQpO1xuICAgIHJldHVybiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeS5lbmRPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeShidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9vcC1pZC1rZXJuZWwtdHlwZS1zdHItYXJncy1lbnRyeS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IEtlcm5lbFR5cGVTdHJSZXNvbHZlciB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogS2VybmVsVHlwZVN0clJlc29sdmVyLFxuICApOiBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoXG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsXG4gICAgb2JqPzogS2VybmVsVHlwZVN0clJlc29sdmVyLFxuICApOiBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIG9wS2VybmVsVHlwZVN0ckFyZ3MoaW5kZXg6IG51bWJlciwgb2JqPzogT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkpOiBPcElkS2VybmVsVHlwZVN0ckFyZ3NFbnRyeSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0XG4gICAgICA/IChvYmogfHwgbmV3IE9wSWRLZXJuZWxUeXBlU3RyQXJnc0VudHJ5KCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIG9wS2VybmVsVHlwZVN0ckFyZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0S2VybmVsVHlwZVN0clJlc29sdmVyKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDEpO1xuICB9XG5cbiAgc3RhdGljIGFkZE9wS2VybmVsVHlwZVN0ckFyZ3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3BLZXJuZWxUeXBlU3RyQXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBvcEtlcm5lbFR5cGVTdHJBcmdzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPcEtlcm5lbFR5cGVTdHJBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE9wS2VybmVsVHlwZVN0ckFyZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGVuZEtlcm5lbFR5cGVTdHJSZXNvbHZlcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBjb25zdCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlS2VybmVsVHlwZVN0clJlc29sdmVyKFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAgb3BLZXJuZWxUeXBlU3RyQXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICApOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIEtlcm5lbFR5cGVTdHJSZXNvbHZlci5zdGFydEtlcm5lbFR5cGVTdHJSZXNvbHZlcihidWlsZGVyKTtcbiAgICBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIuYWRkT3BLZXJuZWxUeXBlU3RyQXJncyhidWlsZGVyLCBvcEtlcm5lbFR5cGVTdHJBcmdzT2Zmc2V0KTtcbiAgICByZXR1cm4gS2VybmVsVHlwZVN0clJlc29sdmVyLmVuZEtlcm5lbFR5cGVTdHJSZXNvbHZlcihidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5leHBvcnQgY2xhc3MgT3BlcmF0b3JTZXRJZCB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgIHRoaXMuYmIgPSBiYjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHN0YXRpYyBnZXRSb290QXNPcGVyYXRvclNldElkKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBPcGVyYXRvclNldElkKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE9wZXJhdG9yU2V0SWQoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNPcGVyYXRvclNldElkKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBPcGVyYXRvclNldElkKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgcmV0dXJuIChvYmogfHwgbmV3IE9wZXJhdG9yU2V0SWQoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGRvbWFpbigpOiBzdHJpbmcgfCBudWxsO1xuICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgZG9tYWluKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgdmVyc2lvbigpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgc3RhdGljIHN0YXJ0T3BlcmF0b3JTZXRJZChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb21haW4oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGRvbWFpbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkVmVyc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2ZXJzaW9uOiBiaWdpbnQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkSW50NjQoMSwgdmVyc2lvbiwgQmlnSW50KCcwJykpO1xuICB9XG5cbiAgc3RhdGljIGVuZE9wZXJhdG9yU2V0SWQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZU9wZXJhdG9yU2V0SWQoXG4gICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcixcbiAgICBkb21haW5PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICB2ZXJzaW9uOiBiaWdpbnQsXG4gICk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgT3BlcmF0b3JTZXRJZC5zdGFydE9wZXJhdG9yU2V0SWQoYnVpbGRlcik7XG4gICAgT3BlcmF0b3JTZXRJZC5hZGREb21haW4oYnVpbGRlciwgZG9tYWluT2Zmc2V0KTtcbiAgICBPcGVyYXRvclNldElkLmFkZFZlcnNpb24oYnVpbGRlciwgdmVyc2lvbik7XG4gICAgcmV0dXJuIE9wZXJhdG9yU2V0SWQuZW5kT3BlcmF0b3JTZXRJZChidWlsZGVyKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5leHBvcnQgY2xhc3MgU3RyaW5nU3RyaW5nRW50cnkge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFN0cmluZ1N0cmluZ0VudHJ5IHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc1N0cmluZ1N0cmluZ0VudHJ5KGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTdHJpbmdTdHJpbmdFbnRyeSk6IFN0cmluZ1N0cmluZ0VudHJ5IHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgU3RyaW5nU3RyaW5nRW50cnkoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNTdHJpbmdTdHJpbmdFbnRyeShcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAgICBvYmo/OiBTdHJpbmdTdHJpbmdFbnRyeSxcbiAgKTogU3RyaW5nU3RyaW5nRW50cnkge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBTdHJpbmdTdHJpbmdFbnRyeSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAga2V5KCk6IHN0cmluZyB8IG51bGw7XG4gIGtleShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBrZXkob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gIH1cblxuICB2YWx1ZSgpOiBzdHJpbmcgfCBudWxsO1xuICB2YWx1ZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICB2YWx1ZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydFN0cmluZ1N0cmluZ0VudHJ5KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICB9XG5cbiAgc3RhdGljIGFkZEtleShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXlPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwga2V5T2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRWYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCB2YWx1ZU9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgZW5kU3RyaW5nU3RyaW5nRW50cnkoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVN0cmluZ1N0cmluZ0VudHJ5KFxuICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsXG4gICAga2V5T2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBTdHJpbmdTdHJpbmdFbnRyeS5zdGFydFN0cmluZ1N0cmluZ0VudHJ5KGJ1aWxkZXIpO1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5LmFkZEtleShidWlsZGVyLCBrZXlPZmZzZXQpO1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5LmFkZFZhbHVlKGJ1aWxkZXIsIHZhbHVlT2Zmc2V0KTtcbiAgICByZXR1cm4gU3RyaW5nU3RyaW5nRW50cnkuZW5kU3RyaW5nU3RyaW5nRW50cnkoYnVpbGRlcik7XG4gIH1cbn1cbiIsICIvLyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBieSB0aGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIsIGRvIG5vdCBtb2RpZnlcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5cbmltcG9ydCAqIGFzIGZsYXRidWZmZXJzIGZyb20gJ2ZsYXRidWZmZXJzJztcblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvZ3JhcGguanMnO1xuaW1wb3J0IHsgT3BlcmF0b3JTZXRJZCB9IGZyb20gJy4uLy4uL29ubnhydW50aW1lL2Zicy9vcGVyYXRvci1zZXQtaWQuanMnO1xuaW1wb3J0IHsgU3RyaW5nU3RyaW5nRW50cnkgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMvc3RyaW5nLXN0cmluZy1lbnRyeS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBNb2RlbCB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogTW9kZWwge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzTW9kZWwoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE1vZGVsKTogTW9kZWwge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBNb2RlbCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc01vZGVsKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBNb2RlbCk6IE1vZGVsIHtcbiAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgTW9kZWwoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgfVxuXG4gIGlyVmVyc2lvbigpOiBiaWdpbnQge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgb3BzZXRJbXBvcnQoaW5kZXg6IG51bWJlciwgb2JqPzogT3BlcmF0b3JTZXRJZCk6IE9wZXJhdG9yU2V0SWQgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBPcGVyYXRvclNldElkKCkpLl9faW5pdChcbiAgICAgICAgICB0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksXG4gICAgICAgICAgdGhpcy5iYiEsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIG9wc2V0SW1wb3J0TGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgfVxuXG4gIHByb2R1Y2VyTmFtZSgpOiBzdHJpbmcgfCBudWxsO1xuICBwcm9kdWNlck5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgcHJvZHVjZXJOYW1lKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgcHJvZHVjZXJWZXJzaW9uKCk6IHN0cmluZyB8IG51bGw7XG4gIHByb2R1Y2VyVmVyc2lvbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBwcm9kdWNlclZlcnNpb24ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgZG9tYWluKCk6IHN0cmluZyB8IG51bGw7XG4gIGRvbWFpbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBkb21haW4ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgbW9kZWxWZXJzaW9uKCk6IGJpZ2ludCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IEJpZ0ludCgnMCcpO1xuICB9XG5cbiAgZG9jU3RyaW5nKCk6IHN0cmluZyB8IG51bGw7XG4gIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsO1xuICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICB9XG5cbiAgZ3JhcGgob2JqPzogR3JhcGgpOiBHcmFwaCB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxOCk7XG4gICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IEdyYXBoKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDogbnVsbDtcbiAgfVxuXG4gIGdyYXBoRG9jU3RyaW5nKCk6IHN0cmluZyB8IG51bGw7XG4gIGdyYXBoRG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGw7XG4gIGdyYXBoRG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIG1ldGFkYXRhUHJvcHMoaW5kZXg6IG51bWJlciwgb2JqPzogU3RyaW5nU3RyaW5nRW50cnkpOiBTdHJpbmdTdHJpbmdFbnRyeSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgcmV0dXJuIG9mZnNldFxuICAgICAgPyAob2JqIHx8IG5ldyBTdHJpbmdTdHJpbmdFbnRyeSgpKS5fX2luaXQoXG4gICAgICAgICAgdGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLFxuICAgICAgICAgIHRoaXMuYmIhLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBtZXRhZGF0YVByb3BzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIyKTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRNb2RlbChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgYnVpbGRlci5zdGFydE9iamVjdCgxMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkSXJWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlyVmVyc2lvbjogYmlnaW50KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDAsIGlyVmVyc2lvbiwgQmlnSW50KCcwJykpO1xuICB9XG5cbiAgc3RhdGljIGFkZE9wc2V0SW1wb3J0KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG9wc2V0SW1wb3J0T2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIG9wc2V0SW1wb3J0T2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVPcHNldEltcG9ydFZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0hKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRPcHNldEltcG9ydFZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gIH1cblxuICBzdGF0aWMgYWRkUHJvZHVjZXJOYW1lKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHByb2R1Y2VyTmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgyLCBwcm9kdWNlck5hbWVPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZFByb2R1Y2VyVmVyc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBwcm9kdWNlclZlcnNpb25PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMywgcHJvZHVjZXJWZXJzaW9uT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGREb21haW4oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDQsIGRvbWFpbk9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkTW9kZWxWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG1vZGVsVmVyc2lvbjogYmlnaW50KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDUsIG1vZGVsVmVyc2lvbiwgQmlnSW50KCcwJykpO1xuICB9XG5cbiAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNiwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRHcmFwaChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBncmFwaE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg3LCBncmFwaE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkR3JhcGhEb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhEb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOCwgZ3JhcGhEb2NTdHJpbmdPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGFkZE1ldGFkYXRhUHJvcHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbWV0YWRhdGFQcm9wc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg5LCBtZXRhZGF0YVByb3BzT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVNZXRhZGF0YVByb3BzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSEpO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE1ldGFkYXRhUHJvcHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICB9XG5cbiAgc3RhdGljIGVuZE1vZGVsKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgIGNvbnN0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIgfSBmcm9tICcuLi8uLi9vbm54cnVudGltZS9mYnMva2VybmVsLXR5cGUtc3RyLXJlc29sdmVyLmpzJztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL21vZGVsLmpzJztcblxuZXhwb3J0IGNsYXNzIEluZmVyZW5jZVNlc3Npb24ge1xuICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciB8IG51bGwgPSBudWxsO1xuICBiYl9wb3MgPSAwO1xuICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IEluZmVyZW5jZVNlc3Npb24ge1xuICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICB0aGlzLmJiID0gYmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgZ2V0Um9vdEFzSW5mZXJlbmNlU2Vzc2lvbihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogSW5mZXJlbmNlU2Vzc2lvbik6IEluZmVyZW5jZVNlc3Npb24ge1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBJbmZlcmVuY2VTZXNzaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzSW5mZXJlbmNlU2Vzc2lvbihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogSW5mZXJlbmNlU2Vzc2lvbik6IEluZmVyZW5jZVNlc3Npb24ge1xuICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgIHJldHVybiAob2JqIHx8IG5ldyBJbmZlcmVuY2VTZXNzaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgYnVmZmVySGFzSWRlbnRpZmllcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBiYi5fX2hhc19pZGVudGlmaWVyKCdPUlRNJyk7XG4gIH1cblxuICBvcnRWZXJzaW9uKCk6IHN0cmluZyB8IG51bGw7XG4gIG9ydFZlcnNpb24ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmcgfCBVaW50OEFycmF5IHwgbnVsbDtcbiAgb3J0VmVyc2lvbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nIHwgVWludDhBcnJheSB8IG51bGwge1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgfVxuXG4gIG1vZGVsKG9iaj86IE1vZGVsKTogTW9kZWwgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IE1vZGVsKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDogbnVsbDtcbiAgfVxuXG4gIGtlcm5lbFR5cGVTdHJSZXNvbHZlcihvYmo/OiBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIpOiBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIgfCBudWxsIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgIHJldHVybiBvZmZzZXRcbiAgICAgID8gKG9iaiB8fCBuZXcgS2VybmVsVHlwZVN0clJlc29sdmVyKCkpLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgc3RhcnRJbmZlcmVuY2VTZXNzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDQpO1xuICB9XG5cbiAgc3RhdGljIGFkZE9ydFZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3J0VmVyc2lvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBvcnRWZXJzaW9uT2Zmc2V0LCAwKTtcbiAgfVxuXG4gIHN0YXRpYyBhZGRNb2RlbChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBtb2RlbE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBtb2RlbE9mZnNldCwgMCk7XG4gIH1cblxuICBzdGF0aWMgYWRkS2VybmVsVHlwZVN0clJlc29sdmVyKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbFR5cGVTdHJSZXNvbHZlck9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgzLCBrZXJuZWxUeXBlU3RyUmVzb2x2ZXJPZmZzZXQsIDApO1xuICB9XG5cbiAgc3RhdGljIGVuZEluZmVyZW5jZVNlc3Npb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGZpbmlzaEluZmVyZW5jZVNlc3Npb25CdWZmZXIoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICBidWlsZGVyLmZpbmlzaChvZmZzZXQsICdPUlRNJyk7XG4gIH1cblxuICBzdGF0aWMgZmluaXNoU2l6ZVByZWZpeGVkSW5mZXJlbmNlU2Vzc2lvbkJ1ZmZlcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgIGJ1aWxkZXIuZmluaXNoKG9mZnNldCwgJ09SVE0nLCB0cnVlKTtcbiAgfVxufVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuZXhwb3J0IHsgQXJnVHlwZSB9IGZyb20gJy4vZmJzL2FyZy10eXBlLmpzJztcbmV4cG9ydCB7IEFyZ1R5cGVBbmRJbmRleCB9IGZyb20gJy4vZmJzL2FyZy10eXBlLWFuZC1pbmRleC5qcyc7XG5leHBvcnQgeyBBdHRyaWJ1dGUgfSBmcm9tICcuL2Zicy9hdHRyaWJ1dGUuanMnO1xuZXhwb3J0IHsgQXR0cmlidXRlVHlwZSB9IGZyb20gJy4vZmJzL2F0dHJpYnV0ZS10eXBlLmpzJztcbmV4cG9ydCB7IERlcHJlY2F0ZWRLZXJuZWxDcmVhdGVJbmZvcyB9IGZyb20gJy4vZmJzL2RlcHJlY2F0ZWQta2VybmVsLWNyZWF0ZS1pbmZvcy5qcyc7XG5leHBvcnQgeyBEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCB9IGZyb20gJy4vZmJzL2RlcHJlY2F0ZWQtbm9kZS1pbmRleC1hbmQta2VybmVsLWRlZi1oYXNoLmpzJztcbmV4cG9ydCB7IERlcHJlY2F0ZWRTZXNzaW9uU3RhdGUgfSBmcm9tICcuL2Zicy9kZXByZWNhdGVkLXNlc3Npb24tc3RhdGUuanMnO1xuZXhwb3J0IHsgRGVwcmVjYXRlZFN1YkdyYXBoU2Vzc2lvblN0YXRlIH0gZnJvbSAnLi9mYnMvZGVwcmVjYXRlZC1zdWItZ3JhcGgtc2Vzc2lvbi1zdGF0ZS5qcyc7XG5leHBvcnQgeyBEaW1lbnNpb24gfSBmcm9tICcuL2Zicy9kaW1lbnNpb24uanMnO1xuZXhwb3J0IHsgRGltZW5zaW9uVmFsdWUgfSBmcm9tICcuL2Zicy9kaW1lbnNpb24tdmFsdWUuanMnO1xuZXhwb3J0IHsgRGltZW5zaW9uVmFsdWVUeXBlIH0gZnJvbSAnLi9mYnMvZGltZW5zaW9uLXZhbHVlLXR5cGUuanMnO1xuZXhwb3J0IHsgRWRnZUVuZCB9IGZyb20gJy4vZmJzL2VkZ2UtZW5kLmpzJztcbmV4cG9ydCB7IEdyYXBoIH0gZnJvbSAnLi9mYnMvZ3JhcGguanMnO1xuZXhwb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiB9IGZyb20gJy4vZmJzL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcbmV4cG9ydCB7IEtlcm5lbFR5cGVTdHJBcmdzRW50cnkgfSBmcm9tICcuL2Zicy9rZXJuZWwtdHlwZS1zdHItYXJncy1lbnRyeS5qcyc7XG5leHBvcnQgeyBLZXJuZWxUeXBlU3RyUmVzb2x2ZXIgfSBmcm9tICcuL2Zicy9rZXJuZWwtdHlwZS1zdHItcmVzb2x2ZXIuanMnO1xuZXhwb3J0IHsgTWFwVHlwZSB9IGZyb20gJy4vZmJzL21hcC10eXBlLmpzJztcbmV4cG9ydCB7IE1vZGVsIH0gZnJvbSAnLi9mYnMvbW9kZWwuanMnO1xuZXhwb3J0IHsgTm9kZSB9IGZyb20gJy4vZmJzL25vZGUuanMnO1xuZXhwb3J0IHsgTm9kZUVkZ2UgfSBmcm9tICcuL2Zicy9ub2RlLWVkZ2UuanMnO1xuZXhwb3J0IHsgTm9kZVR5cGUgfSBmcm9tICcuL2Zicy9ub2RlLXR5cGUuanMnO1xuZXhwb3J0IHsgTm9kZXNUb09wdGltaXplSW5kaWNlcyB9IGZyb20gJy4vZmJzL25vZGVzLXRvLW9wdGltaXplLWluZGljZXMuanMnO1xuZXhwb3J0IHsgT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkgfSBmcm9tICcuL2Zicy9vcC1pZC1rZXJuZWwtdHlwZS1zdHItYXJncy1lbnRyeS5qcyc7XG5leHBvcnQgeyBPcGVyYXRvclNldElkIH0gZnJvbSAnLi9mYnMvb3BlcmF0b3Itc2V0LWlkLmpzJztcbmV4cG9ydCB7IFJ1bnRpbWVPcHRpbWl6YXRpb25SZWNvcmQgfSBmcm9tICcuL2Zicy9ydW50aW1lLW9wdGltaXphdGlvbi1yZWNvcmQuanMnO1xuZXhwb3J0IHsgUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IH0gZnJvbSAnLi9mYnMvcnVudGltZS1vcHRpbWl6YXRpb24tcmVjb3JkLWNvbnRhaW5lci1lbnRyeS5qcyc7XG5leHBvcnQgeyBSdW50aW1lT3B0aW1pemF0aW9ucyB9IGZyb20gJy4vZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9ucy5qcyc7XG5leHBvcnQgeyBTZXF1ZW5jZVR5cGUgfSBmcm9tICcuL2Zicy9zZXF1ZW5jZS10eXBlLmpzJztcbmV4cG9ydCB7IFNoYXBlIH0gZnJvbSAnLi9mYnMvc2hhcGUuanMnO1xuZXhwb3J0IHsgU3BhcnNlVGVuc29yIH0gZnJvbSAnLi9mYnMvc3BhcnNlLXRlbnNvci5qcyc7XG5leHBvcnQgeyBTdHJpbmdTdHJpbmdFbnRyeSB9IGZyb20gJy4vZmJzL3N0cmluZy1zdHJpbmctZW50cnkuanMnO1xuZXhwb3J0IHsgVGVuc29yIH0gZnJvbSAnLi9mYnMvdGVuc29yLmpzJztcbmV4cG9ydCB7IFRlbnNvckRhdGFUeXBlIH0gZnJvbSAnLi9mYnMvdGVuc29yLWRhdGEtdHlwZS5qcyc7XG5leHBvcnQgeyBUZW5zb3JUeXBlQW5kU2hhcGUgfSBmcm9tICcuL2Zicy90ZW5zb3ItdHlwZS1hbmQtc2hhcGUuanMnO1xuZXhwb3J0IHsgVHlwZUluZm8gfSBmcm9tICcuL2Zicy90eXBlLWluZm8uanMnO1xuZXhwb3J0IHsgVHlwZUluZm9WYWx1ZSB9IGZyb20gJy4vZmJzL3R5cGUtaW5mby12YWx1ZS5qcyc7XG5leHBvcnQgeyBWYWx1ZUluZm8gfSBmcm9tICcuL2Zicy92YWx1ZS1pbmZvLmpzJztcbiIsICJleHBvcnQgKiBmcm9tICcuL29ubnhydW50aW1lL2Zicyc7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcbm1vZHVsZS5leHBvcnRzID0gYXNQcm9taXNlO1xyXG5cclxuLyoqXHJcbiAqIENhbGxiYWNrIGFzIHVzZWQgYnkge0BsaW5rIHV0aWwuYXNQcm9taXNlfS5cclxuICogQHR5cGVkZWYgYXNQcm9taXNlQ2FsbGJhY2tcclxuICogQHR5cGUge2Z1bmN0aW9ufVxyXG4gKiBAcGFyYW0ge0Vycm9yfG51bGx9IGVycm9yIEVycm9yLCBpZiBhbnlcclxuICogQHBhcmFtIHsuLi4qfSBwYXJhbXMgQWRkaXRpb25hbCBhcmd1bWVudHNcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIHByb21pc2UgZnJvbSBhIG5vZGUtc3R5bGUgY2FsbGJhY2sgZnVuY3Rpb24uXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBwYXJhbSB7YXNQcm9taXNlQ2FsbGJhY2t9IGZuIEZ1bmN0aW9uIHRvIGNhbGxcclxuICogQHBhcmFtIHsqfSBjdHggRnVuY3Rpb24gY29udGV4dFxyXG4gKiBAcGFyYW0gey4uLip9IHBhcmFtcyBGdW5jdGlvbiBhcmd1bWVudHNcclxuICogQHJldHVybnMge1Byb21pc2U8Kj59IFByb21pc2lmaWVkIGZ1bmN0aW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBhc1Byb21pc2UoZm4sIGN0eC8qLCB2YXJhcmdzICovKSB7XHJcbiAgICB2YXIgcGFyYW1zICA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSksXHJcbiAgICAgICAgb2Zmc2V0ICA9IDAsXHJcbiAgICAgICAgaW5kZXggICA9IDIsXHJcbiAgICAgICAgcGVuZGluZyA9IHRydWU7XHJcbiAgICB3aGlsZSAoaW5kZXggPCBhcmd1bWVudHMubGVuZ3RoKVxyXG4gICAgICAgIHBhcmFtc1tvZmZzZXQrK10gPSBhcmd1bWVudHNbaW5kZXgrK107XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gZXhlY3V0b3IocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgcGFyYW1zW29mZnNldF0gPSBmdW5jdGlvbiBjYWxsYmFjayhlcnIvKiwgdmFyYXJncyAqLykge1xyXG4gICAgICAgICAgICBpZiAocGVuZGluZykge1xyXG4gICAgICAgICAgICAgICAgcGVuZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycilcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJhbXMgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChvZmZzZXQgPCBwYXJhbXMubGVuZ3RoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXNbb2Zmc2V0KytdID0gYXJndW1lbnRzW29mZnNldF07XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZS5hcHBseShudWxsLCBwYXJhbXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBmbi5hcHBseShjdHggfHwgbnVsbCwgcGFyYW1zKTtcclxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgaWYgKHBlbmRpbmcpIHtcclxuICAgICAgICAgICAgICAgIHBlbmRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn1cclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5cclxuLyoqXHJcbiAqIEEgbWluaW1hbCBiYXNlNjQgaW1wbGVtZW50YXRpb24gZm9yIG51bWJlciBhcnJheXMuXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBuYW1lc3BhY2VcclxuICovXHJcbnZhciBiYXNlNjQgPSBleHBvcnRzO1xyXG5cclxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGJ5dGUgbGVuZ3RoIG9mIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIEJhc2U2NCBlbmNvZGVkIHN0cmluZ1xyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBCeXRlIGxlbmd0aFxyXG4gKi9cclxuYmFzZTY0Lmxlbmd0aCA9IGZ1bmN0aW9uIGxlbmd0aChzdHJpbmcpIHtcclxuICAgIHZhciBwID0gc3RyaW5nLmxlbmd0aDtcclxuICAgIGlmICghcClcclxuICAgICAgICByZXR1cm4gMDtcclxuICAgIHZhciBuID0gMDtcclxuICAgIHdoaWxlICgtLXAgJSA0ID4gMSAmJiBzdHJpbmcuY2hhckF0KHApID09PSBcIj1cIilcclxuICAgICAgICArK247XHJcbiAgICByZXR1cm4gTWF0aC5jZWlsKHN0cmluZy5sZW5ndGggKiAzKSAvIDQgLSBuO1xyXG59O1xyXG5cclxuLy8gQmFzZTY0IGVuY29kaW5nIHRhYmxlXHJcbnZhciBiNjQgPSBuZXcgQXJyYXkoNjQpO1xyXG5cclxuLy8gQmFzZTY0IGRlY29kaW5nIHRhYmxlXHJcbnZhciBzNjQgPSBuZXcgQXJyYXkoMTIzKTtcclxuXHJcbi8vIDY1Li45MCwgOTcuLjEyMiwgNDguLjU3LCA0MywgNDdcclxuZm9yICh2YXIgaSA9IDA7IGkgPCA2NDspXHJcbiAgICBzNjRbYjY0W2ldID0gaSA8IDI2ID8gaSArIDY1IDogaSA8IDUyID8gaSArIDcxIDogaSA8IDYyID8gaSAtIDQgOiBpIC0gNTkgfCA0M10gPSBpKys7XHJcblxyXG4vKipcclxuICogRW5jb2RlcyBhIGJ1ZmZlciB0byBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZy5cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgU291cmNlIHN0YXJ0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgU291cmNlIGVuZFxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBCYXNlNjQgZW5jb2RlZCBzdHJpbmdcclxuICovXHJcbmJhc2U2NC5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoYnVmZmVyLCBzdGFydCwgZW5kKSB7XHJcbiAgICB2YXIgcGFydHMgPSBudWxsLFxyXG4gICAgICAgIGNodW5rID0gW107XHJcbiAgICB2YXIgaSA9IDAsIC8vIG91dHB1dCBpbmRleFxyXG4gICAgICAgIGogPSAwLCAvLyBnb3RvIGluZGV4XHJcbiAgICAgICAgdDsgICAgIC8vIHRlbXBvcmFyeVxyXG4gICAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7XHJcbiAgICAgICAgdmFyIGIgPSBidWZmZXJbc3RhcnQrK107XHJcbiAgICAgICAgc3dpdGNoIChqKSB7XHJcbiAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgIGNodW5rW2krK10gPSBiNjRbYiA+PiAyXTtcclxuICAgICAgICAgICAgICAgIHQgPSAoYiAmIDMpIDw8IDQ7XHJcbiAgICAgICAgICAgICAgICBqID0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICBjaHVua1tpKytdID0gYjY0W3QgfCBiID4+IDRdO1xyXG4gICAgICAgICAgICAgICAgdCA9IChiICYgMTUpIDw8IDI7XHJcbiAgICAgICAgICAgICAgICBqID0gMjtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICBjaHVua1tpKytdID0gYjY0W3QgfCBiID4+IDZdO1xyXG4gICAgICAgICAgICAgICAgY2h1bmtbaSsrXSA9IGI2NFtiICYgNjNdO1xyXG4gICAgICAgICAgICAgICAgaiA9IDA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGkgPiA4MTkxKSB7XHJcbiAgICAgICAgICAgIChwYXJ0cyB8fCAocGFydHMgPSBbXSkpLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rKSk7XHJcbiAgICAgICAgICAgIGkgPSAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChqKSB7XHJcbiAgICAgICAgY2h1bmtbaSsrXSA9IGI2NFt0XTtcclxuICAgICAgICBjaHVua1tpKytdID0gNjE7XHJcbiAgICAgICAgaWYgKGogPT09IDEpXHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSA2MTtcclxuICAgIH1cclxuICAgIGlmIChwYXJ0cykge1xyXG4gICAgICAgIGlmIChpKVxyXG4gICAgICAgICAgICBwYXJ0cy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuay5zbGljZSgwLCBpKSkpO1xyXG4gICAgICAgIHJldHVybiBwYXJ0cy5qb2luKFwiXCIpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuay5zbGljZSgwLCBpKSk7XHJcbn07XHJcblxyXG52YXIgaW52YWxpZEVuY29kaW5nID0gXCJpbnZhbGlkIGVuY29kaW5nXCI7XHJcblxyXG4vKipcclxuICogRGVjb2RlcyBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZyB0byBhIGJ1ZmZlci5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTb3VyY2Ugc3RyaW5nXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIERlc3RpbmF0aW9uIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IERlc3RpbmF0aW9uIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgZW5jb2RpbmcgaXMgaW52YWxpZFxyXG4gKi9cclxuYmFzZTY0LmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShzdHJpbmcsIGJ1ZmZlciwgb2Zmc2V0KSB7XHJcbiAgICB2YXIgc3RhcnQgPSBvZmZzZXQ7XHJcbiAgICB2YXIgaiA9IDAsIC8vIGdvdG8gaW5kZXhcclxuICAgICAgICB0OyAgICAgLy8gdGVtcG9yYXJ5XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7KSB7XHJcbiAgICAgICAgdmFyIGMgPSBzdHJpbmcuY2hhckNvZGVBdChpKyspO1xyXG4gICAgICAgIGlmIChjID09PSA2MSAmJiBqID4gMSlcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgaWYgKChjID0gczY0W2NdKSA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihpbnZhbGlkRW5jb2RpbmcpO1xyXG4gICAgICAgIHN3aXRjaCAoaikge1xyXG4gICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICB0ID0gYztcclxuICAgICAgICAgICAgICAgIGogPSAxO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSB0IDw8IDIgfCAoYyAmIDQ4KSA+PiA0O1xyXG4gICAgICAgICAgICAgICAgdCA9IGM7XHJcbiAgICAgICAgICAgICAgICBqID0gMjtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gKHQgJiAxNSkgPDwgNCB8IChjICYgNjApID4+IDI7XHJcbiAgICAgICAgICAgICAgICB0ID0gYztcclxuICAgICAgICAgICAgICAgIGogPSAzO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSAodCAmIDMpIDw8IDYgfCBjO1xyXG4gICAgICAgICAgICAgICAgaiA9IDA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoaiA9PT0gMSlcclxuICAgICAgICB0aHJvdyBFcnJvcihpbnZhbGlkRW5jb2RpbmcpO1xyXG4gICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFwcGVhcnMgdG8gYmUgYmFzZTY0IGVuY29kZWQuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU3RyaW5nIHRvIHRlc3RcclxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBwcm9iYWJseSBiYXNlNjQgZW5jb2RlZCwgb3RoZXJ3aXNlIGZhbHNlXHJcbiAqL1xyXG5iYXNlNjQudGVzdCA9IGZ1bmN0aW9uIHRlc3Qoc3RyaW5nKSB7XHJcbiAgICByZXR1cm4gL14oPzpbQS1aYS16MC05Ky9dezR9KSooPzpbQS1aYS16MC05Ky9dezJ9PT18W0EtWmEtejAtOSsvXXszfT0pPyQvLnRlc3Qoc3RyaW5nKTtcclxufTtcclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcclxuXHJcbi8qKlxyXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IGV2ZW50IGVtaXR0ZXIgaW5zdGFuY2UuXHJcbiAqIEBjbGFzc2Rlc2MgQSBtaW5pbWFsIGV2ZW50IGVtaXR0ZXIuXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKi9cclxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVnaXN0ZXJlZCBsaXN0ZW5lcnMuXHJcbiAgICAgKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsKj59XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB0aGlzLl9saXN0ZW5lcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xyXG59XHJcblxyXG4vKipcclxuICogRXZlbnQgbGlzdGVuZXIgYXMgdXNlZCBieSB7QGxpbmsgdXRpbC5FdmVudEVtaXR0ZXJ9LlxyXG4gKiBAdHlwZWRlZiBFdmVudEVtaXR0ZXJMaXN0ZW5lclxyXG4gKiBAdHlwZSB7ZnVuY3Rpb259XHJcbiAqIEBwYXJhbSB7Li4uKn0gYXJncyBBcmd1bWVudHNcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogUmVnaXN0ZXJzIGFuIGV2ZW50IGxpc3RlbmVyLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZ0IEV2ZW50IG5hbWVcclxuICogQHBhcmFtIHtFdmVudEVtaXR0ZXJMaXN0ZW5lcn0gZm4gTGlzdGVuZXJcclxuICogQHBhcmFtIHsqfSBbY3R4XSBMaXN0ZW5lciBjb250ZXh0XHJcbiAqIEByZXR1cm5zIHt0aGlzfSBgdGhpc2BcclxuICovXHJcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbiBvbihldnQsIGZuLCBjdHgpIHtcclxuICAgICh0aGlzLl9saXN0ZW5lcnNbZXZ0XSB8fCAodGhpcy5fbGlzdGVuZXJzW2V2dF0gPSBbXSkpLnB1c2goe1xyXG4gICAgICAgIGZuICA6IGZuLFxyXG4gICAgICAgIGN0eCA6IGN0eCB8fCB0aGlzXHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJlbW92ZXMgYW4gZXZlbnQgbGlzdGVuZXIgb3IgYW55IG1hdGNoaW5nIGxpc3RlbmVycyBpZiBhcmd1bWVudHMgYXJlIG9taXR0ZWQuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBbZXZ0XSBFdmVudCBuYW1lLiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgaWYgb21pdHRlZC5cclxuICogQHBhcmFtIHtFdmVudEVtaXR0ZXJMaXN0ZW5lcn0gW2ZuXSBMaXN0ZW5lciB0byByZW1vdmUuIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBvZiBgZXZ0YCBpZiBvbWl0dGVkLlxyXG4gKiBAcmV0dXJucyB7dGhpc30gYHRoaXNgXHJcbiAqL1xyXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIG9mZihldnQsIGZuKSB7XHJcbiAgICBpZiAoZXZ0ID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGlmIChmbiA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnNbZXZ0XSA9IFtdO1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzW2V2dF07XHJcbiAgICAgICAgICAgIGlmICghbGlzdGVuZXJzKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDspXHJcbiAgICAgICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmZuID09PSBmbilcclxuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICsraTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBFbWl0cyBhbiBldmVudCBieSBjYWxsaW5nIGl0cyBsaXN0ZW5lcnMgd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cy5cclxuICogQHBhcmFtIHtzdHJpbmd9IGV2dCBFdmVudCBuYW1lXHJcbiAqIEBwYXJhbSB7Li4uKn0gYXJncyBBcmd1bWVudHNcclxuICogQHJldHVybnMge3RoaXN9IGB0aGlzYFxyXG4gKi9cclxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcclxuICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZ0XTtcclxuICAgIGlmIChsaXN0ZW5lcnMpIHtcclxuICAgICAgICB2YXIgYXJncyA9IFtdLFxyXG4gICAgICAgICAgICBpID0gMTtcclxuICAgICAgICBmb3IgKDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7KVxyXG4gICAgICAgICAgICBhcmdzLnB1c2goYXJndW1lbnRzW2krK10pO1xyXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOylcclxuICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmZuLmFwcGx5KGxpc3RlbmVyc1tpKytdLmN0eCwgYXJncyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxufTtcclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KGZhY3RvcnkpO1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIC8gd3JpdGVzIGZsb2F0cyAvIGRvdWJsZXMgZnJvbSAvIHRvIGJ1ZmZlcnMuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXRcclxuICogQG5hbWVzcGFjZVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSAzMiBiaXQgZmxvYXQgdG8gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LndyaXRlRmxvYXRMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgMzIgYml0IGZsb2F0IHRvIGEgYnVmZmVyIHVzaW5nIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC53cml0ZUZsb2F0QkVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgVGFyZ2V0IGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFRhcmdldCBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIGEgMzIgYml0IGZsb2F0IGZyb20gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWRGbG9hdExFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgU291cmNlIGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBhIDMyIGJpdCBmbG9hdCBmcm9tIGEgYnVmZmVyIHVzaW5nIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC5yZWFkRmxvYXRCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgNjQgYml0IGRvdWJsZSB0byBhIGJ1ZmZlciB1c2luZyBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQud3JpdGVEb3VibGVMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgNjQgYml0IGRvdWJsZSB0byBhIGJ1ZmZlciB1c2luZyBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQud3JpdGVEb3VibGVCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogUmVhZHMgYSA2NCBiaXQgZG91YmxlIGZyb20gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWREb3VibGVMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vKipcclxuICogUmVhZHMgYSA2NCBiaXQgZG91YmxlIGZyb20gYSBidWZmZXIgdXNpbmcgYmlnIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWREb3VibGVCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vLyBGYWN0b3J5IGZ1bmN0aW9uIGZvciB0aGUgcHVycG9zZSBvZiBub2RlLWJhc2VkIHRlc3RpbmcgaW4gbW9kaWZpZWQgZ2xvYmFsIGVudmlyb25tZW50c1xyXG5mdW5jdGlvbiBmYWN0b3J5KGV4cG9ydHMpIHtcclxuXHJcbiAgICAvLyBmbG9hdDogdHlwZWQgYXJyYXlcclxuICAgIGlmICh0eXBlb2YgRmxvYXQzMkFycmF5ICE9PSBcInVuZGVmaW5lZFwiKSAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBmMzIgPSBuZXcgRmxvYXQzMkFycmF5KFsgLTAgXSksXHJcbiAgICAgICAgICAgIGY4YiA9IG5ldyBVaW50OEFycmF5KGYzMi5idWZmZXIpLFxyXG4gICAgICAgICAgICBsZSAgPSBmOGJbM10gPT09IDEyODtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gd3JpdGVGbG9hdF9mMzJfY3B5KHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjMyWzBdID0gdmFsO1xyXG4gICAgICAgICAgICBidWZbcG9zICAgIF0gPSBmOGJbMF07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAxXSA9IGY4YlsxXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDJdID0gZjhiWzJdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgM10gPSBmOGJbM107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZUZsb2F0X2YzMl9yZXYodmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmMzJbMF0gPSB2YWw7XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgICAgXSA9IGY4YlszXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDFdID0gZjhiWzJdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMl0gPSBmOGJbMV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAzXSA9IGY4YlswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZUZsb2F0TEUgPSBsZSA/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+Pj4gMDtcclxufVxyXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcbm1vZHVsZS5leHBvcnRzID0gaW5xdWlyZTtcclxuXHJcbi8qKlxyXG4gKiBSZXF1aXJlcyBhIG1vZHVsZSBvbmx5IGlmIGF2YWlsYWJsZS5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQHBhcmFtIHtzdHJpbmd9IG1vZHVsZU5hbWUgTW9kdWxlIHRvIHJlcXVpcmVcclxuICogQHJldHVybnMgez9PYmplY3R9IFJlcXVpcmVkIG1vZHVsZSBpZiBhdmFpbGFibGUgYW5kIG5vdCBlbXB0eSwgb3RoZXJ3aXNlIGBudWxsYFxyXG4gKiBAZGVwcmVjYXRlZCBMZWdhY3kgb3B0aW9uYWwgcmVxdWlyZSBoZWxwZXIuIFdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSByZWxlYXNlLlxyXG4gKi9cclxuZnVuY3Rpb24gaW5xdWlyZShtb2R1bGVOYW1lKSB7XHJcbiAgdHJ5IHtcclxuICAgIGlmICh0eXBlb2YgcmVxdWlyZSAhPT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgdmFyIG1vZCA9IHJlcXVpcmUobW9kdWxlTmFtZSk7XHJcbiAgICBpZiAobW9kICYmIChtb2QubGVuZ3RoIHx8IE9iamVjdC5rZXlzKG1vZCkubGVuZ3RoKSkgcmV0dXJuIG1vZDtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH0gY2F0Y2ggKGVycikge1xyXG4gICAgLy8gaWdub3JlXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcbn1cclxuXHJcbi8qXHJcbi8vIG1heWJlIHdvcnRoIGEgc2hvdCB0byBwcmV2ZW50IHJlbmFtaW5nIGlzc3VlczpcclxuLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vd2VicGFjay93ZWJwYWNrL2Jsb2IvbWFzdGVyL2xpYi9kZXBlbmRlbmNpZXMvQ29tbW9uSnNSZXF1aXJlRGVwZW5kZW5jeVBhcnNlclBsdWdpbi5qc1xyXG4vLyB0cmlnZ2VycyBvbjpcclxuLy8gLSBleHByZXNzaW9uIHJlcXVpcmUuY2FjaGVcclxuLy8gLSBleHByZXNzaW9uIHJlcXVpcmUgKD8/PylcclxuLy8gLSBjYWxsIHJlcXVpcmVcclxuLy8gLSBjYWxsIHJlcXVpcmU6Y29tbW9uanM6aXRlbVxyXG4vLyAtIGNhbGwgcmVxdWlyZTpjb21tb25qczpjb250ZXh0XHJcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRnVuY3Rpb24ucHJvdG90eXBlLCBcIl9fc2VsZlwiLCB7IGdldDogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9IH0pO1xyXG52YXIgciA9IHJlcXVpcmUuX19zZWxmO1xyXG5kZWxldGUgRnVuY3Rpb24ucHJvdG90eXBlLl9fc2VsZjtcclxuKi9cclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5cclxuLyoqXHJcbiAqIEEgbWluaW1hbCBVVEY4IGltcGxlbWVudGF0aW9uIGZvciBudW1iZXIgYXJyYXlzLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAbmFtZXNwYWNlXHJcbiAqL1xyXG52YXIgdXRmOCA9IGV4cG9ydHMsXHJcbiAgICByZXBsYWNlbWVudENoYXIgPSBcIlxcdWZmZmRcIjtcclxuXHJcbi8qKlxyXG4gKiBDYWxjdWxhdGVzIHRoZSBVVEY4IGJ5dGUgbGVuZ3RoIG9mIGEgc3RyaW5nLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFN0cmluZ1xyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBCeXRlIGxlbmd0aFxyXG4gKi9cclxudXRmOC5sZW5ndGggPSBmdW5jdGlvbiB1dGY4X2xlbmd0aChzdHJpbmcpIHtcclxuICAgIHZhciBsZW4gPSAwLFxyXG4gICAgICAgIGMgPSAwO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyArK2kpIHtcclxuICAgICAgICBjID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgaWYgKGMgPCAxMjgpXHJcbiAgICAgICAgICAgIGxlbiArPSAxO1xyXG4gICAgICAgIGVsc2UgaWYgKGMgPCAyMDQ4KVxyXG4gICAgICAgICAgICBsZW4gKz0gMjtcclxuICAgICAgICBlbHNlIGlmICgoYyAmIDB4RkMwMCkgPT09IDB4RDgwMCAmJiAoc3RyaW5nLmNoYXJDb2RlQXQoaSArIDEpICYgMHhGQzAwKSA9PT0gMHhEQzAwKSB7XHJcbiAgICAgICAgICAgICsraTtcclxuICAgICAgICAgICAgbGVuICs9IDQ7XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgIGxlbiArPSAzO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxlbjtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBVVEY4IGJ5dGVzIGFzIGEgc3RyaW5nLlxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZmZlciBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBTb3VyY2Ugc3RhcnRcclxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBTb3VyY2UgZW5kXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFN0cmluZyByZWFkXHJcbiAqL1xyXG51dGY4LnJlYWQgPSBmdW5jdGlvbiB1dGY4X3JlYWQoYnVmZmVyLCBzdGFydCwgZW5kKSB7XHJcbiAgICBpZiAoZW5kIC0gc3RhcnQgPCAxKSB7XHJcbiAgICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHN0ciA9IFwiXCI7XHJcbiAgICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7KSB7XHJcbiAgICAgICAgdmFyIHQgPSBidWZmZXJbaSsrXTtcclxuICAgICAgICBpZiAodCA8PSAweDdGKSB7XHJcbiAgICAgICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHQpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodCA+PSAweEMwICYmIHQgPCAweEUwKSB7XHJcbiAgICAgICAgICAgIHZhciBjMiA9ICh0ICYgMHgxRikgPDwgNiB8IGJ1ZmZlcltpKytdICYgMHgzRjtcclxuICAgICAgICAgICAgc3RyICs9IGMyID49IDB4ODAgPyBTdHJpbmcuZnJvbUNoYXJDb2RlKGMyKSA6IHJlcGxhY2VtZW50Q2hhcjtcclxuICAgICAgICB9IGVsc2UgaWYgKHQgPj0gMHhFMCAmJiB0IDwgMHhGMCkge1xyXG4gICAgICAgICAgICB2YXIgYzMgPSAodCAmIDB4RikgPDwgMTIgfCAoYnVmZmVyW2krK10gJiAweDNGKSA8PCA2IHwgYnVmZmVyW2krK10gJiAweDNGO1xyXG4gICAgICAgICAgICBzdHIgKz0gYzMgPj0gMHg4MDAgPyBTdHJpbmcuZnJvbUNoYXJDb2RlKGMzKSA6IHJlcGxhY2VtZW50Q2hhcjtcclxuICAgICAgICB9IGVsc2UgaWYgKHQgPj0gMHhGMCkge1xyXG4gICAgICAgICAgICB2YXIgdDIgPSAodCAmIDcpIDw8IDE4IHwgKGJ1ZmZlcltpKytdICYgMHgzRikgPDwgMTIgfCAoYnVmZmVyW2krK10gJiAweDNGKSA8PCA2IHwgYnVmZmVyW2krK10gJiAweDNGO1xyXG4gICAgICAgICAgICBpZiAodDIgPCAweDEwMDAwIHx8IHQyID4gMHgxMEZGRkYpXHJcbiAgICAgICAgICAgICAgICBzdHIgKz0gcmVwbGFjZW1lbnRDaGFyO1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHQyIC09IDB4MTAwMDA7XHJcbiAgICAgICAgICAgICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweEQ4MDAgKyAodDIgPj4gMTApKTtcclxuICAgICAgICAgICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4REMwMCArICh0MiAmIDB4M0ZGKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHN0cjtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSBzdHJpbmcgYXMgVVRGOCBieXRlcy5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTb3VyY2Ugc3RyaW5nXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIERlc3RpbmF0aW9uIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IERlc3RpbmF0aW9uIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBCeXRlcyB3cml0dGVuXHJcbiAqL1xyXG51dGY4LndyaXRlID0gZnVuY3Rpb24gdXRmOF93cml0ZShzdHJpbmcsIGJ1ZmZlciwgb2Zmc2V0KSB7XHJcbiAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgYzEsIC8vIGNoYXJhY3RlciAxXHJcbiAgICAgICAgYzI7IC8vIGNoYXJhY3RlciAyXHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7ICsraSkge1xyXG4gICAgICAgIGMxID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgaWYgKGMxIDwgMTI4KSB7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMTtcclxuICAgICAgICB9IGVsc2UgaWYgKGMxIDwgMjA0OCkge1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gNiAgICAgICB8IDE5MjtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxICAgICAgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgfSBlbHNlIGlmICgoYzEgJiAweEZDMDApID09PSAweEQ4MDAgJiYgKChjMiA9IHN0cmluZy5jaGFyQ29kZUF0KGkgKyAxKSkgJiAweEZDMDApID09PSAweERDMDApIHtcclxuICAgICAgICAgICAgYzEgPSAweDEwMDAwICsgKChjMSAmIDB4MDNGRikgPDwgMTApICsgKGMyICYgMHgwM0ZGKTtcclxuICAgICAgICAgICAgKytpO1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gMTggICAgICB8IDI0MDtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+IDEyICYgNjMgfCAxMjg7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiA2ICAmIDYzIHwgMTI4O1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgICAgICAgJiA2MyB8IDEyODtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gMTIgICAgICB8IDIyNDtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+IDYgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSAgICAgICAmIDYzIHwgMTI4O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBvZmZzZXQgLSBzdGFydDtcclxufTtcclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5tb2R1bGUuZXhwb3J0cyA9IHBvb2w7XHJcblxyXG4vKipcclxuICogQW4gYWxsb2NhdG9yIGFzIHVzZWQgYnkge0BsaW5rIHV0aWwucG9vbH0uXHJcbiAqIEB0eXBlZGVmIFBvb2xBbGxvY2F0b3JcclxuICogQHR5cGUge2Z1bmN0aW9ufVxyXG4gKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBCdWZmZXIgc2l6ZVxyXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gQnVmZmVyXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEEgc2xpY2VyIGFzIHVzZWQgYnkge0BsaW5rIHV0aWwucG9vbH0uXHJcbiAqIEB0eXBlZGVmIFBvb2xTbGljZXJcclxuICogQHR5cGUge2Z1bmN0aW9ufVxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgU3RhcnQgb2Zmc2V0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gQnVmZmVyIHNsaWNlXHJcbiAqIEB0aGlzIHtVaW50OEFycmF5fVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBBIGdlbmVyYWwgcHVycG9zZSBidWZmZXIgcG9vbC5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7UG9vbEFsbG9jYXRvcn0gYWxsb2MgQWxsb2NhdG9yXHJcbiAqIEBwYXJhbSB7UG9vbFNsaWNlcn0gc2xpY2UgU2xpY2VyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT04MTkyXSBTbGFiIHNpemVcclxuICogQHJldHVybnMge1Bvb2xBbGxvY2F0b3J9IFBvb2xlZCBhbGxvY2F0b3JcclxuICovXHJcbmZ1bmN0aW9uIHBvb2woYWxsb2MsIHNsaWNlLCBzaXplKSB7XHJcbiAgICB2YXIgU0laRSAgID0gc2l6ZSB8fCA4MTkyO1xyXG4gICAgdmFyIE1BWCAgICA9IFNJWkUgPj4+IDE7XHJcbiAgICB2YXIgc2xhYiAgID0gbnVsbDtcclxuICAgIHZhciBvZmZzZXQgPSBTSVpFO1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIHBvb2xfYWxsb2Moc2l6ZSkge1xyXG4gICAgICAgIGlmIChzaXplIDwgMSB8fCBzaXplID4gTUFYKVxyXG4gICAgICAgICAgICByZXR1cm4gYWxsb2Moc2l6ZSk7XHJcbiAgICAgICAgaWYgKG9mZnNldCArIHNpemUgPiBTSVpFKSB7XHJcbiAgICAgICAgICAgIHNsYWIgPSBhbGxvYyhTSVpFKTtcclxuICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGJ1ZiA9IHNsaWNlLmNhbGwoc2xhYiwgb2Zmc2V0LCBvZmZzZXQgKz0gc2l6ZSk7XHJcbiAgICAgICAgaWYgKG9mZnNldCAmIDcpIC8vIGFsaWduIHRvIDMyIGJpdFxyXG4gICAgICAgICAgICBvZmZzZXQgPSAob2Zmc2V0IHwgNykgKyAxO1xyXG4gICAgICAgIHJldHVybiBidWY7XHJcbiAgICB9O1xyXG59XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gTG9uZ0JpdHM7XG5cbnZhciB1dGlsID0gcmVxdWlyZShcIi4uL3V0aWwvbWluaW1hbFwiKTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIG5ldyBsb25nIGJpdHMuXG4gKiBAY2xhc3NkZXNjIEhlbHBlciBjbGFzcyBmb3Igd29ya2luZyB3aXRoIHRoZSBsb3cgYW5kIGhpZ2ggYml0cyBvZiBhIDY0IGJpdCB2YWx1ZS5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7bnVtYmVyfSBsbyBMb3cgMzIgYml0cywgdW5zaWduZWRcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaSBIaWdoIDMyIGJpdHMsIHVuc2lnbmVkXG4gKi9cbmZ1bmN0aW9uIExvbmdCaXRzKGxvLCBoaSkge1xuXG4gICAgLy8gbm90ZSB0aGF0IHRoZSBjYXN0cyBiZWxvdyBhcmUgdGhlb3JldGljYWxseSB1bm5lY2Vzc2FyeSBhcyBvZiB0b2RheSwgYnV0IG9sZGVyIHN0YXRpY2FsbHlcbiAgICAvLyBnZW5lcmF0ZWQgY29udmVydGVyIGNvZGUgbWlnaHQgc3RpbGwgY2FsbCB0aGUgY3RvciB3aXRoIHNpZ25lZCAzMmJpdHMuIGtlcHQgZm9yIGNvbXBhdC5cblxuICAgIC8qKlxuICAgICAqIExvdyBiaXRzLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sbyA9IGxvID4+PiAwO1xuXG4gICAgLyoqXG4gICAgICogSGlnaCBiaXRzLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5oaSA9IGhpID4+PiAwO1xufVxuXG4vKipcbiAqIFplcm8gYml0cy5cbiAqIEBtZW1iZXJvZiB1dGlsLkxvbmdCaXRzXG4gKiBAdHlwZSB7dXRpbC5Mb25nQml0c31cbiAqL1xudmFyIHplcm8gPSBMb25nQml0cy56ZXJvID0gbmV3IExvbmdCaXRzKDAsIDApO1xuXG56ZXJvLnRvTnVtYmVyID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuemVyby56ekVuY29kZSA9IHplcm8uenpEZWNvZGUgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH07XG56ZXJvLmxlbmd0aCA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMTsgfTtcblxuLyoqXG4gKiBaZXJvIGhhc2guXG4gKiBAbWVtYmVyb2YgdXRpbC5Mb25nQml0c1xuICogQHR5cGUge3N0cmluZ31cbiAqL1xudmFyIHplcm9IYXNoID0gTG9uZ0JpdHMuemVyb0hhc2ggPSBcIlxcMFxcMFxcMFxcMFxcMFxcMFxcMFxcMFwiO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgbmV3IGxvbmcgYml0cyBmcm9tIHRoZSBzcGVjaWZpZWQgbnVtYmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlXG4gKiBAcmV0dXJucyB7dXRpbC5Mb25nQml0c30gSW5zdGFuY2VcbiAqL1xuTG9uZ0JpdHMuZnJvbU51bWJlciA9IGZ1bmN0aW9uIGZyb21OdW1iZXIodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT09IDApXG4gICAgICAgIHJldHVybiB6ZXJvO1xuICAgIHZhciBzaWduID0gdmFsdWUgPCAwO1xuICAgIGlmIChzaWduKVxuICAgICAgICB2YWx1ZSA9IC12YWx1ZTtcbiAgICB2YXIgbG8gPSB2YWx1ZSA+Pj4gMCxcbiAgICAgICAgaGkgPSAodmFsdWUgLSBsbykgLyA0Mjk0OTY3Mjk2ID4+PiAwO1xuICAgIGlmIChzaWduKSB7XG4gICAgICAgIGhpID0gfmhpID4+PiAwO1xuICAgICAgICBsbyA9IH5sbyA+Pj4gMDtcbiAgICAgICAgaWYgKCsrbG8gPiA0Mjk0OTY3Mjk1KSB7XG4gICAgICAgICAgICBsbyA9IDA7XG4gICAgICAgICAgICBpZiAoKytoaSA+IDQyOTQ5NjcyOTUpXG4gICAgICAgICAgICAgICAgaGkgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgTG9uZ0JpdHMobG8sIGhpKTtcbn07XG5cbi8qKlxuICogQ29uc3RydWN0cyBuZXcgbG9uZyBiaXRzIGZyb20gYSBudW1iZXIsIGxvbmcgb3Igc3RyaW5nLlxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlXG4gKiBAcmV0dXJucyB7dXRpbC5Mb25nQml0c30gSW5zdGFuY2VcbiAqL1xuTG9uZ0JpdHMuZnJvbSA9IGZ1bmN0aW9uIGZyb20odmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKVxuICAgICAgICByZXR1cm4gTG9uZ0JpdHMuZnJvbU51bWJlcih2YWx1ZSk7XG4gICAgaWYgKHV0aWwuaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgIGlmICh1dGlsLkxvbmcpXG4gICAgICAgICAgICB2YWx1ZSA9IHV0aWwuTG9uZy5mcm9tU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIExvbmdCaXRzLmZyb21OdW1iZXIocGFyc2VJbnQodmFsdWUsIDEwKSk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZS5sb3cgfHwgdmFsdWUuaGlnaCA/IG5ldyBMb25nQml0cyh2YWx1ZS5sb3cgPj4+IDAsIHZhbHVlLmhpZ2ggPj4+IDApIDogemVybztcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBsb25nIGJpdHMgdG8gYSBwb3NzaWJseSB1bnNhZmUgSmF2YVNjcmlwdCBudW1iZXIuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1bnNpZ25lZD1mYWxzZV0gV2hldGhlciB1bnNpZ25lZCBvciBub3RcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFBvc3NpYmx5IHVuc2FmZSBudW1iZXJcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIodW5zaWduZWQpIHtcbiAgICBpZiAoIXVuc2lnbmVkICYmIHRoaXMuaGkgPj4+IDMxKSB7XG4gICAgICAgIHZhciBsbyA9IH50aGlzLmxvICsgMSA+Pj4gMCxcbiAgICAgICAgICAgIGhpID0gfnRoaXMuaGkgICAgID4+PiAwO1xuICAgICAgICBpZiAoIWxvKVxuICAgICAgICAgICAgaGkgPSBoaSArIDEgPj4+IDA7XG4gICAgICAgIHJldHVybiAtKGxvICsgaGkgKiA0Mjk0OTY3Mjk2KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubG8gKyB0aGlzLmhpICogNDI5NDk2NzI5Njtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBsb25nIGJpdHMgdG8gYSBsb25nLlxuICogQHBhcmFtIHtib29sZWFufSBbdW5zaWduZWQ9ZmFsc2VdIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90XG4gKiBAcmV0dXJucyB7TG9uZ30gTG9uZ1xuICovXG5Mb25nQml0cy5wcm90b3R5cGUudG9Mb25nID0gZnVuY3Rpb24gdG9Mb25nKHVuc2lnbmVkKSB7XG4gICAgcmV0dXJuIHV0aWwuTG9uZ1xuICAgICAgICA/IG5ldyB1dGlsLkxvbmcodGhpcy5sbyB8IDAsIHRoaXMuaGkgfCAwLCBCb29sZWFuKHVuc2lnbmVkKSlcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgOiB7IGxvdzogdGhpcy5sbyB8IDAsIGhpZ2g6IHRoaXMuaGkgfCAwLCB1bnNpZ25lZDogQm9vbGVhbih1bnNpZ25lZCkgfTtcbn07XG5cbnZhciBjaGFyQ29kZUF0ID0gU3RyaW5nLnByb3RvdHlwZS5jaGFyQ29kZUF0O1xuXG4vKipcbiAqIENvbnN0cnVjdHMgbmV3IGxvbmcgYml0cyBmcm9tIHRoZSBzcGVjaWZpZWQgOCBjaGFyYWN0ZXJzIGxvbmcgaGFzaC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoIEhhc2hcbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBCaXRzXG4gKi9cbkxvbmdCaXRzLmZyb21IYXNoID0gZnVuY3Rpb24gZnJvbUhhc2goaGFzaCkge1xuICAgIGlmIChoYXNoID09PSB6ZXJvSGFzaClcbiAgICAgICAgcmV0dXJuIHplcm87XG4gICAgcmV0dXJuIG5ldyBMb25nQml0cyhcbiAgICAgICAgKCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgMClcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgMSkgPDwgOFxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCAyKSA8PCAxNlxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCAzKSA8PCAyNCkgPj4+IDBcbiAgICAsXG4gICAgICAgICggY2hhckNvZGVBdC5jYWxsKGhhc2gsIDQpXG4gICAgICAgIHwgY2hhckNvZGVBdC5jYWxsKGhhc2gsIDUpIDw8IDhcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgNikgPDwgMTZcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgNykgPDwgMjQpID4+PiAwXG4gICAgKTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBsb25nIGJpdHMgdG8gYSA4IGNoYXJhY3RlcnMgbG9uZyBoYXNoLlxuICogQHJldHVybnMge3N0cmluZ30gSGFzaFxuICovXG5Mb25nQml0cy5wcm90b3R5cGUudG9IYXNoID0gZnVuY3Rpb24gdG9IYXNoKCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgICB0aGlzLmxvICAgICAgICAmIDI1NSxcbiAgICAgICAgdGhpcy5sbyA+Pj4gOCAgJiAyNTUsXG4gICAgICAgIHRoaXMubG8gPj4+IDE2ICYgMjU1LFxuICAgICAgICB0aGlzLmxvID4+PiAyNCAgICAgICxcbiAgICAgICAgdGhpcy5oaSAgICAgICAgJiAyNTUsXG4gICAgICAgIHRoaXMuaGkgPj4+IDggICYgMjU1LFxuICAgICAgICB0aGlzLmhpID4+PiAxNiAmIDI1NSxcbiAgICAgICAgdGhpcy5oaSA+Pj4gMjRcbiAgICApO1xufTtcblxuLyoqXG4gKiBaaWctemFnIGVuY29kZXMgdGhpcyBsb25nIGJpdHMuXG4gKiBAcmV0dXJucyB7dXRpbC5Mb25nQml0c30gYHRoaXNgXG4gKi9cbkxvbmdCaXRzLnByb3RvdHlwZS56ekVuY29kZSA9IGZ1bmN0aW9uIHp6RW5jb2RlKCkge1xuICAgIHZhciBtYXNrID0gICB0aGlzLmhpID4+IDMxO1xuICAgIHRoaXMuaGkgID0gKCh0aGlzLmhpIDw8IDEgfCB0aGlzLmxvID4+PiAzMSkgXiBtYXNrKSA+Pj4gMDtcbiAgICB0aGlzLmxvICA9ICggdGhpcy5sbyA8PCAxICAgICAgICAgICAgICAgICAgIF4gbWFzaykgPj4+IDA7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFppZy16YWcgZGVjb2RlcyB0aGlzIGxvbmcgYml0cy5cbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBgdGhpc2BcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLnp6RGVjb2RlID0gZnVuY3Rpb24genpEZWNvZGUoKSB7XG4gICAgdmFyIG1hc2sgPSAtKHRoaXMubG8gJiAxKTtcbiAgICB0aGlzLmxvICA9ICgodGhpcy5sbyA+Pj4gMSB8IHRoaXMuaGkgPDwgMzEpIF4gbWFzaykgPj4+IDA7XG4gICAgdGhpcy5oaSAgPSAoIHRoaXMuaGkgPj4+IDEgICAgICAgICAgICAgICAgICBeIG1hc2spID4+PiAwO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBsZW5ndGggb2YgdGhpcyBsb25nYml0cyB3aGVuIGVuY29kZWQgYXMgYSB2YXJpbnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBMZW5ndGhcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLmxlbmd0aCA9IGZ1bmN0aW9uIGxlbmd0aCgpIHtcbiAgICB2YXIgcGFydDAgPSAgdGhpcy5sbyxcbiAgICAgICAgcGFydDEgPSAodGhpcy5sbyA+Pj4gMjggfCB0aGlzLmhpIDw8IDQpID4+PiAwLFxuICAgICAgICBwYXJ0MiA9ICB0aGlzLmhpID4+PiAyNDtcbiAgICByZXR1cm4gcGFydDIgPT09IDBcbiAgICAgICAgID8gcGFydDEgPT09IDBcbiAgICAgICAgICAgPyBwYXJ0MCA8IDE2Mzg0XG4gICAgICAgICAgICAgPyBwYXJ0MCA8IDEyOCA/IDEgOiAyXG4gICAgICAgICAgICAgOiBwYXJ0MCA8IDIwOTcxNTIgPyAzIDogNFxuICAgICAgICAgICA6IHBhcnQxIDwgMTYzODRcbiAgICAgICAgICAgICA/IHBhcnQxIDwgMTI4ID8gNSA6IDZcbiAgICAgICAgICAgICA6IHBhcnQxIDwgMjA5NzE1MiA/IDcgOiA4XG4gICAgICAgICA6IHBhcnQyIDwgMTI4ID8gOSA6IDEwO1xufTtcbiIsICIvLyBHRU5FUkFURUQgRklMRS4gRE8gTk9UIEVESVQuXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICBmdW5jdGlvbiBwcmVmZXJEZWZhdWx0KGV4cG9ydHMpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5kZWZhdWx0IHx8IGV4cG9ydHM7XG4gIH1cbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgZGVmaW5lKFtdLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgZXhwb3J0cyA9IHt9O1xuICAgICAgZmFjdG9yeShleHBvcnRzKTtcbiAgICAgIHJldHVybiBwcmVmZXJEZWZhdWx0KGV4cG9ydHMpO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG4gICAgZmFjdG9yeShleHBvcnRzKTtcbiAgICBpZiAodHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikgbW9kdWxlLmV4cG9ydHMgPSBwcmVmZXJEZWZhdWx0KGV4cG9ydHMpO1xuICB9IGVsc2Uge1xuICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgZXhwb3J0cyA9IHt9O1xuICAgICAgZmFjdG9yeShleHBvcnRzKTtcbiAgICAgIGdsb2JhbC5Mb25nID0gcHJlZmVyRGVmYXVsdChleHBvcnRzKTtcbiAgICB9KSgpO1xuICB9XG59KShcbiAgdHlwZW9mIGdsb2JhbFRoaXMgIT09IFwidW5kZWZpbmVkXCJcbiAgICA/IGdsb2JhbFRoaXNcbiAgICA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICA/IHNlbGZcbiAgICAgIDogdGhpcyxcbiAgZnVuY3Rpb24gKF9leHBvcnRzKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoX2V4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gICAgICB2YWx1ZTogdHJ1ZSxcbiAgICB9KTtcbiAgICBfZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuICAgIC8qKlxuICAgICAqIEBsaWNlbnNlXG4gICAgICogQ29weXJpZ2h0IDIwMDkgVGhlIENsb3N1cmUgTGlicmFyeSBBdXRob3JzXG4gICAgICogQ29weXJpZ2h0IDIwMjAgRGFuaWVsIFdpcnR6IC8gVGhlIGxvbmcuanMgQXV0aG9ycy5cbiAgICAgKlxuICAgICAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gICAgICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICAgICAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgICAqXG4gICAgICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICAgICAqXG4gICAgICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICAgICAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAgICAgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAgICAgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gICAgICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gICAgICpcbiAgICAgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICAgICAqL1xuXG4gICAgLy8gV2ViQXNzZW1ibHkgb3B0aW1pemF0aW9ucyB0byBkbyBuYXRpdmUgaTY0IG11bHRpcGxpY2F0aW9uIGFuZCBkaXZpZGVcbiAgICB2YXIgd2FzbSA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIHdhc20gPSBuZXcgV2ViQXNzZW1ibHkuSW5zdGFuY2UoXG4gICAgICAgIG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUoXG4gICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoW1xuICAgICAgICAgICAgLy8gXFwwYXNtXG4gICAgICAgICAgICAwLCA5NywgMTE1LCAxMDksXG4gICAgICAgICAgICAvLyB2ZXJzaW9uIDFcbiAgICAgICAgICAgIDEsIDAsIDAsIDAsXG4gICAgICAgICAgICAvLyBzZWN0aW9uIFwidHlwZVwiXG4gICAgICAgICAgICAxLCAxMywgMixcbiAgICAgICAgICAgIC8vIDAsICgpID0+IGkzMlxuICAgICAgICAgICAgOTYsIDAsIDEsIDEyNyxcbiAgICAgICAgICAgIC8vIDEsIChpMzIsIGkzMiwgaTMyLCBpMzIpID0+IGkzMlxuICAgICAgICAgICAgOTYsIDQsIDEyNywgMTI3LCAxMjcsIDEyNywgMSwgMTI3LFxuICAgICAgICAgICAgLy8gc2VjdGlvbiBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgIDMsIDcsIDYsXG4gICAgICAgICAgICAvLyAwLCB0eXBlIDBcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICAvLyAxLCB0eXBlIDFcbiAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAvLyAyLCB0eXBlIDFcbiAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAvLyAzLCB0eXBlIDFcbiAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAvLyA0LCB0eXBlIDFcbiAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAvLyA1LCB0eXBlIDFcbiAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAvLyBzZWN0aW9uIFwiZ2xvYmFsXCJcbiAgICAgICAgICAgIDYsIDYsIDEsXG4gICAgICAgICAgICAvLyAwLCBcImhpZ2hcIiwgbXV0YWJsZSBpMzJcbiAgICAgICAgICAgIDEyNywgMSwgNjUsIDAsIDExLFxuICAgICAgICAgICAgLy8gc2VjdGlvbiBcImV4cG9ydFwiXG4gICAgICAgICAgICA3LCA1MCwgNixcbiAgICAgICAgICAgIC8vIDAsIFwibXVsXCJcbiAgICAgICAgICAgIDMsIDEwOSwgMTE3LCAxMDgsIDAsIDEsXG4gICAgICAgICAgICAvLyAxLCBcImRpdl9zXCJcbiAgICAgICAgICAgIDUsIDEwMCwgMTA1LCAxMTgsIDk1LCAxMTUsIDAsIDIsXG4gICAgICAgICAgICAvLyAyLCBcImRpdl91XCJcbiAgICAgICAgICAgIDUsIDEwMCwgMTA1LCAxMTgsIDk1LCAxMTcsIDAsIDMsXG4gICAgICAgICAgICAvLyAzLCBcInJlbV9zXCJcbiAgICAgICAgICAgIDUsIDExNCwgMTAxLCAxMDksIDk1LCAxMTUsIDAsIDQsXG4gICAgICAgICAgICAvLyA0LCBcInJlbV91XCJcbiAgICAgICAgICAgIDUsIDExNCwgMTAxLCAxMDksIDk1LCAxMTcsIDAsIDUsXG4gICAgICAgICAgICAvLyA1LCBcImdldF9oaWdoXCJcbiAgICAgICAgICAgIDgsIDEwMywgMTAxLCAxMTYsIDk1LCAxMDQsIDEwNSwgMTAzLCAxMDQsIDAsIDAsXG4gICAgICAgICAgICAvLyBzZWN0aW9uIFwiY29kZVwiXG4gICAgICAgICAgICAxMCwgMTkxLCAxLCA2LFxuICAgICAgICAgICAgLy8gMCwgXCJnZXRfaGlnaFwiXG4gICAgICAgICAgICA0LCAwLCAzNSwgMCwgMTEsXG4gICAgICAgICAgICAvLyAxLCBcIm11bFwiXG4gICAgICAgICAgICAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLFxuICAgICAgICAgICAgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI2LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsXG4gICAgICAgICAgICAzMiwgNCwgMTY3LCAxMSxcbiAgICAgICAgICAgIC8vIDIsIFwiZGl2X3NcIlxuICAgICAgICAgICAgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MyxcbiAgICAgICAgICAgIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyNywgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLFxuICAgICAgICAgICAgMzIsIDQsIDE2NywgMTEsXG4gICAgICAgICAgICAvLyAzLCBcImRpdl91XCJcbiAgICAgICAgICAgIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsXG4gICAgICAgICAgICAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjgsIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCxcbiAgICAgICAgICAgIDMyLCA0LCAxNjcsIDExLFxuICAgICAgICAgICAgLy8gNCwgXCJyZW1fc1wiXG4gICAgICAgICAgICAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLFxuICAgICAgICAgICAgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI5LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsXG4gICAgICAgICAgICAzMiwgNCwgMTY3LCAxMSxcbiAgICAgICAgICAgIC8vIDUsIFwicmVtX3VcIlxuICAgICAgICAgICAgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MyxcbiAgICAgICAgICAgIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEzMCwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLFxuICAgICAgICAgICAgMzIsIDQsIDE2NywgMTEsXG4gICAgICAgICAgXSksXG4gICAgICAgICksXG4gICAgICAgIHt9LFxuICAgICAgKS5leHBvcnRzO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gbm8gd2FzbSBzdXBwb3J0IDooXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIsIGdpdmVuIGl0cyBsb3cgYW5kIGhpZ2ggMzIgYml0IHZhbHVlcyBhcyAqc2lnbmVkKiBpbnRlZ2Vycy5cbiAgICAgKiAgU2VlIHRoZSBmcm9tKiBmdW5jdGlvbnMgYmVsb3cgZm9yIG1vcmUgY29udmVuaWVudCB3YXlzIG9mIGNvbnN0cnVjdGluZyBMb25ncy5cbiAgICAgKiBAZXhwb3J0cyBMb25nXG4gICAgICogQGNsYXNzIEEgTG9uZyBjbGFzcyBmb3IgcmVwcmVzZW50aW5nIGEgNjQgYml0IHR3bydzLWNvbXBsZW1lbnQgaW50ZWdlciB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93IFRoZSBsb3cgKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoIFRoZSBoaWdoIChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgZnVuY3Rpb24gTG9uZyhsb3csIGhpZ2gsIHVuc2lnbmVkKSB7XG4gICAgICAvKipcbiAgICAgICAqIFRoZSBsb3cgMzIgYml0cyBhcyBhIHNpZ25lZCB2YWx1ZS5cbiAgICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICAgKi9cbiAgICAgIHRoaXMubG93ID0gbG93IHwgMDtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgaGlnaCAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxuICAgICAgICogQHR5cGUge251bWJlcn1cbiAgICAgICAqL1xuICAgICAgdGhpcy5oaWdoID0gaGlnaCB8IDA7XG5cbiAgICAgIC8qKlxuICAgICAgICogV2hldGhlciB1bnNpZ25lZCBvciBub3QuXG4gICAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgICAqL1xuICAgICAgdGhpcy51bnNpZ25lZCA9ICEhdW5zaWduZWQ7XG4gICAgfVxuXG4gICAgLy8gVGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIGEgbG9uZyBpcyB0aGUgdHdvIGdpdmVuIHNpZ25lZCwgMzItYml0IHZhbHVlcy5cbiAgICAvLyBXZSB1c2UgMzItYml0IHBpZWNlcyBiZWNhdXNlIHRoZXNlIGFyZSB0aGUgc2l6ZSBvZiBpbnRlZ2VycyBvbiB3aGljaFxuICAgIC8vIEphdmFzY3JpcHQgcGVyZm9ybXMgYml0LW9wZXJhdGlvbnMuICBGb3Igb3BlcmF0aW9ucyBsaWtlIGFkZGl0aW9uIGFuZFxuICAgIC8vIG11bHRpcGxpY2F0aW9uLCB3ZSBzcGxpdCBlYWNoIG51bWJlciBpbnRvIDE2IGJpdCBwaWVjZXMsIHdoaWNoIGNhbiBlYXNpbHkgYmVcbiAgICAvLyBtdWx0aXBsaWVkIHdpdGhpbiBKYXZhc2NyaXB0J3MgZmxvYXRpbmctcG9pbnQgcmVwcmVzZW50YXRpb24gd2l0aG91dCBvdmVyZmxvd1xuICAgIC8vIG9yIGNoYW5nZSBpbiBzaWduLlxuICAgIC8vXG4gICAgLy8gSW4gdGhlIGFsZ29yaXRobXMgYmVsb3csIHdlIGZyZXF1ZW50bHkgcmVkdWNlIHRoZSBuZWdhdGl2ZSBjYXNlIHRvIHRoZVxuICAgIC8vIHBvc2l0aXZlIGNhc2UgYnkgbmVnYXRpbmcgdGhlIGlucHV0KHMpIGFuZCB0aGVuIHBvc3QtcHJvY2Vzc2luZyB0aGUgcmVzdWx0LlxuICAgIC8vIE5vdGUgdGhhdCB3ZSBtdXN0IEFMV0FZUyBjaGVjayBzcGVjaWFsbHkgd2hldGhlciB0aG9zZSB2YWx1ZXMgYXJlIE1JTl9WQUxVRVxuICAgIC8vICgtMl42MykgYmVjYXVzZSAtTUlOX1ZBTFVFID09IE1JTl9WQUxVRSAoc2luY2UgMl42MyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgYXNcbiAgICAvLyBhIHBvc2l0aXZlIG51bWJlciwgaXQgb3ZlcmZsb3dzIGJhY2sgaW50byBhIG5lZ2F0aXZlKS4gIE5vdCBoYW5kbGluZyB0aGlzXG4gICAgLy8gY2FzZSB3b3VsZCBvZnRlbiByZXN1bHQgaW4gaW5maW5pdGUgcmVjdXJzaW9uLlxuICAgIC8vXG4gICAgLy8gQ29tbW9uIGNvbnN0YW50IHZhbHVlcyBaRVJPLCBPTkUsIE5FR19PTkUsIGV0Yy4gYXJlIGRlZmluZWQgYmVsb3cgdGhlIGZyb20qXG4gICAgLy8gbWV0aG9kcyBvbiB3aGljaCB0aGV5IGRlcGVuZC5cblxuICAgIC8qKlxuICAgICAqIEFuIGluZGljYXRvciB1c2VkIHRvIHJlbGlhYmx5IGRldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBMb25nIG9yIG5vdC5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAY29uc3RcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIExvbmcucHJvdG90eXBlLl9faXNMb25nX187XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KExvbmcucHJvdG90eXBlLCBcIl9faXNMb25nX19cIiwge1xuICAgICAgdmFsdWU6IHRydWUsXG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyp9IG9iaiBPYmplY3RcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0xvbmcob2JqKSB7XG4gICAgICByZXR1cm4gKG9iaiAmJiBvYmpbXCJfX2lzTG9uZ19fXCJdKSA9PT0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIG51bWJlclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAgICogQGlubmVyXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3R6MzIodmFsdWUpIHtcbiAgICAgIHZhciBjID0gTWF0aC5jbHozMih2YWx1ZSAmIC12YWx1ZSk7XG4gICAgICByZXR1cm4gdmFsdWUgPyAzMSAtIGMgOiBjO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGEgTG9uZy5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyp9IG9iaiBPYmplY3RcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nLmlzTG9uZyA9IGlzTG9uZztcblxuICAgIC8qKlxuICAgICAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIGludGVnZXIgdmFsdWVzLlxuICAgICAqIEB0eXBlIHshT2JqZWN0fVxuICAgICAqIEBpbm5lclxuICAgICAqL1xuICAgIHZhciBJTlRfQ0FDSEUgPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLlxuICAgICAqIEB0eXBlIHshT2JqZWN0fVxuICAgICAqIEBpbm5lclxuICAgICAqL1xuICAgIHZhciBVSU5UX0NBQ0hFID0ge307XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmcm9tSW50KHZhbHVlLCB1bnNpZ25lZCkge1xuICAgICAgdmFyIG9iaiwgY2FjaGVkT2JqLCBjYWNoZTtcbiAgICAgIGlmICh1bnNpZ25lZCkge1xuICAgICAgICB2YWx1ZSA+Pj49IDA7XG4gICAgICAgIGlmICgoY2FjaGUgPSAwIDw9IHZhbHVlICYmIHZhbHVlIDwgMjU2KSkge1xuICAgICAgICAgIGNhY2hlZE9iaiA9IFVJTlRfQ0FDSEVbdmFsdWVdO1xuICAgICAgICAgIGlmIChjYWNoZWRPYmopIHJldHVybiBjYWNoZWRPYmo7XG4gICAgICAgIH1cbiAgICAgICAgb2JqID0gZnJvbUJpdHModmFsdWUsIDAsIHRydWUpO1xuICAgICAgICBpZiAoY2FjaGUpIFVJTlRfQ0FDSEVbdmFsdWVdID0gb2JqO1xuICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgfD0gMDtcbiAgICAgICAgaWYgKChjYWNoZSA9IC0xMjggPD0gdmFsdWUgJiYgdmFsdWUgPCAxMjgpKSB7XG4gICAgICAgICAgY2FjaGVkT2JqID0gSU5UX0NBQ0hFW3ZhbHVlXTtcbiAgICAgICAgICBpZiAoY2FjaGVkT2JqKSByZXR1cm4gY2FjaGVkT2JqO1xuICAgICAgICB9XG4gICAgICAgIG9iaiA9IGZyb21CaXRzKHZhbHVlLCB2YWx1ZSA8IDAgPyAtMSA6IDAsIGZhbHNlKTtcbiAgICAgICAgaWYgKGNhY2hlKSBJTlRfQ0FDSEVbdmFsdWVdID0gb2JqO1xuICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gMzIgYml0IGludGVnZXIgdmFsdWUuXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSAzMiBiaXQgaW50ZWdlciBpbiBxdWVzdGlvblxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAgICAgKi9cbiAgICBMb25nLmZyb21JbnQgPSBmcm9tSW50O1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XG4gICAgICogQGlubmVyXG4gICAgICovXG4gICAgZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSwgdW5zaWduZWQpIHtcbiAgICAgIGlmIChpc05hTih2YWx1ZSkpIHJldHVybiB1bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgICAgIGlmICh1bnNpZ25lZCkge1xuICAgICAgICBpZiAodmFsdWUgPCAwKSByZXR1cm4gVVpFUk87XG4gICAgICAgIGlmICh2YWx1ZSA+PSBUV09fUFdSXzY0X0RCTCkgcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh2YWx1ZSA8PSAtVFdPX1BXUl82M19EQkwpIHJldHVybiBNSU5fVkFMVUU7XG4gICAgICAgIGlmICh2YWx1ZSArIDEgPj0gVFdPX1BXUl82M19EQkwpIHJldHVybiBNQVhfVkFMVUU7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgPCAwKSByZXR1cm4gZnJvbU51bWJlcigtdmFsdWUsIHVuc2lnbmVkKS5uZWcoKTtcbiAgICAgIHJldHVybiBmcm9tQml0cyhcbiAgICAgICAgdmFsdWUgJSBUV09fUFdSXzMyX0RCTCB8IDAsXG4gICAgICAgICh2YWx1ZSAvIFRXT19QV1JfMzJfREJMKSB8IDAsXG4gICAgICAgIHVuc2lnbmVkLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHZhbHVlLCBwcm92aWRlZCB0aGF0IGl0IGlzIGEgZmluaXRlIG51bWJlci4gT3RoZXJ3aXNlLCB6ZXJvIGlzIHJldHVybmVkLlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgbnVtYmVyIGluIHF1ZXN0aW9uXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICAgICAqL1xuICAgIExvbmcuZnJvbU51bWJlciA9IGZyb21OdW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93Qml0c1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoQml0c1xuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXG4gICAgICogQHJldHVybnMgeyFMb25nfVxuICAgICAqIEBpbm5lclxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZyb21CaXRzKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCkge1xuICAgICAgcmV0dXJuIG5ldyBMb25nKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSA2NCBiaXQgaW50ZWdlciB0aGF0IGNvbWVzIGJ5IGNvbmNhdGVuYXRpbmcgdGhlIGdpdmVuIGxvdyBhbmQgaGlnaCBiaXRzLiBFYWNoIGlzXG4gICAgICogIGFzc3VtZWQgdG8gdXNlIDMyIGJpdHMuXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHMgVGhlIGxvdyAzMiBiaXRzXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzIFRoZSBoaWdoIDMyIGJpdHNcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gICAgICovXG4gICAgTG9uZy5mcm9tQml0cyA9IGZyb21CaXRzO1xuXG4gICAgLyoqXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJhc2VcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZXhwb25lbnRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgICAqIEBpbm5lclxuICAgICAqL1xuICAgIHZhciBwb3dfZGJsID0gTWF0aC5wb3c7IC8vIFVzZWQgNCB0aW1lcyAoNCo4IHRvIDE1KzQpXG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gICAgICogQHBhcmFtIHsoYm9vbGVhbnxudW1iZXIpPX0gdW5zaWduZWRcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IHJhZGl4XG4gICAgICogQHJldHVybnMgeyFMb25nfVxuICAgICAqIEBpbm5lclxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZyb21TdHJpbmcoc3RyLCB1bnNpZ25lZCwgcmFkaXgpIHtcbiAgICAgIGlmIChzdHIubGVuZ3RoID09PSAwKSB0aHJvdyBFcnJvcihcImVtcHR5IHN0cmluZ1wiKTtcbiAgICAgIGlmICh0eXBlb2YgdW5zaWduZWQgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgLy8gRm9yIGdvb2cubWF0aC5sb25nIGNvbXBhdGliaWxpdHlcbiAgICAgICAgcmFkaXggPSB1bnNpZ25lZDtcbiAgICAgICAgdW5zaWduZWQgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVuc2lnbmVkID0gISF1bnNpZ25lZDtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgc3RyID09PSBcIk5hTlwiIHx8XG4gICAgICAgIHN0ciA9PT0gXCJJbmZpbml0eVwiIHx8XG4gICAgICAgIHN0ciA9PT0gXCIrSW5maW5pdHlcIiB8fFxuICAgICAgICBzdHIgPT09IFwiLUluZmluaXR5XCJcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIHVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xuICAgICAgcmFkaXggPSByYWRpeCB8fCAxMDtcbiAgICAgIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeCkgdGhyb3cgUmFuZ2VFcnJvcihcInJhZGl4XCIpO1xuICAgICAgdmFyIHA7XG4gICAgICBpZiAoKHAgPSBzdHIuaW5kZXhPZihcIi1cIikpID4gMCkgdGhyb3cgRXJyb3IoXCJpbnRlcmlvciBoeXBoZW5cIik7XG4gICAgICBlbHNlIGlmIChwID09PSAwKSB7XG4gICAgICAgIHJldHVybiBmcm9tU3RyaW5nKHN0ci5zdWJzdHJpbmcoMSksIHVuc2lnbmVkLCByYWRpeCkubmVnKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIERvIHNldmVyYWwgKDgpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cbiAgICAgIC8vIG1pbmltaXplIHRoZSBjYWxscyB0byB0aGUgdmVyeSBleHBlbnNpdmUgZW11bGF0ZWQgZGl2LlxuICAgICAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgOCkpO1xuICAgICAgdmFyIHJlc3VsdCA9IFpFUk87XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkgKz0gOCkge1xuICAgICAgICB2YXIgc2l6ZSA9IE1hdGgubWluKDgsIHN0ci5sZW5ndGggLSBpKSxcbiAgICAgICAgICB2YWx1ZSA9IHBhcnNlSW50KHN0ci5zdWJzdHJpbmcoaSwgaSArIHNpemUpLCByYWRpeCk7XG4gICAgICAgIGlmIChzaXplIDwgOCkge1xuICAgICAgICAgIHZhciBwb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgc2l6ZSkpO1xuICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5tdWwocG93ZXIpLmFkZChmcm9tTnVtYmVyKHZhbHVlKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChyYWRpeFRvUG93ZXIpO1xuICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXN1bHQudW5zaWduZWQgPSB1bnNpZ25lZDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIHN0cmluZywgd3JpdHRlbiB1c2luZyB0aGUgc3BlY2lmaWVkIHJhZGl4LlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIExvbmdcbiAgICAgKiBAcGFyYW0geyhib29sZWFufG51bWJlcik9fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSByYWRpeCBUaGUgcmFkaXggaW4gd2hpY2ggdGhlIHRleHQgaXMgd3JpdHRlbiAoMi0zNiksIGRlZmF1bHRzIHRvIDEwXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gICAgICovXG4gICAgTG9uZy5mcm9tU3RyaW5nID0gZnJvbVN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XG4gICAgICogQGlubmVyXG4gICAgICovXG4gICAgZnVuY3Rpb24gZnJvbVZhbHVlKHZhbCwgdW5zaWduZWQpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsID09PSBcIm51bWJlclwiKSByZXR1cm4gZnJvbU51bWJlcih2YWwsIHVuc2lnbmVkKTtcbiAgICAgIGlmICh0eXBlb2YgdmFsID09PSBcInN0cmluZ1wiKSByZXR1cm4gZnJvbVN0cmluZyh2YWwsIHVuc2lnbmVkKTtcbiAgICAgIC8vIFRocm93cyBmb3Igbm9uLW9iamVjdHMsIGNvbnZlcnRzIG5vbi1pbnN0YW5jZW9mIExvbmc6XG4gICAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICAgIHZhbC5sb3csXG4gICAgICAgIHZhbC5oaWdoLFxuICAgICAgICB0eXBlb2YgdW5zaWduZWQgPT09IFwiYm9vbGVhblwiID8gdW5zaWduZWQgOiB2YWwudW5zaWduZWQsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgdmFsdWUgdG8gYSBMb25nIHVzaW5nIHRoZSBhcHByb3ByaWF0ZSBmcm9tKiBmdW5jdGlvbiBmb3IgaXRzIHR5cGUuXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsIFZhbHVlXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cbiAgICAgKi9cbiAgICBMb25nLmZyb21WYWx1ZSA9IGZyb21WYWx1ZTtcblxuICAgIC8vIE5PVEU6IHRoZSBjb21waWxlciBzaG91bGQgaW5saW5lIHRoZXNlIGNvbnN0YW50IHZhbHVlcyBiZWxvdyBhbmQgdGhlbiByZW1vdmUgdGhlc2UgdmFyaWFibGVzLCBzbyB0aGVyZSBzaG91bGQgYmVcbiAgICAvLyBubyBydW50aW1lIHBlbmFsdHkgZm9yIHRoZXNlLlxuXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAY29uc3RcbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICB2YXIgVFdPX1BXUl8xNl9EQkwgPSAxIDw8IDE2O1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAY29uc3RcbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICB2YXIgVFdPX1BXUl8yNF9EQkwgPSAxIDw8IDI0O1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAY29uc3RcbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICB2YXIgVFdPX1BXUl8zMl9EQkwgPSBUV09fUFdSXzE2X0RCTCAqIFRXT19QV1JfMTZfREJMO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAY29uc3RcbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICB2YXIgVFdPX1BXUl82NF9EQkwgPSBUV09fUFdSXzMyX0RCTCAqIFRXT19QV1JfMzJfREJMO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAY29uc3RcbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICB2YXIgVFdPX1BXUl82M19EQkwgPSBUV09fUFdSXzY0X0RCTCAvIDI7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IUxvbmd9XG4gICAgICogQGNvbnN0XG4gICAgICogQGlubmVyXG4gICAgICovXG4gICAgdmFyIFRXT19QV1JfMjQgPSBmcm9tSW50KFRXT19QV1JfMjRfREJMKTtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHshTG9uZ31cbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICB2YXIgWkVSTyA9IGZyb21JbnQoMCk7XG5cbiAgICAvKipcbiAgICAgKiBTaWduZWQgemVyby5cbiAgICAgKiBAdHlwZSB7IUxvbmd9XG4gICAgICovXG4gICAgTG9uZy5aRVJPID0gWkVSTztcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHshTG9uZ31cbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICB2YXIgVVpFUk8gPSBmcm9tSW50KDAsIHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVW5zaWduZWQgemVyby5cbiAgICAgKiBAdHlwZSB7IUxvbmd9XG4gICAgICovXG4gICAgTG9uZy5VWkVSTyA9IFVaRVJPO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFMb25nfVxuICAgICAqIEBpbm5lclxuICAgICAqL1xuICAgIHZhciBPTkUgPSBmcm9tSW50KDEpO1xuXG4gICAgLyoqXG4gICAgICogU2lnbmVkIG9uZS5cbiAgICAgKiBAdHlwZSB7IUxvbmd9XG4gICAgICovXG4gICAgTG9uZy5PTkUgPSBPTkU7XG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IUxvbmd9XG4gICAgICogQGlubmVyXG4gICAgICovXG4gICAgdmFyIFVPTkUgPSBmcm9tSW50KDEsIHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVW5zaWduZWQgb25lLlxuICAgICAqIEB0eXBlIHshTG9uZ31cbiAgICAgKi9cbiAgICBMb25nLlVPTkUgPSBVT05FO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFMb25nfVxuICAgICAqIEBpbm5lclxuICAgICAqL1xuICAgIHZhciBORUdfT05FID0gZnJvbUludCgtMSk7XG5cbiAgICAvKipcbiAgICAgKiBTaWduZWQgbmVnYXRpdmUgb25lLlxuICAgICAqIEB0eXBlIHshTG9uZ31cbiAgICAgKi9cbiAgICBMb25nLk5FR19PTkUgPSBORUdfT05FO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFMb25nfVxuICAgICAqIEBpbm5lclxuICAgICAqL1xuICAgIHZhciBNQVhfVkFMVUUgPSBmcm9tQml0cygweGZmZmZmZmZmIHwgMCwgMHg3ZmZmZmZmZiB8IDAsIGZhbHNlKTtcblxuICAgIC8qKlxuICAgICAqIE1heGltdW0gc2lnbmVkIHZhbHVlLlxuICAgICAqIEB0eXBlIHshTG9uZ31cbiAgICAgKi9cbiAgICBMb25nLk1BWF9WQUxVRSA9IE1BWF9WQUxVRTtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHshTG9uZ31cbiAgICAgKiBAaW5uZXJcbiAgICAgKi9cbiAgICB2YXIgTUFYX1VOU0lHTkVEX1ZBTFVFID0gZnJvbUJpdHMoMHhmZmZmZmZmZiB8IDAsIDB4ZmZmZmZmZmYgfCAwLCB0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIE1heGltdW0gdW5zaWduZWQgdmFsdWUuXG4gICAgICogQHR5cGUgeyFMb25nfVxuICAgICAqL1xuICAgIExvbmcuTUFYX1VOU0lHTkVEX1ZBTFVFID0gTUFYX1VOU0lHTkVEX1ZBTFVFO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFMb25nfVxuICAgICAqIEBpbm5lclxuICAgICAqL1xuICAgIHZhciBNSU5fVkFMVUUgPSBmcm9tQml0cygwLCAweDgwMDAwMDAwIHwgMCwgZmFsc2UpO1xuXG4gICAgLyoqXG4gICAgICogTWluaW11bSBzaWduZWQgdmFsdWUuXG4gICAgICogQHR5cGUgeyFMb25nfVxuICAgICAqL1xuICAgIExvbmcuTUlOX1ZBTFVFID0gTUlOX1ZBTFVFO1xuXG4gICAgLyoqXG4gICAgICogQGFsaWFzIExvbmcucHJvdG90eXBlXG4gICAgICogQGlubmVyXG4gICAgICovXG4gICAgdmFyIExvbmdQcm90b3R5cGUgPSBMb25nLnByb3RvdHlwZTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgMzIgYml0IGludGVnZXIsIGFzc3VtaW5nIGl0IGlzIGEgMzIgYml0IGludGVnZXIuXG4gICAgICogQHRoaXMgeyFMb25nfVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS50b0ludCA9IGZ1bmN0aW9uIHRvSW50KCkge1xuICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyB0aGlzLmxvdyA+Pj4gMCA6IHRoaXMubG93O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBhIHRoZSBuZWFyZXN0IGZsb2F0aW5nLXBvaW50IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgdmFsdWUgKGRvdWJsZSwgNTMgYml0IG1hbnRpc3NhKS5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMge251bWJlcn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIoKSB7XG4gICAgICBpZiAodGhpcy51bnNpZ25lZClcbiAgICAgICAgcmV0dXJuICh0aGlzLmhpZ2ggPj4+IDApICogVFdPX1BXUl8zMl9EQkwgKyAodGhpcy5sb3cgPj4+IDApO1xuICAgICAgcmV0dXJuIHRoaXMuaGlnaCAqIFRXT19QV1JfMzJfREJMICsgKHRoaXMubG93ID4+PiAwKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSBzdHJpbmcgd3JpdHRlbiBpbiB0aGUgc3BlY2lmaWVkIHJhZGl4LlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFJhZGl4ICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAqIEBvdmVycmlkZVxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGByYWRpeGAgaXMgb3V0IG9mIHJhbmdlXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKHJhZGl4KSB7XG4gICAgICByYWRpeCA9IHJhZGl4IHx8IDEwO1xuICAgICAgaWYgKHJhZGl4IDwgMiB8fCAzNiA8IHJhZGl4KSB0aHJvdyBSYW5nZUVycm9yKFwicmFkaXhcIik7XG4gICAgICBpZiAodGhpcy5pc1plcm8oKSkgcmV0dXJuIFwiMFwiO1xuICAgICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XG4gICAgICAgIC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxuICAgICAgICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKSB7XG4gICAgICAgICAgLy8gV2UgbmVlZCB0byBjaGFuZ2UgdGhlIExvbmcgdmFsdWUgYmVmb3JlIGl0IGNhbiBiZSBuZWdhdGVkLCBzbyB3ZSByZW1vdmVcbiAgICAgICAgICAvLyB0aGUgYm90dG9tLW1vc3QgZGlnaXQgaW4gdGhpcyBiYXNlIGFuZCB0aGVuIHJlY3Vyc2UgdG8gZG8gdGhlIHJlc3QuXG4gICAgICAgICAgdmFyIHJhZGl4TG9uZyA9IGZyb21OdW1iZXIocmFkaXgpLFxuICAgICAgICAgICAgZGl2ID0gdGhpcy5kaXYocmFkaXhMb25nKSxcbiAgICAgICAgICAgIHJlbTEgPSBkaXYubXVsKHJhZGl4TG9uZykuc3ViKHRoaXMpO1xuICAgICAgICAgIHJldHVybiBkaXYudG9TdHJpbmcocmFkaXgpICsgcmVtMS50b0ludCgpLnRvU3RyaW5nKHJhZGl4KTtcbiAgICAgICAgfSBlbHNlIHJldHVybiBcIi1cIiArIHRoaXMubmVnKCkudG9TdHJpbmcocmFkaXgpO1xuICAgICAgfVxuXG4gICAgICAvLyBEbyBzZXZlcmFsICg2KSBkaWdpdHMgZWFjaCB0aW1lIHRocm91Z2ggdGhlIGxvb3AsIHNvIGFzIHRvXG4gICAgICAvLyBtaW5pbWl6ZSB0aGUgY2FsbHMgdG8gdGhlIHZlcnkgZXhwZW5zaXZlIGVtdWxhdGVkIGRpdi5cbiAgICAgIHZhciByYWRpeFRvUG93ZXIgPSBmcm9tTnVtYmVyKHBvd19kYmwocmFkaXgsIDYpLCB0aGlzLnVuc2lnbmVkKSxcbiAgICAgICAgcmVtID0gdGhpcztcbiAgICAgIHZhciByZXN1bHQgPSBcIlwiO1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgdmFyIHJlbURpdiA9IHJlbS5kaXYocmFkaXhUb1Bvd2VyKSxcbiAgICAgICAgICBpbnR2YWwgPSByZW0uc3ViKHJlbURpdi5tdWwocmFkaXhUb1Bvd2VyKSkudG9JbnQoKSA+Pj4gMCxcbiAgICAgICAgICBkaWdpdHMgPSBpbnR2YWwudG9TdHJpbmcocmFkaXgpO1xuICAgICAgICByZW0gPSByZW1EaXY7XG4gICAgICAgIGlmIChyZW0uaXNaZXJvKCkpIHJldHVybiBkaWdpdHMgKyByZXN1bHQ7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHdoaWxlIChkaWdpdHMubGVuZ3RoIDwgNikgZGlnaXRzID0gXCIwXCIgKyBkaWdpdHM7XG4gICAgICAgICAgcmVzdWx0ID0gXCJcIiArIGRpZ2l0cyArIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMge251bWJlcn0gU2lnbmVkIGhpZ2ggYml0c1xuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUuZ2V0SGlnaEJpdHMgPSBmdW5jdGlvbiBnZXRIaWdoQml0cygpIHtcbiAgICAgIHJldHVybiB0aGlzLmhpZ2g7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGhpZ2ggMzIgYml0cyBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBoaWdoIGJpdHNcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmdldEhpZ2hCaXRzVW5zaWduZWQgPSBmdW5jdGlvbiBnZXRIaWdoQml0c1Vuc2lnbmVkKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaGlnaCA+Pj4gMDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMge251bWJlcn0gU2lnbmVkIGxvdyBiaXRzXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzID0gZnVuY3Rpb24gZ2V0TG93Qml0cygpIHtcbiAgICAgIHJldHVybiB0aGlzLmxvdztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgbG93IGJpdHNcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmdldExvd0JpdHNVbnNpZ25lZCA9IGZ1bmN0aW9uIGdldExvd0JpdHNVbnNpZ25lZCgpIHtcbiAgICAgIHJldHVybiB0aGlzLmxvdyA+Pj4gMDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGJpdHMgbmVlZGVkIHRvIHJlcHJlc2VudCB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhpcyBMb25nLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUuZ2V0TnVtQml0c0FicyA9IGZ1bmN0aW9uIGdldE51bUJpdHNBYnMoKSB7XG4gICAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpXG4gICAgICAgIC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxuICAgICAgICByZXR1cm4gdGhpcy5lcShNSU5fVkFMVUUpID8gNjQgOiB0aGlzLm5lZygpLmdldE51bUJpdHNBYnMoKTtcbiAgICAgIHZhciB2YWwgPSB0aGlzLmhpZ2ggIT0gMCA/IHRoaXMuaGlnaCA6IHRoaXMubG93O1xuICAgICAgZm9yICh2YXIgYml0ID0gMzE7IGJpdCA+IDA7IGJpdC0tKSBpZiAoKHZhbCAmICgxIDw8IGJpdCkpICE9IDApIGJyZWFrO1xuICAgICAgcmV0dXJuIHRoaXMuaGlnaCAhPSAwID8gYml0ICsgMzMgOiBiaXQgKyAxO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcgY2FuIGJlIHNhZmVseSByZXByZXNlbnRlZCBhcyBhIEphdmFTY3JpcHQgbnVtYmVyLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmlzU2FmZUludGVnZXIgPSBmdW5jdGlvbiBpc1NhZmVJbnRlZ2VyKCkge1xuICAgICAgLy8gMl41My0xIGlzIHRoZSBtYXhpbXVtIHNhZmUgdmFsdWVcbiAgICAgIHZhciB0b3AxMUJpdHMgPSB0aGlzLmhpZ2ggPj4gMjE7XG4gICAgICAvLyBbMCwgMl41My0xXVxuICAgICAgaWYgKCF0b3AxMUJpdHMpIHJldHVybiB0cnVlO1xuICAgICAgLy8gPiAyXjUzLTFcbiAgICAgIGlmICh0aGlzLnVuc2lnbmVkKSByZXR1cm4gZmFsc2U7XG4gICAgICAvLyBbLTJeNTMsIC0xXSBleGNlcHQgLTJeNTNcbiAgICAgIHJldHVybiB0b3AxMUJpdHMgPT09IC0xICYmICEodGhpcy5sb3cgPT09IDAgJiYgdGhpcy5oaWdoID09PSAtMHgyMDAwMDApO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgemVyby5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5pc1plcm8gPSBmdW5jdGlvbiBpc1plcm8oKSB7XG4gICAgICByZXR1cm4gdGhpcy5oaWdoID09PSAwICYmIHRoaXMubG93ID09PSAwO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgemVyby4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNpc1plcm99LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUuZXF6ID0gTG9uZ1Byb3RvdHlwZS5pc1plcm87XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBuZWdhdGl2ZS5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5pc05lZ2F0aXZlID0gZnVuY3Rpb24gaXNOZWdhdGl2ZSgpIHtcbiAgICAgIHJldHVybiAhdGhpcy51bnNpZ25lZCAmJiB0aGlzLmhpZ2ggPCAwO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBwb3NpdGl2ZSBvciB6ZXJvLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmlzUG9zaXRpdmUgPSBmdW5jdGlvbiBpc1Bvc2l0aXZlKCkge1xuICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgfHwgdGhpcy5oaWdoID49IDA7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG9kZC5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5pc09kZCA9IGZ1bmN0aW9uIGlzT2RkKCkge1xuICAgICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAxO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBldmVuLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmlzRXZlbiA9IGZ1bmN0aW9uIGlzRXZlbigpIHtcbiAgICAgIHJldHVybiAodGhpcy5sb3cgJiAxKSA9PT0gMDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyhvdGhlcikge1xuICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKSBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMudW5zaWduZWQgIT09IG90aGVyLnVuc2lnbmVkICYmXG4gICAgICAgIHRoaXMuaGlnaCA+Pj4gMzEgPT09IDEgJiZcbiAgICAgICAgb3RoZXIuaGlnaCA+Pj4gMzEgPT09IDFcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHRoaXMuaGlnaCA9PT0gb3RoZXIuaGlnaCAmJiB0aGlzLmxvdyA9PT0gb3RoZXIubG93O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2VxdWFsc30uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmVxID0gTG9uZ1Byb3RvdHlwZS5lcXVhbHM7XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUubm90RXF1YWxzID0gZnVuY3Rpb24gbm90RXF1YWxzKG90aGVyKSB7XG4gICAgICByZXR1cm4gIXRoaXMuZXEoLyogdmFsaWRhdGVzICovIG90aGVyKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNub3RFcXVhbHN9LlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5uZXEgPSBMb25nUHJvdG90eXBlLm5vdEVxdWFscztcblxuICAgIC8qKlxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUubmUgPSBMb25nUHJvdG90eXBlLm5vdEVxdWFscztcblxuICAgIC8qKlxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuXG4gICAgICogQHRoaXMgeyFMb25nfVxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbiA9IGZ1bmN0aW9uIGxlc3NUaGFuKG90aGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPCAwO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFufS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUubHQgPSBMb25nUHJvdG90eXBlLmxlc3NUaGFuO1xuXG4gICAgLyoqXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbCA9IGZ1bmN0aW9uIGxlc3NUaGFuT3JFcXVhbChvdGhlcikge1xuICAgICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpIDw9IDA7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW5PckVxdWFsfS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUubHRlID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWw7XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFuT3JFcXVhbH0uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmxlID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWw7XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW4gPSBmdW5jdGlvbiBncmVhdGVyVGhhbihvdGhlcikge1xuICAgICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID4gMDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbn0uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmd0ID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbjtcblxuICAgIC8qKlxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuXG4gICAgICogQHRoaXMgeyFMb25nfVxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBncmVhdGVyVGhhbk9yRXF1YWwob3RoZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA+PSAwO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2dyZWF0ZXJUaGFuT3JFcXVhbH0uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmd0ZSA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsO1xuXG4gICAgLyoqXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbk9yRXF1YWx9LlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5nZSA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsO1xuXG4gICAgLyoqXG4gICAgICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuXG4gICAgICogQHRoaXMgeyFMb25nfVxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gICAgICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxuICAgICAqICBpZiB0aGUgZ2l2ZW4gb25lIGlzIGdyZWF0ZXJcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlKG90aGVyKSB7XG4gICAgICBpZiAoIWlzTG9uZyhvdGhlcikpIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcbiAgICAgIGlmICh0aGlzLmVxKG90aGVyKSkgcmV0dXJuIDA7XG4gICAgICB2YXIgdGhpc05lZyA9IHRoaXMuaXNOZWdhdGl2ZSgpLFxuICAgICAgICBvdGhlck5lZyA9IG90aGVyLmlzTmVnYXRpdmUoKTtcbiAgICAgIGlmICh0aGlzTmVnICYmICFvdGhlck5lZykgcmV0dXJuIC0xO1xuICAgICAgaWYgKCF0aGlzTmVnICYmIG90aGVyTmVnKSByZXR1cm4gMTtcbiAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHNpZ24gYml0cyBhcmUgdGhlIHNhbWVcbiAgICAgIGlmICghdGhpcy51bnNpZ25lZCkgcmV0dXJuIHRoaXMuc3ViKG90aGVyKS5pc05lZ2F0aXZlKCkgPyAtMSA6IDE7XG4gICAgICAvLyBCb3RoIGFyZSBwb3NpdGl2ZSBpZiBhdCBsZWFzdCBvbmUgaXMgdW5zaWduZWRcbiAgICAgIHJldHVybiBvdGhlci5oaWdoID4+PiAwID4gdGhpcy5oaWdoID4+PiAwIHx8XG4gICAgICAgIChvdGhlci5oaWdoID09PSB0aGlzLmhpZ2ggJiYgb3RoZXIubG93ID4+PiAwID4gdGhpcy5sb3cgPj4+IDApXG4gICAgICAgID8gLTFcbiAgICAgICAgOiAxO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb21wYXJlcyB0aGlzIExvbmcncyB2YWx1ZSB3aXRoIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNjb21wYXJlfS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcbiAgICAgKiAgaWYgdGhlIGdpdmVuIG9uZSBpcyBncmVhdGVyXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5jb21wID0gTG9uZ1Byb3RvdHlwZS5jb21wYXJlO1xuXG4gICAgLyoqXG4gICAgICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMgeyFMb25nfSBOZWdhdGVkIExvbmdcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLm5lZ2F0ZSA9IGZ1bmN0aW9uIG5lZ2F0ZSgpIHtcbiAgICAgIGlmICghdGhpcy51bnNpZ25lZCAmJiB0aGlzLmVxKE1JTl9WQUxVRSkpIHJldHVybiBNSU5fVkFMVUU7XG4gICAgICByZXR1cm4gdGhpcy5ub3QoKS5hZGQoT05FKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNuZWdhdGV9LlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5uZWcgPSBMb25nUHJvdG90eXBlLm5lZ2F0ZTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHN1bSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXG4gICAgICogQHRoaXMgeyFMb25nfVxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IGFkZGVuZCBBZGRlbmRcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFN1bVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkKGFkZGVuZCkge1xuICAgICAgaWYgKCFpc0xvbmcoYWRkZW5kKSkgYWRkZW5kID0gZnJvbVZhbHVlKGFkZGVuZCk7XG5cbiAgICAgIC8vIERpdmlkZSBlYWNoIG51bWJlciBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIHN1bSB0aGUgY2h1bmtzLlxuXG4gICAgICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcbiAgICAgIHZhciBhMzIgPSB0aGlzLmhpZ2ggJiAweGZmZmY7XG4gICAgICB2YXIgYTE2ID0gdGhpcy5sb3cgPj4+IDE2O1xuICAgICAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhmZmZmO1xuICAgICAgdmFyIGI0OCA9IGFkZGVuZC5oaWdoID4+PiAxNjtcbiAgICAgIHZhciBiMzIgPSBhZGRlbmQuaGlnaCAmIDB4ZmZmZjtcbiAgICAgIHZhciBiMTYgPSBhZGRlbmQubG93ID4+PiAxNjtcbiAgICAgIHZhciBiMDAgPSBhZGRlbmQubG93ICYgMHhmZmZmO1xuICAgICAgdmFyIGM0OCA9IDAsXG4gICAgICAgIGMzMiA9IDAsXG4gICAgICAgIGMxNiA9IDAsXG4gICAgICAgIGMwMCA9IDA7XG4gICAgICBjMDAgKz0gYTAwICsgYjAwO1xuICAgICAgYzE2ICs9IGMwMCA+Pj4gMTY7XG4gICAgICBjMDAgJj0gMHhmZmZmO1xuICAgICAgYzE2ICs9IGExNiArIGIxNjtcbiAgICAgIGMzMiArPSBjMTYgPj4+IDE2O1xuICAgICAgYzE2ICY9IDB4ZmZmZjtcbiAgICAgIGMzMiArPSBhMzIgKyBiMzI7XG4gICAgICBjNDggKz0gYzMyID4+PiAxNjtcbiAgICAgIGMzMiAmPSAweGZmZmY7XG4gICAgICBjNDggKz0gYTQ4ICsgYjQ4O1xuICAgICAgYzQ4ICY9IDB4ZmZmZjtcbiAgICAgIHJldHVybiBmcm9tQml0cygoYzE2IDw8IDE2KSB8IGMwMCwgKGM0OCA8PCAxNikgfCBjMzIsIHRoaXMudW5zaWduZWQpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gc3VidHJhaGVuZCBTdWJ0cmFoZW5kXG4gICAgICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdCA9IGZ1bmN0aW9uIHN1YnRyYWN0KHN1YnRyYWhlbmQpIHtcbiAgICAgIGlmICghaXNMb25nKHN1YnRyYWhlbmQpKSBzdWJ0cmFoZW5kID0gZnJvbVZhbHVlKHN1YnRyYWhlbmQpO1xuICAgICAgcmV0dXJuIHRoaXMuYWRkKHN1YnRyYWhlbmQubmVnKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzdWJ0cmFjdH0uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gc3VidHJhaGVuZCBTdWJ0cmFoZW5kXG4gICAgICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5zdWIgPSBMb25nUHJvdG90eXBlLnN1YnRyYWN0O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcHJvZHVjdCBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXG4gICAgICogQHRoaXMgeyFMb25nfVxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG11bHRpcGxpZXIgTXVsdGlwbGllclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUHJvZHVjdFxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUubXVsdGlwbHkgPSBmdW5jdGlvbiBtdWx0aXBseShtdWx0aXBsaWVyKSB7XG4gICAgICBpZiAodGhpcy5pc1plcm8oKSkgcmV0dXJuIHRoaXM7XG4gICAgICBpZiAoIWlzTG9uZyhtdWx0aXBsaWVyKSkgbXVsdGlwbGllciA9IGZyb21WYWx1ZShtdWx0aXBsaWVyKTtcblxuICAgICAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XG4gICAgICBpZiAod2FzbSkge1xuICAgICAgICB2YXIgbG93ID0gd2FzbVtcIm11bFwiXShcbiAgICAgICAgICB0aGlzLmxvdyxcbiAgICAgICAgICB0aGlzLmhpZ2gsXG4gICAgICAgICAgbXVsdGlwbGllci5sb3csXG4gICAgICAgICAgbXVsdGlwbGllci5oaWdoLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtW1wiZ2V0X2hpZ2hcIl0oKSwgdGhpcy51bnNpZ25lZCk7XG4gICAgICB9XG4gICAgICBpZiAobXVsdGlwbGllci5pc1plcm8oKSkgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gICAgICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKSByZXR1cm4gbXVsdGlwbGllci5pc09kZCgpID8gTUlOX1ZBTFVFIDogWkVSTztcbiAgICAgIGlmIChtdWx0aXBsaWVyLmVxKE1JTl9WQUxVRSkpIHJldHVybiB0aGlzLmlzT2RkKCkgPyBNSU5fVkFMVUUgOiBaRVJPO1xuICAgICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XG4gICAgICAgIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSkgcmV0dXJuIHRoaXMubmVnKCkubXVsKG11bHRpcGxpZXIubmVnKCkpO1xuICAgICAgICBlbHNlIHJldHVybiB0aGlzLm5lZygpLm11bChtdWx0aXBsaWVyKS5uZWcoKTtcbiAgICAgIH0gZWxzZSBpZiAobXVsdGlwbGllci5pc05lZ2F0aXZlKCkpXG4gICAgICAgIHJldHVybiB0aGlzLm11bChtdWx0aXBsaWVyLm5lZygpKS5uZWcoKTtcblxuICAgICAgLy8gSWYgYm90aCBsb25ncyBhcmUgc21hbGwsIHVzZSBmbG9hdCBtdWx0aXBsaWNhdGlvblxuICAgICAgaWYgKHRoaXMubHQoVFdPX1BXUl8yNCkgJiYgbXVsdGlwbGllci5sdChUV09fUFdSXzI0KSlcbiAgICAgICAgcmV0dXJuIGZyb21OdW1iZXIoXG4gICAgICAgICAgdGhpcy50b051bWJlcigpICogbXVsdGlwbGllci50b051bWJlcigpLFxuICAgICAgICAgIHRoaXMudW5zaWduZWQsXG4gICAgICAgICk7XG5cbiAgICAgIC8vIERpdmlkZSBlYWNoIGxvbmcgaW50byA0IGNodW5rcyBvZiAxNiBiaXRzLCBhbmQgdGhlbiBhZGQgdXAgNHg0IHByb2R1Y3RzLlxuICAgICAgLy8gV2UgY2FuIHNraXAgcHJvZHVjdHMgdGhhdCB3b3VsZCBvdmVyZmxvdy5cblxuICAgICAgdmFyIGE0OCA9IHRoaXMuaGlnaCA+Pj4gMTY7XG4gICAgICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhmZmZmO1xuICAgICAgdmFyIGExNiA9IHRoaXMubG93ID4+PiAxNjtcbiAgICAgIHZhciBhMDAgPSB0aGlzLmxvdyAmIDB4ZmZmZjtcbiAgICAgIHZhciBiNDggPSBtdWx0aXBsaWVyLmhpZ2ggPj4+IDE2O1xuICAgICAgdmFyIGIzMiA9IG11bHRpcGxpZXIuaGlnaCAmIDB4ZmZmZjtcbiAgICAgIHZhciBiMTYgPSBtdWx0aXBsaWVyLmxvdyA+Pj4gMTY7XG4gICAgICB2YXIgYjAwID0gbXVsdGlwbGllci5sb3cgJiAweGZmZmY7XG4gICAgICB2YXIgYzQ4ID0gMCxcbiAgICAgICAgYzMyID0gMCxcbiAgICAgICAgYzE2ID0gMCxcbiAgICAgICAgYzAwID0gMDtcbiAgICAgIGMwMCArPSBhMDAgKiBiMDA7XG4gICAgICBjMTYgKz0gYzAwID4+PiAxNjtcbiAgICAgIGMwMCAmPSAweGZmZmY7XG4gICAgICBjMTYgKz0gYTE2ICogYjAwO1xuICAgICAgYzMyICs9IGMxNiA+Pj4gMTY7XG4gICAgICBjMTYgJj0gMHhmZmZmO1xuICAgICAgYzE2ICs9IGEwMCAqIGIxNjtcbiAgICAgIGMzMiArPSBjMTYgPj4+IDE2O1xuICAgICAgYzE2ICY9IDB4ZmZmZjtcbiAgICAgIGMzMiArPSBhMzIgKiBiMDA7XG4gICAgICBjNDggKz0gYzMyID4+PiAxNjtcbiAgICAgIGMzMiAmPSAweGZmZmY7XG4gICAgICBjMzIgKz0gYTE2ICogYjE2O1xuICAgICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XG4gICAgICBjMzIgJj0gMHhmZmZmO1xuICAgICAgYzMyICs9IGEwMCAqIGIzMjtcbiAgICAgIGM0OCArPSBjMzIgPj4+IDE2O1xuICAgICAgYzMyICY9IDB4ZmZmZjtcbiAgICAgIGM0OCArPSBhNDggKiBiMDAgKyBhMzIgKiBiMTYgKyBhMTYgKiBiMzIgKyBhMDAgKiBiNDg7XG4gICAgICBjNDggJj0gMHhmZmZmO1xuICAgICAgcmV0dXJuIGZyb21CaXRzKChjMTYgPDwgMTYpIHwgYzAwLCAoYzQ4IDw8IDE2KSB8IGMzMiwgdGhpcy51bnNpZ25lZCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI211bHRpcGx5fS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFByb2R1Y3RcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLm11bCA9IExvbmdQcm90b3R5cGUubXVsdGlwbHk7XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyBkaXZpZGVkIGJ5IHRoZSBzcGVjaWZpZWQuIFRoZSByZXN1bHQgaXMgc2lnbmVkIGlmIHRoaXMgTG9uZyBpcyBzaWduZWQgb3JcbiAgICAgKiAgdW5zaWduZWQgaWYgdGhpcyBMb25nIGlzIHVuc2lnbmVkLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5kaXZpZGUgPSBmdW5jdGlvbiBkaXZpZGUoZGl2aXNvcikge1xuICAgICAgaWYgKCFpc0xvbmcoZGl2aXNvcikpIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XG4gICAgICBpZiAoZGl2aXNvci5pc1plcm8oKSkgdGhyb3cgRXJyb3IoXCJkaXZpc2lvbiBieSB6ZXJvXCIpO1xuXG4gICAgICAvLyB1c2Ugd2FzbSBzdXBwb3J0IGlmIHByZXNlbnRcbiAgICAgIGlmICh3YXNtKSB7XG4gICAgICAgIC8vIGd1YXJkIGFnYWluc3Qgc2lnbmVkIGRpdmlzaW9uIG92ZXJmbG93OiB0aGUgbGFyZ2VzdFxuICAgICAgICAvLyBuZWdhdGl2ZSBudW1iZXIgLyAtMSB3b3VsZCBiZSAxIGxhcmdlciB0aGFuIHRoZSBsYXJnZXN0XG4gICAgICAgIC8vIHBvc2l0aXZlIG51bWJlciwgZHVlIHRvIHR3bydzIGNvbXBsZW1lbnQuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhdGhpcy51bnNpZ25lZCAmJlxuICAgICAgICAgIHRoaXMuaGlnaCA9PT0gLTB4ODAwMDAwMDAgJiZcbiAgICAgICAgICBkaXZpc29yLmxvdyA9PT0gLTEgJiZcbiAgICAgICAgICBkaXZpc29yLmhpZ2ggPT09IC0xXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIGJlIGNvbnNpc3RlbnQgd2l0aCBub24td2FzbSBjb2RlIHBhdGhcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICB2YXIgbG93ID0gKHRoaXMudW5zaWduZWQgPyB3YXNtW1wiZGl2X3VcIl0gOiB3YXNtW1wiZGl2X3NcIl0pKFxuICAgICAgICAgIHRoaXMubG93LFxuICAgICAgICAgIHRoaXMuaGlnaCxcbiAgICAgICAgICBkaXZpc29yLmxvdyxcbiAgICAgICAgICBkaXZpc29yLmhpZ2gsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBmcm9tQml0cyhsb3csIHdhc21bXCJnZXRfaGlnaFwiXSgpLCB0aGlzLnVuc2lnbmVkKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmlzWmVybygpKSByZXR1cm4gdGhpcy51bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgICAgIHZhciBhcHByb3gsIHJlbSwgcmVzO1xuICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkKSB7XG4gICAgICAgIC8vIFRoaXMgc2VjdGlvbiBpcyBvbmx5IHJlbGV2YW50IGZvciBzaWduZWQgbG9uZ3MgYW5kIGlzIGRlcml2ZWQgZnJvbSB0aGVcbiAgICAgICAgLy8gY2xvc3VyZSBsaWJyYXJ5IGFzIGEgd2hvbGUuXG4gICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcbiAgICAgICAgICBpZiAoZGl2aXNvci5lcShPTkUpIHx8IGRpdmlzb3IuZXEoTkVHX09ORSkpXG4gICAgICAgICAgICByZXR1cm4gTUlOX1ZBTFVFOyAvLyByZWNhbGwgdGhhdCAtTUlOX1ZBTFVFID09IE1JTl9WQUxVRVxuICAgICAgICAgIGVsc2UgaWYgKGRpdmlzb3IuZXEoTUlOX1ZBTFVFKSkgcmV0dXJuIE9ORTtcbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQsIHdlIGhhdmUgfG90aGVyfCA+PSAyLCBzbyB8dGhpcy9vdGhlcnwgPCB8TUlOX1ZBTFVFfC5cbiAgICAgICAgICAgIHZhciBoYWxmVGhpcyA9IHRoaXMuc2hyKDEpO1xuICAgICAgICAgICAgYXBwcm94ID0gaGFsZlRoaXMuZGl2KGRpdmlzb3IpLnNobCgxKTtcbiAgICAgICAgICAgIGlmIChhcHByb3guZXEoWkVSTykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGRpdmlzb3IuaXNOZWdhdGl2ZSgpID8gT05FIDogTkVHX09ORTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlbSA9IHRoaXMuc3ViKGRpdmlzb3IubXVsKGFwcHJveCkpO1xuICAgICAgICAgICAgICByZXMgPSBhcHByb3guYWRkKHJlbS5kaXYoZGl2aXNvcikpO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xuICAgICAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHtcbiAgICAgICAgICBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yLm5lZygpKTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5kaXYoZGl2aXNvcikubmVnKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpIHJldHVybiB0aGlzLmRpdihkaXZpc29yLm5lZygpKS5uZWcoKTtcbiAgICAgICAgcmVzID0gWkVSTztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoZSBhbGdvcml0aG0gYmVsb3cgaGFzIG5vdCBiZWVuIG1hZGUgZm9yIHVuc2lnbmVkIGxvbmdzLiBJdCdzIHRoZXJlZm9yZVxuICAgICAgICAvLyByZXF1aXJlZCB0byB0YWtlIHNwZWNpYWwgY2FyZSBvZiB0aGUgTVNCIHByaW9yIHRvIHJ1bm5pbmcgaXQuXG4gICAgICAgIGlmICghZGl2aXNvci51bnNpZ25lZCkgZGl2aXNvciA9IGRpdmlzb3IudG9VbnNpZ25lZCgpO1xuICAgICAgICBpZiAoZGl2aXNvci5ndCh0aGlzKSkgcmV0dXJuIFVaRVJPO1xuICAgICAgICBpZiAoZGl2aXNvci5ndCh0aGlzLnNocnUoMSkpKVxuICAgICAgICAgIC8vIDE1ID4+PiAxID0gNyA7IHdpdGggZGl2aXNvciA9IDggOyB0cnVlXG4gICAgICAgICAgcmV0dXJuIFVPTkU7XG4gICAgICAgIHJlcyA9IFVaRVJPO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXBlYXQgdGhlIGZvbGxvd2luZyB1bnRpbCB0aGUgcmVtYWluZGVyIGlzIGxlc3MgdGhhbiBvdGhlcjogIGZpbmQgYVxuICAgICAgLy8gZmxvYXRpbmctcG9pbnQgdGhhdCBhcHByb3hpbWF0ZXMgcmVtYWluZGVyIC8gb3RoZXIgKmZyb20gYmVsb3cqLCBhZGQgdGhpc1xuICAgICAgLy8gaW50byB0aGUgcmVzdWx0LCBhbmQgc3VidHJhY3QgaXQgZnJvbSB0aGUgcmVtYWluZGVyLiAgSXQgaXMgY3JpdGljYWwgdGhhdFxuICAgICAgLy8gdGhlIGFwcHJveGltYXRlIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgcmVhbCB2YWx1ZSBzbyB0aGF0IHRoZVxuICAgICAgLy8gcmVtYWluZGVyIG5ldmVyIGJlY29tZXMgbmVnYXRpdmUuXG4gICAgICByZW0gPSB0aGlzO1xuICAgICAgd2hpbGUgKHJlbS5ndGUoZGl2aXNvcikpIHtcbiAgICAgICAgLy8gQXBwcm94aW1hdGUgdGhlIHJlc3VsdCBvZiBkaXZpc2lvbi4gVGhpcyBtYXkgYmUgYSBsaXR0bGUgZ3JlYXRlciBvclxuICAgICAgICAvLyBzbWFsbGVyIHRoYW4gdGhlIGFjdHVhbCB2YWx1ZS5cbiAgICAgICAgYXBwcm94ID0gTWF0aC5tYXgoMSwgTWF0aC5mbG9vcihyZW0udG9OdW1iZXIoKSAvIGRpdmlzb3IudG9OdW1iZXIoKSkpO1xuXG4gICAgICAgIC8vIFdlIHdpbGwgdHdlYWsgdGhlIGFwcHJveGltYXRlIHJlc3VsdCBieSBjaGFuZ2luZyBpdCBpbiB0aGUgNDgtdGggZGlnaXQgb3JcbiAgICAgICAgLy8gdGhlIHNtYWxsZXN0IG5vbi1mcmFjdGlvbmFsIGRpZ2l0LCB3aGljaGV2ZXIgaXMgbGFyZ2VyLlxuICAgICAgICB2YXIgbG9nMiA9IE1hdGguY2VpbChNYXRoLmxvZyhhcHByb3gpIC8gTWF0aC5MTjIpLFxuICAgICAgICAgIGRlbHRhID0gbG9nMiA8PSA0OCA/IDEgOiBwb3dfZGJsKDIsIGxvZzIgLSA0OCksXG4gICAgICAgICAgLy8gRGVjcmVhc2UgdGhlIGFwcHJveGltYXRpb24gdW50aWwgaXQgaXMgc21hbGxlciB0aGFuIHRoZSByZW1haW5kZXIuICBOb3RlXG4gICAgICAgICAgLy8gdGhhdCBpZiBpdCBpcyB0b28gbGFyZ2UsIHRoZSBwcm9kdWN0IG92ZXJmbG93cyBhbmQgaXMgbmVnYXRpdmUuXG4gICAgICAgICAgYXBwcm94UmVzID0gZnJvbU51bWJlcihhcHByb3gpLFxuICAgICAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XG4gICAgICAgIHdoaWxlIChhcHByb3hSZW0uaXNOZWdhdGl2ZSgpIHx8IGFwcHJveFJlbS5ndChyZW0pKSB7XG4gICAgICAgICAgYXBwcm94IC09IGRlbHRhO1xuICAgICAgICAgIGFwcHJveFJlcyA9IGZyb21OdW1iZXIoYXBwcm94LCB0aGlzLnVuc2lnbmVkKTtcbiAgICAgICAgICBhcHByb3hSZW0gPSBhcHByb3hSZXMubXVsKGRpdmlzb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2Uga25vdyB0aGUgYW5zd2VyIGNhbid0IGJlIHplcm8uLi4gYW5kIGFjdHVhbGx5LCB6ZXJvIHdvdWxkIGNhdXNlXG4gICAgICAgIC8vIGluZmluaXRlIHJlY3Vyc2lvbiBzaW5jZSB3ZSB3b3VsZCBtYWtlIG5vIHByb2dyZXNzLlxuICAgICAgICBpZiAoYXBwcm94UmVzLmlzWmVybygpKSBhcHByb3hSZXMgPSBPTkU7XG4gICAgICAgIHJlcyA9IHJlcy5hZGQoYXBwcm94UmVzKTtcbiAgICAgICAgcmVtID0gcmVtLnN1YihhcHByb3hSZW0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgZGl2aWRlZCBieSB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2RpdmlkZX0uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gICAgICogQHJldHVybnMgeyFMb25nfSBRdW90aWVudFxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUuZGl2ID0gTG9uZ1Byb3RvdHlwZS5kaXZpZGU7XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gICAgICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLm1vZHVsbyA9IGZ1bmN0aW9uIG1vZHVsbyhkaXZpc29yKSB7XG4gICAgICBpZiAoIWlzTG9uZyhkaXZpc29yKSkgZGl2aXNvciA9IGZyb21WYWx1ZShkaXZpc29yKTtcblxuICAgICAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XG4gICAgICBpZiAod2FzbSkge1xuICAgICAgICB2YXIgbG93ID0gKHRoaXMudW5zaWduZWQgPyB3YXNtW1wicmVtX3VcIl0gOiB3YXNtW1wicmVtX3NcIl0pKFxuICAgICAgICAgIHRoaXMubG93LFxuICAgICAgICAgIHRoaXMuaGlnaCxcbiAgICAgICAgICBkaXZpc29yLmxvdyxcbiAgICAgICAgICBkaXZpc29yLmhpZ2gsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBmcm9tQml0cyhsb3csIHdhc21bXCJnZXRfaGlnaFwiXSgpLCB0aGlzLnVuc2lnbmVkKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnN1Yih0aGlzLmRpdihkaXZpc29yKS5tdWwoZGl2aXNvcikpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNtb2R1bG99LlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5tb2QgPSBMb25nUHJvdG90eXBlLm1vZHVsbztcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIG1vZHVsbyB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI21vZHVsb30uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8YmlnaW50fHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gICAgICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLnJlbSA9IExvbmdQcm90b3R5cGUubW9kdWxvO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgYml0d2lzZSBOT1Qgb2YgdGhpcyBMb25nLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5ub3QgPSBmdW5jdGlvbiBub3QoKSB7XG4gICAgICByZXR1cm4gZnJvbUJpdHMofnRoaXMubG93LCB+dGhpcy5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBjb3VudCBsZWFkaW5nIHplcm9zIG9mIHRoaXMgTG9uZy5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMgeyFudW1iZXJ9XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5jb3VudExlYWRpbmdaZXJvcyA9IGZ1bmN0aW9uIGNvdW50TGVhZGluZ1plcm9zKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaGlnaCA/IE1hdGguY2x6MzIodGhpcy5oaWdoKSA6IE1hdGguY2x6MzIodGhpcy5sb3cpICsgMzI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgY291bnQgbGVhZGluZyB6ZXJvcy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNjb3VudExlYWRpbmdaZXJvc30uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHshTG9uZ31cbiAgICAgKiBAcmV0dXJucyB7IW51bWJlcn1cbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLmNseiA9IExvbmdQcm90b3R5cGUuY291bnRMZWFkaW5nWmVyb3M7XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGNvdW50IHRyYWlsaW5nIHplcm9zIG9mIHRoaXMgTG9uZy5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMgeyFudW1iZXJ9XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5jb3VudFRyYWlsaW5nWmVyb3MgPSBmdW5jdGlvbiBjb3VudFRyYWlsaW5nWmVyb3MoKSB7XG4gICAgICByZXR1cm4gdGhpcy5sb3cgPyBjdHozMih0aGlzLmxvdykgOiBjdHozMih0aGlzLmhpZ2gpICsgMzI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgY291bnQgdHJhaWxpbmcgemVyb3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY291bnRUcmFpbGluZ1plcm9zfS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyFMb25nfVxuICAgICAqIEByZXR1cm5zIHshbnVtYmVyfVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUuY3R6ID0gTG9uZ1Byb3RvdHlwZS5jb3VudFRyYWlsaW5nWmVyb3M7XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBiaXR3aXNlIEFORCBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXG4gICAgICogQHRoaXMgeyFMb25nfVxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfGJpZ2ludHxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5hbmQgPSBmdW5jdGlvbiBhbmQob3RoZXIpIHtcbiAgICAgIGlmICghaXNMb25nKG90aGVyKSkgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICAgICAgcmV0dXJuIGZyb21CaXRzKFxuICAgICAgICB0aGlzLmxvdyAmIG90aGVyLmxvdyxcbiAgICAgICAgdGhpcy5oaWdoICYgb3RoZXIuaGlnaCxcbiAgICAgICAgdGhpcy51bnNpZ25lZCxcbiAgICAgICk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGJpdHdpc2UgT1Igb2YgdGhpcyBMb25nIGFuZCB0aGUgc3BlY2lmaWVkLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXG4gICAgICogQHJldHVybnMgeyFMb25nfVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUub3IgPSBmdW5jdGlvbiBvcihvdGhlcikge1xuICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKSBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XG4gICAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICAgIHRoaXMubG93IHwgb3RoZXIubG93LFxuICAgICAgICB0aGlzLmhpZ2ggfCBvdGhlci5oaWdoLFxuICAgICAgICB0aGlzLnVuc2lnbmVkLFxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgYml0d2lzZSBYT1Igb2YgdGhpcyBMb25nIGFuZCB0aGUgZ2l2ZW4gb25lLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxiaWdpbnR8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXG4gICAgICogQHJldHVybnMgeyFMb25nfVxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUueG9yID0gZnVuY3Rpb24geG9yKG90aGVyKSB7XG4gICAgICBpZiAoIWlzTG9uZyhvdGhlcikpIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcbiAgICAgIHJldHVybiBmcm9tQml0cyhcbiAgICAgICAgdGhpcy5sb3cgXiBvdGhlci5sb3csXG4gICAgICAgIHRoaXMuaGlnaCBeIG90aGVyLmhpZ2gsXG4gICAgICAgIHRoaXMudW5zaWduZWQsXG4gICAgICApO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgc2hpZnRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQgPSBmdW5jdGlvbiBzaGlmdExlZnQobnVtQml0cykge1xuICAgICAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgICAgIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApIHJldHVybiB0aGlzO1xuICAgICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxuICAgICAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICAgICAgdGhpcy5sb3cgPDwgbnVtQml0cyxcbiAgICAgICAgICAodGhpcy5oaWdoIDw8IG51bUJpdHMpIHwgKHRoaXMubG93ID4+PiAoMzIgLSBudW1CaXRzKSksXG4gICAgICAgICAgdGhpcy51bnNpZ25lZCxcbiAgICAgICAgKTtcbiAgICAgIGVsc2UgcmV0dXJuIGZyb21CaXRzKDAsIHRoaXMubG93IDw8IChudW1CaXRzIC0gMzIpLCB0aGlzLnVuc2lnbmVkKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHNoaWZ0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdExlZnR9LlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLnNobCA9IExvbmdQcm90b3R5cGUuc2hpZnRMZWZ0O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXG4gICAgICogQHRoaXMgeyFMb25nfVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBmdW5jdGlvbiBzaGlmdFJpZ2h0KG51bUJpdHMpIHtcbiAgICAgIGlmIChpc0xvbmcobnVtQml0cykpIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XG4gICAgICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKSByZXR1cm4gdGhpcztcbiAgICAgIGVsc2UgaWYgKG51bUJpdHMgPCAzMilcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKFxuICAgICAgICAgICh0aGlzLmxvdyA+Pj4gbnVtQml0cykgfCAodGhpcy5oaWdoIDw8ICgzMiAtIG51bUJpdHMpKSxcbiAgICAgICAgICB0aGlzLmhpZ2ggPj4gbnVtQml0cyxcbiAgICAgICAgICB0aGlzLnVuc2lnbmVkLFxuICAgICAgICApO1xuICAgICAgZWxzZVxuICAgICAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICAgICAgdGhpcy5oaWdoID4+IChudW1CaXRzIC0gMzIpLFxuICAgICAgICAgIHRoaXMuaGlnaCA+PSAwID8gMCA6IC0xLFxuICAgICAgICAgIHRoaXMudW5zaWduZWQsXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0UmlnaHR9LlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAgICAgKi9cbiAgICBMb25nUHJvdG90eXBlLnNociA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodDtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkID0gZnVuY3Rpb24gc2hpZnRSaWdodFVuc2lnbmVkKG51bUJpdHMpIHtcbiAgICAgIGlmIChpc0xvbmcobnVtQml0cykpIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XG4gICAgICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKSByZXR1cm4gdGhpcztcbiAgICAgIGlmIChudW1CaXRzIDwgMzIpXG4gICAgICAgIHJldHVybiBmcm9tQml0cyhcbiAgICAgICAgICAodGhpcy5sb3cgPj4+IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA8PCAoMzIgLSBudW1CaXRzKSksXG4gICAgICAgICAgdGhpcy5oaWdoID4+PiBudW1CaXRzLFxuICAgICAgICAgIHRoaXMudW5zaWduZWQsXG4gICAgICAgICk7XG4gICAgICBpZiAobnVtQml0cyA9PT0gMzIpIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2gsIDAsIHRoaXMudW5zaWduZWQpO1xuICAgICAgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCA+Pj4gKG51bUJpdHMgLSAzMiksIDAsIHRoaXMudW5zaWduZWQpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5zaHJ1ID0gTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQ7XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5zaHJfdSA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHJvdGF0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFJvdGF0ZWQgTG9uZ1xuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUucm90YXRlTGVmdCA9IGZ1bmN0aW9uIHJvdGF0ZUxlZnQobnVtQml0cykge1xuICAgICAgdmFyIGI7XG4gICAgICBpZiAoaXNMb25nKG51bUJpdHMpKSBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xuICAgICAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gICAgICBpZiAobnVtQml0cyA9PT0gMzIpIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2gsIHRoaXMubG93LCB0aGlzLnVuc2lnbmVkKTtcbiAgICAgIGlmIChudW1CaXRzIDwgMzIpIHtcbiAgICAgICAgYiA9IDMyIC0gbnVtQml0cztcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKFxuICAgICAgICAgICh0aGlzLmxvdyA8PCBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPj4+IGIpLFxuICAgICAgICAgICh0aGlzLmhpZ2ggPDwgbnVtQml0cykgfCAodGhpcy5sb3cgPj4+IGIpLFxuICAgICAgICAgIHRoaXMudW5zaWduZWQsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBudW1CaXRzIC09IDMyO1xuICAgICAgYiA9IDMyIC0gbnVtQml0cztcbiAgICAgIHJldHVybiBmcm9tQml0cyhcbiAgICAgICAgKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gYiksXG4gICAgICAgICh0aGlzLmxvdyA8PCBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPj4+IGIpLFxuICAgICAgICB0aGlzLnVuc2lnbmVkLFxuICAgICAgKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyByb3RhdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjcm90YXRlTGVmdH0uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFJvdGF0ZWQgTG9uZ1xuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUucm90bCA9IExvbmdQcm90b3R5cGUucm90YXRlTGVmdDtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyByb3RhdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUm90YXRlZCBMb25nXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS5yb3RhdGVSaWdodCA9IGZ1bmN0aW9uIHJvdGF0ZVJpZ2h0KG51bUJpdHMpIHtcbiAgICAgIHZhciBiO1xuICAgICAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgICAgIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApIHJldHVybiB0aGlzO1xuICAgICAgaWYgKG51bUJpdHMgPT09IDMyKSByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoLCB0aGlzLmxvdywgdGhpcy51bnNpZ25lZCk7XG4gICAgICBpZiAobnVtQml0cyA8IDMyKSB7XG4gICAgICAgIGIgPSAzMiAtIG51bUJpdHM7XG4gICAgICAgIHJldHVybiBmcm9tQml0cyhcbiAgICAgICAgICAodGhpcy5oaWdoIDw8IGIpIHwgKHRoaXMubG93ID4+PiBudW1CaXRzKSxcbiAgICAgICAgICAodGhpcy5sb3cgPDwgYikgfCAodGhpcy5oaWdoID4+PiBudW1CaXRzKSxcbiAgICAgICAgICB0aGlzLnVuc2lnbmVkLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgbnVtQml0cyAtPSAzMjtcbiAgICAgIGIgPSAzMiAtIG51bUJpdHM7XG4gICAgICByZXR1cm4gZnJvbUJpdHMoXG4gICAgICAgICh0aGlzLmxvdyA8PCBiKSB8ICh0aGlzLmhpZ2ggPj4+IG51bUJpdHMpLFxuICAgICAgICAodGhpcy5oaWdoIDw8IGIpIHwgKHRoaXMubG93ID4+PiBudW1CaXRzKSxcbiAgICAgICAgdGhpcy51bnNpZ25lZCxcbiAgICAgICk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgcm90YXRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNyb3RhdGVSaWdodH0uXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFJvdGF0ZWQgTG9uZ1xuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUucm90ciA9IExvbmdQcm90b3R5cGUucm90YXRlUmlnaHQ7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gc2lnbmVkLlxuICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNpZ25lZCBsb25nXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS50b1NpZ25lZCA9IGZ1bmN0aW9uIHRvU2lnbmVkKCkge1xuICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkKSByZXR1cm4gdGhpcztcbiAgICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdywgdGhpcy5oaWdoLCBmYWxzZSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byB1bnNpZ25lZC5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMgeyFMb25nfSBVbnNpZ25lZCBsb25nXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS50b1Vuc2lnbmVkID0gZnVuY3Rpb24gdG9VbnNpZ25lZCgpIHtcbiAgICAgIGlmICh0aGlzLnVuc2lnbmVkKSByZXR1cm4gdGhpcztcbiAgICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdywgdGhpcy5oaWdoLCB0cnVlKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxlIFdoZXRoZXIgbGl0dGxlIG9yIGJpZyBlbmRpYW4sIGRlZmF1bHRzIHRvIGJpZyBlbmRpYW5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQnl0ZSByZXByZXNlbnRhdGlvblxuICAgICAqL1xuICAgIExvbmdQcm90b3R5cGUudG9CeXRlcyA9IGZ1bmN0aW9uIHRvQnl0ZXMobGUpIHtcbiAgICAgIHJldHVybiBsZSA/IHRoaXMudG9CeXRlc0xFKCkgOiB0aGlzLnRvQnl0ZXNCRSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGxpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gTGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS50b0J5dGVzTEUgPSBmdW5jdGlvbiB0b0J5dGVzTEUoKSB7XG4gICAgICB2YXIgaGkgPSB0aGlzLmhpZ2gsXG4gICAgICAgIGxvID0gdGhpcy5sb3c7XG4gICAgICByZXR1cm4gW1xuICAgICAgICBsbyAmIDB4ZmYsXG4gICAgICAgIChsbyA+Pj4gOCkgJiAweGZmLFxuICAgICAgICAobG8gPj4+IDE2KSAmIDB4ZmYsXG4gICAgICAgIGxvID4+PiAyNCxcbiAgICAgICAgaGkgJiAweGZmLFxuICAgICAgICAoaGkgPj4+IDgpICYgMHhmZixcbiAgICAgICAgKGhpID4+PiAxNikgJiAweGZmLFxuICAgICAgICBoaSA+Pj4gMjQsXG4gICAgICBdO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAgICAgKiBAdGhpcyB7IUxvbmd9XG4gICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXG4gICAgICovXG4gICAgTG9uZ1Byb3RvdHlwZS50b0J5dGVzQkUgPSBmdW5jdGlvbiB0b0J5dGVzQkUoKSB7XG4gICAgICB2YXIgaGkgPSB0aGlzLmhpZ2gsXG4gICAgICAgIGxvID0gdGhpcy5sb3c7XG4gICAgICByZXR1cm4gW1xuICAgICAgICBoaSA+Pj4gMjQsXG4gICAgICAgIChoaSA+Pj4gMTYpICYgMHhmZixcbiAgICAgICAgKGhpID4+PiA4KSAmIDB4ZmYsXG4gICAgICAgIGhpICYgMHhmZixcbiAgICAgICAgbG8gPj4+IDI0LFxuICAgICAgICAobG8gPj4+IDE2KSAmIDB4ZmYsXG4gICAgICAgIChsbyA+Pj4gOCkgJiAweGZmLFxuICAgICAgICBsbyAmIDB4ZmYsXG4gICAgICBdO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgTG9uZyBmcm9tIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxuICAgICAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBCeXRlIHJlcHJlc2VudGF0aW9uXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxlIFdoZXRoZXIgbGl0dGxlIG9yIGJpZyBlbmRpYW4sIGRlZmF1bHRzIHRvIGJpZyBlbmRpYW5cbiAgICAgKiBAcmV0dXJucyB7TG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICAgICAqL1xuICAgIExvbmcuZnJvbUJ5dGVzID0gZnVuY3Rpb24gZnJvbUJ5dGVzKGJ5dGVzLCB1bnNpZ25lZCwgbGUpIHtcbiAgICAgIHJldHVybiBsZVxuICAgICAgICA/IExvbmcuZnJvbUJ5dGVzTEUoYnl0ZXMsIHVuc2lnbmVkKVxuICAgICAgICA6IExvbmcuZnJvbUJ5dGVzQkUoYnl0ZXMsIHVuc2lnbmVkKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgbGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxuICAgICAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gICAgICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAgICAgKi9cbiAgICBMb25nLmZyb21CeXRlc0xFID0gZnVuY3Rpb24gZnJvbUJ5dGVzTEUoYnl0ZXMsIHVuc2lnbmVkKSB7XG4gICAgICByZXR1cm4gbmV3IExvbmcoXG4gICAgICAgIGJ5dGVzWzBdIHwgKGJ5dGVzWzFdIDw8IDgpIHwgKGJ5dGVzWzJdIDw8IDE2KSB8IChieXRlc1szXSA8PCAyNCksXG4gICAgICAgIGJ5dGVzWzRdIHwgKGJ5dGVzWzVdIDw8IDgpIHwgKGJ5dGVzWzZdIDw8IDE2KSB8IChieXRlc1s3XSA8PCAyNCksXG4gICAgICAgIHVuc2lnbmVkLFxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgYmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxuICAgICAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBCaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gICAgICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAgICAgKi9cbiAgICBMb25nLmZyb21CeXRlc0JFID0gZnVuY3Rpb24gZnJvbUJ5dGVzQkUoYnl0ZXMsIHVuc2lnbmVkKSB7XG4gICAgICByZXR1cm4gbmV3IExvbmcoXG4gICAgICAgIChieXRlc1s0XSA8PCAyNCkgfCAoYnl0ZXNbNV0gPDwgMTYpIHwgKGJ5dGVzWzZdIDw8IDgpIHwgYnl0ZXNbN10sXG4gICAgICAgIChieXRlc1swXSA8PCAyNCkgfCAoYnl0ZXNbMV0gPDwgMTYpIHwgKGJ5dGVzWzJdIDw8IDgpIHwgYnl0ZXNbM10sXG4gICAgICAgIHVuc2lnbmVkLFxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgLy8gU3VwcG9ydCBjb252ZXJzaW9uIHRvL2Zyb20gQmlnSW50IHdoZXJlIGF2YWlsYWJsZVxuICAgIGlmICh0eXBlb2YgQmlnSW50ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIC8qKlxuICAgICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiBiaWcgaW50ZWdlci5cbiAgICAgICAqIEBmdW5jdGlvblxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBiaWcgaW50ZWdlciB2YWx1ZVxuICAgICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICAgICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gICAgICAgKi9cbiAgICAgIExvbmcuZnJvbUJpZ0ludCA9IGZ1bmN0aW9uIGZyb21CaWdJbnQodmFsdWUsIHVuc2lnbmVkKSB7XG4gICAgICAgIHZhciBsb3dCaXRzID0gTnVtYmVyKEJpZ0ludC5hc0ludE4oMzIsIHZhbHVlKSk7XG4gICAgICAgIHZhciBoaWdoQml0cyA9IE51bWJlcihCaWdJbnQuYXNJbnROKDMyLCB2YWx1ZSA+PiBCaWdJbnQoMzIpKSk7XG4gICAgICAgIHJldHVybiBmcm9tQml0cyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpO1xuICAgICAgfTtcblxuICAgICAgLy8gT3ZlcnJpZGVcbiAgICAgIExvbmcuZnJvbVZhbHVlID0gZnVuY3Rpb24gZnJvbVZhbHVlV2l0aEJpZ0ludCh2YWx1ZSwgdW5zaWduZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJiaWdpbnRcIikgcmV0dXJuIExvbmcuZnJvbUJpZ0ludCh2YWx1ZSwgdW5zaWduZWQpO1xuICAgICAgICByZXR1cm4gZnJvbVZhbHVlKHZhbHVlLCB1bnNpZ25lZCk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGl0cyBiaWcgaW50ZWdlciByZXByZXNlbnRhdGlvbi5cbiAgICAgICAqIEB0aGlzIHshTG9uZ31cbiAgICAgICAqIEByZXR1cm5zIHtiaWdpbnR9XG4gICAgICAgKi9cbiAgICAgIExvbmdQcm90b3R5cGUudG9CaWdJbnQgPSBmdW5jdGlvbiB0b0JpZ0ludCgpIHtcbiAgICAgICAgdmFyIGxvd0JpZ0ludCA9IEJpZ0ludCh0aGlzLmxvdyA+Pj4gMCk7XG4gICAgICAgIHZhciBoaWdoQmlnSW50ID0gQmlnSW50KHRoaXMudW5zaWduZWQgPyB0aGlzLmhpZ2ggPj4+IDAgOiB0aGlzLmhpZ2gpO1xuICAgICAgICByZXR1cm4gKGhpZ2hCaWdJbnQgPDwgQmlnSW50KDMyKSkgfCBsb3dCaWdJbnQ7XG4gICAgICB9O1xuICAgIH1cbiAgICB2YXIgX2RlZmF1bHQgPSAoX2V4cG9ydHMuZGVmYXVsdCA9IExvbmcpO1xuICB9LFxuKTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbnZhciB1dGlsID0gZXhwb3J0cztcblxuLy8gdXNlZCB0byByZXR1cm4gYSBQcm9taXNlIHdoZXJlIGNhbGxiYWNrIGlzIG9taXR0ZWRcbnV0aWwuYXNQcm9taXNlID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2FzcHJvbWlzZVwiKTtcblxuLy8gY29udmVydHMgdG8gLyBmcm9tIGJhc2U2NCBlbmNvZGVkIHN0cmluZ3NcbnV0aWwuYmFzZTY0ID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2Jhc2U2NFwiKTtcblxuLy8gYmFzZSBjbGFzcyBvZiBycGMuU2VydmljZVxudXRpbC5FdmVudEVtaXR0ZXIgPSByZXF1aXJlKFwiQHByb3RvYnVmanMvZXZlbnRlbWl0dGVyXCIpO1xuXG4vLyBmbG9hdCBoYW5kbGluZyBhY2Nyb3NzIGJyb3dzZXJzXG51dGlsLmZsb2F0ID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2Zsb2F0XCIpO1xuXG4vLyByZXF1aXJlcyBtb2R1bGVzIG9wdGlvbmFsbHkgYW5kIGhpZGVzIHRoZSBjYWxsIGZyb20gYnVuZGxlcnNcbnV0aWwuaW5xdWlyZSA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9pbnF1aXJlXCIpO1xuXG4vLyBjb252ZXJ0cyB0byAvIGZyb20gdXRmOCBlbmNvZGVkIHN0cmluZ3NcbnV0aWwudXRmOCA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy91dGY4XCIpO1xuXG4vLyBwcm92aWRlcyBhIG5vZGUtbGlrZSBidWZmZXIgcG9vbCBpbiB0aGUgYnJvd3NlclxudXRpbC5wb29sID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL3Bvb2xcIik7XG5cbi8vIHV0aWxpdHkgdG8gd29yayB3aXRoIHRoZSBsb3cgYW5kIGhpZ2ggYml0cyBvZiBhIDY0IGJpdCB2YWx1ZVxudXRpbC5Mb25nQml0cyA9IHJlcXVpcmUoXCIuL2xvbmdiaXRzXCIpO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQga2V5IGNhbiBhZmZlY3Qgb2JqZWN0IHByb3RvdHlwZXMuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUga2V5IGlzIHVuc2FmZVxuICovXG5mdW5jdGlvbiBpc1Vuc2FmZVByb3BlcnR5KGtleSkge1xuICAgIHJldHVybiBrZXkgPT09IFwiX19wcm90b19fXCIgfHwga2V5ID09PSBcInByb3RvdHlwZVwiIHx8IGtleSA9PT0gXCJjb25zdHJ1Y3RvclwiO1xufVxuXG51dGlsLmlzVW5zYWZlUHJvcGVydHkgPSBpc1Vuc2FmZVByb3BlcnR5O1xuXG4vKipcbiAqIFdoZXRoZXIgcnVubmluZyB3aXRoaW4gbm9kZSBvciBub3QuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHR5cGUge2Jvb2xlYW59XG4gKi9cbnV0aWwuaXNOb2RlID0gQm9vbGVhbih0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICAgICAgICAgICAgICAgJiYgZ2xvYmFsXG4gICAgICAgICAgICAgICAgICAgJiYgZ2xvYmFsLnByb2Nlc3NcbiAgICAgICAgICAgICAgICAgICAmJiBnbG9iYWwucHJvY2Vzcy52ZXJzaW9uc1xuICAgICAgICAgICAgICAgICAgICYmIGdsb2JhbC5wcm9jZXNzLnZlcnNpb25zLm5vZGUpO1xuXG4vKipcbiAqIEdsb2JhbCBvYmplY3QgcmVmZXJlbmNlLlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbnV0aWwuZ2xvYmFsID0gdXRpbC5pc05vZGUgJiYgZ2xvYmFsXG4gICAgICAgICAgIHx8IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93XG4gICAgICAgICAgIHx8IHR5cGVvZiBzZWxmICAgIT09IFwidW5kZWZpbmVkXCIgJiYgc2VsZlxuICAgICAgICAgICB8fCB0aGlzOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWludmFsaWQtdGhpc1xuXG4vKipcbiAqIEFuIGltbXVhYmxlIGVtcHR5IGFycmF5LlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtBcnJheS48Kj59XG4gKiBAY29uc3RcbiAqL1xudXRpbC5lbXB0eUFycmF5ID0gT2JqZWN0LmZyZWV6ZSA/IE9iamVjdC5mcmVlemUoW10pIDogLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gW107IC8vIHVzZWQgb24gcHJvdG90eXBlc1xuXG4vKipcbiAqIEFuIGltbXV0YWJsZSBlbXB0eSBvYmplY3QuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQGNvbnN0XG4gKi9cbnV0aWwuZW1wdHlPYmplY3QgPSBPYmplY3QuZnJlZXplID8gT2JqZWN0LmZyZWV6ZSh7fSkgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB7fTsgLy8gdXNlZCBvbiBwcm90b3R5cGVzXG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhbiBpbnRlZ2VyLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGFuIGludGVnZXJcbiAqL1xudXRpbC5pc0ludGVnZXIgPSBOdW1iZXIuaXNJbnRlZ2VyIHx8IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIGZ1bmN0aW9uIGlzSW50ZWdlcih2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgaXNGaW5pdGUodmFsdWUpICYmIE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZTtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIHN0cmluZy5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgdmFsdWUgaXMgYSBzdHJpbmdcbiAqL1xudXRpbC5pc1N0cmluZyA9IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiB8fCB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZztcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIG5vbi1udWxsIG9iamVjdC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgdmFsdWUgaXMgYSBub24tbnVsbCBvYmplY3RcbiAqL1xudXRpbC5pc09iamVjdCA9IGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIjtcbn07XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgcHJvcGVydHkgb24gYSBtZXNzYWdlIGlzIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudC5cbiAqIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIHV0aWwuaXNTZXR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFBsYWluIG9iamVjdCBvciBtZXNzYWdlIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcCBQcm9wZXJ0eSBuYW1lXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudCwgb3RoZXJ3aXNlIGBmYWxzZWBcbiAqL1xudXRpbC5pc3NldCA9XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgcHJvcGVydHkgb24gYSBtZXNzYWdlIGlzIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogUGxhaW4gb2JqZWN0IG9yIG1lc3NhZ2UgaW5zdGFuY2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIFByb3BlcnR5IG5hbWVcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgY29uc2lkZXJlZCB0byBiZSBwcmVzZW50LCBvdGhlcndpc2UgYGZhbHNlYFxuICovXG51dGlsLmlzU2V0ID0gZnVuY3Rpb24gaXNTZXQob2JqLCBwcm9wKSB7XG4gICAgdmFyIHZhbHVlID0gb2JqW3Byb3BdO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUubGVuZ3RoIDogT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCkgPiAwO1xuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQW55IGNvbXBhdGlibGUgQnVmZmVyIGluc3RhbmNlLlxuICogVGhpcyBpcyBhIG1pbmltYWwgc3RhbmQtYWxvbmUgZGVmaW5pdGlvbiBvZiBhIEJ1ZmZlciBpbnN0YW5jZS4gVGhlIGFjdHVhbCB0eXBlIGlzIHRoYXQgZXhwb3J0ZWQgYnkgbm9kZSdzIHR5cGluZ3MuXG4gKiBAaW50ZXJmYWNlIEJ1ZmZlclxuICogQGV4dGVuZHMgVWludDhBcnJheVxuICovXG5cbi8qKlxuICogTm9kZSdzIEJ1ZmZlciBjbGFzcyBpZiBhdmFpbGFibGUuXG4gKiBAdHlwZSB7Q29uc3RydWN0b3I8QnVmZmVyPn1cbiAqL1xudXRpbC5CdWZmZXIgPSAoZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgdmFyIEJ1ZmZlciA9IHV0aWwuZ2xvYmFsLkJ1ZmZlcjtcbiAgICAgICAgLy8gcmVmdXNlIHRvIHVzZSBub24tbm9kZSBidWZmZXJzIGlmIG5vdCBleHBsaWNpdGx5IGFzc2lnbmVkIChwZXJmIHJlYXNvbnMpOlxuICAgICAgICByZXR1cm4gQnVmZmVyLnByb3RvdHlwZS51dGY4V3JpdGUgPyBCdWZmZXIgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBudWxsO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufSkoKTtcblxuLy8gSW50ZXJuYWwgYWxpYXMgb2Ygb3IgcG9seWZ1bGwgZm9yIEJ1ZmZlci5mcm9tLlxudXRpbC5fQnVmZmVyX2Zyb20gPSBudWxsO1xuXG4vLyBJbnRlcm5hbCBhbGlhcyBvZiBvciBwb2x5ZmlsbCBmb3IgQnVmZmVyLmFsbG9jVW5zYWZlLlxudXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlID0gbnVsbDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGJ1ZmZlciBvZiB3aGF0ZXZlciB0eXBlIHN1cHBvcnRlZCBieSB0aGUgZW52aXJvbm1lbnQuXG4gKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gW3NpemVPckFycmF5PTBdIEJ1ZmZlciBzaXplIG9yIG51bWJlciBhcnJheVxuICogQHJldHVybnMge1VpbnQ4QXJyYXl8QnVmZmVyfSBCdWZmZXJcbiAqL1xudXRpbC5uZXdCdWZmZXIgPSBmdW5jdGlvbiBuZXdCdWZmZXIoc2l6ZU9yQXJyYXkpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHJldHVybiB0eXBlb2Ygc2l6ZU9yQXJyYXkgPT09IFwibnVtYmVyXCJcbiAgICAgICAgPyB1dGlsLkJ1ZmZlclxuICAgICAgICAgICAgPyB1dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmUoc2l6ZU9yQXJyYXkpXG4gICAgICAgICAgICA6IG5ldyB1dGlsLkFycmF5KHNpemVPckFycmF5KVxuICAgICAgICA6IHV0aWwuQnVmZmVyXG4gICAgICAgICAgICA/IHV0aWwuX0J1ZmZlcl9mcm9tKHNpemVPckFycmF5KVxuICAgICAgICAgICAgOiB0eXBlb2YgVWludDhBcnJheSA9PT0gXCJ1bmRlZmluZWRcIlxuICAgICAgICAgICAgICAgID8gc2l6ZU9yQXJyYXlcbiAgICAgICAgICAgICAgICA6IG5ldyBVaW50OEFycmF5KHNpemVPckFycmF5KTtcbn07XG5cbi8qKlxuICogQXJyYXkgaW1wbGVtZW50YXRpb24gdXNlZCBpbiB0aGUgYnJvd3Nlci4gYFVpbnQ4QXJyYXlgIGlmIHN1cHBvcnRlZCwgb3RoZXJ3aXNlIGBBcnJheWAuXG4gKiBAdHlwZSB7Q29uc3RydWN0b3I8VWludDhBcnJheT59XG4gKi9cbnV0aWwuQXJyYXkgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gXCJ1bmRlZmluZWRcIiA/IFVpbnQ4QXJyYXkgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gOiBBcnJheTtcblxuLyoqXG4gKiBBbnkgY29tcGF0aWJsZSBMb25nIGluc3RhbmNlLlxuICogVGhpcyBpcyBhIG1pbmltYWwgc3RhbmQtYWxvbmUgZGVmaW5pdGlvbiBvZiBhIExvbmcgaW5zdGFuY2UuIFRoZSBhY3R1YWwgdHlwZSBpcyB0aGF0IGV4cG9ydGVkIGJ5IGxvbmcuanMuXG4gKiBAaW50ZXJmYWNlIExvbmdcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb3cgTG93IGJpdHNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBoaWdoIEhpZ2ggYml0c1xuICogQHByb3BlcnR5IHtib29sZWFufSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdFxuICovXG5cbi8qKlxuICogTG9uZy5qcydzIExvbmcgY2xhc3MgaWYgYXZhaWxhYmxlLlxuICogQHR5cGUge0NvbnN0cnVjdG9yPExvbmc+fVxuICovXG51dGlsLkxvbmcgPSAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB1dGlsLmdsb2JhbC5kY29kZUlPICYmIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHV0aWwuZ2xvYmFsLmRjb2RlSU8uTG9uZ1xuICAgICAgICAgfHwgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gdXRpbC5nbG9iYWwuTG9uZ1xuICAgICAgICAgfHwgKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBMb25nID0gcmVxdWlyZShcImxvbmdcIik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBMb25nICYmIExvbmcuaXNMb25nID8gTG9uZyA6IG51bGw7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSgpO1xuXG4vKipcbiAqIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIHRvIHZlcmlmeSAyIGJpdCAoYGJvb2xgKSBtYXAga2V5cy5cbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5rZXkyUmUgPSAvXnRydWV8ZmFsc2V8MHwxJC87XG5cbi8qKlxuICogUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gdmVyaWZ5IDMyIGJpdCAoYGludDMyYCBldGMuKSBtYXAga2V5cy5cbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5rZXkzMlJlID0gL14tPyg/OjB8WzEtOV1bMC05XSopJC87XG5cbi8qKlxuICogUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gdmVyaWZ5IDY0IGJpdCAoYGludDY0YCBldGMuKSBtYXAga2V5cy5cbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5rZXk2NFJlID0gL14oPzpbXFxcXHgwMC1cXFxceGZmXXs4fXwtPyg/OjB8WzEtOV1bMC05XSopKSQvO1xuXG4vKipcbiAqIENvbnZlcnRzIGEgbnVtYmVyIG9yIGxvbmcgdG8gYW4gOCBjaGFyYWN0ZXJzIGxvbmcgaGFzaCBzdHJpbmcuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyB7c3RyaW5nfSBIYXNoXG4gKi9cbnV0aWwubG9uZ1RvSGFzaCA9IGZ1bmN0aW9uIGxvbmdUb0hhc2godmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgPyB1dGlsLkxvbmdCaXRzLmZyb20odmFsdWUpLnRvSGFzaCgpXG4gICAgICAgIDogdXRpbC5Mb25nQml0cy56ZXJvSGFzaDtcbn07XG5cbi8qKlxuICogQ29udmVydHMgYW4gOCBjaGFyYWN0ZXJzIGxvbmcgaGFzaCBzdHJpbmcgdG8gYSBsb25nIG9yIG51bWJlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoIEhhc2hcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Vuc2lnbmVkPWZhbHNlXSBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdFxuICogQHJldHVybnMge0xvbmd8bnVtYmVyfSBPcmlnaW5hbCB2YWx1ZVxuICovXG51dGlsLmxvbmdGcm9tSGFzaCA9IGZ1bmN0aW9uIGxvbmdGcm9tSGFzaChoYXNoLCB1bnNpZ25lZCkge1xuICAgIHZhciBiaXRzID0gdXRpbC5Mb25nQml0cy5mcm9tSGFzaChoYXNoKTtcbiAgICBpZiAodXRpbC5Mb25nKVxuICAgICAgICByZXR1cm4gdXRpbC5Mb25nLmZyb21CaXRzKGJpdHMubG8sIGJpdHMuaGksIHVuc2lnbmVkKTtcbiAgICByZXR1cm4gYml0cy50b051bWJlcihCb29sZWFuKHVuc2lnbmVkKSk7XG59O1xuXG4vKipcbiAqIE1lcmdlcyB0aGUgcHJvcGVydGllcyBvZiB0aGUgc291cmNlIG9iamVjdCBpbnRvIHRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gZHN0IERlc3RpbmF0aW9uIG9iamVjdFxuICogQHBhcmFtIHsuLi4oT2JqZWN0LjxzdHJpbmcsKj58Ym9vbGVhbil9IHNyYyBTb3VyY2Ugb2JqZWN0cywgb3B0aW9uYWxseSBmb2xsb3dlZCBieSBhbiBgaWZOb3RTZXRgIGZsYWdcbiAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gRGVzdGluYXRpb24gb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIG1lcmdlKGRzdCkgeyAvLyB1c2VkIGJ5IGNvbnZlcnRlcnNcbiAgICB2YXIgaWZOb3RTZXQgPSB0eXBlb2YgYXJndW1lbnRzW2FyZ3VtZW50cy5sZW5ndGggLSAxXSA9PT0gXCJib29sZWFuXCIsXG4gICAgICAgIGxpbWl0ID0gaWZOb3RTZXQgPyBhcmd1bWVudHMubGVuZ3RoIC0gMSA6IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgaWZOb3RTZXQgPSBpZk5vdFNldCAmJiBhcmd1bWVudHNbYXJndW1lbnRzLmxlbmd0aCAtIDFdO1xuICAgIGZvciAodmFyIGEgPSAxOyBhIDwgbGltaXQ7ICsrYSkge1xuICAgICAgICB2YXIgc3JjID0gYXJndW1lbnRzW2FdO1xuICAgICAgICBpZiAoIXNyYylcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMoc3JjKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgaWYgKCFpc1Vuc2FmZVByb3BlcnR5KGtleXNbaV0pICYmIChkc3Rba2V5c1tpXV0gPT09IHVuZGVmaW5lZCB8fCAhaWZOb3RTZXQpKVxuICAgICAgICAgICAgICAgIGRzdFtrZXlzW2ldXSA9IHNyY1trZXlzW2ldXTtcbiAgICB9XG4gICAgcmV0dXJuIGRzdDtcbn1cblxudXRpbC5tZXJnZSA9IG1lcmdlO1xuXG4vKipcbiAqIFNjaGVtYSBkZWNsYXJhdGlvbiBuZXN0aW5nIGxpbWl0LlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbnV0aWwubmVzdGluZ0xpbWl0ID0gMzI7IC8vIHByb3RvYzogTWF4TWVzc2FnZURlY2xhcmF0aW9uTmVzdGluZ0RlcHRoXG5cbi8qKlxuICogUmVjdXJzaW9uIGxpbWl0LlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbnV0aWwucmVjdXJzaW9uTGltaXQgPSAxMDA7IC8vIHByb3RvYzogQ29kZWRJbnB1dFN0cmVhbTo6ZGVmYXVsdF9yZWN1cnNpb25fbGltaXRfXG5cbi8qKlxuICogTWFrZXMgYSBwcm9wZXJ0eSBzYWZlIGZvciBhc3NpZ25tZW50IGFzIGFuIG93biBwcm9wZXJ0eS5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmogT2JqZWN0XG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFByb3BlcnR5IGtleVxuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqL1xudXRpbC5tYWtlUHJvcCA9IGZ1bmN0aW9uIG1ha2VQcm9wKG9iaiwga2V5KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7XG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICB9KTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBhIHN0cmluZyB0byBsb3dlciBjYXNlLlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gY29udmVydFxuICogQHJldHVybnMge3N0cmluZ30gQ29udmVydGVkIHN0cmluZ1xuICovXG51dGlsLmxjRmlyc3QgPSBmdW5jdGlvbiBsY0ZpcnN0KHN0cikge1xuICAgIHJldHVybiBzdHIuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBzdHIuc3Vic3RyaW5nKDEpO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY3VzdG9tIGVycm9yIGNvbnN0cnVjdG9yLlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIEVycm9yIG5hbWVcbiAqIEByZXR1cm5zIHtDb25zdHJ1Y3RvcjxFcnJvcj59IEN1c3RvbSBlcnJvciBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBuZXdFcnJvcihuYW1lKSB7XG5cbiAgICBmdW5jdGlvbiBDdXN0b21FcnJvcihtZXNzYWdlLCBwcm9wZXJ0aWVzKSB7XG5cbiAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEN1c3RvbUVycm9yKSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ3VzdG9tRXJyb3IobWVzc2FnZSwgcHJvcGVydGllcyk7XG5cbiAgICAgICAgLy8gRXJyb3IuY2FsbCh0aGlzLCBtZXNzYWdlKTtcbiAgICAgICAgLy8gXiBqdXN0IHJldHVybnMgYSBuZXcgZXJyb3IgaW5zdGFuY2UgYmVjYXVzZSB0aGUgY3RvciBjYW4gYmUgY2FsbGVkIGFzIGEgZnVuY3Rpb25cblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJtZXNzYWdlXCIsIHsgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1lc3NhZ2U7IH0gfSk7XG5cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSAvLyBub2RlXG4gICAgICAgICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBDdXN0b21FcnJvcik7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcInN0YWNrXCIsIHsgdmFsdWU6IG5ldyBFcnJvcigpLnN0YWNrIHx8IFwiXCIgfSk7XG5cbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICBtZXJnZSh0aGlzLCBwcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBDdXN0b21FcnJvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgICAgdmFsdWU6IEN1c3RvbUVycm9yLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgbmFtZToge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7IHJldHVybiBuYW1lOyB9LFxuICAgICAgICAgICAgc2V0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIC8vIGNvbmZpZ3VyYWJsZTogZmFsc2Ugd291bGQgYWNjdXJhdGVseSBwcmVzZXJ2ZSB0aGUgYmVoYXZpb3Igb2ZcbiAgICAgICAgICAgIC8vIHRoZSBvcmlnaW5hbCwgYnV0IEknbSBndWVzc2luZyB0aGF0IHdhcyBub3QgaW50ZW50aW9uYWwuXG4gICAgICAgICAgICAvLyBGb3IgYW4gYWN0dWFsIGVycm9yIHN1YmNsYXNzLCB0aGlzIHByb3BlcnR5IHdvdWxkXG4gICAgICAgICAgICAvLyBiZSBjb25maWd1cmFibGUuXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIHRvU3RyaW5nOiB7XG4gICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUoKSB7IHJldHVybiB0aGlzLm5hbWUgKyBcIjogXCIgKyB0aGlzLm1lc3NhZ2U7IH0sXG4gICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB9LFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIEN1c3RvbUVycm9yO1xufVxuXG51dGlsLm5ld0Vycm9yID0gbmV3RXJyb3I7XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyBwcm90b2NvbCBlcnJvci5cbiAqIEBjbGFzc2Rlc2MgRXJyb3Igc3ViY2xhc3MgaW5kaWNhdGluZyBhIHByb3RvY29sIHNwZWNpZmMgZXJyb3IuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQGV4dGVuZHMgRXJyb3JcbiAqIEB0ZW1wbGF0ZSBUIGV4dGVuZHMgTWVzc2FnZTxUPlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBFcnJvciBtZXNzYWdlXG4gKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBbcHJvcGVydGllc10gQWRkaXRpb25hbCBwcm9wZXJ0aWVzXG4gKiBAZXhhbXBsZVxuICogdHJ5IHtcbiAqICAgICBNeU1lc3NhZ2UuZGVjb2RlKHNvbWVCdWZmZXIpOyAvLyB0aHJvd3MgaWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gKiB9IGNhdGNoIChlKSB7XG4gKiAgICAgaWYgKGUgaW5zdGFuY2VvZiBQcm90b2NvbEVycm9yICYmIGUuaW5zdGFuY2UpXG4gKiAgICAgICAgIGNvbnNvbGUubG9nKFwiZGVjb2RlZCBzbyBmYXI6IFwiICsgSlNPTi5zdHJpbmdpZnkoZS5pbnN0YW5jZSkpO1xuICogfVxuICovXG51dGlsLlByb3RvY29sRXJyb3IgPSBuZXdFcnJvcihcIlByb3RvY29sRXJyb3JcIik7XG5cbi8qKlxuICogU28gZmFyIGRlY29kZWQgbWVzc2FnZSBpbnN0YW5jZS5cbiAqIEBuYW1lIHV0aWwuUHJvdG9jb2xFcnJvciNpbnN0YW5jZVxuICogQHR5cGUge01lc3NhZ2U8VD59XG4gKi9cblxuLyoqXG4gKiBBIE9uZU9mIGdldHRlciBhcyByZXR1cm5lZCBieSB7QGxpbmsgdXRpbC5vbmVPZkdldHRlcn0uXG4gKiBAdHlwZWRlZiBPbmVPZkdldHRlclxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR9IFNldCBmaWVsZCBuYW1lLCBpZiBhbnlcbiAqL1xuXG4vKipcbiAqIEJ1aWxkcyBhIGdldHRlciBmb3IgYSBvbmVvZidzIHByZXNlbnQgZmllbGQgbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nW119IGZpZWxkTmFtZXMgRmllbGQgbmFtZXNcbiAqIEByZXR1cm5zIHtPbmVPZkdldHRlcn0gVW5ib3VuZCBnZXR0ZXJcbiAqL1xudXRpbC5vbmVPZkdldHRlciA9IGZ1bmN0aW9uIGdldE9uZU9mKGZpZWxkTmFtZXMpIHtcbiAgICB2YXIgZmllbGRNYXAgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpZWxkTmFtZXMubGVuZ3RoOyArK2kpXG4gICAgICAgIGZpZWxkTWFwW2ZpZWxkTmFtZXNbaV1dID0gMTtcblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfSBTZXQgZmllbGQgbmFtZSwgaWYgYW55XG4gICAgICogQHRoaXMgT2JqZWN0XG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbigpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXModGhpcyksIGkgPSBrZXlzLmxlbmd0aCAtIDE7IGkgPiAtMTsgLS1pKVxuICAgICAgICAgICAgaWYgKGZpZWxkTWFwW2tleXNbaV1dID09PSAxICYmIHRoaXNba2V5c1tpXV0gIT09IHVuZGVmaW5lZCAmJiB0aGlzW2tleXNbaV1dICE9PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBrZXlzW2ldO1xuICAgIH07XG59O1xuXG4vKipcbiAqIEEgT25lT2Ygc2V0dGVyIGFzIHJldHVybmVkIGJ5IHtAbGluayB1dGlsLm9uZU9mU2V0dGVyfS5cbiAqIEB0eXBlZGVmIE9uZU9mU2V0dGVyXG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcGFyYW0ge3N0cmluZ3x1bmRlZmluZWR9IHZhbHVlIEZpZWxkIG5hbWVcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKi9cblxuLyoqXG4gKiBCdWlsZHMgYSBzZXR0ZXIgZm9yIGEgb25lb2YncyBwcmVzZW50IGZpZWxkIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBmaWVsZE5hbWVzIEZpZWxkIG5hbWVzXG4gKiBAcmV0dXJucyB7T25lT2ZTZXR0ZXJ9IFVuYm91bmQgc2V0dGVyXG4gKi9cbnV0aWwub25lT2ZTZXR0ZXIgPSBmdW5jdGlvbiBzZXRPbmVPZihmaWVsZE5hbWVzKSB7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBGaWVsZCBuYW1lXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAgICAgKiBAdGhpcyBPYmplY3RcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWVsZE5hbWVzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgaWYgKGZpZWxkTmFtZXNbaV0gIT09IG5hbWUpXG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXNbZmllbGROYW1lc1tpXV07XG4gICAgfTtcbn07XG5cbi8qKlxuICogRGVmYXVsdCBjb252ZXJzaW9uIG9wdGlvbnMgdXNlZCBmb3Ige0BsaW5rIE1lc3NhZ2UjdG9KU09OfSBpbXBsZW1lbnRhdGlvbnMuXG4gKlxuICogVGhlc2Ugb3B0aW9ucyBhcmUgY2xvc2UgdG8gcHJvdG8zJ3MgSlNPTiBtYXBwaW5nIHdpdGggdGhlIGV4Y2VwdGlvbiB0aGF0IGludGVybmFsIHR5cGVzIGxpa2UgQW55IGFyZSBoYW5kbGVkIGp1c3QgbGlrZSBtZXNzYWdlcy4gTW9yZSBwcmVjaXNlbHk6XG4gKlxuICogLSBMb25ncyBiZWNvbWUgc3RyaW5nc1xuICogLSBFbnVtcyBiZWNvbWUgc3RyaW5nIGtleXNcbiAqIC0gQnl0ZXMgYmVjb21lIGJhc2U2NCBlbmNvZGVkIHN0cmluZ3NcbiAqIC0gKFN1Yi0pTWVzc2FnZXMgYmVjb21lIHBsYWluIG9iamVjdHNcbiAqIC0gTWFwcyBiZWNvbWUgcGxhaW4gb2JqZWN0cyB3aXRoIGFsbCBzdHJpbmcga2V5c1xuICogLSBSZXBlYXRlZCBmaWVsZHMgYmVjb21lIGFycmF5c1xuICogLSBOYU4gYW5kIEluZmluaXR5IGZvciBmbG9hdCBhbmQgZG91YmxlIGZpZWxkcyBiZWNvbWUgc3RyaW5nc1xuICpcbiAqIEB0eXBlIHtJQ29udmVyc2lvbk9wdGlvbnN9XG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvZG9jcy9wcm90bzM/aGw9ZW4janNvblxuICovXG51dGlsLnRvSlNPTk9wdGlvbnMgPSB7XG4gICAgbG9uZ3M6IFN0cmluZyxcbiAgICBlbnVtczogU3RyaW5nLFxuICAgIGJ5dGVzOiBTdHJpbmcsXG4gICAganNvbjogdHJ1ZVxufTtcblxuLy8gU2V0cyB1cCBidWZmZXIgdXRpbGl0eSBhY2NvcmRpbmcgdG8gdGhlIGVudmlyb25tZW50IChjYWxsZWQgaW4gaW5kZXgtbWluaW1hbClcbnV0aWwuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBCdWZmZXIgPSB1dGlsLkJ1ZmZlcjtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoIUJ1ZmZlcikge1xuICAgICAgICB1dGlsLl9CdWZmZXJfZnJvbSA9IHV0aWwuX0J1ZmZlcl9hbGxvY1Vuc2FmZSA9IG51bGw7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gYmVjYXVzZSBub2RlIDQueCBidWZmZXJzIGFyZSBpbmNvbXBhdGlibGUgJiBpbW11dGFibGVcbiAgICAvLyBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL3Byb3RvYnVmLmpzL3B1bGwvNjY1XG4gICAgdXRpbC5fQnVmZmVyX2Zyb20gPSBCdWZmZXIuZnJvbSAhPT0gVWludDhBcnJheS5mcm9tICYmIEJ1ZmZlci5mcm9tIHx8XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGZ1bmN0aW9uIEJ1ZmZlcl9mcm9tKHZhbHVlLCBlbmNvZGluZykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIodmFsdWUsIGVuY29kaW5nKTtcbiAgICAgICAgfTtcbiAgICB1dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmUgPSBCdWZmZXIuYWxsb2NVbnNhZmUgfHxcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgZnVuY3Rpb24gQnVmZmVyX2FsbG9jVW5zYWZlKHNpemUpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQnVmZmVyKHNpemUpO1xuICAgICAgICB9O1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gV3JpdGVyO1xuXG52YXIgdXRpbCAgICAgID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xuXG52YXIgQnVmZmVyV3JpdGVyOyAvLyBjeWNsaWNcblxudmFyIExvbmdCaXRzICA9IHV0aWwuTG9uZ0JpdHMsXG4gICAgYmFzZTY0ICAgID0gdXRpbC5iYXNlNjQsXG4gICAgdXRmOCAgICAgID0gdXRpbC51dGY4O1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgd3JpdGVyIG9wZXJhdGlvbiBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgU2NoZWR1bGVkIHdyaXRlciBvcGVyYXRpb24uXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKiwgVWludDhBcnJheSwgbnVtYmVyKX0gZm4gRnVuY3Rpb24gdG8gY2FsbFxuICogQHBhcmFtIHtudW1iZXJ9IGxlbiBWYWx1ZSBieXRlIGxlbmd0aFxuICogQHBhcmFtIHsqfSB2YWwgVmFsdWUgdG8gd3JpdGVcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gT3AoZm4sIGxlbiwgdmFsKSB7XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0byBjYWxsLlxuICAgICAqIEB0eXBlIHtmdW5jdGlvbihVaW50OEFycmF5LCBudW1iZXIsICopfVxuICAgICAqL1xuICAgIHRoaXMuZm4gPSBmbjtcblxuICAgIC8qKlxuICAgICAqIFZhbHVlIGJ5dGUgbGVuZ3RoLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sZW4gPSBsZW47XG5cbiAgICAvKipcbiAgICAgKiBOZXh0IG9wZXJhdGlvbi5cbiAgICAgKiBAdHlwZSB7V3JpdGVyLk9wfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICB0aGlzLm5leHQgPSB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSB0byB3cml0ZS5cbiAgICAgKiBAdHlwZSB7Kn1cbiAgICAgKi9cbiAgICB0aGlzLnZhbCA9IHZhbDsgLy8gdHlwZSB2YXJpZXNcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIG5vb3AoKSB7fSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWVtcHR5LWZ1bmN0aW9uXG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyB3cml0ZXIgc3RhdGUgaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIENvcGllZCB3cml0ZXIgc3RhdGUuXG4gKiBAbWVtYmVyb2YgV3JpdGVyXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7V3JpdGVyfSB3cml0ZXIgV3JpdGVyIHRvIGNvcHkgc3RhdGUgZnJvbVxuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBTdGF0ZSh3cml0ZXIpIHtcblxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgaGVhZC5cbiAgICAgKiBAdHlwZSB7V3JpdGVyLk9wfVxuICAgICAqL1xuICAgIHRoaXMuaGVhZCA9IHdyaXRlci5oZWFkO1xuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCB0YWlsLlxuICAgICAqIEB0eXBlIHtXcml0ZXIuT3B9XG4gICAgICovXG4gICAgdGhpcy50YWlsID0gd3JpdGVyLnRhaWw7XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IGJ1ZmZlciBsZW5ndGguXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxlbiA9IHdyaXRlci5sZW47XG5cbiAgICAvKipcbiAgICAgKiBOZXh0IHN0YXRlLlxuICAgICAqIEB0eXBlIHtTdGF0ZXxudWxsfVxuICAgICAqL1xuICAgIHRoaXMubmV4dCA9IHdyaXRlci5zdGF0ZXM7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyB3cml0ZXIgaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFdpcmUgZm9ybWF0IHdyaXRlciB1c2luZyBgVWludDhBcnJheWAgaWYgYXZhaWxhYmxlLCBvdGhlcndpc2UgYEFycmF5YC5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBXcml0ZXIoKSB7XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IGxlbmd0aC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMubGVuID0gMDtcblxuICAgIC8qKlxuICAgICAqIE9wZXJhdGlvbnMgaGVhZC5cbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIHRoaXMuaGVhZCA9IG5ldyBPcChub29wLCAwLCAwKTtcblxuICAgIC8qKlxuICAgICAqIE9wZXJhdGlvbnMgdGFpbFxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG4gICAgdGhpcy50YWlsID0gdGhpcy5oZWFkO1xuXG4gICAgLyoqXG4gICAgICogTGlua2VkIGZvcmtlZCBzdGF0ZXMuXG4gICAgICogQHR5cGUge09iamVjdHxudWxsfVxuICAgICAqL1xuICAgIHRoaXMuc3RhdGVzID0gbnVsbDtcblxuICAgIC8vIFdoZW4gYSB2YWx1ZSBpcyB3cml0dGVuLCB0aGUgd3JpdGVyIGNhbGN1bGF0ZXMgaXRzIGJ5dGUgbGVuZ3RoIGFuZCBwdXRzIGl0IGludG8gYSBsaW5rZWRcbiAgICAvLyBsaXN0IG9mIG9wZXJhdGlvbnMgdG8gcGVyZm9ybSB3aGVuIGZpbmlzaCgpIGlzIGNhbGxlZC4gVGhpcyBib3RoIGFsbG93cyB1cyB0byBhbGxvY2F0ZVxuICAgIC8vIGJ1ZmZlcnMgb2YgdGhlIGV4YWN0IHJlcXVpcmVkIHNpemUgYW5kIHJlZHVjZXMgdGhlIGFtb3VudCBvZiB3b3JrIHdlIGhhdmUgdG8gZG8gY29tcGFyZWRcbiAgICAvLyB0byBmaXJzdCBjYWxjdWxhdGluZyBvdmVyIG9iamVjdHMgYW5kIHRoZW4gZW5jb2Rpbmcgb3ZlciBvYmplY3RzLiBJbiBvdXIgY2FzZSwgdGhlIGVuY29kaW5nXG4gICAgLy8gcGFydCBpcyBqdXN0IGEgbGlua2VkIGxpc3Qgd2FsayBjYWxsaW5nIG9wZXJhdGlvbnMgd2l0aCBhbHJlYWR5IHByZXBhcmVkIHZhbHVlcy5cbn1cblxudmFyIGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICByZXR1cm4gdXRpbC5CdWZmZXJcbiAgICAgICAgPyBmdW5jdGlvbiBjcmVhdGVfYnVmZmVyX3NldHVwKCkge1xuICAgICAgICAgICAgcmV0dXJuIChXcml0ZXIuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlX2J1ZmZlcigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcldyaXRlcigpO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICA6IGZ1bmN0aW9uIGNyZWF0ZV9hcnJheSgpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgV3JpdGVyKCk7XG4gICAgICAgIH07XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgd3JpdGVyLlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7QnVmZmVyV3JpdGVyfFdyaXRlcn0gQSB7QGxpbmsgQnVmZmVyV3JpdGVyfSB3aGVuIEJ1ZmZlcnMgYXJlIHN1cHBvcnRlZCwgb3RoZXJ3aXNlIGEge0BsaW5rIFdyaXRlcn1cbiAqL1xuV3JpdGVyLmNyZWF0ZSA9IGNyZWF0ZSgpO1xuXG4vKipcbiAqIEFsbG9jYXRlcyBhIGJ1ZmZlciBvZiB0aGUgc3BlY2lmaWVkIHNpemUuXG4gKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBCdWZmZXIgc2l6ZVxuICogQHJldHVybnMge1VpbnQ4QXJyYXl9IEJ1ZmZlclxuICovXG5Xcml0ZXIuYWxsb2MgPSBmdW5jdGlvbiBhbGxvYyhzaXplKSB7XG4gICAgcmV0dXJuIG5ldyB1dGlsLkFycmF5KHNpemUpO1xufTtcblxuLy8gVXNlIFVpbnQ4QXJyYXkgYnVmZmVyIHBvb2wgaW4gdGhlIGJyb3dzZXIsIGp1c3QgbGlrZSBub2RlIGRvZXMgd2l0aCBidWZmZXJzXG4vKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuaWYgKHV0aWwuQXJyYXkgIT09IEFycmF5KVxuICAgIFdyaXRlci5hbGxvYyA9IHV0aWwucG9vbChXcml0ZXIuYWxsb2MsIHV0aWwuQXJyYXkucHJvdG90eXBlLnN1YmFycmF5KTtcblxuLyoqXG4gKiBQdXNoZXMgYSBuZXcgb3BlcmF0aW9uIHRvIHRoZSBxdWV1ZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oVWludDhBcnJheSwgbnVtYmVyLCAqKX0gZm4gRnVuY3Rpb24gdG8gY2FsbFxuICogQHBhcmFtIHtudW1iZXJ9IGxlbiBWYWx1ZSBieXRlIGxlbmd0aFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKiBAcHJpdmF0ZVxuICovXG5Xcml0ZXIucHJvdG90eXBlLl9wdXNoID0gZnVuY3Rpb24gcHVzaChmbiwgbGVuLCB2YWwpIHtcbiAgICB0aGlzLnRhaWwgPSB0aGlzLnRhaWwubmV4dCA9IG5ldyBPcChmbiwgbGVuLCB2YWwpO1xuICAgIHRoaXMubGVuICs9IGxlbjtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHdyaXRlQnl0ZSh2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgYnVmW3Bvc10gPSB2YWwgJiAyNTU7XG59XG5cbmZ1bmN0aW9uIHdyaXRlVmFyaW50MzIodmFsLCBidWYsIHBvcykge1xuICAgIHdoaWxlICh2YWwgPiAxMjcpIHtcbiAgICAgICAgYnVmW3BvcysrXSA9IHZhbCAmIDEyNyB8IDEyODtcbiAgICAgICAgdmFsID4+Pj0gNztcbiAgICB9XG4gICAgYnVmW3Bvc10gPSB2YWw7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyB2YXJpbnQgd3JpdGVyIG9wZXJhdGlvbiBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgU2NoZWR1bGVkIHZhcmludCB3cml0ZXIgb3BlcmF0aW9uLlxuICogQGV4dGVuZHMgT3BcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtudW1iZXJ9IGxlbiBWYWx1ZSBieXRlIGxlbmd0aFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBWYXJpbnRPcChsZW4sIHZhbCkge1xuICAgIHRoaXMubGVuID0gbGVuO1xuICAgIHRoaXMubmV4dCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnZhbCA9IHZhbDtcbn1cblxuVmFyaW50T3AucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShPcC5wcm90b3R5cGUpO1xuVmFyaW50T3AucHJvdG90eXBlLmZuID0gd3JpdGVWYXJpbnQzMjtcblxuLyoqXG4gKiBXcml0ZXMgYW4gdW5zaWduZWQgMzIgYml0IHZhbHVlIGFzIGEgdmFyaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS51aW50MzIgPSBmdW5jdGlvbiB3cml0ZV91aW50MzIodmFsdWUpIHtcbiAgICAvLyBoZXJlLCB0aGUgY2FsbCB0byB0aGlzLnB1c2ggaGFzIGJlZW4gaW5saW5lZCBhbmQgYSB2YXJpbnQgc3BlY2lmaWMgT3Agc3ViY2xhc3MgaXMgdXNlZC5cbiAgICAvLyB1aW50MzIgaXMgYnkgZmFyIHRoZSBtb3N0IGZyZXF1ZW50bHkgdXNlZCBvcGVyYXRpb24gYW5kIGJlbmVmaXRzIHNpZ25pZmljYW50bHkgZnJvbSB0aGlzLlxuICAgIHRoaXMubGVuICs9ICh0aGlzLnRhaWwgPSB0aGlzLnRhaWwubmV4dCA9IG5ldyBWYXJpbnRPcChcbiAgICAgICAgKHZhbHVlID0gdmFsdWUgPj4+IDApXG4gICAgICAgICAgICAgICAgPCAxMjggICAgICAgPyAxXG4gICAgICAgIDogdmFsdWUgPCAxNjM4NCAgICAgPyAyXG4gICAgICAgIDogdmFsdWUgPCAyMDk3MTUyICAgPyAzXG4gICAgICAgIDogdmFsdWUgPCAyNjg0MzU0NTYgPyA0XG4gICAgICAgIDogICAgICAgICAgICAgICAgICAgICA1LFxuICAgIHZhbHVlKSkubGVuO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzaWduZWQgMzIgYml0IHZhbHVlIGFzIGEgdmFyaW50LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmludDMyID0gZnVuY3Rpb24gd3JpdGVfaW50MzIodmFsdWUpIHtcbiAgICByZXR1cm4gKHZhbHVlIHw9IDApIDwgMFxuICAgICAgICA/IHRoaXMuX3B1c2god3JpdGVWYXJpbnQ2NCwgMTAsIExvbmdCaXRzLmZyb21OdW1iZXIodmFsdWUpKSAvLyAxMCBieXRlcyBwZXIgc3BlY1xuICAgICAgICA6IHRoaXMudWludDMyKHZhbHVlKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgMzIgYml0IHZhbHVlIGFzIGEgdmFyaW50LCB6aWctemFnIGVuY29kZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnNpbnQzMiA9IGZ1bmN0aW9uIHdyaXRlX3NpbnQzMih2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLnVpbnQzMigodmFsdWUgPDwgMSBeIHZhbHVlID4+IDMxKSA+Pj4gMCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZVZhcmludDY0KHZhbCwgYnVmLCBwb3MpIHtcbiAgICB2YXIgbG8gPSB2YWwubG8sXG4gICAgICAgIGhpID0gdmFsLmhpO1xuICAgIHdoaWxlIChoaSkge1xuICAgICAgICBidWZbcG9zKytdID0gbG8gJiAxMjcgfCAxMjg7XG4gICAgICAgIGxvID0gKGxvID4+PiA3IHwgaGkgPDwgMjUpID4+PiAwO1xuICAgICAgICBoaSA+Pj49IDc7XG4gICAgfVxuICAgIHdoaWxlIChsbyA+IDEyNykge1xuICAgICAgICBidWZbcG9zKytdID0gbG8gJiAxMjcgfCAxMjg7XG4gICAgICAgIGxvID0gbG8gPj4+IDc7XG4gICAgfVxuICAgIGJ1Zltwb3MrK10gPSBsbztcbn1cblxuLyoqXG4gKiBXcml0ZXMgYW4gdW5zaWduZWQgNjQgYml0IHZhbHVlIGFzIGEgdmFyaW50LlxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUudWludDY0ID0gZnVuY3Rpb24gd3JpdGVfdWludDY0KHZhbHVlKSB7XG4gICAgdmFyIGJpdHMgPSBMb25nQml0cy5mcm9tKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZVZhcmludDY0LCBiaXRzLmxlbmd0aCgpLCBiaXRzKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDY0IGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUuaW50NjQgPSBXcml0ZXIucHJvdG90eXBlLnVpbnQ2NDtcblxuLyoqXG4gKiBXcml0ZXMgYSBzaWduZWQgNjQgYml0IHZhbHVlIGFzIGEgdmFyaW50LCB6aWctemFnIGVuY29kZWQuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgdmFsdWVgIGlzIGEgc3RyaW5nIGFuZCBubyBsb25nIGxpYnJhcnkgaXMgcHJlc2VudC5cbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5zaW50NjQgPSBmdW5jdGlvbiB3cml0ZV9zaW50NjQodmFsdWUpIHtcbiAgICB2YXIgYml0cyA9IExvbmdCaXRzLmZyb20odmFsdWUpLnp6RW5jb2RlKCk7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2god3JpdGVWYXJpbnQ2NCwgYml0cy5sZW5ndGgoKSwgYml0cyk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIGJvb2xpc2ggdmFsdWUgYXMgYSB2YXJpbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5ib29sID0gZnVuY3Rpb24gd3JpdGVfYm9vbCh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHdyaXRlQnl0ZSwgMSwgdmFsdWUgPyAxIDogMCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUZpeGVkMzIodmFsLCBidWYsIHBvcykge1xuICAgIGJ1Zltwb3MgICAgXSA9ICB2YWwgICAgICAgICAmIDI1NTtcbiAgICBidWZbcG9zICsgMV0gPSAgdmFsID4+PiA4ICAgJiAyNTU7XG4gICAgYnVmW3BvcyArIDJdID0gIHZhbCA+Pj4gMTYgICYgMjU1O1xuICAgIGJ1Zltwb3MgKyAzXSA9ICB2YWwgPj4+IDI0O1xufVxuXG4vKipcbiAqIFdyaXRlcyBhbiB1bnNpZ25lZCAzMiBiaXQgdmFsdWUgYXMgZml4ZWQgMzIgYml0cy5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZml4ZWQzMiA9IGZ1bmN0aW9uIHdyaXRlX2ZpeGVkMzIodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUZpeGVkMzIsIDQsIHZhbHVlID4+PiAwKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBmaXhlZCAzMiBiaXRzLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnNmaXhlZDMyID0gV3JpdGVyLnByb3RvdHlwZS5maXhlZDMyO1xuXG4vKipcbiAqIFdyaXRlcyBhbiB1bnNpZ25lZCA2NCBiaXQgdmFsdWUgYXMgZml4ZWQgNjQgYml0cy5cbiAqIEBwYXJhbSB7TG9uZ3xudW1iZXJ8c3RyaW5nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGB2YWx1ZWAgaXMgYSBzdHJpbmcgYW5kIG5vIGxvbmcgbGlicmFyeSBpcyBwcmVzZW50LlxuICovXG5Xcml0ZXIucHJvdG90eXBlLmZpeGVkNjQgPSBmdW5jdGlvbiB3cml0ZV9maXhlZDY0KHZhbHVlKSB7XG4gICAgdmFyIGJpdHMgPSBMb25nQml0cy5mcm9tKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUZpeGVkMzIsIDQsIGJpdHMubG8pLl9wdXNoKHdyaXRlRml4ZWQzMiwgNCwgYml0cy5oaSk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUgYXMgZml4ZWQgNjQgYml0cy5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUuc2ZpeGVkNjQgPSBXcml0ZXIucHJvdG90eXBlLmZpeGVkNjQ7XG5cbi8qKlxuICogV3JpdGVzIGEgZmxvYXQgKDMyIGJpdCkuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZmxvYXQgPSBmdW5jdGlvbiB3cml0ZV9mbG9hdCh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHV0aWwuZmxvYXQud3JpdGVGbG9hdExFLCA0LCB2YWx1ZSk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIGRvdWJsZSAoNjQgYml0IGZsb2F0KS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5kb3VibGUgPSBmdW5jdGlvbiB3cml0ZV9kb3VibGUodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh1dGlsLmZsb2F0LndyaXRlRG91YmxlTEUsIDgsIHZhbHVlKTtcbn07XG5cbnZhciB3cml0ZUJ5dGVzID0gdXRpbC5BcnJheS5wcm90b3R5cGUuc2V0XG4gICAgPyBmdW5jdGlvbiB3cml0ZUJ5dGVzX3NldCh2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgICAgIGJ1Zi5zZXQodmFsLCBwb3MpOyAvLyBhbHNvIHdvcmtzIGZvciBwbGFpbiBhcnJheSB2YWx1ZXNcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICA6IGZ1bmN0aW9uIHdyaXRlQnl0ZXNfZm9yKHZhbCwgYnVmLCBwb3MpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWwubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBidWZbcG9zICsgaV0gPSB2YWxbaV07XG4gICAgfTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzZXF1ZW5jZSBvZiBieXRlcy5cbiAqIEBwYXJhbSB7VWludDhBcnJheXxzdHJpbmd9IHZhbHVlIEJ1ZmZlciBvciBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24gd3JpdGVfYnl0ZXModmFsdWUpIHtcbiAgICB2YXIgbGVuID0gdmFsdWUubGVuZ3RoID4+PiAwO1xuICAgIGlmICghbGVuKVxuICAgICAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUJ5dGUsIDEsIDApO1xuICAgIGlmICh1dGlsLmlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgICB2YXIgYnVmID0gV3JpdGVyLmFsbG9jKGxlbiA9IGJhc2U2NC5sZW5ndGgodmFsdWUpKTtcbiAgICAgICAgYmFzZTY0LmRlY29kZSh2YWx1ZSwgYnVmLCAwKTtcbiAgICAgICAgdmFsdWUgPSBidWY7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnVpbnQzMihsZW4pLl9wdXNoKHdyaXRlQnl0ZXMsIGxlbiwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnN0cmluZyA9IGZ1bmN0aW9uIHdyaXRlX3N0cmluZyh2YWx1ZSkge1xuICAgIHZhciBsZW4gPSB1dGY4Lmxlbmd0aCh2YWx1ZSk7XG4gICAgcmV0dXJuIGxlblxuICAgICAgICA/IHRoaXMudWludDMyKGxlbikuX3B1c2godXRmOC53cml0ZSwgbGVuLCB2YWx1ZSlcbiAgICAgICAgOiB0aGlzLl9wdXNoKHdyaXRlQnl0ZSwgMSwgMCk7XG59O1xuXG4vKipcbiAqIEZvcmtzIHRoaXMgd3JpdGVyJ3Mgc3RhdGUgYnkgcHVzaGluZyBpdCB0byBhIHN0YWNrLlxuICogQ2FsbGluZyB7QGxpbmsgV3JpdGVyI3Jlc2V0fHJlc2V0fSBvciB7QGxpbmsgV3JpdGVyI2xkZWxpbXxsZGVsaW19IHJlc2V0cyB0aGUgd3JpdGVyIHRvIHRoZSBwcmV2aW91cyBzdGF0ZS5cbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmZvcmsgPSBmdW5jdGlvbiBmb3JrKCkge1xuICAgIHRoaXMuc3RhdGVzID0gbmV3IFN0YXRlKHRoaXMpO1xuICAgIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG5ldyBPcChub29wLCAwLCAwKTtcbiAgICB0aGlzLmxlbiA9IDA7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlc2V0cyB0aGlzIGluc3RhbmNlIHRvIHRoZSBsYXN0IHN0YXRlLlxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiByZXNldCgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZXMpIHtcbiAgICAgICAgdGhpcy5oZWFkICAgPSB0aGlzLnN0YXRlcy5oZWFkO1xuICAgICAgICB0aGlzLnRhaWwgICA9IHRoaXMuc3RhdGVzLnRhaWw7XG4gICAgICAgIHRoaXMubGVuICAgID0gdGhpcy5zdGF0ZXMubGVuO1xuICAgICAgICB0aGlzLnN0YXRlcyA9IHRoaXMuc3RhdGVzLm5leHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbmV3IE9wKG5vb3AsIDAsIDApO1xuICAgICAgICB0aGlzLmxlbiAgPSAwO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVzZXRzIHRvIHRoZSBsYXN0IHN0YXRlIGFuZCBhcHBlbmRzIHRoZSBmb3JrIHN0YXRlJ3MgY3VycmVudCB3cml0ZSBsZW5ndGggYXMgYSB2YXJpbnQgZm9sbG93ZWQgYnkgaXRzIG9wZXJhdGlvbnMuXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5sZGVsaW0gPSBmdW5jdGlvbiBsZGVsaW0oKSB7XG4gICAgdmFyIGhlYWQgPSB0aGlzLmhlYWQsXG4gICAgICAgIHRhaWwgPSB0aGlzLnRhaWwsXG4gICAgICAgIGxlbiAgPSB0aGlzLmxlbjtcbiAgICB0aGlzLnJlc2V0KCkudWludDMyKGxlbik7XG4gICAgaWYgKGxlbikge1xuICAgICAgICB0aGlzLnRhaWwubmV4dCA9IGhlYWQubmV4dDsgLy8gc2tpcCBub29wXG4gICAgICAgIHRoaXMudGFpbCA9IHRhaWw7XG4gICAgICAgIHRoaXMubGVuICs9IGxlbjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEZpbmlzaGVzIHRoZSB3cml0ZSBvcGVyYXRpb24uXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gRmluaXNoZWQgYnVmZmVyXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gZmluaXNoKCkge1xuICAgIHZhciBoZWFkID0gdGhpcy5oZWFkLm5leHQsIC8vIHNraXAgbm9vcFxuICAgICAgICBidWYgID0gdGhpcy5jb25zdHJ1Y3Rvci5hbGxvYyh0aGlzLmxlbiksXG4gICAgICAgIHBvcyAgPSAwO1xuICAgIHdoaWxlIChoZWFkKSB7XG4gICAgICAgIGhlYWQuZm4oaGVhZC52YWwsIGJ1ZiwgcG9zKTtcbiAgICAgICAgcG9zICs9IGhlYWQubGVuO1xuICAgICAgICBoZWFkID0gaGVhZC5uZXh0O1xuICAgIH1cbiAgICAvLyB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO1xuICAgIHJldHVybiBidWY7XG59O1xuXG5Xcml0ZXIuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uKEJ1ZmZlcldyaXRlcl8pIHtcbiAgICBCdWZmZXJXcml0ZXIgPSBCdWZmZXJXcml0ZXJfO1xuICAgIFdyaXRlci5jcmVhdGUgPSBjcmVhdGUoKTtcbiAgICBCdWZmZXJXcml0ZXIuX2NvbmZpZ3VyZSgpO1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gQnVmZmVyV3JpdGVyO1xuXG4vLyBleHRlbmRzIFdyaXRlclxudmFyIFdyaXRlciA9IHJlcXVpcmUoXCIuL3dyaXRlclwiKTtcbihCdWZmZXJXcml0ZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShXcml0ZXIucHJvdG90eXBlKSkuY29uc3RydWN0b3IgPSBCdWZmZXJXcml0ZXI7XG5cbnZhciB1dGlsID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgYnVmZmVyIHdyaXRlciBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgV2lyZSBmb3JtYXQgd3JpdGVyIHVzaW5nIG5vZGUgYnVmZmVycy5cbiAqIEBleHRlbmRzIFdyaXRlclxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIEJ1ZmZlcldyaXRlcigpIHtcbiAgICBXcml0ZXIuY2FsbCh0aGlzKTtcbn1cblxuQnVmZmVyV3JpdGVyLl9jb25maWd1cmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogQWxsb2NhdGVzIGEgYnVmZmVyIG9mIHRoZSBzcGVjaWZpZWQgc2l6ZS5cbiAgICAgKiBAZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBCdWZmZXIgc2l6ZVxuICAgICAqIEByZXR1cm5zIHtCdWZmZXJ9IEJ1ZmZlclxuICAgICAqL1xuICAgIEJ1ZmZlcldyaXRlci5hbGxvYyA9IHV0aWwuX0J1ZmZlcl9hbGxvY1Vuc2FmZTtcblxuICAgIEJ1ZmZlcldyaXRlci53cml0ZUJ5dGVzQnVmZmVyID0gdXRpbC5CdWZmZXIgJiYgdXRpbC5CdWZmZXIucHJvdG90eXBlIGluc3RhbmNlb2YgVWludDhBcnJheSAmJiB1dGlsLkJ1ZmZlci5wcm90b3R5cGUuc2V0Lm5hbWUgPT09IFwic2V0XCJcbiAgICAgICAgPyBmdW5jdGlvbiB3cml0ZUJ5dGVzQnVmZmVyX3NldCh2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgICAgICAgYnVmLnNldCh2YWwsIHBvcyk7IC8vIGZhc3RlciB0aGFuIGNvcHkgKHJlcXVpcmVzIG5vZGUgPj0gNCB3aGVyZSBCdWZmZXJzIGV4dGVuZCBVaW50OEFycmF5IGFuZCBzZXQgaXMgcHJvcGVybHkgaW5oZXJpdGVkKVxuICAgICAgICAgIC8vIGFsc28gd29ya3MgZm9yIHBsYWluIGFycmF5IHZhbHVlc1xuICAgICAgICB9XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIDogZnVuY3Rpb24gd3JpdGVCeXRlc0J1ZmZlcl9jb3B5KHZhbCwgYnVmLCBwb3MpIHtcbiAgICAgICAgICBpZiAodmFsLmNvcHkpIC8vIEJ1ZmZlciB2YWx1ZXNcbiAgICAgICAgICAgIHZhbC5jb3B5KGJ1ZiwgcG9zLCAwLCB2YWwubGVuZ3RoKTtcbiAgICAgICAgICBlbHNlIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsLmxlbmd0aDspIC8vIHBsYWluIGFycmF5IHZhbHVlc1xuICAgICAgICAgICAgYnVmW3BvcysrXSA9IHZhbFtpKytdO1xuICAgICAgICB9O1xufTtcblxuXG4vKipcbiAqIEBvdmVycmlkZVxuICovXG5CdWZmZXJXcml0ZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24gd3JpdGVfYnl0ZXNfYnVmZmVyKHZhbHVlKSB7XG4gICAgaWYgKHV0aWwuaXNTdHJpbmcodmFsdWUpKVxuICAgICAgICB2YWx1ZSA9IHV0aWwuX0J1ZmZlcl9mcm9tKHZhbHVlLCBcImJhc2U2NFwiKTtcbiAgICB2YXIgbGVuID0gdmFsdWUubGVuZ3RoID4+PiAwO1xuICAgIHRoaXMudWludDMyKGxlbik7XG4gICAgaWYgKGxlbilcbiAgICAgICAgdGhpcy5fcHVzaChCdWZmZXJXcml0ZXIud3JpdGVCeXRlc0J1ZmZlciwgbGVuLCB2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiB3cml0ZVN0cmluZ0J1ZmZlcih2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgaWYgKHZhbC5sZW5ndGggPCA0MCkgLy8gcGxhaW4ganMgaXMgZmFzdGVyIGZvciBzaG9ydCBzdHJpbmdzIChwcm9iYWJseSBkdWUgdG8gcmVkdW5kYW50IGFzc2VydGlvbnMpXG4gICAgICAgIHV0aWwudXRmOC53cml0ZSh2YWwsIGJ1ZiwgcG9zKTtcbiAgICBlbHNlIGlmIChidWYudXRmOFdyaXRlKVxuICAgICAgICBidWYudXRmOFdyaXRlKHZhbCwgcG9zKTtcbiAgICBlbHNlXG4gICAgICAgIGJ1Zi53cml0ZSh2YWwsIHBvcyk7XG59XG5cbi8qKlxuICogQG92ZXJyaWRlXG4gKi9cbkJ1ZmZlcldyaXRlci5wcm90b3R5cGUuc3RyaW5nID0gZnVuY3Rpb24gd3JpdGVfc3RyaW5nX2J1ZmZlcih2YWx1ZSkge1xuICAgIHZhciBsZW4gPSB1dGlsLkJ1ZmZlci5ieXRlTGVuZ3RoKHZhbHVlKTtcbiAgICB0aGlzLnVpbnQzMihsZW4pO1xuICAgIGlmIChsZW4pXG4gICAgICAgIHRoaXMuX3B1c2god3JpdGVTdHJpbmdCdWZmZXIsIGxlbiwgdmFsdWUpO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuXG4vKipcbiAqIEZpbmlzaGVzIHRoZSB3cml0ZSBvcGVyYXRpb24uXG4gKiBAbmFtZSBCdWZmZXJXcml0ZXIjZmluaXNoXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtCdWZmZXJ9IEZpbmlzaGVkIGJ1ZmZlclxuICovXG5cbkJ1ZmZlcldyaXRlci5fY29uZmlndXJlKCk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRlcjtcblxudmFyIHV0aWwgICAgICA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcblxudmFyIEJ1ZmZlclJlYWRlcjsgLy8gY3ljbGljXG5cbnZhciBMb25nQml0cyAgPSB1dGlsLkxvbmdCaXRzLFxuICAgIHV0ZjggICAgICA9IHV0aWwudXRmODtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIGluZGV4T3V0T2ZSYW5nZShyZWFkZXIsIHdyaXRlTGVuZ3RoKSB7XG4gICAgcmV0dXJuIFJhbmdlRXJyb3IoXCJpbmRleCBvdXQgb2YgcmFuZ2U6IFwiICsgcmVhZGVyLnBvcyArIFwiICsgXCIgKyAod3JpdGVMZW5ndGggfHwgMSkgKyBcIiA+IFwiICsgcmVhZGVyLmxlbik7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyByZWFkZXIgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBidWZmZXIuXG4gKiBAY2xhc3NkZXNjIFdpcmUgZm9ybWF0IHJlYWRlciB1c2luZyBgVWludDhBcnJheWAgaWYgYXZhaWxhYmxlLCBvdGhlcndpc2UgYEFycmF5YC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgQnVmZmVyIHRvIHJlYWQgZnJvbVxuICovXG5mdW5jdGlvbiBSZWFkZXIoYnVmZmVyKSB7XG5cbiAgICAvKipcbiAgICAgKiBSZWFkIGJ1ZmZlci5cbiAgICAgKiBAdHlwZSB7VWludDhBcnJheX1cbiAgICAgKi9cbiAgICB0aGlzLmJ1ZiA9IGJ1ZmZlcjtcblxuICAgIC8qKlxuICAgICAqIFJlYWQgYnVmZmVyIHBvc2l0aW9uLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5wb3MgPSAwO1xuXG4gICAgLyoqXG4gICAgICogUmVhZCBidWZmZXIgbGVuZ3RoLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sZW4gPSBidWZmZXIubGVuZ3RoO1xufVxuXG52YXIgY3JlYXRlX2FycmF5ID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09IFwidW5kZWZpbmVkXCJcbiAgICA/IGZ1bmN0aW9uIGNyZWF0ZV90eXBlZF9hcnJheShidWZmZXIpIHtcbiAgICAgICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkgfHwgQXJyYXkuaXNBcnJheShidWZmZXIpKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWFkZXIoYnVmZmVyKTtcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJpbGxlZ2FsIGJ1ZmZlclwiKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICA6IGZ1bmN0aW9uIGNyZWF0ZV9hcnJheShidWZmZXIpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYnVmZmVyKSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVhZGVyKGJ1ZmZlcik7XG4gICAgICAgIHRocm93IEVycm9yKFwiaWxsZWdhbCBidWZmZXJcIik7XG4gICAgfTtcblxudmFyIGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICByZXR1cm4gdXRpbC5CdWZmZXJcbiAgICAgICAgPyBmdW5jdGlvbiBjcmVhdGVfYnVmZmVyX3NldHVwKGJ1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIChSZWFkZXIuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlX2J1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXRpbC5CdWZmZXIuaXNCdWZmZXIoYnVmZmVyKVxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBCdWZmZXJSZWFkZXIoYnVmZmVyKVxuICAgICAgICAgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgICAgICAgICAgICA6IGNyZWF0ZV9hcnJheShidWZmZXIpO1xuICAgICAgICAgICAgfSkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICA6IGNyZWF0ZV9hcnJheTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyByZWFkZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBidWZmZXIuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7VWludDhBcnJheXxCdWZmZXJ9IGJ1ZmZlciBCdWZmZXIgdG8gcmVhZCBmcm9tXG4gKiBAcmV0dXJucyB7UmVhZGVyfEJ1ZmZlclJlYWRlcn0gQSB7QGxpbmsgQnVmZmVyUmVhZGVyfSBpZiBgYnVmZmVyYCBpcyBhIEJ1ZmZlciwgb3RoZXJ3aXNlIGEge0BsaW5rIFJlYWRlcn1cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBgYnVmZmVyYCBpcyBub3QgYSB2YWxpZCBidWZmZXJcbiAqL1xuUmVhZGVyLmNyZWF0ZSA9IGNyZWF0ZSgpO1xuXG5SZWFkZXIucHJvdG90eXBlLl9zbGljZSA9IHV0aWwuQXJyYXkucHJvdG90eXBlLnN1YmFycmF5IHx8IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHV0aWwuQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGFuIHVuc2lnbmVkIDMyIGJpdCB2YWx1ZS5cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLnVpbnQzMiA9IChmdW5jdGlvbiByZWFkX3VpbnQzMl9zZXR1cCgpIHtcbiAgICB2YXIgdmFsdWUgPSA0Mjk0OTY3Mjk1OyAvLyBvcHRpbWl6ZXIgdHlwZS1oaW50LCB0ZW5kcyB0byBkZW9wdCBvdGhlcndpc2UgKD8hKVxuICAgIHJldHVybiBmdW5jdGlvbiByZWFkX3VpbnQzMigpIHtcbiAgICAgICAgdmFsdWUgPSAoICAgICAgICAgdGhpcy5idWZbdGhpcy5wb3NdICYgMTI3ICAgICAgICkgPj4+IDA7IGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOCkgcmV0dXJuIHZhbHVlO1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8ICA3KSA+Pj4gMDsgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KSByZXR1cm4gdmFsdWU7XG4gICAgICAgIHZhbHVlID0gKHZhbHVlIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgMTQpID4+PiAwOyBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpIHJldHVybiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSAodmFsdWUgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCAyMSkgPj4+IDA7IGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOCkgcmV0dXJuIHZhbHVlO1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAgMTUpIDw8IDI4KSA+Pj4gMDsgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KSByZXR1cm4gdmFsdWU7XG5cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgIGlmICgodGhpcy5wb3MgKz0gNSkgPiB0aGlzLmxlbikge1xuICAgICAgICAgICAgdGhpcy5wb3MgPSB0aGlzLmxlbjtcbiAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCAxMCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG59KSgpO1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5pbnQzMiA9IGZ1bmN0aW9uIHJlYWRfaW50MzIoKSB7XG4gICAgcmV0dXJuIHRoaXMudWludDMyKCkgfCAwO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIHppZy16YWcgZW5jb2RlZCB2YXJpbnQgYXMgYSBzaWduZWQgMzIgYml0IHZhbHVlLlxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLnNpbnQzMiA9IGZ1bmN0aW9uIHJlYWRfc2ludDMyKCkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMudWludDMyKCk7XG4gICAgcmV0dXJuIHZhbHVlID4+PiAxIF4gLSh2YWx1ZSAmIDEpIHwgMDtcbn07XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWludmFsaWQtdGhpcyAqL1xuXG5mdW5jdGlvbiByZWFkTG9uZ1ZhcmludCgpIHtcbiAgICAvLyB0ZW5kcyB0byBkZW9wdCB3aXRoIGxvY2FsIHZhcnMgZm9yIG9jdGV0IGV0Yy5cbiAgICB2YXIgYml0cyA9IG5ldyBMb25nQml0cygwLCAwKTtcbiAgICB2YXIgaSA9IDA7XG4gICAgaWYgKHRoaXMubGVuIC0gdGhpcy5wb3MgPiA0KSB7IC8vIGZhc3Qgcm91dGUgKGxvKVxuICAgICAgICBmb3IgKDsgaSA8IDQ7ICsraSkge1xuICAgICAgICAgICAgLy8gMXN0Li40dGhcbiAgICAgICAgICAgIGJpdHMubG8gPSAoYml0cy5sbyB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3KSA+Pj4gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgfVxuICAgICAgICAvLyA1dGhcbiAgICAgICAgYml0cy5sbyA9IChiaXRzLmxvIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgMjgpID4+PiAwO1xuICAgICAgICBiaXRzLmhpID0gKGJpdHMuaGkgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA+PiAgNCkgPj4+IDA7XG4gICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICBpID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKDsgaSA8IDM7ICsraSkge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5sZW4pXG4gICAgICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMpO1xuICAgICAgICAgICAgLy8gMXN0Li4zdGhcbiAgICAgICAgICAgIGJpdHMubG8gPSAoYml0cy5sbyB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3KSA+Pj4gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgfVxuICAgICAgICAvLyA0dGhcbiAgICAgICAgYml0cy5sbyA9IChiaXRzLmxvIHwgKHRoaXMuYnVmW3RoaXMucG9zKytdICYgMTI3KSA8PCBpICogNykgPj4+IDA7XG4gICAgICAgIHJldHVybiBiaXRzO1xuICAgIH1cbiAgICBpZiAodGhpcy5sZW4gLSB0aGlzLnBvcyA+IDQpIHsgLy8gZmFzdCByb3V0ZSAoaGkpXG4gICAgICAgIGZvciAoOyBpIDwgNTsgKytpKSB7XG4gICAgICAgICAgICAvLyA2dGguLjEwdGhcbiAgICAgICAgICAgIGJpdHMuaGkgPSAoYml0cy5oaSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3ICsgMykgPj4+IDA7XG4gICAgICAgICAgICBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKDsgaSA8IDU7ICsraSkge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5sZW4pXG4gICAgICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMpO1xuICAgICAgICAgICAgLy8gNnRoLi4xMHRoXG4gICAgICAgICAgICBiaXRzLmhpID0gKGJpdHMuaGkgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCBpICogNyArIDMpID4+PiAwO1xuICAgICAgICAgICAgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KVxuICAgICAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgdGhyb3cgRXJyb3IoXCJpbnZhbGlkIHZhcmludCBlbmNvZGluZ1wiKTtcbn1cblxuLyogZXNsaW50LWVuYWJsZSBuby1pbnZhbGlkLXRoaXMgKi9cblxuLyoqXG4gKiBSZWFkcyBhIHZhcmludCBhcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUuXG4gKiBAbmFtZSBSZWFkZXIjaW50NjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGFuIHVuc2lnbmVkIDY0IGJpdCB2YWx1ZS5cbiAqIEBuYW1lIFJlYWRlciN1aW50NjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIGEgemlnLXphZyBlbmNvZGVkIHZhcmludCBhcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUuXG4gKiBAbmFtZSBSZWFkZXIjc2ludDY0XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtMb25nfSBWYWx1ZSByZWFkXG4gKi9cblxuLyoqXG4gKiBSZWFkcyBhIHZhcmludCBhcyBhIGJvb2xlYW4uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmJvb2wgPSBmdW5jdGlvbiByZWFkX2Jvb2woKSB7XG4gICAgcmV0dXJuIHRoaXMudWludDMyKCkgIT09IDA7XG59O1xuXG5mdW5jdGlvbiByZWFkRml4ZWQzMl9lbmQoYnVmLCBlbmQpIHsgLy8gbm90ZSB0aGF0IHRoaXMgdXNlcyBgZW5kYCwgbm90IGBwb3NgXG4gICAgcmV0dXJuIChidWZbZW5kIC0gNF1cbiAgICAgICAgICB8IGJ1ZltlbmQgLSAzXSA8PCA4XG4gICAgICAgICAgfCBidWZbZW5kIC0gMl0gPDwgMTZcbiAgICAgICAgICB8IGJ1ZltlbmQgLSAxXSA8PCAyNCkgPj4+IDA7XG59XG5cbi8qKlxuICogUmVhZHMgZml4ZWQgMzIgYml0cyBhcyBhbiB1bnNpZ25lZCAzMiBiaXQgaW50ZWdlci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5maXhlZDMyID0gZnVuY3Rpb24gcmVhZF9maXhlZDMyKCkge1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHRoaXMucG9zICsgNCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgNCk7XG5cbiAgICByZXR1cm4gcmVhZEZpeGVkMzJfZW5kKHRoaXMuYnVmLCB0aGlzLnBvcyArPSA0KTtcbn07XG5cbi8qKlxuICogUmVhZHMgZml4ZWQgMzIgYml0cyBhcyBhIHNpZ25lZCAzMiBiaXQgaW50ZWdlci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5zZml4ZWQzMiA9IGZ1bmN0aW9uIHJlYWRfc2ZpeGVkMzIoKSB7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodGhpcy5wb3MgKyA0ID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCA0KTtcblxuICAgIHJldHVybiByZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpIHwgMDtcbn07XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWludmFsaWQtdGhpcyAqL1xuXG5mdW5jdGlvbiByZWFkRml4ZWQ2NCgvKiB0aGlzOiBSZWFkZXIgKi8pIHtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICh0aGlzLnBvcyArIDggPiB0aGlzLmxlbilcbiAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIDgpO1xuXG4gICAgcmV0dXJuIG5ldyBMb25nQml0cyhyZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpLCByZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpKTtcbn1cblxuLyogZXNsaW50LWVuYWJsZSBuby1pbnZhbGlkLXRoaXMgKi9cblxuLyoqXG4gKiBSZWFkcyBmaXhlZCA2NCBiaXRzLlxuICogQG5hbWUgUmVhZGVyI2ZpeGVkNjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIHppZy16YWcgZW5jb2RlZCBmaXhlZCA2NCBiaXRzLlxuICogQG5hbWUgUmVhZGVyI3NmaXhlZDY0XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtMb25nfSBWYWx1ZSByZWFkXG4gKi9cblxuLyoqXG4gKiBSZWFkcyBhIGZsb2F0ICgzMiBiaXQpIGFzIGEgbnVtYmVyLlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuZmxvYXQgPSBmdW5jdGlvbiByZWFkX2Zsb2F0KCkge1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHRoaXMucG9zICsgNCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgNCk7XG5cbiAgICB2YXIgdmFsdWUgPSB1dGlsLmZsb2F0LnJlYWRGbG9hdExFKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gNDtcbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgZG91YmxlICg2NCBiaXQgZmxvYXQpIGFzIGEgbnVtYmVyLlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuZG91YmxlID0gZnVuY3Rpb24gcmVhZF9kb3VibGUoKSB7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodGhpcy5wb3MgKyA4ID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCA0KTtcblxuICAgIHZhciB2YWx1ZSA9IHV0aWwuZmxvYXQucmVhZERvdWJsZUxFKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gODtcbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgc2VxdWVuY2Ugb2YgYnl0ZXMgcHJlY2VlZGVkIGJ5IGl0cyBsZW5ndGggYXMgYSB2YXJpbnQuXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24gcmVhZF9ieXRlcygpIHtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy51aW50MzIoKSxcbiAgICAgICAgc3RhcnQgID0gdGhpcy5wb3MsXG4gICAgICAgIGVuZCAgICA9IHRoaXMucG9zICsgbGVuZ3RoO1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKGVuZCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgbGVuZ3RoKTtcblxuICAgIHRoaXMucG9zICs9IGxlbmd0aDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmJ1ZikpIC8vIHBsYWluIGFycmF5XG4gICAgICAgIHJldHVybiB0aGlzLmJ1Zi5zbGljZShzdGFydCwgZW5kKTtcblxuICAgIGlmIChzdGFydCA9PT0gZW5kKSB7IC8vIGZpeCBmb3IgSUUgMTAvV2luOCBhbmQgb3RoZXJzJyBzdWJhcnJheSByZXR1cm5pbmcgYXJyYXkgb2Ygc2l6ZSAxXG4gICAgICAgIHZhciBuYXRpdmVCdWZmZXIgPSB1dGlsLkJ1ZmZlcjtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUJ1ZmZlclxuICAgICAgICAgICAgPyBuYXRpdmVCdWZmZXIuYWxsb2MoMClcbiAgICAgICAgICAgIDogbmV3IHRoaXMuYnVmLmNvbnN0cnVjdG9yKDApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2xpY2UuY2FsbCh0aGlzLmJ1Ziwgc3RhcnQsIGVuZCk7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgc3RyaW5nIHByZWNlZWRlZCBieSBpdHMgYnl0ZSBsZW5ndGggYXMgYSB2YXJpbnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuc3RyaW5nID0gZnVuY3Rpb24gcmVhZF9zdHJpbmcoKSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy5ieXRlcygpO1xuICAgIHJldHVybiB1dGY4LnJlYWQoYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCk7XG59O1xuXG4vKipcbiAqIFNraXBzIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzIGlmIHNwZWNpZmllZCwgb3RoZXJ3aXNlIHNraXBzIGEgdmFyaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIExlbmd0aCBpZiBrbm93biwgb3RoZXJ3aXNlIGEgdmFyaW50IGlzIGFzc3VtZWRcbiAqIEByZXR1cm5zIHtSZWFkZXJ9IGB0aGlzYFxuICovXG5SZWFkZXIucHJvdG90eXBlLnNraXAgPSBmdW5jdGlvbiBza2lwKGxlbmd0aCkge1xuICAgIGlmICh0eXBlb2YgbGVuZ3RoID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAodGhpcy5wb3MgKyBsZW5ndGggPiB0aGlzLmxlbilcbiAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB0aGlzLnBvcyArPSBsZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5sZW4pXG4gICAgICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMpO1xuICAgICAgICB9IHdoaWxlICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSAmIDEyOCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZWN1cnNpb24gbGltaXQuXG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5SZWFkZXIucmVjdXJzaW9uTGltaXQgPSB1dGlsLnJlY3Vyc2lvbkxpbWl0O1xuXG4vKipcbiAqIFNraXBzIHRoZSBuZXh0IGVsZW1lbnQgb2YgdGhlIHNwZWNpZmllZCB3aXJlIHR5cGUuXG4gKiBAcGFyYW0ge251bWJlcn0gd2lyZVR5cGUgV2lyZSB0eXBlIHJlY2VpdmVkXG4gKiBAcGFyYW0ge251bWJlcn0gW2RlcHRoXSBEZXB0aCBvZiByZWN1cnNpb24gdG8gY29udHJvbCBuZXN0ZWQgY2FsbHM7IDAgaWYgb21pdHRlZFxuICogQHJldHVybnMge1JlYWRlcn0gYHRoaXNgXG4gKi9cblJlYWRlci5wcm90b3R5cGUuc2tpcFR5cGUgPSBmdW5jdGlvbih3aXJlVHlwZSwgZGVwdGgpIHtcbiAgICBpZiAoZGVwdGggPT09IHVuZGVmaW5lZCkgZGVwdGggPSAwO1xuICAgIGlmIChkZXB0aCA+IFJlYWRlci5yZWN1cnNpb25MaW1pdClcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJtYXhpbXVtIG5lc3RpbmcgZGVwdGggZXhjZWVkZWRcIik7XG4gICAgc3dpdGNoICh3aXJlVHlwZSkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICB0aGlzLnNraXAoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICB0aGlzLnNraXAoOCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgdGhpcy5za2lwKHRoaXMudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgIHdoaWxlICgod2lyZVR5cGUgPSB0aGlzLnVpbnQzMigpICYgNykgIT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNraXBUeXBlKHdpcmVUeXBlLCBkZXB0aCArIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgIHRoaXMuc2tpcCg0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcImludmFsaWQgd2lyZSB0eXBlIFwiICsgd2lyZVR5cGUgKyBcIiBhdCBvZmZzZXQgXCIgKyB0aGlzLnBvcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcblxuUmVhZGVyLl9jb25maWd1cmUgPSBmdW5jdGlvbihCdWZmZXJSZWFkZXJfKSB7XG4gICAgQnVmZmVyUmVhZGVyID0gQnVmZmVyUmVhZGVyXztcbiAgICBSZWFkZXIuY3JlYXRlID0gY3JlYXRlKCk7XG4gICAgQnVmZmVyUmVhZGVyLl9jb25maWd1cmUoKTtcblxuICAgIHZhciBmbiA9IHV0aWwuTG9uZyA/IFwidG9Mb25nXCIgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBcInRvTnVtYmVyXCI7XG4gICAgdXRpbC5tZXJnZShSZWFkZXIucHJvdG90eXBlLCB7XG5cbiAgICAgICAgaW50NjQ6IGZ1bmN0aW9uIHJlYWRfaW50NjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZExvbmdWYXJpbnQuY2FsbCh0aGlzKVtmbl0oZmFsc2UpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHVpbnQ2NDogZnVuY3Rpb24gcmVhZF91aW50NjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZExvbmdWYXJpbnQuY2FsbCh0aGlzKVtmbl0odHJ1ZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2ludDY0OiBmdW5jdGlvbiByZWFkX3NpbnQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkTG9uZ1ZhcmludC5jYWxsKHRoaXMpLnp6RGVjb2RlKClbZm5dKGZhbHNlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBmaXhlZDY0OiBmdW5jdGlvbiByZWFkX2ZpeGVkNjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZEZpeGVkNjQuY2FsbCh0aGlzKVtmbl0odHJ1ZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2ZpeGVkNjQ6IGZ1bmN0aW9uIHJlYWRfc2ZpeGVkNjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZEZpeGVkNjQuY2FsbCh0aGlzKVtmbl0oZmFsc2UpO1xuICAgICAgICB9XG5cbiAgICB9KTtcbn07XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IEJ1ZmZlclJlYWRlcjtcblxuLy8gZXh0ZW5kcyBSZWFkZXJcbnZhciBSZWFkZXIgPSByZXF1aXJlKFwiLi9yZWFkZXJcIik7XG4oQnVmZmVyUmVhZGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoUmVhZGVyLnByb3RvdHlwZSkpLmNvbnN0cnVjdG9yID0gQnVmZmVyUmVhZGVyO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IGJ1ZmZlciByZWFkZXIgaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFdpcmUgZm9ybWF0IHJlYWRlciB1c2luZyBub2RlIGJ1ZmZlcnMuXG4gKiBAZXh0ZW5kcyBSZWFkZXJcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciBCdWZmZXIgdG8gcmVhZCBmcm9tXG4gKi9cbmZ1bmN0aW9uIEJ1ZmZlclJlYWRlcihidWZmZXIpIHtcbiAgICBSZWFkZXIuY2FsbCh0aGlzLCBidWZmZXIpO1xuXG4gICAgLyoqXG4gICAgICogUmVhZCBidWZmZXIuXG4gICAgICogQG5hbWUgQnVmZmVyUmVhZGVyI2J1ZlxuICAgICAqIEB0eXBlIHtCdWZmZXJ9XG4gICAgICovXG59XG5cbkJ1ZmZlclJlYWRlci5fY29uZmlndXJlID0gZnVuY3Rpb24gKCkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHV0aWwuQnVmZmVyKVxuICAgICAgICBCdWZmZXJSZWFkZXIucHJvdG90eXBlLl9zbGljZSA9IHV0aWwuQnVmZmVyLnByb3RvdHlwZS5zbGljZTtcbn07XG5cblxuLyoqXG4gKiBAb3ZlcnJpZGVcbiAqL1xuQnVmZmVyUmVhZGVyLnByb3RvdHlwZS5zdHJpbmcgPSBmdW5jdGlvbiByZWFkX3N0cmluZ19idWZmZXIoKSB7XG4gICAgdmFyIGxlbiA9IHRoaXMudWludDMyKCk7IC8vIG1vZGlmaWVzIHBvc1xuICAgIHJldHVybiB0aGlzLmJ1Zi51dGY4U2xpY2VcbiAgICAgICAgPyB0aGlzLmJ1Zi51dGY4U2xpY2UodGhpcy5wb3MsIHRoaXMucG9zID0gTWF0aC5taW4odGhpcy5wb3MgKyBsZW4sIHRoaXMubGVuKSlcbiAgICAgICAgOiB0aGlzLmJ1Zi50b1N0cmluZyhcInV0Zi04XCIsIHRoaXMucG9zLCB0aGlzLnBvcyA9IE1hdGgubWluKHRoaXMucG9zICsgbGVuLCB0aGlzLmxlbikpO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIHNlcXVlbmNlIG9mIGJ5dGVzIHByZWNlZWRlZCBieSBpdHMgbGVuZ3RoIGFzIGEgdmFyaW50LlxuICogQG5hbWUgQnVmZmVyUmVhZGVyI2J5dGVzXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtCdWZmZXJ9IFZhbHVlIHJlYWRcbiAqL1xuXG5CdWZmZXJSZWFkZXIuX2NvbmZpZ3VyZSgpO1xuIiwgIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBTZXJ2aWNlO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsL21pbmltYWxcIik7XG5cbi8vIEV4dGVuZHMgRXZlbnRFbWl0dGVyXG4oU2VydmljZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHV0aWwuRXZlbnRFbWl0dGVyLnByb3RvdHlwZSkpLmNvbnN0cnVjdG9yID0gU2VydmljZTtcblxuLyoqXG4gKiBBIHNlcnZpY2UgbWV0aG9kIGNhbGxiYWNrIGFzIHVzZWQgYnkge0BsaW5rIHJwYy5TZXJ2aWNlTWV0aG9kfFNlcnZpY2VNZXRob2R9LlxuICpcbiAqIERpZmZlcnMgZnJvbSB7QGxpbmsgUlBDSW1wbENhbGxiYWNrfSBpbiB0aGF0IGl0IGlzIGFuIGFjdHVhbCBjYWxsYmFjayBvZiBhIHNlcnZpY2UgbWV0aG9kIHdoaWNoIG1heSBub3QgcmV0dXJuIGByZXNwb25zZSA9IG51bGxgLlxuICogQHR5cGVkZWYgcnBjLlNlcnZpY2VNZXRob2RDYWxsYmFja1xuICogQHRlbXBsYXRlIFRSZXMgZXh0ZW5kcyBNZXNzYWdlPFRSZXM+XG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcGFyYW0ge0Vycm9yfG51bGx9IGVycm9yIEVycm9yLCBpZiBhbnlcbiAqIEBwYXJhbSB7VFJlc30gW3Jlc3BvbnNlXSBSZXNwb25zZSBtZXNzYWdlXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICovXG5cbi8qKlxuICogQSBzZXJ2aWNlIG1ldGhvZCBwYXJ0IG9mIGEge0BsaW5rIHJwYy5TZXJ2aWNlfSBhcyBjcmVhdGVkIGJ5IHtAbGluayBTZXJ2aWNlLmNyZWF0ZX0uXG4gKiBAdHlwZWRlZiBycGMuU2VydmljZU1ldGhvZFxuICogQHRlbXBsYXRlIFRSZXEgZXh0ZW5kcyBNZXNzYWdlPFRSZXE+XG4gKiBAdGVtcGxhdGUgVFJlcyBleHRlbmRzIE1lc3NhZ2U8VFJlcz5cbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7VFJlcXxQcm9wZXJ0aWVzPFRSZXE+fSByZXF1ZXN0IFJlcXVlc3QgbWVzc2FnZSBvciBwbGFpbiBvYmplY3RcbiAqIEBwYXJhbSB7cnBjLlNlcnZpY2VNZXRob2RDYWxsYmFjazxUUmVzPn0gW2NhbGxiYWNrXSBOb2RlLXN0eWxlIGNhbGxiYWNrIGNhbGxlZCB3aXRoIHRoZSBlcnJvciwgaWYgYW55LCBhbmQgdGhlIHJlc3BvbnNlIG1lc3NhZ2VcbiAqIEByZXR1cm5zIHtQcm9taXNlPE1lc3NhZ2U8VFJlcz4+fSBQcm9taXNlIGlmIGBjYWxsYmFja2AgaGFzIGJlZW4gb21pdHRlZCwgb3RoZXJ3aXNlIGB1bmRlZmluZWRgXG4gKi9cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IFJQQyBzZXJ2aWNlIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBBbiBSUEMgc2VydmljZSBhcyByZXR1cm5lZCBieSB7QGxpbmsgU2VydmljZSNjcmVhdGV9LlxuICogQGV4cG9ydHMgcnBjLlNlcnZpY2VcbiAqIEBleHRlbmRzIHV0aWwuRXZlbnRFbWl0dGVyXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7UlBDSW1wbH0gcnBjSW1wbCBSUEMgaW1wbGVtZW50YXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JlcXVlc3REZWxpbWl0ZWQ9ZmFsc2VdIFdoZXRoZXIgcmVxdWVzdHMgYXJlIGxlbmd0aC1kZWxpbWl0ZWRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Jlc3BvbnNlRGVsaW1pdGVkPWZhbHNlXSBXaGV0aGVyIHJlc3BvbnNlcyBhcmUgbGVuZ3RoLWRlbGltaXRlZFxuICovXG5mdW5jdGlvbiBTZXJ2aWNlKHJwY0ltcGwsIHJlcXVlc3REZWxpbWl0ZWQsIHJlc3BvbnNlRGVsaW1pdGVkKSB7XG5cbiAgICBpZiAodHlwZW9mIHJwY0ltcGwgIT09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwicnBjSW1wbCBtdXN0IGJlIGEgZnVuY3Rpb25cIik7XG5cbiAgICB1dGlsLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xuXG4gICAgLyoqXG4gICAgICogUlBDIGltcGxlbWVudGF0aW9uLiBCZWNvbWVzIGBudWxsYCBvbmNlIHRoZSBzZXJ2aWNlIGlzIGVuZGVkLlxuICAgICAqIEB0eXBlIHtSUENJbXBsfG51bGx9XG4gICAgICovXG4gICAgdGhpcy5ycGNJbXBsID0gcnBjSW1wbDtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgcmVxdWVzdHMgYXJlIGxlbmd0aC1kZWxpbWl0ZWQuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5yZXF1ZXN0RGVsaW1pdGVkID0gQm9vbGVhbihyZXF1ZXN0RGVsaW1pdGVkKTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgcmVzcG9uc2VzIGFyZSBsZW5ndGgtZGVsaW1pdGVkLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMucmVzcG9uc2VEZWxpbWl0ZWQgPSBCb29sZWFuKHJlc3BvbnNlRGVsaW1pdGVkKTtcbn1cblxuLyoqXG4gKiBDYWxscyBhIHNlcnZpY2UgbWV0aG9kIHRocm91Z2gge0BsaW5rIHJwYy5TZXJ2aWNlI3JwY0ltcGx8cnBjSW1wbH0uXG4gKiBAcGFyYW0ge01ldGhvZHxycGMuU2VydmljZU1ldGhvZDxUUmVxLFRSZXM+fSBtZXRob2QgUmVmbGVjdGVkIG9yIHN0YXRpYyBtZXRob2RcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8VFJlcT59IHJlcXVlc3RDdG9yIFJlcXVlc3QgY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8VFJlcz59IHJlc3BvbnNlQ3RvciBSZXNwb25zZSBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtUUmVxfFByb3BlcnRpZXM8VFJlcT59IHJlcXVlc3QgUmVxdWVzdCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdFxuICogQHBhcmFtIHtycGMuU2VydmljZU1ldGhvZENhbGxiYWNrPFRSZXM+fSBjYWxsYmFjayBTZXJ2aWNlIGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICogQHRlbXBsYXRlIFRSZXEgZXh0ZW5kcyBNZXNzYWdlPFRSZXE+XG4gKiBAdGVtcGxhdGUgVFJlcyBleHRlbmRzIE1lc3NhZ2U8VFJlcz5cbiAqL1xuU2VydmljZS5wcm90b3R5cGUucnBjQ2FsbCA9IGZ1bmN0aW9uIHJwY0NhbGwobWV0aG9kLCByZXF1ZXN0Q3RvciwgcmVzcG9uc2VDdG9yLCByZXF1ZXN0LCBjYWxsYmFjaykge1xuXG4gICAgaWYgKCFyZXF1ZXN0KVxuICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJyZXF1ZXN0IG11c3QgYmUgc3BlY2lmaWVkXCIpO1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgIHJldHVybiB1dGlsLmFzUHJvbWlzZShycGNDYWxsLCBzZWxmLCBtZXRob2QsIHJlcXVlc3RDdG9yLCByZXNwb25zZUN0b3IsIHJlcXVlc3QpO1xuXG4gICAgaWYgKCFzZWxmLnJwY0ltcGwpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgY2FsbGJhY2soRXJyb3IoXCJhbHJlYWR5IGVuZGVkXCIpKTsgfSwgMCk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHNlbGYucnBjSW1wbChcbiAgICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICAgIHJlcXVlc3RDdG9yW3NlbGYucmVxdWVzdERlbGltaXRlZCA/IFwiZW5jb2RlRGVsaW1pdGVkXCIgOiBcImVuY29kZVwiXShyZXF1ZXN0KS5maW5pc2goKSxcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJwY0NhbGxiYWNrKGVyciwgcmVzcG9uc2UpIHtcblxuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgZXJyLCBtZXRob2QpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbmQoLyogZW5kZWRCeVJQQyAqLyB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIShyZXNwb25zZSBpbnN0YW5jZW9mIHJlc3BvbnNlQ3RvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gcmVzcG9uc2VDdG9yW3NlbGYucmVzcG9uc2VEZWxpbWl0ZWQgPyBcImRlY29kZURlbGltaXRlZFwiIDogXCJkZWNvZGVcIl0ocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdChcImVycm9yXCIsIGVyciwgbWV0aG9kKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgc2VsZi5lbWl0KFwiZGF0YVwiLCByZXNwb25zZSwgbWV0aG9kKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnIsIG1ldGhvZCk7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNhbGxiYWNrKGVycik7IH0sIDApO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbn07XG5cbi8qKlxuICogRW5kcyB0aGlzIHNlcnZpY2UgYW5kIGVtaXRzIHRoZSBgZW5kYCBldmVudC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2VuZGVkQnlSUEM9ZmFsc2VdIFdoZXRoZXIgdGhlIHNlcnZpY2UgaGFzIGJlZW4gZW5kZWQgYnkgdGhlIFJQQyBpbXBsZW1lbnRhdGlvbi5cbiAqIEByZXR1cm5zIHtycGMuU2VydmljZX0gYHRoaXNgXG4gKi9cblNlcnZpY2UucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIGVuZChlbmRlZEJ5UlBDKSB7XG4gICAgaWYgKHRoaXMucnBjSW1wbCkge1xuICAgICAgICBpZiAoIWVuZGVkQnlSUEMpIC8vIHNpZ25hbCBlbmQgdG8gcnBjSW1wbFxuICAgICAgICAgICAgdGhpcy5ycGNJbXBsKG51bGwsIG51bGwsIG51bGwpO1xuICAgICAgICB0aGlzLnJwY0ltcGwgPSBudWxsO1xuICAgICAgICB0aGlzLmVtaXQoXCJlbmRcIikub2ZmKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcblxuLyoqXG4gKiBTdHJlYW1pbmcgUlBDIGhlbHBlcnMuXG4gKiBAbmFtZXNwYWNlXG4gKi9cbnZhciBycGMgPSBleHBvcnRzO1xuXG4vKipcbiAqIFJQQyBpbXBsZW1lbnRhdGlvbiBwYXNzZWQgdG8ge0BsaW5rIFNlcnZpY2UjY3JlYXRlfSBwZXJmb3JtaW5nIGEgc2VydmljZSByZXF1ZXN0IG9uIG5ldHdvcmsgbGV2ZWwsIGkuZS4gYnkgdXRpbGl6aW5nIGh0dHAgcmVxdWVzdHMgb3Igd2Vic29ja2V0cy5cbiAqIEB0eXBlZGVmIFJQQ0ltcGxcbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7TWV0aG9kfHJwYy5TZXJ2aWNlTWV0aG9kPE1lc3NhZ2U8e30+LE1lc3NhZ2U8e30+Pn0gbWV0aG9kIFJlZmxlY3RlZCBvciBzdGF0aWMgbWV0aG9kIGJlaW5nIGNhbGxlZFxuICogQHBhcmFtIHtVaW50OEFycmF5fSByZXF1ZXN0RGF0YSBSZXF1ZXN0IGRhdGFcbiAqIEBwYXJhbSB7UlBDSW1wbENhbGxiYWNrfSBjYWxsYmFjayBDYWxsYmFjayBmdW5jdGlvblxuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqIEBleGFtcGxlXG4gKiBmdW5jdGlvbiBycGNJbXBsKG1ldGhvZCwgcmVxdWVzdERhdGEsIGNhbGxiYWNrKSB7XG4gKiAgICAgaWYgKHByb3RvYnVmLnV0aWwubGNGaXJzdChtZXRob2QubmFtZSkgIT09IFwibXlNZXRob2RcIikgLy8gY29tcGF0aWJsZSB3aXRoIHN0YXRpYyBjb2RlXG4gKiAgICAgICAgIHRocm93IEVycm9yKFwibm8gc3VjaCBtZXRob2RcIik7XG4gKiAgICAgYXN5bmNocm9ub3VzbHlPYnRhaW5BUmVzcG9uc2UocmVxdWVzdERhdGEsIGZ1bmN0aW9uKGVyciwgcmVzcG9uc2VEYXRhKSB7XG4gKiAgICAgICAgIGNhbGxiYWNrKGVyciwgcmVzcG9uc2VEYXRhKTtcbiAqICAgICB9KTtcbiAqIH1cbiAqL1xuXG4vKipcbiAqIE5vZGUtc3R5bGUgY2FsbGJhY2sgYXMgdXNlZCBieSB7QGxpbmsgUlBDSW1wbH0uXG4gKiBAdHlwZWRlZiBSUENJbXBsQ2FsbGJhY2tcbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7RXJyb3J8bnVsbH0gZXJyb3IgRXJyb3IsIGlmIGFueSwgb3RoZXJ3aXNlIGBudWxsYFxuICogQHBhcmFtIHtVaW50OEFycmF5fG51bGx9IFtyZXNwb25zZV0gUmVzcG9uc2UgZGF0YSBvciBgbnVsbGAgdG8gc2lnbmFsIGVuZCBvZiBzdHJlYW0sIGlmIHRoZXJlIGhhc24ndCBiZWVuIGFuIGVycm9yXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICovXG5cbnJwYy5TZXJ2aWNlID0gcmVxdWlyZShcIi4vcnBjL3NlcnZpY2VcIik7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbi8qKlxuICogTmFtZWQgcm9vdHMuXG4gKiBUaGlzIGlzIHdoZXJlIHBianMgc3RvcmVzIGdlbmVyYXRlZCBzdHJ1Y3R1cmVzICh0aGUgb3B0aW9uIGAtciwgLS1yb290YCBzcGVjaWZpZXMgYSBuYW1lKS5cbiAqIENhbiBhbHNvIGJlIHVzZWQgbWFudWFsbHkgdG8gbWFrZSByb290cyBhdmFpbGFibGUgYWNyb3NzIG1vZHVsZXMuXG4gKiBAbmFtZSByb290c1xuICogQHR5cGUge09iamVjdC48c3RyaW5nLFJvb3Q+fVxuICogQGV4YW1wbGVcbiAqIC8vIHBianMgLXIgbXlyb290IC1vIGNvbXBpbGVkLmpzIC4uLlxuICpcbiAqIC8vIGluIGFub3RoZXIgbW9kdWxlOlxuICogcmVxdWlyZShcIi4vY29tcGlsZWQuanNcIik7XG4gKlxuICogLy8gaW4gYW55IHN1YnNlcXVlbnQgbW9kdWxlOlxuICogdmFyIHJvb3QgPSBwcm90b2J1Zi5yb290c1tcIm15cm9vdFwiXTtcbiAqL1xuIiwgIlwidXNlIHN0cmljdFwiO1xudmFyIHByb3RvYnVmID0gZXhwb3J0cztcblxuLyoqXG4gKiBCdWlsZCB0eXBlLCBvbmUgb2YgYFwiZnVsbFwiYCwgYFwibGlnaHRcImAgb3IgYFwibWluaW1hbFwiYC5cbiAqIEBuYW1lIGJ1aWxkXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGNvbnN0XG4gKi9cbnByb3RvYnVmLmJ1aWxkID0gXCJtaW5pbWFsXCI7XG5cbi8vIFNlcmlhbGl6YXRpb25cbnByb3RvYnVmLldyaXRlciAgICAgICA9IHJlcXVpcmUoXCIuL3dyaXRlclwiKTtcbnByb3RvYnVmLkJ1ZmZlcldyaXRlciA9IHJlcXVpcmUoXCIuL3dyaXRlcl9idWZmZXJcIik7XG5wcm90b2J1Zi5SZWFkZXIgICAgICAgPSByZXF1aXJlKFwiLi9yZWFkZXJcIik7XG5wcm90b2J1Zi5CdWZmZXJSZWFkZXIgPSByZXF1aXJlKFwiLi9yZWFkZXJfYnVmZmVyXCIpO1xuXG4vLyBVdGlsaXR5XG5wcm90b2J1Zi51dGlsICAgICAgICAgPSByZXF1aXJlKFwiLi91dGlsL21pbmltYWxcIik7XG5wcm90b2J1Zi5ycGMgICAgICAgICAgPSByZXF1aXJlKFwiLi9ycGNcIik7XG5wcm90b2J1Zi5yb290cyAgICAgICAgPSByZXF1aXJlKFwiLi9yb290c1wiKTtcbnByb3RvYnVmLmNvbmZpZ3VyZSAgICA9IGNvbmZpZ3VyZTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbi8qKlxuICogUmVjb25maWd1cmVzIHRoZSBsaWJyYXJ5IGFjY29yZGluZyB0byB0aGUgZW52aXJvbm1lbnQuXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBjb25maWd1cmUoKSB7XG4gICAgcHJvdG9idWYudXRpbC5fY29uZmlndXJlKCk7XG4gICAgcHJvdG9idWYuV3JpdGVyLl9jb25maWd1cmUocHJvdG9idWYuQnVmZmVyV3JpdGVyKTtcbiAgICBwcm90b2J1Zi5SZWFkZXIuX2NvbmZpZ3VyZShwcm90b2J1Zi5CdWZmZXJSZWFkZXIpO1xufVxuXG4vLyBTZXQgdXAgYnVmZmVyIHV0aWxpdHkgYWNjb3JkaW5nIHRvIHRoZSBlbnZpcm9ubWVudFxuY29uZmlndXJlKCk7XG4iLCAiLy8gbWluaW1hbCBsaWJyYXJ5IGVudHJ5IHBvaW50LlxuXG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vc3JjL2luZGV4LW1pbmltYWxcIik7XG4iLCAiLyplc2xpbnQtZGlzYWJsZSBibG9jay1zY29wZWQtdmFyLCBpZC1sZW5ndGgsIG5vLWNvbnRyb2wtcmVnZXgsIG5vLW1hZ2ljLW51bWJlcnMsIG5vLXByb3RvdHlwZS1idWlsdGlucywgbm8tcmVkZWNsYXJlLCBuby1zaGFkb3csIG5vLXZhciwgc29ydC12YXJzKi9cbid1c2Ugc3RyaWN0JztcblxudmFyICRwcm90b2J1ZiA9IHJlcXVpcmUoJ3Byb3RvYnVmanMvbWluaW1hbCcpO1xuXG4vLyBDb21tb24gYWxpYXNlc1xudmFyICRSZWFkZXIgPSAkcHJvdG9idWYuUmVhZGVyLFxuICAkV3JpdGVyID0gJHByb3RvYnVmLldyaXRlcixcbiAgJHV0aWwgPSAkcHJvdG9idWYudXRpbDtcblxuLy8gRXhwb3J0ZWQgcm9vdCBuYW1lc3BhY2VcbnZhciAkcm9vdCA9ICRwcm90b2J1Zi5yb290c1snZGVmYXVsdCddIHx8ICgkcHJvdG9idWYucm9vdHNbJ2RlZmF1bHQnXSA9IHt9KTtcblxuJHJvb3Qub25ueCA9IChmdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBOYW1lc3BhY2Ugb25ueC5cbiAgICogQGV4cG9ydHMgb25ueFxuICAgKiBAbmFtZXNwYWNlXG4gICAqL1xuICB2YXIgb25ueCA9IHt9O1xuXG4gIC8qKlxuICAgKiBWZXJzaW9uIGVudW0uXG4gICAqIEBuYW1lIG9ubnguVmVyc2lvblxuICAgKiBAZW51bSB7bnVtYmVyfVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gX1NUQVJUX1ZFUlNJT049MCBfU1RBUlRfVkVSU0lPTiB2YWx1ZVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDE3XzEwXzEwPTEgSVJfVkVSU0lPTl8yMDE3XzEwXzEwIHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMTdfMTBfMzA9MiBJUl9WRVJTSU9OXzIwMTdfMTBfMzAgdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxN18xMV8zPTMgSVJfVkVSU0lPTl8yMDE3XzExXzMgdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxOV8xXzIyPTQgSVJfVkVSU0lPTl8yMDE5XzFfMjIgdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxOV8zXzE4PTUgSVJfVkVSU0lPTl8yMDE5XzNfMTggdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxOV85XzE5PTYgSVJfVkVSU0lPTl8yMDE5XzlfMTkgdmFsdWVcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAyMF81Xzg9NyBJUl9WRVJTSU9OXzIwMjBfNV84IHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMjFfN18zMD04IElSX1ZFUlNJT05fMjAyMV83XzMwIHZhbHVlXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OPTkgSVJfVkVSU0lPTiB2YWx1ZVxuICAgKi9cbiAgb25ueC5WZXJzaW9uID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LFxuICAgICAgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMF0gPSAnX1NUQVJUX1ZFUlNJT04nKV0gPSAwO1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxXSA9ICdJUl9WRVJTSU9OXzIwMTdfMTBfMTAnKV0gPSAxO1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFsyXSA9ICdJUl9WRVJTSU9OXzIwMTdfMTBfMzAnKV0gPSAyO1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFszXSA9ICdJUl9WRVJTSU9OXzIwMTdfMTFfMycpXSA9IDM7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzRdID0gJ0lSX1ZFUlNJT05fMjAxOV8xXzIyJyldID0gNDtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbNV0gPSAnSVJfVkVSU0lPTl8yMDE5XzNfMTgnKV0gPSA1O1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFs2XSA9ICdJUl9WRVJTSU9OXzIwMTlfOV8xOScpXSA9IDY7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzddID0gJ0lSX1ZFUlNJT05fMjAyMF81XzgnKV0gPSA3O1xuICAgIHZhbHVlc1sodmFsdWVzQnlJZFs4XSA9ICdJUl9WRVJTSU9OXzIwMjFfN18zMCcpXSA9IDg7XG4gICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzldID0gJ0lSX1ZFUlNJT04nKV0gPSA5O1xuICAgIHJldHVybiB2YWx1ZXM7XG4gIH0pKCk7XG5cbiAgb25ueC5BdHRyaWJ1dGVQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhbiBBdHRyaWJ1dGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSUF0dHJpYnV0ZVByb3RvXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW25hbWVdIEF0dHJpYnV0ZVByb3RvIG5hbWVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbcmVmQXR0ck5hbWVdIEF0dHJpYnV0ZVByb3RvIHJlZkF0dHJOYW1lXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gQXR0cmlidXRlUHJvdG8gZG9jU3RyaW5nXG4gICAgICogQHByb3BlcnR5IHtvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGV8bnVsbH0gW3R5cGVdIEF0dHJpYnV0ZVByb3RvIHR5cGVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBbZl0gQXR0cmlidXRlUHJvdG8gZlxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW2ldIEF0dHJpYnV0ZVByb3RvIGlcbiAgICAgKiBAcHJvcGVydHkge1VpbnQ4QXJyYXl8bnVsbH0gW3NdIEF0dHJpYnV0ZVByb3RvIHNcbiAgICAgKiBAcHJvcGVydHkge29ubnguSVRlbnNvclByb3RvfG51bGx9IFt0XSBBdHRyaWJ1dGVQcm90byB0XG4gICAgICogQHByb3BlcnR5IHtvbm54LklHcmFwaFByb3RvfG51bGx9IFtnXSBBdHRyaWJ1dGVQcm90byBnXG4gICAgICogQHByb3BlcnR5IHtvbm54LklTcGFyc2VUZW5zb3JQcm90b3xudWxsfSBbc3BhcnNlVGVuc29yXSBBdHRyaWJ1dGVQcm90byBzcGFyc2VUZW5zb3JcbiAgICAgKiBAcHJvcGVydHkge29ubnguSVR5cGVQcm90b3xudWxsfSBbdHBdIEF0dHJpYnV0ZVByb3RvIHRwXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyPnxudWxsfSBbZmxvYXRzXSBBdHRyaWJ1dGVQcm90byBmbG9hdHNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXJ8TG9uZz58bnVsbH0gW2ludHNdIEF0dHJpYnV0ZVByb3RvIGludHNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxVaW50OEFycmF5PnxudWxsfSBbc3RyaW5nc10gQXR0cmlidXRlUHJvdG8gc3RyaW5nc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVRlbnNvclByb3RvPnxudWxsfSBbdGVuc29yc10gQXR0cmlidXRlUHJvdG8gdGVuc29yc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSUdyYXBoUHJvdG8+fG51bGx9IFtncmFwaHNdIEF0dHJpYnV0ZVByb3RvIGdyYXBoc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVNwYXJzZVRlbnNvclByb3RvPnxudWxsfSBbc3BhcnNlVGVuc29yc10gQXR0cmlidXRlUHJvdG8gc3BhcnNlVGVuc29yc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVR5cGVQcm90bz58bnVsbH0gW3R5cGVQcm90b3NdIEF0dHJpYnV0ZVByb3RvIHR5cGVQcm90b3NcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgQXR0cmlidXRlUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYW4gQXR0cmlidXRlUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSUF0dHJpYnV0ZVByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklBdHRyaWJ1dGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEF0dHJpYnV0ZVByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMuZmxvYXRzID0gW107XG4gICAgICB0aGlzLmludHMgPSBbXTtcbiAgICAgIHRoaXMuc3RyaW5ncyA9IFtdO1xuICAgICAgdGhpcy50ZW5zb3JzID0gW107XG4gICAgICB0aGlzLmdyYXBocyA9IFtdO1xuICAgICAgdGhpcy5zcGFyc2VUZW5zb3JzID0gW107XG4gICAgICB0aGlzLnR5cGVQcm90b3MgPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBuYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLm5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIHJlZkF0dHJOYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gcmVmQXR0ck5hbWVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5yZWZBdHRyTmFtZSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gZG9jU3RyaW5nLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9jU3RyaW5nXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byB0eXBlLlxuICAgICAqIEBtZW1iZXIge29ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZX0gdHlwZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnR5cGUgPSAwO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gZi5cbiAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGZcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5mID0gMDtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIGkuXG4gICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IGlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5pID0gJHV0aWwuTG9uZyA/ICR1dGlsLkxvbmcuZnJvbUJpdHMoMCwgMCwgZmFsc2UpIDogMDtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVByb3RvIHMuXG4gICAgICogQG1lbWJlciB7VWludDhBcnJheX0gc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnMgPSAkdXRpbC5uZXdCdWZmZXIoW10pO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gdC5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklUZW5zb3JQcm90b3xudWxsfHVuZGVmaW5lZH0gdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnQgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gZy5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklHcmFwaFByb3RvfG51bGx8dW5kZWZpbmVkfSBnXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZyA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBzcGFyc2VUZW5zb3IuXG4gICAgICogQG1lbWJlciB7b25ueC5JU3BhcnNlVGVuc29yUHJvdG98bnVsbHx1bmRlZmluZWR9IHNwYXJzZVRlbnNvclxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnNwYXJzZVRlbnNvciA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byB0cC5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklUeXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IHRwXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUudHAgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gZmxvYXRzLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXI+fSBmbG9hdHNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5mbG9hdHMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gaW50cy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSBpbnRzXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuaW50cyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBzdHJpbmdzLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxVaW50OEFycmF5Pn0gc3RyaW5nc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnN0cmluZ3MgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gdGVuc29ycy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVGVuc29yUHJvdG8+fSB0ZW5zb3JzXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUudGVuc29ycyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byBncmFwaHMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSUdyYXBoUHJvdG8+fSBncmFwaHNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5ncmFwaHMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlUHJvdG8gc3BhcnNlVGVuc29ycy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JU3BhcnNlVGVuc29yUHJvdG8+fSBzcGFyc2VUZW5zb3JzXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuc3BhcnNlVGVuc29ycyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGVQcm90byB0eXBlUHJvdG9zLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklUeXBlUHJvdG8+fSB0eXBlUHJvdG9zXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUudHlwZVByb3RvcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IEF0dHJpYnV0ZVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklBdHRyaWJ1dGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LkF0dHJpYnV0ZVByb3RvfSBBdHRyaWJ1dGVQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZVByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgQXR0cmlidXRlUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5BdHRyaWJ1dGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklBdHRyaWJ1dGVQcm90b30gbWVzc2FnZSBBdHRyaWJ1dGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ25hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5mICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2YnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSA1ID0qLyAyMSkuZmxvYXQobWVzc2FnZS5mKTtcbiAgICAgIGlmIChtZXNzYWdlLmkgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnaScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDAgPSovIDI0KS5pbnQ2NChtZXNzYWdlLmkpO1xuICAgICAgaWYgKG1lc3NhZ2UucyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdzJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8gMzQpLmJ5dGVzKG1lc3NhZ2Uucyk7XG4gICAgICBpZiAobWVzc2FnZS50ICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3QnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JQcm90by5lbmNvZGUobWVzc2FnZS50LCB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovIDQyKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdnJykpXG4gICAgICAgICRyb290Lm9ubnguR3JhcGhQcm90by5lbmNvZGUobWVzc2FnZS5nLCB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovIDUwKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZmxvYXRzICE9IG51bGwgJiYgbWVzc2FnZS5mbG9hdHMubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNywgd2lyZVR5cGUgMiA9Ki8gNTgpLmZvcmsoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmZsb2F0cy5sZW5ndGg7ICsraSkgd3JpdGVyLmZsb2F0KG1lc3NhZ2UuZmxvYXRzW2ldKTtcbiAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW50cyAhPSBudWxsICYmIG1lc3NhZ2UuaW50cy5sZW5ndGgpIHtcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLyA2NikuZm9yaygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50cy5sZW5ndGg7ICsraSkgd3JpdGVyLmludDY0KG1lc3NhZ2UuaW50c1tpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnN0cmluZ3MgIT0gbnVsbCAmJiBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDksIHdpcmVUeXBlIDIgPSovIDc0KS5ieXRlcyhtZXNzYWdlLnN0cmluZ3NbaV0pO1xuICAgICAgaWYgKG1lc3NhZ2UudGVuc29ycyAhPSBudWxsICYmIG1lc3NhZ2UudGVuc29ycy5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uZW5jb2RlKG1lc3NhZ2UudGVuc29yc1tpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxMCwgd2lyZVR5cGUgMiA9Ki8gODIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5ncmFwaHMgIT0gbnVsbCAmJiBtZXNzYWdlLmdyYXBocy5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5ncmFwaHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmdyYXBoc1tpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxMSwgd2lyZVR5cGUgMiA9Ki8gOTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZG9jU3RyaW5nJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTMsIHdpcmVUeXBlIDIgPSovIDEwNikuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChtZXNzYWdlLnRwICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3RwJykpXG4gICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShtZXNzYWdlLnRwLCB3cml0ZXIudWludDMyKC8qIGlkIDE0LCB3aXJlVHlwZSAyID0qLyAxMTQpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS50eXBlUHJvdG9zICE9IG51bGwgJiYgbWVzc2FnZS50eXBlUHJvdG9zLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS50eXBlUHJvdG9zW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNSwgd2lyZVR5cGUgMiA9Ki8gMTIyKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAndHlwZScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIwLCB3aXJlVHlwZSAwID0qLyAxNjApLmludDMyKG1lc3NhZ2UudHlwZSk7XG4gICAgICBpZiAobWVzc2FnZS5yZWZBdHRyTmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdyZWZBdHRyTmFtZScpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIxLCB3aXJlVHlwZSAyID0qLyAxNzApLnN0cmluZyhtZXNzYWdlLnJlZkF0dHJOYW1lKTtcbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvciAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdzcGFyc2VUZW5zb3InKSlcbiAgICAgICAgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5lbmNvZGUoXG4gICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3IsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMiwgd2lyZVR5cGUgMiA9Ki8gMTc4KS5mb3JrKCksXG4gICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3JzICE9IG51bGwgJiYgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnNwYXJzZVRlbnNvcnMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvcnNbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIzLCB3aXJlVHlwZSAyID0qLyAxODYpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguQXR0cmlidXRlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JQXR0cmlidXRlUHJvdG99IG1lc3NhZ2UgQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguQXR0cmlidXRlUHJvdG99IEF0dHJpYnV0ZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDIxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnJlZkF0dHJOYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTM6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjA6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5mID0gcmVhZGVyLmZsb2F0KCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmkgPSByZWFkZXIuaW50NjQoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UucyA9IHJlYWRlci5ieXRlcygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgbWVzc2FnZS50ID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgbWVzc2FnZS5nID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3IgPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxNDoge1xuICAgICAgICAgICAgbWVzc2FnZS50cCA9ICRyb290Lm9ubnguVHlwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA3OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmZsb2F0cyAmJiBtZXNzYWdlLmZsb2F0cy5sZW5ndGgpKSBtZXNzYWdlLmZsb2F0cyA9IFtdO1xuICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMikgbWVzc2FnZS5mbG9hdHMucHVzaChyZWFkZXIuZmxvYXQoKSk7XG4gICAgICAgICAgICB9IGVsc2UgbWVzc2FnZS5mbG9hdHMucHVzaChyZWFkZXIuZmxvYXQoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA4OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmludHMgJiYgbWVzc2FnZS5pbnRzLmxlbmd0aCkpIG1lc3NhZ2UuaW50cyA9IFtdO1xuICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMikgbWVzc2FnZS5pbnRzLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuaW50cy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDk6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3RyaW5ncyAmJiBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoKSkgbWVzc2FnZS5zdHJpbmdzID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnN0cmluZ3MucHVzaChyZWFkZXIuYnl0ZXMoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS50ZW5zb3JzICYmIG1lc3NhZ2UudGVuc29ycy5sZW5ndGgpKSBtZXNzYWdlLnRlbnNvcnMgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UudGVuc29ycy5wdXNoKCRyb290Lm9ubnguVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5ncmFwaHMgJiYgbWVzc2FnZS5ncmFwaHMubGVuZ3RoKSkgbWVzc2FnZS5ncmFwaHMgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuZ3JhcGhzLnB1c2goJHJvb3Qub25ueC5HcmFwaFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjM6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyAmJiBtZXNzYWdlLnNwYXJzZVRlbnNvcnMubGVuZ3RoKSkgbWVzc2FnZS5zcGFyc2VUZW5zb3JzID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvcnMucHVzaCgkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTU6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UudHlwZVByb3RvcyAmJiBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoKSkgbWVzc2FnZS50eXBlUHJvdG9zID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnR5cGVQcm90b3MucHVzaCgkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LkF0dHJpYnV0ZVByb3RvfSBBdHRyaWJ1dGVQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhbiBBdHRyaWJ1dGVQcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCduYW1lJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5uYW1lKSkgcmV0dXJuICduYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UucmVmQXR0ck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdyZWZBdHRyTmFtZScpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UucmVmQXR0ck5hbWUpKSByZXR1cm4gJ3JlZkF0dHJOYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpKSByZXR1cm4gJ2RvY1N0cmluZzogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0eXBlJykpXG4gICAgICAgIHN3aXRjaCAobWVzc2FnZS50eXBlKSB7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiAndHlwZTogZW51bSB2YWx1ZSBleHBlY3RlZCc7XG4gICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgY2FzZSAxMTpcbiAgICAgICAgICBjYXNlIDEzOlxuICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgIGNhc2UgOTpcbiAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgIGNhc2UgMTI6XG4gICAgICAgICAgY2FzZSAxNDpcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5mICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZicpKVxuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZiAhPT0gJ251bWJlcicpIHJldHVybiAnZjogbnVtYmVyIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmkgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpJykpXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaSkgJiZcbiAgICAgICAgICAhKG1lc3NhZ2UuaSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaS5oaWdoKSlcbiAgICAgICAgKVxuICAgICAgICAgIHJldHVybiAnaTogaW50ZWdlcnxMb25nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzJykpXG4gICAgICAgIGlmICghKChtZXNzYWdlLnMgJiYgdHlwZW9mIG1lc3NhZ2Uucy5sZW5ndGggPT09ICdudW1iZXInKSB8fCAkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnMpKSlcbiAgICAgICAgICByZXR1cm4gJ3M6IGJ1ZmZlciBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndCcpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2UudCk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd0LicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdnJykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnZlcmlmeShtZXNzYWdlLmcpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnZy4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3IgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzcGFyc2VUZW5zb3InKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLnZlcmlmeShtZXNzYWdlLnNwYXJzZVRlbnNvcik7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzcGFyc2VUZW5zb3IuJyArIGVycm9yO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudHAgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0cCcpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnRwKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3RwLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmZsb2F0cyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2Zsb2F0cycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmZsb2F0cykpIHJldHVybiAnZmxvYXRzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmZsb2F0c1tpXSAhPT0gJ251bWJlcicpIHJldHVybiAnZmxvYXRzOiBudW1iZXJbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbnRzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaW50cycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmludHMpKSByZXR1cm4gJ2ludHM6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmludHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludHNbaV0pICYmXG4gICAgICAgICAgICAhKG1lc3NhZ2UuaW50c1tpXSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pbnRzW2ldLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50c1tpXS5oaWdoKSlcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ2ludHM6IGludGVnZXJ8TG9uZ1tdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnN0cmluZ3MgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzdHJpbmdzJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uuc3RyaW5ncykpIHJldHVybiAnc3RyaW5nczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhKFxuICAgICAgICAgICAgICAobWVzc2FnZS5zdHJpbmdzW2ldICYmIHR5cGVvZiBtZXNzYWdlLnN0cmluZ3NbaV0ubGVuZ3RoID09PSAnbnVtYmVyJykgfHxcbiAgICAgICAgICAgICAgJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5zdHJpbmdzW2ldKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAnc3RyaW5nczogYnVmZmVyW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudGVuc29ycyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3RlbnNvcnMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS50ZW5zb3JzKSkgcmV0dXJuICd0ZW5zb3JzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS50ZW5zb3JzW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndGVuc29ycy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmdyYXBocyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2dyYXBocycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmdyYXBocykpIHJldHVybiAnZ3JhcGhzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5ncmFwaHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udmVyaWZ5KG1lc3NhZ2UuZ3JhcGhzW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnZ3JhcGhzLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NwYXJzZVRlbnNvcnMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5zcGFyc2VUZW5zb3JzKSkgcmV0dXJuICdzcGFyc2VUZW5zb3JzOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS5zcGFyc2VUZW5zb3JzW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnc3BhcnNlVGVuc29ycy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnR5cGVQcm90b3MgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0eXBlUHJvdG9zJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudHlwZVByb3RvcykpIHJldHVybiAndHlwZVByb3RvczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudHlwZVByb3Rvcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnR5cGVQcm90b3NbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd0eXBlUHJvdG9zLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LkF0dHJpYnV0ZVByb3RvfSBBdHRyaWJ1dGVQcm90b1xuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbCkgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgIGlmIChvYmplY3QucmVmQXR0ck5hbWUgIT0gbnVsbCkgbWVzc2FnZS5yZWZBdHRyTmFtZSA9IFN0cmluZyhvYmplY3QucmVmQXR0ck5hbWUpO1xuICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbCkgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICBzd2l0Y2ggKG9iamVjdC50eXBlKSB7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IG9iamVjdC50eXBlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdVTkRFRklORUQnOlxuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnRkxPQVQnOlxuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnSU5UJzpcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1NUUklORyc6XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdURU5TT1InOlxuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gNDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnR1JBUEgnOlxuICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gNTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnU1BBUlNFX1RFTlNPUic6XG4gICAgICAgIGNhc2UgMTE6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMTE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1RZUEVfUFJPVE8nOlxuICAgICAgICBjYXNlIDEzOlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDEzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdGTE9BVFMnOlxuICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gNjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnSU5UUyc6XG4gICAgICAgIGNhc2UgNzpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSA3O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdTVFJJTkdTJzpcbiAgICAgICAgY2FzZSA4OlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDg7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1RFTlNPUlMnOlxuICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gOTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnR1JBUEhTJzpcbiAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAxMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnU1BBUlNFX1RFTlNPUlMnOlxuICAgICAgICBjYXNlIDEyOlxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDEyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdUWVBFX1BST1RPUyc6XG4gICAgICAgIGNhc2UgMTQ6XG4gICAgICAgICAgbWVzc2FnZS50eXBlID0gMTQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmYgIT0gbnVsbCkgbWVzc2FnZS5mID0gTnVtYmVyKG9iamVjdC5mKTtcbiAgICAgIGlmIChvYmplY3QuaSAhPSBudWxsKVxuICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuaSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5pKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pID09PSAnc3RyaW5nJykgbWVzc2FnZS5pID0gcGFyc2VJbnQob2JqZWN0LmksIDEwKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pID09PSAnbnVtYmVyJykgbWVzc2FnZS5pID0gb2JqZWN0Lmk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgbWVzc2FnZS5pID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5pLmxvdyA+Pj4gMCwgb2JqZWN0LmkuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgIGlmIChvYmplY3QucyAhPSBudWxsKVxuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zID09PSAnc3RyaW5nJylcbiAgICAgICAgICAkdXRpbC5iYXNlNjQuZGVjb2RlKG9iamVjdC5zLCAobWVzc2FnZS5zID0gJHV0aWwubmV3QnVmZmVyKCR1dGlsLmJhc2U2NC5sZW5ndGgob2JqZWN0LnMpKSksIDApO1xuICAgICAgICBlbHNlIGlmIChvYmplY3Qucy5sZW5ndGggPj0gMCkgbWVzc2FnZS5zID0gb2JqZWN0LnM7XG4gICAgICBpZiAob2JqZWN0LnQgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50ICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by50OiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS50ID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC50KTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZyAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmcgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLmc6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmcgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZyk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnNwYXJzZVRlbnNvciAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNwYXJzZVRlbnNvciAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5zcGFyc2VUZW5zb3I6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvciA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3Quc3BhcnNlVGVuc29yKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudHAgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50cCAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguQXR0cmlidXRlUHJvdG8udHA6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnRwID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3QudHApO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5mbG9hdHMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5mbG9hdHMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLmZsb2F0czogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5mbG9hdHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZmxvYXRzLmxlbmd0aDsgKytpKSBtZXNzYWdlLmZsb2F0c1tpXSA9IE51bWJlcihvYmplY3QuZmxvYXRzW2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuaW50cykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmludHMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLmludHM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW50cyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnRzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSAobWVzc2FnZS5pbnRzW2ldID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmludHNbaV0pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50c1tpXSA9PT0gJ3N0cmluZycpIG1lc3NhZ2UuaW50c1tpXSA9IHBhcnNlSW50KG9iamVjdC5pbnRzW2ldLCAxMCk7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnRzW2ldID09PSAnbnVtYmVyJykgbWVzc2FnZS5pbnRzW2ldID0gb2JqZWN0LmludHNbaV07XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnRzW2ldID09PSAnb2JqZWN0JylcbiAgICAgICAgICAgIG1lc3NhZ2UuaW50c1tpXSA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuaW50c1tpXS5sb3cgPj4+IDAsIG9iamVjdC5pbnRzW2ldLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnN0cmluZ3MpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zdHJpbmdzKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5zdHJpbmdzOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnN0cmluZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Quc3RyaW5ncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zdHJpbmdzW2ldID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICR1dGlsLmJhc2U2NC5kZWNvZGUoXG4gICAgICAgICAgICAgIG9iamVjdC5zdHJpbmdzW2ldLFxuICAgICAgICAgICAgICAobWVzc2FnZS5zdHJpbmdzW2ldID0gJHV0aWwubmV3QnVmZmVyKCR1dGlsLmJhc2U2NC5sZW5ndGgob2JqZWN0LnN0cmluZ3NbaV0pKSksXG4gICAgICAgICAgICAgIDAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIGVsc2UgaWYgKG9iamVjdC5zdHJpbmdzW2ldLmxlbmd0aCA+PSAwKSBtZXNzYWdlLnN0cmluZ3NbaV0gPSBvYmplY3Quc3RyaW5nc1tpXTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudGVuc29ycykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnRlbnNvcnMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnRlbnNvcnM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC50ZW5zb3JzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudGVuc29yc1tpXSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguQXR0cmlidXRlUHJvdG8udGVuc29yczogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS50ZW5zb3JzW2ldID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC50ZW5zb3JzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5ncmFwaHMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5ncmFwaHMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLmdyYXBoczogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5ncmFwaHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZ3JhcGhzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZ3JhcGhzW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5BdHRyaWJ1dGVQcm90by5ncmFwaHM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuZ3JhcGhzW2ldID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmZyb21PYmplY3Qob2JqZWN0LmdyYXBoc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Quc3BhcnNlVGVuc29ycykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnNwYXJzZVRlbnNvcnMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnNwYXJzZVRlbnNvcnM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5zcGFyc2VUZW5zb3JzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlVGVuc29yc1tpXSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnNwYXJzZVRlbnNvcnM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29yc1tpXSA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3Quc3BhcnNlVGVuc29yc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QudHlwZVByb3Rvcykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnR5cGVQcm90b3MpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnR5cGVQcm90b3M6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudHlwZVByb3RvcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC50eXBlUHJvdG9zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudHlwZVByb3Rvc1tpXSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkF0dHJpYnV0ZVByb3RvLnR5cGVQcm90b3M6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UudHlwZVByb3Rvc1tpXSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnR5cGVQcm90b3NbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguQXR0cmlidXRlUHJvdG99IG1lc3NhZ2UgQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIEF0dHJpYnV0ZVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QuZmxvYXRzID0gW107XG4gICAgICAgIG9iamVjdC5pbnRzID0gW107XG4gICAgICAgIG9iamVjdC5zdHJpbmdzID0gW107XG4gICAgICAgIG9iamVjdC50ZW5zb3JzID0gW107XG4gICAgICAgIG9iamVjdC5ncmFwaHMgPSBbXTtcbiAgICAgICAgb2JqZWN0LnR5cGVQcm90b3MgPSBbXTtcbiAgICAgICAgb2JqZWN0LnNwYXJzZVRlbnNvcnMgPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5uYW1lID0gJyc7XG4gICAgICAgIG9iamVjdC5mID0gMDtcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICBvYmplY3QuaSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgIH0gZWxzZSBvYmplY3QuaSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICcwJyA6IDA7XG4gICAgICAgIGlmIChvcHRpb25zLmJ5dGVzID09PSBTdHJpbmcpIG9iamVjdC5zID0gJyc7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIG9iamVjdC5zID0gW107XG4gICAgICAgICAgaWYgKG9wdGlvbnMuYnl0ZXMgIT09IEFycmF5KSBvYmplY3QucyA9ICR1dGlsLm5ld0J1ZmZlcihvYmplY3Qucyk7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0LnQgPSBudWxsO1xuICAgICAgICBvYmplY3QuZyA9IG51bGw7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgICAgb2JqZWN0LnRwID0gbnVsbDtcbiAgICAgICAgb2JqZWN0LnR5cGUgPSBvcHRpb25zLmVudW1zID09PSBTdHJpbmcgPyAnVU5ERUZJTkVEJyA6IDA7XG4gICAgICAgIG9iamVjdC5yZWZBdHRyTmFtZSA9ICcnO1xuICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29yID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCduYW1lJykpIG9iamVjdC5uYW1lID0gbWVzc2FnZS5uYW1lO1xuICAgICAgaWYgKG1lc3NhZ2UuZiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2YnKSlcbiAgICAgICAgb2JqZWN0LmYgPSBvcHRpb25zLmpzb24gJiYgIWlzRmluaXRlKG1lc3NhZ2UuZikgPyBTdHJpbmcobWVzc2FnZS5mKSA6IG1lc3NhZ2UuZjtcbiAgICAgIGlmIChtZXNzYWdlLmkgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpJykpXG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5pID09PSAnbnVtYmVyJykgb2JqZWN0LmkgPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5pKSA6IG1lc3NhZ2UuaTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIG9iamVjdC5pID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZ1xuICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pKVxuICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuaS5sb3cgPj4+IDAsIG1lc3NhZ2UuaS5oaWdoID4+PiAwKS50b051bWJlcigpXG4gICAgICAgICAgICAgICAgOiBtZXNzYWdlLmk7XG4gICAgICBpZiAobWVzc2FnZS5zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncycpKVxuICAgICAgICBvYmplY3QucyA9XG4gICAgICAgICAgb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nXG4gICAgICAgICAgICA/ICR1dGlsLmJhc2U2NC5lbmNvZGUobWVzc2FnZS5zLCAwLCBtZXNzYWdlLnMubGVuZ3RoKVxuICAgICAgICAgICAgOiBvcHRpb25zLmJ5dGVzID09PSBBcnJheVxuICAgICAgICAgICAgICA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG1lc3NhZ2UucylcbiAgICAgICAgICAgICAgOiBtZXNzYWdlLnM7XG4gICAgICBpZiAobWVzc2FnZS50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndCcpKVxuICAgICAgICBvYmplY3QudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS50LCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdnJykpXG4gICAgICAgIG9iamVjdC5nID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZywgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5mbG9hdHMgJiYgbWVzc2FnZS5mbG9hdHMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5mbG9hdHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmZsb2F0cy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZmxvYXRzW2pdID1cbiAgICAgICAgICAgIG9wdGlvbnMuanNvbiAmJiAhaXNGaW5pdGUobWVzc2FnZS5mbG9hdHNbal0pID8gU3RyaW5nKG1lc3NhZ2UuZmxvYXRzW2pdKSA6IG1lc3NhZ2UuZmxvYXRzW2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW50cyAmJiBtZXNzYWdlLmludHMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5pbnRzID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnRzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5pbnRzW2pdID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIG9iamVjdC5pbnRzW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuaW50c1tqXSkgOiBtZXNzYWdlLmludHNbal07XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgb2JqZWN0LmludHNbal0gPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pbnRzW2pdKVxuICAgICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmludHNbal0ubG93ID4+PiAwLCBtZXNzYWdlLmludHNbal0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLmludHNbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zdHJpbmdzICYmIG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnN0cmluZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnN0cmluZ3Nbal0gPVxuICAgICAgICAgICAgb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgID8gJHV0aWwuYmFzZTY0LmVuY29kZShtZXNzYWdlLnN0cmluZ3Nbal0sIDAsIG1lc3NhZ2Uuc3RyaW5nc1tqXS5sZW5ndGgpXG4gICAgICAgICAgICAgIDogb3B0aW9ucy5ieXRlcyA9PT0gQXJyYXlcbiAgICAgICAgICAgICAgICA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG1lc3NhZ2Uuc3RyaW5nc1tqXSlcbiAgICAgICAgICAgICAgICA6IG1lc3NhZ2Uuc3RyaW5nc1tqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvcnMgJiYgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QudGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UudGVuc29ycy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QudGVuc29yc1tqXSA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS50ZW5zb3JzW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmdyYXBocyAmJiBtZXNzYWdlLmdyYXBocy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmdyYXBocyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZ3JhcGhzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5ncmFwaHNbal0gPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udG9PYmplY3QobWVzc2FnZS5ncmFwaHNbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgIGlmIChtZXNzYWdlLnRwICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHAnKSlcbiAgICAgICAgb2JqZWN0LnRwID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udG9PYmplY3QobWVzc2FnZS50cCwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS50eXBlUHJvdG9zICYmIG1lc3NhZ2UudHlwZVByb3Rvcy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnR5cGVQcm90b3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnR5cGVQcm90b3Nbal0gPSAkcm9vdC5vbm54LlR5cGVQcm90by50b09iamVjdChtZXNzYWdlLnR5cGVQcm90b3Nbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3R5cGUnKSlcbiAgICAgICAgb2JqZWN0LnR5cGUgPVxuICAgICAgICAgIG9wdGlvbnMuZW51bXMgPT09IFN0cmluZ1xuICAgICAgICAgICAgPyAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVbbWVzc2FnZS50eXBlXSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gbWVzc2FnZS50eXBlXG4gICAgICAgICAgICAgIDogJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlW21lc3NhZ2UudHlwZV1cbiAgICAgICAgICAgIDogbWVzc2FnZS50eXBlO1xuICAgICAgaWYgKG1lc3NhZ2UucmVmQXR0ck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdyZWZBdHRyTmFtZScpKVxuICAgICAgICBvYmplY3QucmVmQXR0ck5hbWUgPSBtZXNzYWdlLnJlZkF0dHJOYW1lO1xuICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29yICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3BhcnNlVGVuc29yJykpXG4gICAgICAgIG9iamVjdC5zcGFyc2VUZW5zb3IgPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc3BhcnNlVGVuc29yLCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvcnMgJiYgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLmxlbmd0aCkge1xuICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uuc3BhcnNlVGVuc29ycy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29yc1tqXSA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS5zcGFyc2VUZW5zb3JzW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgQXR0cmlidXRlUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBBdHRyaWJ1dGVQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5BdHRyaWJ1dGVQcm90byc7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZVR5cGUgZW51bS5cbiAgICAgKiBAbmFtZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVcbiAgICAgKiBAZW51bSB7bnVtYmVyfVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVTkRFRklORUQ9MCBVTkRFRklORUQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ9MSBGTE9BVCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJTlQ9MiBJTlQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1RSSU5HPTMgU1RSSU5HIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFRFTlNPUj00IFRFTlNPUiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBHUkFQSD01IEdSQVBIIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNQQVJTRV9URU5TT1I9MTEgU1BBUlNFX1RFTlNPUiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBUWVBFX1BST1RPPTEzIFRZUEVfUFJPVE8gdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVRTPTYgRkxPQVRTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IElOVFM9NyBJTlRTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNUUklOR1M9OCBTVFJJTkdTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFRFTlNPUlM9OSBURU5TT1JTIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEdSQVBIUz0xMCBHUkFQSFMgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1BBUlNFX1RFTlNPUlM9MTIgU1BBUlNFX1RFTlNPUlMgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gVFlQRV9QUk9UT1M9MTQgVFlQRV9QUk9UT1MgdmFsdWVcbiAgICAgKi9cbiAgICBBdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB2YWx1ZXNCeUlkID0ge30sXG4gICAgICAgIHZhbHVlcyA9IE9iamVjdC5jcmVhdGUodmFsdWVzQnlJZCk7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMF0gPSAnVU5ERUZJTkVEJyldID0gMDtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxXSA9ICdGTE9BVCcpXSA9IDE7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMl0gPSAnSU5UJyldID0gMjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFszXSA9ICdTVFJJTkcnKV0gPSAzO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzRdID0gJ1RFTlNPUicpXSA9IDQ7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbNV0gPSAnR1JBUEgnKV0gPSA1O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzExXSA9ICdTUEFSU0VfVEVOU09SJyldID0gMTE7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTNdID0gJ1RZUEVfUFJPVE8nKV0gPSAxMztcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs2XSA9ICdGTE9BVFMnKV0gPSA2O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzddID0gJ0lOVFMnKV0gPSA3O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzhdID0gJ1NUUklOR1MnKV0gPSA4O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzldID0gJ1RFTlNPUlMnKV0gPSA5O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzEwXSA9ICdHUkFQSFMnKV0gPSAxMDtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxMl0gPSAnU1BBUlNFX1RFTlNPUlMnKV0gPSAxMjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxNF0gPSAnVFlQRV9QUk9UT1MnKV0gPSAxNDtcbiAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfSkoKTtcblxuICAgIHJldHVybiBBdHRyaWJ1dGVQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlZhbHVlSW5mb1Byb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVmFsdWVJbmZvUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElWYWx1ZUluZm9Qcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBWYWx1ZUluZm9Qcm90byBuYW1lXG4gICAgICogQHByb3BlcnR5IHtvbm54LklUeXBlUHJvdG98bnVsbH0gW3R5cGVdIFZhbHVlSW5mb1Byb3RvIHR5cGVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBWYWx1ZUluZm9Qcm90byBkb2NTdHJpbmdcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVmFsdWVJbmZvUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBWYWx1ZUluZm9Qcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSVZhbHVlSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gVmFsdWVJbmZvUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFZhbHVlSW5mb1Byb3RvIG5hbWUuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBWYWx1ZUluZm9Qcm90by5wcm90b3R5cGUubmFtZSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogVmFsdWVJbmZvUHJvdG8gdHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LklUeXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IHR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLnByb3RvdHlwZS50eXBlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFZhbHVlSW5mb1Byb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBWYWx1ZUluZm9Qcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVmFsdWVJbmZvUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5WYWx1ZUluZm9Qcm90b30gVmFsdWVJbmZvUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBWYWx1ZUluZm9Qcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBWYWx1ZUluZm9Qcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVmFsdWVJbmZvUHJvdG99IG1lc3NhZ2UgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICduYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICd0eXBlJykpXG4gICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShtZXNzYWdlLnR5cGUsIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZG9jU3RyaW5nJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8gMjYpLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICByZXR1cm4gd3JpdGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5WYWx1ZUluZm9Qcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklWYWx1ZUluZm9Qcm90b30gbWVzc2FnZSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlZhbHVlSW5mb1Byb3RvfSBWYWx1ZUluZm9Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMzoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlZhbHVlSW5mb1Byb3RvfSBWYWx1ZUluZm9Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKSByZXR1cm4gJ25hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS50eXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHlwZScpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnR5cGUpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndHlwZS4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpIHJldHVybiAnZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguVmFsdWVJbmZvUHJvdG99IFZhbHVlSW5mb1Byb3RvXG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKSBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgaWYgKG9iamVjdC50eXBlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudHlwZSAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguVmFsdWVJbmZvUHJvdG8udHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnR5cGUpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbCkgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5WYWx1ZUluZm9Qcm90b30gbWVzc2FnZSBWYWx1ZUluZm9Qcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgVmFsdWVJbmZvUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5uYW1lID0gJyc7XG4gICAgICAgIG9iamVjdC50eXBlID0gbnVsbDtcbiAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSkgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICBpZiAobWVzc2FnZS50eXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndHlwZScpKVxuICAgICAgICBvYmplY3QudHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudHlwZSwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSkgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBWYWx1ZUluZm9Qcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBWYWx1ZUluZm9Qcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFZhbHVlSW5mb1Byb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIFZhbHVlSW5mb1Byb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlZhbHVlSW5mb1Byb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIFZhbHVlSW5mb1Byb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguTm9kZVByb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgTm9kZVByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJTm9kZVByb3RvXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48c3RyaW5nPnxudWxsfSBbaW5wdXRdIE5vZGVQcm90byBpbnB1dFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW291dHB1dF0gTm9kZVByb3RvIG91dHB1dFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBOb2RlUHJvdG8gbmFtZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtvcFR5cGVdIE5vZGVQcm90byBvcFR5cGVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9tYWluXSBOb2RlUHJvdG8gZG9tYWluXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fG51bGx9IFthdHRyaWJ1dGVdIE5vZGVQcm90byBhdHRyaWJ1dGVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBOb2RlUHJvdG8gZG9jU3RyaW5nXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IE5vZGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIE5vZGVQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJTm9kZVByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklOb2RlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBOb2RlUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5pbnB1dCA9IFtdO1xuICAgICAgdGhpcy5vdXRwdXQgPSBbXTtcbiAgICAgIHRoaXMuYXR0cmlidXRlID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIGlucHV0LlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxzdHJpbmc+fSBpbnB1dFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE5vZGVQcm90by5wcm90b3R5cGUuaW5wdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIG91dHB1dC5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48c3RyaW5nPn0gb3V0cHV0XG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5vdXRwdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIG5hbWUuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5uYW1lID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBOb2RlUHJvdG8gb3BUeXBlLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gb3BUeXBlXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5vcFR5cGUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIE5vZGVQcm90byBkb21haW4uXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb21haW5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8ucHJvdG90eXBlLmRvbWFpbiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogTm9kZVByb3RvIGF0dHJpYnV0ZS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fSBhdHRyaWJ1dGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8ucHJvdG90eXBlLmF0dHJpYnV0ZSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBOb2RlUHJvdG8gZG9jU3RyaW5nLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9jU3RyaW5nXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTm9kZVByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgTm9kZVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTm9kZVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguTm9kZVByb3RvfSBOb2RlUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgTm9kZVByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgTm9kZVByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguTm9kZVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklOb2RlUHJvdG99IG1lc3NhZ2UgTm9kZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UuaW5wdXRbaV0pO1xuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLnN0cmluZyhtZXNzYWdlLm91dHB1dFtpXSk7XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ25hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLyAyNikuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5vcFR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnb3BUeXBlJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8gMzQpLnN0cmluZyhtZXNzYWdlLm9wVHlwZSk7XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgIT0gbnVsbCAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVtpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovIDUwKS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvbWFpbicpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDcsIHdpcmVUeXBlIDIgPSovIDU4KS5zdHJpbmcobWVzc2FnZS5kb21haW4pO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE5vZGVQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54Lk5vZGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTm9kZVByb3RvfSBtZXNzYWdlIE5vZGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgTm9kZVByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgTm9kZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54Lk5vZGVQcm90b30gTm9kZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguTm9kZVByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkpIG1lc3NhZ2UuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXQucHVzaChyZWFkZXIuc3RyaW5nKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSkgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0LnB1c2gocmVhZGVyLnN0cmluZygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3BUeXBlID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNzoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb21haW4gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA1OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmF0dHJpYnV0ZSAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpKSBtZXNzYWdlLmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGUucHVzaCgkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIE5vZGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguTm9kZVByb3RvfSBOb2RlUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIE5vZGVQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgTm9kZVByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIE5vZGVQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2lucHV0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW5wdXQpKSByZXR1cm4gJ2lucHV0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuaW5wdXRbaV0pKSByZXR1cm4gJ2lucHV0OiBzdHJpbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5vdXRwdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdvdXRwdXQnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5vdXRwdXQpKSByZXR1cm4gJ291dHB1dDogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5vdXRwdXRbaV0pKSByZXR1cm4gJ291dHB1dDogc3RyaW5nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKSByZXR1cm4gJ25hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5vcFR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdvcFR5cGUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm9wVHlwZSkpIHJldHVybiAnb3BUeXBlOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9tYWluJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb21haW4pKSByZXR1cm4gJ2RvbWFpbjogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2F0dHJpYnV0ZScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmF0dHJpYnV0ZSkpIHJldHVybiAnYXR0cmlidXRlOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLnZlcmlmeShtZXNzYWdlLmF0dHJpYnV0ZVtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2F0dHJpYnV0ZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSkgcmV0dXJuICdkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIE5vZGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54Lk5vZGVQcm90b30gTm9kZVByb3RvXG4gICAgICovXG4gICAgTm9kZVByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguTm9kZVByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5Ob2RlUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuaW5wdXQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbnB1dCkpIHRocm93IFR5cGVFcnJvcignLm9ubnguTm9kZVByb3RvLmlucHV0OiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmlucHV0Lmxlbmd0aDsgKytpKSBtZXNzYWdlLmlucHV0W2ldID0gU3RyaW5nKG9iamVjdC5pbnB1dFtpXSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm91dHB1dCkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm91dHB1dCkpIHRocm93IFR5cGVFcnJvcignLm9ubnguTm9kZVByb3RvLm91dHB1dDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qub3V0cHV0Lmxlbmd0aDsgKytpKSBtZXNzYWdlLm91dHB1dFtpXSA9IFN0cmluZyhvYmplY3Qub3V0cHV0W2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKSBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgaWYgKG9iamVjdC5vcFR5cGUgIT0gbnVsbCkgbWVzc2FnZS5vcFR5cGUgPSBTdHJpbmcob2JqZWN0Lm9wVHlwZSk7XG4gICAgICBpZiAob2JqZWN0LmRvbWFpbiAhPSBudWxsKSBtZXNzYWdlLmRvbWFpbiA9IFN0cmluZyhvYmplY3QuZG9tYWluKTtcbiAgICAgIGlmIChvYmplY3QuYXR0cmlidXRlKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuYXR0cmlidXRlKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Ob2RlUHJvdG8uYXR0cmlidXRlOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5hdHRyaWJ1dGVbaV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54Lk5vZGVQcm90by5hdHRyaWJ1dGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlW2ldID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5hdHRyaWJ1dGVbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKSBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBOb2RlUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguTm9kZVByb3RvfSBtZXNzYWdlIE5vZGVQcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgTm9kZVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICBvYmplY3QuYXR0cmlidXRlID0gW107XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QubmFtZSA9ICcnO1xuICAgICAgICBvYmplY3Qub3BUeXBlID0gJyc7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgICAgb2JqZWN0LmRvbWFpbiA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraikgb2JqZWN0LmlucHV0W2pdID0gbWVzc2FnZS5pbnB1dFtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytqKSBvYmplY3Qub3V0cHV0W2pdID0gbWVzc2FnZS5vdXRwdXRbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKSBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgIGlmIChtZXNzYWdlLm9wVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ29wVHlwZScpKSBvYmplY3Qub3BUeXBlID0gbWVzc2FnZS5vcFR5cGU7XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgJiYgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuYXR0cmlidXRlW2pdID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by50b09iamVjdChtZXNzYWdlLmF0dHJpYnV0ZVtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSkgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9tYWluJykpIG9iamVjdC5kb21haW4gPSBtZXNzYWdlLmRvbWFpbjtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgTm9kZVByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBOb2RlUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBOb2RlUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIE5vZGVQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5Ob2RlUHJvdG8nO1xuICAgIH07XG5cbiAgICByZXR1cm4gTm9kZVByb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguVHJhaW5pbmdJbmZvUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBUcmFpbmluZ0luZm9Qcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHByb3BlcnR5IHtvbm54LklHcmFwaFByb3RvfG51bGx9IFtpbml0aWFsaXphdGlvbl0gVHJhaW5pbmdJbmZvUHJvdG8gaW5pdGlhbGl6YXRpb25cbiAgICAgKiBAcHJvcGVydHkge29ubnguSUdyYXBoUHJvdG98bnVsbH0gW2FsZ29yaXRobV0gVHJhaW5pbmdJbmZvUHJvdG8gYWxnb3JpdGhtXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz58bnVsbH0gW2luaXRpYWxpemF0aW9uQmluZGluZ10gVHJhaW5pbmdJbmZvUHJvdG8gaW5pdGlhbGl6YXRpb25CaW5kaW5nXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz58bnVsbH0gW3VwZGF0ZUJpbmRpbmddIFRyYWluaW5nSW5mb1Byb3RvIHVwZGF0ZUJpbmRpbmdcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVHJhaW5pbmdJbmZvUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBUcmFpbmluZ0luZm9Qcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSVRyYWluaW5nSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gVHJhaW5pbmdJbmZvUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSBbXTtcbiAgICAgIHRoaXMudXBkYXRlQmluZGluZyA9IFtdO1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyYWluaW5nSW5mb1Byb3RvIGluaXRpYWxpemF0aW9uLlxuICAgICAqIEBtZW1iZXIge29ubnguSUdyYXBoUHJvdG98bnVsbHx1bmRlZmluZWR9IGluaXRpYWxpemF0aW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5wcm90b3R5cGUuaW5pdGlhbGl6YXRpb24gPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVHJhaW5pbmdJbmZvUHJvdG8gYWxnb3JpdGhtLlxuICAgICAqIEBtZW1iZXIge29ubnguSUdyYXBoUHJvdG98bnVsbHx1bmRlZmluZWR9IGFsZ29yaXRobVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8ucHJvdG90eXBlLmFsZ29yaXRobSA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBUcmFpbmluZ0luZm9Qcm90byBpbml0aWFsaXphdGlvbkJpbmRpbmcuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSBpbml0aWFsaXphdGlvbkJpbmRpbmdcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLnByb3RvdHlwZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVHJhaW5pbmdJbmZvUHJvdG8gdXBkYXRlQmluZGluZy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz59IHVwZGF0ZUJpbmRpbmdcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLnByb3RvdHlwZS51cGRhdGVCaW5kaW5nID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgVHJhaW5pbmdJbmZvUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRyYWluaW5nSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguVHJhaW5pbmdJbmZvUHJvdG99IFRyYWluaW5nSW5mb1Byb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgVHJhaW5pbmdJbmZvUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRyYWluaW5nSW5mb1Byb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRyYWluaW5nSW5mb1Byb3RvfSBtZXNzYWdlIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2luaXRpYWxpemF0aW9uJykpXG4gICAgICAgICRyb290Lm9ubnguR3JhcGhQcm90by5lbmNvZGUobWVzc2FnZS5pbml0aWFsaXphdGlvbiwgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmFsZ29yaXRobSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdhbGdvcml0aG0nKSlcbiAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmFsZ29yaXRobSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZyAhPSBudWxsICYmIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmdbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovIDI2KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS51cGRhdGVCaW5kaW5nW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLyAzNCkuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICByZXR1cm4gd3JpdGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UcmFpbmluZ0luZm9Qcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUcmFpbmluZ0luZm9Qcm90b30gbWVzc2FnZSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRyYWluaW5nSW5mb1Byb3RvfSBUcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHJhaW5pbmdJbmZvUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemF0aW9uID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmFsZ29yaXRobSA9ICRyb290Lm9ubnguR3JhcGhQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMzoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgJiYgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoKSlcbiAgICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLnB1c2goJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS51cGRhdGVCaW5kaW5nICYmIG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGgpKSBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UudXBkYXRlQmluZGluZy5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguVHJhaW5pbmdJbmZvUHJvdG99IFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXphdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luaXRpYWxpemF0aW9uJykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnZlcmlmeShtZXNzYWdlLmluaXRpYWxpemF0aW9uKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2luaXRpYWxpemF0aW9uLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmFsZ29yaXRobSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2FsZ29yaXRobScpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguR3JhcGhQcm90by52ZXJpZnkobWVzc2FnZS5hbGdvcml0aG0pO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnYWxnb3JpdGhtLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luaXRpYWxpemF0aW9uQmluZGluZycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZykpIHJldHVybiAnaW5pdGlhbGl6YXRpb25CaW5kaW5nOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnaW5pdGlhbGl6YXRpb25CaW5kaW5nLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudXBkYXRlQmluZGluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3VwZGF0ZUJpbmRpbmcnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS51cGRhdGVCaW5kaW5nKSkgcmV0dXJuICd1cGRhdGVCaW5kaW5nOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS51cGRhdGVCaW5kaW5nLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnZlcmlmeShtZXNzYWdlLnVwZGF0ZUJpbmRpbmdbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd1cGRhdGVCaW5kaW5nLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguVHJhaW5pbmdJbmZvUHJvdG99IFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICovXG4gICAgVHJhaW5pbmdJbmZvUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHJhaW5pbmdJbmZvUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuaW5pdGlhbGl6YXRpb24gIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5pbml0aWFsaXphdGlvbiAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by5pbml0aWFsaXphdGlvbjogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb24gPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZnJvbU9iamVjdChvYmplY3QuaW5pdGlhbGl6YXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5hbGdvcml0aG0gIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5hbGdvcml0aG0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmFsZ29yaXRobTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuYWxnb3JpdGhtID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmZyb21PYmplY3Qob2JqZWN0LmFsZ29yaXRobSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZykpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by5pbml0aWFsaXphdGlvbkJpbmRpbmc6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZ1tpXSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmluaXRpYWxpemF0aW9uQmluZGluZzogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmdbaV0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdChcbiAgICAgICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmdbaV0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC51cGRhdGVCaW5kaW5nKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QudXBkYXRlQmluZGluZykpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by51cGRhdGVCaW5kaW5nOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QudXBkYXRlQmluZGluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnVwZGF0ZUJpbmRpbmdbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UcmFpbmluZ0luZm9Qcm90by51cGRhdGVCaW5kaW5nOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnVwZGF0ZUJpbmRpbmdbaV0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdChvYmplY3QudXBkYXRlQmluZGluZ1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LlRyYWluaW5nSW5mb1Byb3RvfSBtZXNzYWdlIFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZyA9IFtdO1xuICAgICAgICBvYmplY3QudXBkYXRlQmluZGluZyA9IFtdO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmluaXRpYWxpemF0aW9uID0gbnVsbDtcbiAgICAgICAgb2JqZWN0LmFsZ29yaXRobSA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXphdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luaXRpYWxpemF0aW9uJykpXG4gICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbiA9ICRyb290Lm9ubnguR3JhcGhQcm90by50b09iamVjdChtZXNzYWdlLmluaXRpYWxpemF0aW9uLCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLmFsZ29yaXRobSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2FsZ29yaXRobScpKVxuICAgICAgICBvYmplY3QuYWxnb3JpdGhtID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuYWxnb3JpdGhtLCBvcHRpb25zKTtcbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZyAmJiBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmdbal0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udG9PYmplY3QoXG4gICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZ1tqXSxcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgJiYgbWVzc2FnZS51cGRhdGVCaW5kaW5nLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QudXBkYXRlQmluZGluZyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QudXBkYXRlQmluZGluZ1tqXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by50b09iamVjdChtZXNzYWdlLnVwZGF0ZUJpbmRpbmdbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBUcmFpbmluZ0luZm9Qcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBUcmFpbmluZ0luZm9Qcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIFRyYWluaW5nSW5mb1Byb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlRyYWluaW5nSW5mb1Byb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIFRyYWluaW5nSW5mb1Byb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguTW9kZWxQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIE1vZGVsUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElNb2RlbFByb3RvXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbaXJWZXJzaW9uXSBNb2RlbFByb3RvIGlyVmVyc2lvblxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSU9wZXJhdG9yU2V0SWRQcm90bz58bnVsbH0gW29wc2V0SW1wb3J0XSBNb2RlbFByb3RvIG9wc2V0SW1wb3J0XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3Byb2R1Y2VyTmFtZV0gTW9kZWxQcm90byBwcm9kdWNlck5hbWVcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbcHJvZHVjZXJWZXJzaW9uXSBNb2RlbFByb3RvIHByb2R1Y2VyVmVyc2lvblxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb21haW5dIE1vZGVsUHJvdG8gZG9tYWluXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbbW9kZWxWZXJzaW9uXSBNb2RlbFByb3RvIG1vZGVsVmVyc2lvblxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIE1vZGVsUHJvdG8gZG9jU3RyaW5nXG4gICAgICogQHByb3BlcnR5IHtvbm54LklHcmFwaFByb3RvfG51bGx9IFtncmFwaF0gTW9kZWxQcm90byBncmFwaFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFttZXRhZGF0YVByb3BzXSBNb2RlbFByb3RvIG1ldGFkYXRhUHJvcHNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUcmFpbmluZ0luZm9Qcm90bz58bnVsbH0gW3RyYWluaW5nSW5mb10gTW9kZWxQcm90byB0cmFpbmluZ0luZm9cbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklGdW5jdGlvblByb3RvPnxudWxsfSBbZnVuY3Rpb25zXSBNb2RlbFByb3RvIGZ1bmN0aW9uc1xuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBNb2RlbFByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgTW9kZWxQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJTW9kZWxQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JTW9kZWxQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIE1vZGVsUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgdGhpcy5tZXRhZGF0YVByb3BzID0gW107XG4gICAgICB0aGlzLnRyYWluaW5nSW5mbyA9IFtdO1xuICAgICAgdGhpcy5mdW5jdGlvbnMgPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIGlyVmVyc2lvbi5cbiAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gaXJWZXJzaW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLmlyVmVyc2lvbiA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsIDAsIGZhbHNlKSA6IDA7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIG9wc2V0SW1wb3J0LlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklPcGVyYXRvclNldElkUHJvdG8+fSBvcHNldEltcG9ydFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5vcHNldEltcG9ydCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIHByb2R1Y2VyTmFtZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IHByb2R1Y2VyTmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5wcm9kdWNlck5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIE1vZGVsUHJvdG8gcHJvZHVjZXJWZXJzaW9uLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gcHJvZHVjZXJWZXJzaW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLnByb2R1Y2VyVmVyc2lvbiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBkb21haW4uXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb21haW5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUuZG9tYWluID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIG1vZGVsVmVyc2lvbi5cbiAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gbW9kZWxWZXJzaW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLm1vZGVsVmVyc2lvbiA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsIDAsIGZhbHNlKSA6IDA7XG5cbiAgICAvKipcbiAgICAgKiBNb2RlbFByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIE1vZGVsUHJvdG8gZ3JhcGguXG4gICAgICogQG1lbWJlciB7b25ueC5JR3JhcGhQcm90b3xudWxsfHVuZGVmaW5lZH0gZ3JhcGhcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUuZ3JhcGggPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBtZXRhZGF0YVByb3BzLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPn0gbWV0YWRhdGFQcm9wc1xuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5tZXRhZGF0YVByb3BzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIE1vZGVsUHJvdG8gdHJhaW5pbmdJbmZvLlxuICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklUcmFpbmluZ0luZm9Qcm90bz59IHRyYWluaW5nSW5mb1xuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLnByb3RvdHlwZS50cmFpbmluZ0luZm8gPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogTW9kZWxQcm90byBmdW5jdGlvbnMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSUZ1bmN0aW9uUHJvdG8+fSBmdW5jdGlvbnNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgTW9kZWxQcm90by5wcm90b3R5cGUuZnVuY3Rpb25zID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgTW9kZWxQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklNb2RlbFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguTW9kZWxQcm90b30gTW9kZWxQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgTW9kZWxQcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1vZGVsUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5Nb2RlbFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTW9kZWxQcm90b30gbWVzc2FnZSBNb2RlbFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuaXJWZXJzaW9uICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2lyVmVyc2lvbicpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDAgPSovIDgpLmludDY0KG1lc3NhZ2UuaXJWZXJzaW9uKTtcbiAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyTmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdwcm9kdWNlck5hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuc3RyaW5nKG1lc3NhZ2UucHJvZHVjZXJOYW1lKTtcbiAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdwcm9kdWNlclZlcnNpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLyAyNikuc3RyaW5nKG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb21haW4nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLyAzNCkuc3RyaW5nKG1lc3NhZ2UuZG9tYWluKTtcbiAgICAgIGlmIChtZXNzYWdlLm1vZGVsVmVyc2lvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdtb2RlbFZlcnNpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA1LCB3aXJlVHlwZSAwID0qLyA0MCkuaW50NjQobWVzc2FnZS5tb2RlbFZlcnNpb24pO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovIDUwKS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG1lc3NhZ2UuZ3JhcGggIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZ3JhcGgnKSlcbiAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmdyYXBoLCB3cml0ZXIudWludDMyKC8qIGlkIDcsIHdpcmVUeXBlIDIgPSovIDU4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnRbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDgsIHdpcmVUeXBlIDIgPSovIDY2KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLm1ldGFkYXRhUHJvcHMgIT0gbnVsbCAmJiBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5tZXRhZGF0YVByb3BzW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNCwgd2lyZVR5cGUgMiA9Ki8gMTE0KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnRyYWluaW5nSW5mbyAhPSBudWxsICYmIG1lc3NhZ2UudHJhaW5pbmdJbmZvLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UudHJhaW5pbmdJbmZvW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMCwgd2lyZVR5cGUgMiA9Ki8gMTYyKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmZ1bmN0aW9ucyAhPSBudWxsICYmIG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmZ1bmN0aW9ucy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LkZ1bmN0aW9uUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnNbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDI1LCB3aXJlVHlwZSAyID0qLyAyMDIpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1vZGVsUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5Nb2RlbFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JTW9kZWxQcm90b30gbWVzc2FnZSBNb2RlbFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBNb2RlbFByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgTW9kZWxQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguTW9kZWxQcm90b30gTW9kZWxQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgTW9kZWxQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5Nb2RlbFByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS5pclZlcnNpb24gPSByZWFkZXIuaW50NjQoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uub3BzZXRJbXBvcnQgJiYgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGgpKSBtZXNzYWdlLm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0LnB1c2goJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICBtZXNzYWdlLnByb2R1Y2VyTmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb21haW4gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA1OiB7XG4gICAgICAgICAgICBtZXNzYWdlLm1vZGVsVmVyc2lvbiA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA3OiB7XG4gICAgICAgICAgICBtZXNzYWdlLmdyYXBoID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxNDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5tZXRhZGF0YVByb3BzICYmIG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGgpKSBtZXNzYWdlLm1ldGFkYXRhUHJvcHMgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDIwOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLnRyYWluaW5nSW5mbyAmJiBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGgpKSBtZXNzYWdlLnRyYWluaW5nSW5mbyA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS50cmFpbmluZ0luZm8ucHVzaCgkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjU6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZnVuY3Rpb25zICYmIG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aCkpIG1lc3NhZ2UuZnVuY3Rpb25zID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmZ1bmN0aW9ucy5wdXNoKCRyb290Lm9ubnguRnVuY3Rpb25Qcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgTW9kZWxQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54Lk1vZGVsUHJvdG99IE1vZGVsUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIE1vZGVsUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIE1vZGVsUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuaXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaXJWZXJzaW9uJykpXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaXJWZXJzaW9uKSAmJlxuICAgICAgICAgICEobWVzc2FnZS5pclZlcnNpb24gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaXJWZXJzaW9uLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaXJWZXJzaW9uLmhpZ2gpKVxuICAgICAgICApXG4gICAgICAgICAgcmV0dXJuICdpclZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5vcHNldEltcG9ydCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ29wc2V0SW1wb3J0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3BzZXRJbXBvcnQpKSByZXR1cm4gJ29wc2V0SW1wb3J0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeShtZXNzYWdlLm9wc2V0SW1wb3J0W2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnb3BzZXRJbXBvcnQuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5wcm9kdWNlck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdwcm9kdWNlck5hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnByb2R1Y2VyTmFtZSkpIHJldHVybiAncHJvZHVjZXJOYW1lOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncHJvZHVjZXJWZXJzaW9uJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5wcm9kdWNlclZlcnNpb24pKSByZXR1cm4gJ3Byb2R1Y2VyVmVyc2lvbjogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvbWFpbicpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9tYWluKSkgcmV0dXJuICdkb21haW46IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5tb2RlbFZlcnNpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdtb2RlbFZlcnNpb24nKSlcbiAgICAgICAgaWYgKFxuICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5tb2RlbFZlcnNpb24pICYmXG4gICAgICAgICAgIShcbiAgICAgICAgICAgIG1lc3NhZ2UubW9kZWxWZXJzaW9uICYmXG4gICAgICAgICAgICAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5tb2RlbFZlcnNpb24ubG93KSAmJlxuICAgICAgICAgICAgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UubW9kZWxWZXJzaW9uLmhpZ2gpXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICAgICAgcmV0dXJuICdtb2RlbFZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpIHJldHVybiAnZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZ3JhcGggIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdncmFwaCcpKSB7XG4gICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguR3JhcGhQcm90by52ZXJpZnkobWVzc2FnZS5ncmFwaCk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdncmFwaC4nICsgZXJyb3I7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5tZXRhZGF0YVByb3BzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbWV0YWRhdGFQcm9wcycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm1ldGFkYXRhUHJvcHMpKSByZXR1cm4gJ21ldGFkYXRhUHJvcHM6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ21ldGFkYXRhUHJvcHMuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS50cmFpbmluZ0luZm8gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0cmFpbmluZ0luZm8nKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS50cmFpbmluZ0luZm8pKSByZXR1cm4gJ3RyYWluaW5nSW5mbzogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudHJhaW5pbmdJbmZvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90by52ZXJpZnkobWVzc2FnZS50cmFpbmluZ0luZm9baV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICd0cmFpbmluZ0luZm8uJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5mdW5jdGlvbnMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdmdW5jdGlvbnMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5mdW5jdGlvbnMpKSByZXR1cm4gJ2Z1bmN0aW9uczogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLnZlcmlmeShtZXNzYWdlLmZ1bmN0aW9uc1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2Z1bmN0aW9ucy4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgTW9kZWxQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5Nb2RlbFByb3RvfSBNb2RlbFByb3RvXG4gICAgICovXG4gICAgTW9kZWxQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54Lk1vZGVsUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk1vZGVsUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuaXJWZXJzaW9uICE9IG51bGwpXG4gICAgICAgIGlmICgkdXRpbC5Mb25nKSAobWVzc2FnZS5pclZlcnNpb24gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuaXJWZXJzaW9uKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pclZlcnNpb24gPT09ICdzdHJpbmcnKSBtZXNzYWdlLmlyVmVyc2lvbiA9IHBhcnNlSW50KG9iamVjdC5pclZlcnNpb24sIDEwKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pclZlcnNpb24gPT09ICdudW1iZXInKSBtZXNzYWdlLmlyVmVyc2lvbiA9IG9iamVjdC5pclZlcnNpb247XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaXJWZXJzaW9uID09PSAnb2JqZWN0JylcbiAgICAgICAgICBtZXNzYWdlLmlyVmVyc2lvbiA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuaXJWZXJzaW9uLmxvdyA+Pj4gMCwgb2JqZWN0LmlyVmVyc2lvbi5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgaWYgKG9iamVjdC5vcHNldEltcG9ydCkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm9wc2V0SW1wb3J0KSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLm9wc2V0SW1wb3J0OiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Qub3BzZXRJbXBvcnRbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLm9wc2V0SW1wb3J0OiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0W2ldID0gJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8uZnJvbU9iamVjdChvYmplY3Qub3BzZXRJbXBvcnRbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnByb2R1Y2VyTmFtZSAhPSBudWxsKSBtZXNzYWdlLnByb2R1Y2VyTmFtZSA9IFN0cmluZyhvYmplY3QucHJvZHVjZXJOYW1lKTtcbiAgICAgIGlmIChvYmplY3QucHJvZHVjZXJWZXJzaW9uICE9IG51bGwpIG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uID0gU3RyaW5nKG9iamVjdC5wcm9kdWNlclZlcnNpb24pO1xuICAgICAgaWYgKG9iamVjdC5kb21haW4gIT0gbnVsbCkgbWVzc2FnZS5kb21haW4gPSBTdHJpbmcob2JqZWN0LmRvbWFpbik7XG4gICAgICBpZiAob2JqZWN0Lm1vZGVsVmVyc2lvbiAhPSBudWxsKVxuICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UubW9kZWxWZXJzaW9uID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0Lm1vZGVsVmVyc2lvbikpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QubW9kZWxWZXJzaW9uID09PSAnc3RyaW5nJykgbWVzc2FnZS5tb2RlbFZlcnNpb24gPSBwYXJzZUludChvYmplY3QubW9kZWxWZXJzaW9uLCAxMCk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QubW9kZWxWZXJzaW9uID09PSAnbnVtYmVyJykgbWVzc2FnZS5tb2RlbFZlcnNpb24gPSBvYmplY3QubW9kZWxWZXJzaW9uO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0Lm1vZGVsVmVyc2lvbiA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgbWVzc2FnZS5tb2RlbFZlcnNpb24gPSBuZXcgJHV0aWwuTG9uZ0JpdHMoXG4gICAgICAgICAgICBvYmplY3QubW9kZWxWZXJzaW9uLmxvdyA+Pj4gMCxcbiAgICAgICAgICAgIG9iamVjdC5tb2RlbFZlcnNpb24uaGlnaCA+Pj4gMCxcbiAgICAgICAgICApLnRvTnVtYmVyKCk7XG4gICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKSBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChvYmplY3QuZ3JhcGggIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5ncmFwaCAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by5ncmFwaDogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZ3JhcGggPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZ3JhcGgpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5tZXRhZGF0YVByb3BzKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QubWV0YWRhdGFQcm9wcykpIHRocm93IFR5cGVFcnJvcignLm9ubnguTW9kZWxQcm90by5tZXRhZGF0YVByb3BzOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLm1ldGFkYXRhUHJvcHMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm1ldGFkYXRhUHJvcHNbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLm1ldGFkYXRhUHJvcHM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tpXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0KG9iamVjdC5tZXRhZGF0YVByb3BzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC50cmFpbmluZ0luZm8pIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC50cmFpbmluZ0luZm8pKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54Lk1vZGVsUHJvdG8udHJhaW5pbmdJbmZvOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnRyYWluaW5nSW5mbyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC50cmFpbmluZ0luZm8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50cmFpbmluZ0luZm9baV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLnRyYWluaW5nSW5mbzogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS50cmFpbmluZ0luZm9baV0gPSAkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0LnRyYWluaW5nSW5mb1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZnVuY3Rpb25zKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZnVuY3Rpb25zKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLmZ1bmN0aW9uczogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZnVuY3Rpb25zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZnVuY3Rpb25zW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5Nb2RlbFByb3RvLmZ1bmN0aW9uczogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnNbaV0gPSAkcm9vdC5vbm54LkZ1bmN0aW9uUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZnVuY3Rpb25zW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIE1vZGVsUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54Lk1vZGVsUHJvdG99IG1lc3NhZ2UgTW9kZWxQcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgTW9kZWxQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0Lm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgIG9iamVjdC5tZXRhZGF0YVByb3BzID0gW107XG4gICAgICAgIG9iamVjdC50cmFpbmluZ0luZm8gPSBbXTtcbiAgICAgICAgb2JqZWN0LmZ1bmN0aW9ucyA9IFtdO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICBvYmplY3QuaXJWZXJzaW9uID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgIH0gZWxzZSBvYmplY3QuaXJWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJzAnIDogMDtcbiAgICAgICAgb2JqZWN0LnByb2R1Y2VyTmFtZSA9ICcnO1xuICAgICAgICBvYmplY3QucHJvZHVjZXJWZXJzaW9uID0gJyc7XG4gICAgICAgIG9iamVjdC5kb21haW4gPSAnJztcbiAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICBvYmplY3QubW9kZWxWZXJzaW9uID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgIH0gZWxzZSBvYmplY3QubW9kZWxWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJzAnIDogMDtcbiAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9ICcnO1xuICAgICAgICBvYmplY3QuZ3JhcGggPSBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaXJWZXJzaW9uJykpXG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5pclZlcnNpb24gPT09ICdudW1iZXInKVxuICAgICAgICAgIG9iamVjdC5pclZlcnNpb24gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5pclZlcnNpb24pIDogbWVzc2FnZS5pclZlcnNpb247XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBvYmplY3QuaXJWZXJzaW9uID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZ1xuICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pclZlcnNpb24pXG4gICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5pclZlcnNpb24ubG93ID4+PiAwLCBtZXNzYWdlLmlyVmVyc2lvbi5oaWdoID4+PiAwKS50b051bWJlcigpXG4gICAgICAgICAgICAgICAgOiBtZXNzYWdlLmlyVmVyc2lvbjtcbiAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyTmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3Byb2R1Y2VyTmFtZScpKVxuICAgICAgICBvYmplY3QucHJvZHVjZXJOYW1lID0gbWVzc2FnZS5wcm9kdWNlck5hbWU7XG4gICAgICBpZiAobWVzc2FnZS5wcm9kdWNlclZlcnNpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdwcm9kdWNlclZlcnNpb24nKSlcbiAgICAgICAgb2JqZWN0LnByb2R1Y2VyVmVyc2lvbiA9IG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9tYWluJykpIG9iamVjdC5kb21haW4gPSBtZXNzYWdlLmRvbWFpbjtcbiAgICAgIGlmIChtZXNzYWdlLm1vZGVsVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ21vZGVsVmVyc2lvbicpKVxuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UubW9kZWxWZXJzaW9uID09PSAnbnVtYmVyJylcbiAgICAgICAgICBvYmplY3QubW9kZWxWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UubW9kZWxWZXJzaW9uKSA6IG1lc3NhZ2UubW9kZWxWZXJzaW9uO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgb2JqZWN0Lm1vZGVsVmVyc2lvbiA9XG4gICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UubW9kZWxWZXJzaW9uKVxuICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UubW9kZWxWZXJzaW9uLmxvdyA+Pj4gMCwgbWVzc2FnZS5tb2RlbFZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgIDogbWVzc2FnZS5tb2RlbFZlcnNpb247XG4gICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb2NTdHJpbmcnKSkgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgaWYgKG1lc3NhZ2UuZ3JhcGggIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdncmFwaCcpKVxuICAgICAgICBvYmplY3QuZ3JhcGggPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udG9PYmplY3QobWVzc2FnZS5ncmFwaCwgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5vcHNldEltcG9ydCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3Qub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5vcHNldEltcG9ydFtqXSA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uub3BzZXRJbXBvcnRbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubWV0YWRhdGFQcm9wcyAmJiBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5tZXRhZGF0YVByb3BzID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5tZXRhZGF0YVByb3BzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5tZXRhZGF0YVByb3BzW2pdID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS50cmFpbmluZ0luZm8gJiYgbWVzc2FnZS50cmFpbmluZ0luZm8ubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC50cmFpbmluZ0luZm8gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QudHJhaW5pbmdJbmZvW2pdID0gJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90by50b09iamVjdChtZXNzYWdlLnRyYWluaW5nSW5mb1tqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5mdW5jdGlvbnMgJiYgbWVzc2FnZS5mdW5jdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5mdW5jdGlvbnMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmZ1bmN0aW9ucy5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZnVuY3Rpb25zW2pdID0gJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZnVuY3Rpb25zW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgTW9kZWxQcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBNb2RlbFByb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgTW9kZWxQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5Nb2RlbFByb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIE1vZGVsUHJvdG87XG4gIH0pKCk7XG5cbiAgb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBba2V5XSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIGtleVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFt2YWx1ZV0gU3RyaW5nU3RyaW5nRW50cnlQcm90byB2YWx1ZVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ocHJvcGVydGllcykge1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ga2V5LlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30ga2V5XG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLmtleSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogU3RyaW5nU3RyaW5nRW50cnlQcm90byB2YWx1ZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IHZhbHVlXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLnZhbHVlID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IG1lc3NhZ2UgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLmtleSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdrZXknKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2Uua2V5KTtcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3ZhbHVlJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLnN0cmluZyhtZXNzYWdlLnZhbHVlKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IG1lc3NhZ2UgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uua2V5ID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS52YWx1ZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2Uua2V5ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgna2V5JykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5rZXkpKSByZXR1cm4gJ2tleTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnZhbHVlKSkgcmV0dXJuICd2YWx1ZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3Qua2V5ICE9IG51bGwpIG1lc3NhZ2Uua2V5ID0gU3RyaW5nKG9iamVjdC5rZXkpO1xuICAgICAgaWYgKG9iamVjdC52YWx1ZSAhPSBudWxsKSBtZXNzYWdlLnZhbHVlID0gU3RyaW5nKG9iamVjdC52YWx1ZSk7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b30gbWVzc2FnZSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3Qua2V5ID0gJyc7XG4gICAgICAgIG9iamVjdC52YWx1ZSA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uua2V5ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgna2V5JykpIG9iamVjdC5rZXkgPSBtZXNzYWdlLmtleTtcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWUnKSkgb2JqZWN0LnZhbHVlID0gbWVzc2FnZS52YWx1ZTtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgU3RyaW5nU3RyaW5nRW50cnlQcm90byB0byBKU09OLlxuICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvJztcbiAgICB9O1xuXG4gICAgcmV0dXJuIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG87XG4gIH0pKCk7XG5cbiAgb25ueC5UZW5zb3JBbm5vdGF0aW9uID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVGVuc29yQW5ub3RhdGlvbi5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVRlbnNvckFubm90YXRpb25cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbdGVuc29yTmFtZV0gVGVuc29yQW5ub3RhdGlvbiB0ZW5zb3JOYW1lXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz58bnVsbH0gW3F1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNdIFRlbnNvckFubm90YXRpb24gcXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1xuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3JBbm5vdGF0aW9uLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVGVuc29yQW5ub3RhdGlvbi5cbiAgICAgKiBAaW1wbGVtZW50cyBJVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yQW5ub3RhdGlvbj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFRlbnNvckFubm90YXRpb24ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGVuc29yQW5ub3RhdGlvbiB0ZW5zb3JOYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gdGVuc29yTmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLnByb3RvdHlwZS50ZW5zb3JOYW1lID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JBbm5vdGF0aW9uIHF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSBxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24ucHJvdG90eXBlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBUZW5zb3JBbm5vdGF0aW9uIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvckFubm90YXRpb249fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JBbm5vdGF0aW9ufSBUZW5zb3JBbm5vdGF0aW9uIGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBUZW5zb3JBbm5vdGF0aW9uKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvckFubm90YXRpb24udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JBbm5vdGF0aW9ufSBtZXNzYWdlIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS50ZW5zb3JOYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3RlbnNvck5hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UudGVuc29yTmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzICE9IG51bGwgJiYgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JBbm5vdGF0aW9uLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yQW5ub3RhdGlvbn0gbWVzc2FnZSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yQW5ub3RhdGlvbn0gVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS50ZW5zb3JOYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzICYmIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGgpKVxuICAgICAgICAgICAgICBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvckFubm90YXRpb259IFRlbnNvckFubm90YXRpb25cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UudGVuc29yTmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3RlbnNvck5hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnRlbnNvck5hbWUpKSByZXR1cm4gJ3RlbnNvck5hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMpKSByZXR1cm4gJ3F1YW50UGFyYW1ldGVyVGVuc29yTmFtZXM6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3F1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yQW5ub3RhdGlvbn0gVGVuc29yQW5ub3RhdGlvblxuICAgICAqL1xuICAgIFRlbnNvckFubm90YXRpb24uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uKCk7XG4gICAgICBpZiAob2JqZWN0LnRlbnNvck5hbWUgIT0gbnVsbCkgbWVzc2FnZS50ZW5zb3JOYW1lID0gU3RyaW5nKG9iamVjdC50ZW5zb3JOYW1lKTtcbiAgICAgIGlmIChvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMpKVxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yQW5ub3RhdGlvbi5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JBbm5vdGF0aW9uLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXM6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tpXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0KFxuICAgICAgICAgICAgb2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LlRlbnNvckFubm90YXRpb259IG1lc3NhZ2UgVGVuc29yQW5ub3RhdGlvblxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LnRlbnNvck5hbWUgPSAnJztcbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0ZW5zb3JOYW1lJykpIG9iamVjdC50ZW5zb3JOYW1lID0gbWVzc2FnZS50ZW5zb3JOYW1lO1xuICAgICAgaWYgKG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyAmJiBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2pdID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0KFxuICAgICAgICAgICAgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2pdLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBUZW5zb3JBbm5vdGF0aW9uIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgVGVuc29yQW5ub3RhdGlvbi5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFRlbnNvckFubm90YXRpb25cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBUZW5zb3JBbm5vdGF0aW9uLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlRlbnNvckFubm90YXRpb24nO1xuICAgIH07XG5cbiAgICByZXR1cm4gVGVuc29yQW5ub3RhdGlvbjtcbiAgfSkoKTtcblxuICBvbm54LkdyYXBoUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBHcmFwaFByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJR3JhcGhQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSU5vZGVQcm90bz58bnVsbH0gW25vZGVdIEdyYXBoUHJvdG8gbm9kZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBHcmFwaFByb3RvIG5hbWVcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUZW5zb3JQcm90bz58bnVsbH0gW2luaXRpYWxpemVyXSBHcmFwaFByb3RvIGluaXRpYWxpemVyXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3BhcnNlVGVuc29yUHJvdG8+fG51bGx9IFtzcGFyc2VJbml0aWFsaXplcl0gR3JhcGhQcm90byBzcGFyc2VJbml0aWFsaXplclxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIEdyYXBoUHJvdG8gZG9jU3RyaW5nXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JVmFsdWVJbmZvUHJvdG8+fG51bGx9IFtpbnB1dF0gR3JhcGhQcm90byBpbnB1dFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPnxudWxsfSBbb3V0cHV0XSBHcmFwaFByb3RvIG91dHB1dFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPnxudWxsfSBbdmFsdWVJbmZvXSBHcmFwaFByb3RvIHZhbHVlSW5mb1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVRlbnNvckFubm90YXRpb24+fG51bGx9IFtxdWFudGl6YXRpb25Bbm5vdGF0aW9uXSBHcmFwaFByb3RvIHF1YW50aXphdGlvbkFubm90YXRpb25cbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgR3JhcGhQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIEdyYXBoUHJvdG8uXG4gICAgICogQGltcGxlbWVudHMgSUdyYXBoUHJvdG9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBHcmFwaFByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgIHRoaXMubm9kZSA9IFtdO1xuICAgICAgdGhpcy5pbml0aWFsaXplciA9IFtdO1xuICAgICAgdGhpcy5zcGFyc2VJbml0aWFsaXplciA9IFtdO1xuICAgICAgdGhpcy5pbnB1dCA9IFtdO1xuICAgICAgdGhpcy5vdXRwdXQgPSBbXTtcbiAgICAgIHRoaXMudmFsdWVJbmZvID0gW107XG4gICAgICB0aGlzLnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIG5vZGUuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSU5vZGVQcm90bz59IG5vZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUubm9kZSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIG5hbWUuXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLm5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEdyYXBoUHJvdG8gaW5pdGlhbGl6ZXIuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVRlbnNvclByb3RvPn0gaW5pdGlhbGl6ZXJcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUuaW5pdGlhbGl6ZXIgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogR3JhcGhQcm90byBzcGFyc2VJbml0aWFsaXplci5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JU3BhcnNlVGVuc29yUHJvdG8+fSBzcGFyc2VJbml0aWFsaXplclxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5zcGFyc2VJbml0aWFsaXplciA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEdyYXBoUHJvdG8gaW5wdXQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPn0gaW5wdXRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUuaW5wdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogR3JhcGhQcm90byBvdXRwdXQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPn0gb3V0cHV0XG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLm91dHB1dCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBHcmFwaFByb3RvIHZhbHVlSW5mby5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVmFsdWVJbmZvUHJvdG8+fSB2YWx1ZUluZm9cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUudmFsdWVJbmZvID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEdyYXBoUHJvdG8gcXVhbnRpemF0aW9uQW5ub3RhdGlvbi5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVGVuc29yQW5ub3RhdGlvbj59IHF1YW50aXphdGlvbkFubm90YXRpb25cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgR3JhcGhQcm90by5wcm90b3R5cGUucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IEdyYXBoUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JR3JhcGhQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LkdyYXBoUHJvdG99IEdyYXBoUHJvdG8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IEdyYXBoUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBHcmFwaFByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguR3JhcGhQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG99IG1lc3NhZ2UgR3JhcGhQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgR3JhcGhQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLm5vZGUgIT0gbnVsbCAmJiBtZXNzYWdlLm5vZGUubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54Lk5vZGVQcm90by5lbmNvZGUobWVzc2FnZS5ub2RlW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICduYW1lJykpXG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8gMTgpLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5pdGlhbGl6ZXIgIT0gbnVsbCAmJiBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXplcltpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEwLCB3aXJlVHlwZSAyID0qLyA4Mikuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChtZXNzYWdlLmlucHV0ICE9IG51bGwgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXRbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDExLCB3aXJlVHlwZSAyID0qLyA5MCkuZm9yaygpLFxuICAgICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5vdXRwdXQgIT0gbnVsbCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLm91dHB1dFtpXSxcbiAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTIsIHdpcmVUeXBlIDIgPSovIDk4KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlSW5mbyAhPSBudWxsICYmIG1lc3NhZ2UudmFsdWVJbmZvLmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVJbmZvW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMywgd2lyZVR5cGUgMiA9Ki8gMTA2KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNCwgd2lyZVR5cGUgMiA9Ki8gMTE0KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyICE9IG51bGwgJiYgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXJbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDE1LCB3aXJlVHlwZSAyID0qLyAxMjIpLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEdyYXBoUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5HcmFwaFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JR3JhcGhQcm90b30gbWVzc2FnZSBHcmFwaFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgR3JhcGhQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguR3JhcGhQcm90b30gR3JhcGhQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgR3JhcGhQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5HcmFwaFByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpKSBtZXNzYWdlLm5vZGUgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uubm9kZS5wdXNoKCRyb290Lm9ubnguTm9kZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbml0aWFsaXplciAmJiBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aCkpIG1lc3NhZ2UuaW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6ZXIucHVzaCgkcm9vdC5vbm54LlRlbnNvclByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTU6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIgJiYgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGgpKSBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLnB1c2goJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEwOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDExOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmlucHV0ICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKSkgbWVzc2FnZS5pbnB1dCA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5pbnB1dC5wdXNoKCRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMjoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSkgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0LnB1c2goJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEzOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLnZhbHVlSW5mbyAmJiBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGgpKSBtZXNzYWdlLnZhbHVlSW5mbyA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS52YWx1ZUluZm8ucHVzaCgkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTQ6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAmJiBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoKSlcbiAgICAgICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ucHVzaCgkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIEdyYXBoUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5HcmFwaFByb3RvfSBHcmFwaFByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBHcmFwaFByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLm5vZGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdub2RlJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uubm9kZSkpIHJldHVybiAnbm9kZTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguTm9kZVByb3RvLnZlcmlmeShtZXNzYWdlLm5vZGVbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdub2RlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKSByZXR1cm4gJ25hbWU6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXplciAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luaXRpYWxpemVyJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW5pdGlhbGl6ZXIpKSByZXR1cm4gJ2luaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2UuaW5pdGlhbGl6ZXJbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdpbml0aWFsaXplci4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3BhcnNlSW5pdGlhbGl6ZXInKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplcikpIHJldHVybiAnc3BhcnNlSW5pdGlhbGl6ZXI6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplcltpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3NwYXJzZUluaXRpYWxpemVyLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpXG4gICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpKSByZXR1cm4gJ2RvY1N0cmluZzogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmlucHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaW5wdXQnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnB1dCkpIHJldHVybiAnaW5wdXQ6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by52ZXJpZnkobWVzc2FnZS5pbnB1dFtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2lucHV0LicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnb3V0cHV0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3V0cHV0KSkgcmV0dXJuICdvdXRwdXQ6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5KG1lc3NhZ2Uub3V0cHV0W2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnb3V0cHV0LicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UudmFsdWVJbmZvICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWVJbmZvJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudmFsdWVJbmZvKSkgcmV0dXJuICd2YWx1ZUluZm86IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5KG1lc3NhZ2UudmFsdWVJbmZvW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndmFsdWVJbmZvLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3F1YW50aXphdGlvbkFubm90YXRpb24nKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uKSkgcmV0dXJuICdxdWFudGl6YXRpb25Bbm5vdGF0aW9uOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLnZlcmlmeShtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb25baV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdxdWFudGl6YXRpb25Bbm5vdGF0aW9uLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBHcmFwaFByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LkdyYXBoUHJvdG99IEdyYXBoUHJvdG9cbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguR3JhcGhQcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguR3JhcGhQcm90bygpO1xuICAgICAgaWYgKG9iamVjdC5ub2RlKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qubm9kZSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguR3JhcGhQcm90by5ub2RlOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLm5vZGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qubm9kZS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm5vZGVbaV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8ubm9kZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5ub2RlW2ldID0gJHJvb3Qub25ueC5Ob2RlUHJvdG8uZnJvbU9iamVjdChvYmplY3Qubm9kZVtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKSBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgaWYgKG9iamVjdC5pbml0aWFsaXplcikge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmluaXRpYWxpemVyKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLmluaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmluaXRpYWxpemVyID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmluaXRpYWxpemVyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5pdGlhbGl6ZXJbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLmluaXRpYWxpemVyOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemVyW2ldID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC5pbml0aWFsaXplcltpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXIpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zcGFyc2VJbml0aWFsaXplcikpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLnNwYXJzZUluaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXJbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLnNwYXJzZUluaXRpYWxpemVyOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyW2ldID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC5zcGFyc2VJbml0aWFsaXplcltpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZG9jU3RyaW5nICE9IG51bGwpIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG9iamVjdC5pbnB1dCkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmlucHV0KSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLmlucHV0OiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmlucHV0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5wdXRbaV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8uaW5wdXQ6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuaW5wdXRbaV0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0LmlucHV0W2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5vdXRwdXQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5vdXRwdXQpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8ub3V0cHV0OiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLm91dHB1dCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5vdXRwdXQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5vdXRwdXRbaV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8ub3V0cHV0OiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLm91dHB1dFtpXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZnJvbU9iamVjdChvYmplY3Qub3V0cHV0W2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC52YWx1ZUluZm8pIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC52YWx1ZUluZm8pKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8udmFsdWVJbmZvOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnZhbHVlSW5mbyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC52YWx1ZUluZm8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC52YWx1ZUluZm9baV0gIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8udmFsdWVJbmZvOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnZhbHVlSW5mb1tpXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZnJvbU9iamVjdChvYmplY3QudmFsdWVJbmZvW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbikpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5HcmFwaFByb3RvLnF1YW50aXphdGlvbkFubm90YXRpb246IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbltpXSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkdyYXBoUHJvdG8ucXVhbnRpemF0aW9uQW5ub3RhdGlvbjogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2ldID0gJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLmZyb21PYmplY3Qob2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25baV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgR3JhcGhQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguR3JhcGhQcm90b30gbWVzc2FnZSBHcmFwaFByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3Qubm9kZSA9IFtdO1xuICAgICAgICBvYmplY3QuaW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgIG9iamVjdC5vdXRwdXQgPSBbXTtcbiAgICAgICAgb2JqZWN0LnZhbHVlSW5mbyA9IFtdO1xuICAgICAgICBvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9IFtdO1xuICAgICAgICBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5uYW1lID0gJyc7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm5vZGUgJiYgbWVzc2FnZS5ub2RlLmxlbmd0aCkge1xuICAgICAgICBvYmplY3Qubm9kZSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3Qubm9kZVtqXSA9ICRyb290Lm9ubnguTm9kZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uubm9kZVtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKSBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemVyICYmIG1lc3NhZ2UuaW5pdGlhbGl6ZXIubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5pbml0aWFsaXplciA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW5pdGlhbGl6ZXIubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmluaXRpYWxpemVyW2pdID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by50b09iamVjdChtZXNzYWdlLmluaXRpYWxpemVyW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKSBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5pbnB1dFtqXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS5pbnB1dFtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5vdXRwdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3Qub3V0cHV0W2pdID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by50b09iamVjdChtZXNzYWdlLm91dHB1dFtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS52YWx1ZUluZm8gJiYgbWVzc2FnZS52YWx1ZUluZm8ubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QudmFsdWVJbmZvW2pdID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by50b09iamVjdChtZXNzYWdlLnZhbHVlSW5mb1tqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uICYmIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25bal0gPSAkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24udG9PYmplY3QoXG4gICAgICAgICAgICBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb25bal0sXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplciAmJiBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aCkge1xuICAgICAgICBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aDsgKytqKVxuICAgICAgICAgIG9iamVjdC5zcGFyc2VJbml0aWFsaXplcltqXSA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplcltqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIEdyYXBoUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBHcmFwaFByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgR3JhcGhQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIEdyYXBoUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguR3JhcGhQcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBHcmFwaFByb3RvO1xuICB9KSgpO1xuXG4gIG9ubnguVGVuc29yUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBUZW5zb3JQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVRlbnNvclByb3RvXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyfExvbmc+fG51bGx9IFtkaW1zXSBUZW5zb3JQcm90byBkaW1zXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ8bnVsbH0gW2RhdGFUeXBlXSBUZW5zb3JQcm90byBkYXRhVHlwZVxuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UZW5zb3JQcm90by5JU2VnbWVudHxudWxsfSBbc2VnbWVudF0gVGVuc29yUHJvdG8gc2VnbWVudFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcj58bnVsbH0gW2Zsb2F0RGF0YV0gVGVuc29yUHJvdG8gZmxvYXREYXRhXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyPnxudWxsfSBbaW50MzJEYXRhXSBUZW5zb3JQcm90byBpbnQzMkRhdGFcbiAgICAgKiBAcHJvcGVydHkge0FycmF5LjxVaW50OEFycmF5PnxudWxsfSBbc3RyaW5nRGF0YV0gVGVuc29yUHJvdG8gc3RyaW5nRGF0YVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbaW50NjREYXRhXSBUZW5zb3JQcm90byBpbnQ2NERhdGFcbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbbmFtZV0gVGVuc29yUHJvdG8gbmFtZVxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIFRlbnNvclByb3RvIGRvY1N0cmluZ1xuICAgICAqIEBwcm9wZXJ0eSB7VWludDhBcnJheXxudWxsfSBbcmF3RGF0YV0gVGVuc29yUHJvdG8gcmF3RGF0YVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFtleHRlcm5hbERhdGFdIFRlbnNvclByb3RvIGV4dGVybmFsRGF0YVxuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UZW5zb3JQcm90by5EYXRhTG9jYXRpb258bnVsbH0gW2RhdGFMb2NhdGlvbl0gVGVuc29yUHJvdG8gZGF0YUxvY2F0aW9uXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyPnxudWxsfSBbZG91YmxlRGF0YV0gVGVuc29yUHJvdG8gZG91YmxlRGF0YVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbdWludDY0RGF0YV0gVGVuc29yUHJvdG8gdWludDY0RGF0YVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3JQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFRlbnNvclByb3RvLlxuICAgICAqIEBpbXBsZW1lbnRzIElUZW5zb3JQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBUZW5zb3JQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmRpbXMgPSBbXTtcbiAgICAgIHRoaXMuZmxvYXREYXRhID0gW107XG4gICAgICB0aGlzLmludDMyRGF0YSA9IFtdO1xuICAgICAgdGhpcy5zdHJpbmdEYXRhID0gW107XG4gICAgICB0aGlzLmludDY0RGF0YSA9IFtdO1xuICAgICAgdGhpcy5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgIHRoaXMuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgdGhpcy51aW50NjREYXRhID0gW107XG4gICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gZGltcy5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSBkaW1zXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZGltcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBkYXRhVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGRhdGFUeXBlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZGF0YVR5cGUgPSAwO1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gc2VnbWVudC5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlRlbnNvclByb3RvLklTZWdtZW50fG51bGx8dW5kZWZpbmVkfSBzZWdtZW50XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuc2VnbWVudCA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBmbG9hdERhdGEuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcj59IGZsb2F0RGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmZsb2F0RGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBpbnQzMkRhdGEuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcj59IGludDMyRGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmludDMyRGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBzdHJpbmdEYXRhLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxVaW50OEFycmF5Pn0gc3RyaW5nRGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLnN0cmluZ0RhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gaW50NjREYXRhLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXJ8TG9uZz59IGludDY0RGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmludDY0RGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBuYW1lLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLm5hbWUgPSAnJztcblxuICAgIC8qKlxuICAgICAqIFRlbnNvclByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gcmF3RGF0YS5cbiAgICAgKiBAbWVtYmVyIHtVaW50OEFycmF5fSByYXdEYXRhXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUucmF3RGF0YSA9ICR1dGlsLm5ld0J1ZmZlcihbXSk7XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JQcm90byBleHRlcm5hbERhdGEuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSBleHRlcm5hbERhdGFcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5leHRlcm5hbERhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gZGF0YUxvY2F0aW9uLlxuICAgICAqIEBtZW1iZXIge29ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9ufSBkYXRhTG9jYXRpb25cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5kYXRhTG9jYXRpb24gPSAwO1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gZG91YmxlRGF0YS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyPn0gZG91YmxlRGF0YVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmRvdWJsZURhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogVGVuc29yUHJvdG8gdWludDY0RGF0YS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSB1aW50NjREYXRhXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5wcm90b3R5cGUudWludDY0RGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IFRlbnNvclByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvfSBUZW5zb3JQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICByZXR1cm4gbmV3IFRlbnNvclByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90b30gbWVzc2FnZSBUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5kaW1zICE9IG51bGwgJiYgbWVzc2FnZS5kaW1zLmxlbmd0aCkge1xuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5mb3JrKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytpKSB3cml0ZXIuaW50NjQobWVzc2FnZS5kaW1zW2ldKTtcbiAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGF0YVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZGF0YVR5cGUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAwID0qLyAxNikuaW50MzIobWVzc2FnZS5kYXRhVHlwZSk7XG4gICAgICBpZiAobWVzc2FnZS5zZWdtZW50ICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3NlZ21lbnQnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JQcm90by5TZWdtZW50LmVuY29kZShcbiAgICAgICAgICBtZXNzYWdlLnNlZ21lbnQsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLyAyNikuZm9yaygpLFxuICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZmxvYXREYXRhICE9IG51bGwgJiYgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8gMzQpLmZvcmsoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmZsb2F0RGF0YS5sZW5ndGg7ICsraSkgd3JpdGVyLmZsb2F0KG1lc3NhZ2UuZmxvYXREYXRhW2ldKTtcbiAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuaW50MzJEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLmZvcmsoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmludDMyRGF0YS5sZW5ndGg7ICsraSkgd3JpdGVyLmludDMyKG1lc3NhZ2UuaW50MzJEYXRhW2ldKTtcbiAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5nRGF0YSAhPSBudWxsICYmIG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zdHJpbmdEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki8gNTApLmJ5dGVzKG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSk7XG4gICAgICBpZiAobWVzc2FnZS5pbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA3LCB3aXJlVHlwZSAyID0qLyA1OCkuZm9yaygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aDsgKytpKSB3cml0ZXIuaW50NjQobWVzc2FnZS5pbnQ2NERhdGFbaV0pO1xuICAgICAgICB3cml0ZXIubGRlbGltKCk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ25hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLyA2Nikuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5yYXdEYXRhICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3Jhd0RhdGEnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA5LCB3aXJlVHlwZSAyID0qLyA3NCkuYnl0ZXMobWVzc2FnZS5yYXdEYXRhKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvdWJsZURhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTAsIHdpcmVUeXBlIDIgPSovIDgyKS5mb3JrKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kb3VibGVEYXRhLmxlbmd0aDsgKytpKSB3cml0ZXIuZG91YmxlKG1lc3NhZ2UuZG91YmxlRGF0YVtpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnVpbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLnVpbnQ2NERhdGEubGVuZ3RoKSB7XG4gICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTEsIHdpcmVUeXBlIDIgPSovIDkwKS5mb3JrKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aDsgKytpKSB3cml0ZXIudWludDY0KG1lc3NhZ2UudWludDY0RGF0YVtpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb2NTdHJpbmcnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMiwgd2lyZVR5cGUgMiA9Ki8gOTgpLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICBpZiAobWVzc2FnZS5leHRlcm5hbERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmV4dGVybmFsRGF0YS5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMywgd2lyZVR5cGUgMiA9Ki8gMTA2KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmRhdGFMb2NhdGlvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkYXRhTG9jYXRpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNCwgd2lyZVR5cGUgMCA9Ki8gMTEyKS5pbnQzMihtZXNzYWdlLmRhdGFMb2NhdGlvbik7XG4gICAgICByZXR1cm4gd3JpdGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90b30gbWVzc2FnZSBUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBUZW5zb3JQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvfSBUZW5zb3JQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yUHJvdG8oKTtcbiAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLmRpbXMgJiYgbWVzc2FnZS5kaW1zLmxlbmd0aCkpIG1lc3NhZ2UuZGltcyA9IFtdO1xuICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMikgbWVzc2FnZS5kaW1zLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuZGltcy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZGF0YVR5cGUgPSByZWFkZXIuaW50MzIoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uuc2VnbWVudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5mbG9hdERhdGEgJiYgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoKSkgbWVzc2FnZS5mbG9hdERhdGEgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UuZmxvYXREYXRhLnB1c2gocmVhZGVyLmZsb2F0KCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuZmxvYXREYXRhLnB1c2gocmVhZGVyLmZsb2F0KCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnQzMkRhdGEgJiYgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoKSkgbWVzc2FnZS5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UuaW50MzJEYXRhLnB1c2gocmVhZGVyLmludDMyKCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuaW50MzJEYXRhLnB1c2gocmVhZGVyLmludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5zdHJpbmdEYXRhICYmIG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGgpKSBtZXNzYWdlLnN0cmluZ0RhdGEgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uuc3RyaW5nRGF0YS5wdXNoKHJlYWRlci5ieXRlcygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDc6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW50NjREYXRhICYmIG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aCkpIG1lc3NhZ2UuaW50NjREYXRhID0gW107XG4gICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKSBtZXNzYWdlLmludDY0RGF0YS5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBtZXNzYWdlLmludDY0RGF0YS5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDEyOiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDk6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UucmF3RGF0YSA9IHJlYWRlci5ieXRlcygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTM6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhICYmIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aCkpIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmV4dGVybmFsRGF0YS5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDE0OiB7XG4gICAgICAgICAgICBtZXNzYWdlLmRhdGFMb2NhdGlvbiA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTA6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZG91YmxlRGF0YSAmJiBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoKSkgbWVzc2FnZS5kb3VibGVEYXRhID0gW107XG4gICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKSBtZXNzYWdlLmRvdWJsZURhdGEucHVzaChyZWFkZXIuZG91YmxlKCkpO1xuICAgICAgICAgICAgfSBlbHNlIG1lc3NhZ2UuZG91YmxlRGF0YS5wdXNoKHJlYWRlci5kb3VibGUoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS51aW50NjREYXRhICYmIG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGgpKSBtZXNzYWdlLnVpbnQ2NERhdGEgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UudWludDY0RGF0YS5wdXNoKHJlYWRlci51aW50NjQoKSk7XG4gICAgICAgICAgICB9IGVsc2UgbWVzc2FnZS51aW50NjREYXRhLnB1c2gocmVhZGVyLnVpbnQ2NCgpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG99IFRlbnNvclByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5kaW1zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZGltcycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmRpbXMpKSByZXR1cm4gJ2RpbXM6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRpbXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbXNbaV0pICYmXG4gICAgICAgICAgICAhKG1lc3NhZ2UuZGltc1tpXSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1zW2ldLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXS5oaWdoKSlcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ2RpbXM6IGludGVnZXJ8TG9uZ1tdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRhdGFUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZGF0YVR5cGUnKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kYXRhVHlwZSkpIHJldHVybiAnZGF0YVR5cGU6IGludGVnZXIgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2Uuc2VnbWVudCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NlZ21lbnQnKSkge1xuICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQudmVyaWZ5KG1lc3NhZ2Uuc2VnbWVudCk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzZWdtZW50LicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmZsb2F0RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2Zsb2F0RGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmZsb2F0RGF0YSkpIHJldHVybiAnZmxvYXREYXRhOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmZsb2F0RGF0YVtpXSAhPT0gJ251bWJlcicpIHJldHVybiAnZmxvYXREYXRhOiBudW1iZXJbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5pbnQzMkRhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbnQzMkRhdGEnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnQzMkRhdGEpKSByZXR1cm4gJ2ludDMyRGF0YTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50MzJEYXRhW2ldKSkgcmV0dXJuICdpbnQzMkRhdGE6IGludGVnZXJbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zdHJpbmdEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3RyaW5nRGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnN0cmluZ0RhdGEpKSByZXR1cm4gJ3N0cmluZ0RhdGE6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIShcbiAgICAgICAgICAgICAgKG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSAmJiB0eXBlb2YgbWVzc2FnZS5zdHJpbmdEYXRhW2ldLmxlbmd0aCA9PT0gJ251bWJlcicpIHx8XG4gICAgICAgICAgICAgICR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ3N0cmluZ0RhdGE6IGJ1ZmZlcltdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmludDY0RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2ludDY0RGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmludDY0RGF0YSkpIHJldHVybiAnaW50NjREYXRhOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDY0RGF0YVtpXSkgJiZcbiAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgIG1lc3NhZ2UuaW50NjREYXRhW2ldICYmXG4gICAgICAgICAgICAgICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDY0RGF0YVtpXS5sb3cpICYmXG4gICAgICAgICAgICAgICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDY0RGF0YVtpXS5oaWdoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAnaW50NjREYXRhOiBpbnRlZ2VyfExvbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpIHJldHVybiAnbmFtZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSkgcmV0dXJuICdkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5yYXdEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncmF3RGF0YScpKVxuICAgICAgICBpZiAoISgobWVzc2FnZS5yYXdEYXRhICYmIHR5cGVvZiBtZXNzYWdlLnJhd0RhdGEubGVuZ3RoID09PSAnbnVtYmVyJykgfHwgJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5yYXdEYXRhKSkpXG4gICAgICAgICAgcmV0dXJuICdyYXdEYXRhOiBidWZmZXIgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZXh0ZXJuYWxEYXRhJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZXh0ZXJuYWxEYXRhKSkgcmV0dXJuICdleHRlcm5hbERhdGE6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmV4dGVybmFsRGF0YS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnkobWVzc2FnZS5leHRlcm5hbERhdGFbaV0pO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdleHRlcm5hbERhdGEuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kYXRhTG9jYXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkYXRhTG9jYXRpb24nKSlcbiAgICAgICAgc3dpdGNoIChtZXNzYWdlLmRhdGFMb2NhdGlvbikge1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gJ2RhdGFMb2NhdGlvbjogZW51bSB2YWx1ZSBleHBlY3RlZCc7XG4gICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb3VibGVEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG91YmxlRGF0YScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmRvdWJsZURhdGEpKSByZXR1cm4gJ2RvdWJsZURhdGE6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmRvdWJsZURhdGFbaV0gIT09ICdudW1iZXInKSByZXR1cm4gJ2RvdWJsZURhdGE6IG51bWJlcltdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnVpbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd1aW50NjREYXRhJykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudWludDY0RGF0YSkpIHJldHVybiAndWludDY0RGF0YTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudWludDY0RGF0YVtpXSkgJiZcbiAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgIG1lc3NhZ2UudWludDY0RGF0YVtpXSAmJlxuICAgICAgICAgICAgICAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS51aW50NjREYXRhW2ldLmxvdykgJiZcbiAgICAgICAgICAgICAgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudWludDY0RGF0YVtpXS5oaWdoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAndWludDY0RGF0YTogaW50ZWdlcnxMb25nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBUZW5zb3JQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG99IFRlbnNvclByb3RvXG4gICAgICovXG4gICAgVGVuc29yUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JQcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuZGltcykge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmRpbXMpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRlbnNvclByb3RvLmRpbXM6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZGltcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5kaW1zLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSAobWVzc2FnZS5kaW1zW2ldID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmRpbXNbaV0pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gJ3N0cmluZycpIG1lc3NhZ2UuZGltc1tpXSA9IHBhcnNlSW50KG9iamVjdC5kaW1zW2ldLCAxMCk7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1zW2ldID09PSAnbnVtYmVyJykgbWVzc2FnZS5kaW1zW2ldID0gb2JqZWN0LmRpbXNbaV07XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1zW2ldID09PSAnb2JqZWN0JylcbiAgICAgICAgICAgIG1lc3NhZ2UuZGltc1tpXSA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuZGltc1tpXS5sb3cgPj4+IDAsIG9iamVjdC5kaW1zW2ldLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRhdGFUeXBlICE9IG51bGwpIG1lc3NhZ2UuZGF0YVR5cGUgPSBvYmplY3QuZGF0YVR5cGUgfCAwO1xuICAgICAgaWYgKG9iamVjdC5zZWdtZW50ICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc2VnbWVudCAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uc2VnbWVudDogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uuc2VnbWVudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC5mcm9tT2JqZWN0KG9iamVjdC5zZWdtZW50KTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZmxvYXREYXRhKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZmxvYXREYXRhKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5mbG9hdERhdGE6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZmxvYXREYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmZsb2F0RGF0YS5sZW5ndGg7ICsraSkgbWVzc2FnZS5mbG9hdERhdGFbaV0gPSBOdW1iZXIob2JqZWN0LmZsb2F0RGF0YVtpXSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmludDMyRGF0YSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmludDMyRGF0YSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uaW50MzJEYXRhOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmludDMyRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnQzMkRhdGEubGVuZ3RoOyArK2kpIG1lc3NhZ2UuaW50MzJEYXRhW2ldID0gb2JqZWN0LmludDMyRGF0YVtpXSB8IDA7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LnN0cmluZ0RhdGEpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zdHJpbmdEYXRhKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5zdHJpbmdEYXRhOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnN0cmluZ0RhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Quc3RyaW5nRGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zdHJpbmdEYXRhW2ldID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICR1dGlsLmJhc2U2NC5kZWNvZGUoXG4gICAgICAgICAgICAgIG9iamVjdC5zdHJpbmdEYXRhW2ldLFxuICAgICAgICAgICAgICAobWVzc2FnZS5zdHJpbmdEYXRhW2ldID0gJHV0aWwubmV3QnVmZmVyKCR1dGlsLmJhc2U2NC5sZW5ndGgob2JqZWN0LnN0cmluZ0RhdGFbaV0pKSksXG4gICAgICAgICAgICAgIDAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIGVsc2UgaWYgKG9iamVjdC5zdHJpbmdEYXRhW2ldLmxlbmd0aCA+PSAwKSBtZXNzYWdlLnN0cmluZ0RhdGFbaV0gPSBvYmplY3Quc3RyaW5nRGF0YVtpXTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuaW50NjREYXRhKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW50NjREYXRhKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5pbnQ2NERhdGE6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW50NjREYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmludDY0RGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuaW50NjREYXRhW2ldID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmludDY0RGF0YVtpXSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnQ2NERhdGFbaV0gPT09ICdzdHJpbmcnKSBtZXNzYWdlLmludDY0RGF0YVtpXSA9IHBhcnNlSW50KG9iamVjdC5pbnQ2NERhdGFbaV0sIDEwKTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmludDY0RGF0YVtpXSA9PT0gJ251bWJlcicpIG1lc3NhZ2UuaW50NjREYXRhW2ldID0gb2JqZWN0LmludDY0RGF0YVtpXTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmludDY0RGF0YVtpXSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YVtpXSA9IG5ldyAkdXRpbC5Mb25nQml0cyhcbiAgICAgICAgICAgICAgb2JqZWN0LmludDY0RGF0YVtpXS5sb3cgPj4+IDAsXG4gICAgICAgICAgICAgIG9iamVjdC5pbnQ2NERhdGFbaV0uaGlnaCA+Pj4gMCxcbiAgICAgICAgICAgICkudG9OdW1iZXIoKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKSBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbCkgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICBpZiAob2JqZWN0LnJhd0RhdGEgIT0gbnVsbClcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QucmF3RGF0YSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgJHV0aWwuYmFzZTY0LmRlY29kZShcbiAgICAgICAgICAgIG9iamVjdC5yYXdEYXRhLFxuICAgICAgICAgICAgKG1lc3NhZ2UucmF3RGF0YSA9ICR1dGlsLm5ld0J1ZmZlcigkdXRpbC5iYXNlNjQubGVuZ3RoKG9iamVjdC5yYXdEYXRhKSkpLFxuICAgICAgICAgICAgMCxcbiAgICAgICAgICApO1xuICAgICAgICBlbHNlIGlmIChvYmplY3QucmF3RGF0YS5sZW5ndGggPj0gMCkgbWVzc2FnZS5yYXdEYXRhID0gb2JqZWN0LnJhd0RhdGE7XG4gICAgICBpZiAob2JqZWN0LmV4dGVybmFsRGF0YSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmV4dGVybmFsRGF0YSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8uZXh0ZXJuYWxEYXRhOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmV4dGVybmFsRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5leHRlcm5hbERhdGEubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5leHRlcm5hbERhdGFbaV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JQcm90by5leHRlcm5hbERhdGE6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmZyb21PYmplY3Qob2JqZWN0LmV4dGVybmFsRGF0YVtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN3aXRjaCAob2JqZWN0LmRhdGFMb2NhdGlvbikge1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmRhdGFMb2NhdGlvbiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZGF0YUxvY2F0aW9uID0gb2JqZWN0LmRhdGFMb2NhdGlvbjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnREVGQVVMVCc6XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICBtZXNzYWdlLmRhdGFMb2NhdGlvbiA9IDA7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0VYVEVSTkFMJzpcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIG1lc3NhZ2UuZGF0YUxvY2F0aW9uID0gMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZG91YmxlRGF0YSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmRvdWJsZURhdGEpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlRlbnNvclByb3RvLmRvdWJsZURhdGE6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5kb3VibGVEYXRhLmxlbmd0aDsgKytpKSBtZXNzYWdlLmRvdWJsZURhdGFbaV0gPSBOdW1iZXIob2JqZWN0LmRvdWJsZURhdGFbaV0pO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC51aW50NjREYXRhKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QudWludDY0RGF0YSkpIHRocm93IFR5cGVFcnJvcignLm9ubnguVGVuc29yUHJvdG8udWludDY0RGF0YTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS51aW50NjREYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnVpbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QudWludDY0RGF0YVtpXSkpLnVuc2lnbmVkID0gdHJ1ZTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnVpbnQ2NERhdGFbaV0gPT09ICdzdHJpbmcnKSBtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSBwYXJzZUludChvYmplY3QudWludDY0RGF0YVtpXSwgMTApO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudWludDY0RGF0YVtpXSA9PT0gJ251bWJlcicpIG1lc3NhZ2UudWludDY0RGF0YVtpXSA9IG9iamVjdC51aW50NjREYXRhW2ldO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudWludDY0RGF0YVtpXSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMoXG4gICAgICAgICAgICAgIG9iamVjdC51aW50NjREYXRhW2ldLmxvdyA+Pj4gMCxcbiAgICAgICAgICAgICAgb2JqZWN0LnVpbnQ2NERhdGFbaV0uaGlnaCA+Pj4gMCxcbiAgICAgICAgICAgICkudG9OdW1iZXIodHJ1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVGVuc29yUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JQcm90b30gbWVzc2FnZSBUZW5zb3JQcm90b1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICovXG4gICAgVGVuc29yUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5kaW1zID0gW107XG4gICAgICAgIG9iamVjdC5mbG9hdERhdGEgPSBbXTtcbiAgICAgICAgb2JqZWN0LmludDMyRGF0YSA9IFtdO1xuICAgICAgICBvYmplY3Quc3RyaW5nRGF0YSA9IFtdO1xuICAgICAgICBvYmplY3QuaW50NjREYXRhID0gW107XG4gICAgICAgIG9iamVjdC5kb3VibGVEYXRhID0gW107XG4gICAgICAgIG9iamVjdC51aW50NjREYXRhID0gW107XG4gICAgICAgIG9iamVjdC5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5kYXRhVHlwZSA9IDA7XG4gICAgICAgIG9iamVjdC5zZWdtZW50ID0gbnVsbDtcbiAgICAgICAgb2JqZWN0Lm5hbWUgPSAnJztcbiAgICAgICAgaWYgKG9wdGlvbnMuYnl0ZXMgPT09IFN0cmluZykgb2JqZWN0LnJhd0RhdGEgPSAnJztcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgb2JqZWN0LnJhd0RhdGEgPSBbXTtcbiAgICAgICAgICBpZiAob3B0aW9ucy5ieXRlcyAhPT0gQXJyYXkpIG9iamVjdC5yYXdEYXRhID0gJHV0aWwubmV3QnVmZmVyKG9iamVjdC5yYXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gJyc7XG4gICAgICAgIG9iamVjdC5kYXRhTG9jYXRpb24gPSBvcHRpb25zLmVudW1zID09PSBTdHJpbmcgPyAnREVGQVVMVCcgOiAwO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGltcyAmJiBtZXNzYWdlLmRpbXMubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5kaW1zID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytqKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5kaW1zW2pdID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIG9iamVjdC5kaW1zW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZGltc1tqXSkgOiBtZXNzYWdlLmRpbXNbal07XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgb2JqZWN0LmRpbXNbal0gPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5kaW1zW2pdKVxuICAgICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmRpbXNbal0ubG93ID4+PiAwLCBtZXNzYWdlLmRpbXNbal0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLmRpbXNbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kYXRhVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RhdGFUeXBlJykpIG9iamVjdC5kYXRhVHlwZSA9IG1lc3NhZ2UuZGF0YVR5cGU7XG4gICAgICBpZiAobWVzc2FnZS5zZWdtZW50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc2VnbWVudCcpKVxuICAgICAgICBvYmplY3Quc2VnbWVudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC50b09iamVjdChtZXNzYWdlLnNlZ21lbnQsIG9wdGlvbnMpO1xuICAgICAgaWYgKG1lc3NhZ2UuZmxvYXREYXRhICYmIG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuZmxvYXREYXRhID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LmZsb2F0RGF0YVtqXSA9XG4gICAgICAgICAgICBvcHRpb25zLmpzb24gJiYgIWlzRmluaXRlKG1lc3NhZ2UuZmxvYXREYXRhW2pdKSA/IFN0cmluZyhtZXNzYWdlLmZsb2F0RGF0YVtqXSkgOiBtZXNzYWdlLmZsb2F0RGF0YVtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmludDMyRGF0YSAmJiBtZXNzYWdlLmludDMyRGF0YS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmludDMyRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aDsgKytqKSBvYmplY3QuaW50MzJEYXRhW2pdID0gbWVzc2FnZS5pbnQzMkRhdGFbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zdHJpbmdEYXRhICYmIG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LnN0cmluZ0RhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0LnN0cmluZ0RhdGFbal0gPVxuICAgICAgICAgICAgb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgID8gJHV0aWwuYmFzZTY0LmVuY29kZShtZXNzYWdlLnN0cmluZ0RhdGFbal0sIDAsIG1lc3NhZ2Uuc3RyaW5nRGF0YVtqXS5sZW5ndGgpXG4gICAgICAgICAgICAgIDogb3B0aW9ucy5ieXRlcyA9PT0gQXJyYXlcbiAgICAgICAgICAgICAgICA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG1lc3NhZ2Uuc3RyaW5nRGF0YVtqXSlcbiAgICAgICAgICAgICAgICA6IG1lc3NhZ2Uuc3RyaW5nRGF0YVtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmludDY0RGF0YSAmJiBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmludDY0RGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5pbnQ2NERhdGFbal0gPT09ICdudW1iZXInKVxuICAgICAgICAgICAgb2JqZWN0LmludDY0RGF0YVtqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmludDY0RGF0YVtqXSkgOiBtZXNzYWdlLmludDY0RGF0YVtqXTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBvYmplY3QuaW50NjREYXRhW2pdID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuaW50NjREYXRhW2pdKVxuICAgICAgICAgICAgICAgIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyXG4gICAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmludDY0RGF0YVtqXS5sb3cgPj4+IDAsIG1lc3NhZ2UuaW50NjREYXRhW2pdLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICAgIDogbWVzc2FnZS5pbnQ2NERhdGFbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKSBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgIGlmIChtZXNzYWdlLnJhd0RhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdyYXdEYXRhJykpXG4gICAgICAgIG9iamVjdC5yYXdEYXRhID1cbiAgICAgICAgICBvcHRpb25zLmJ5dGVzID09PSBTdHJpbmdcbiAgICAgICAgICAgID8gJHV0aWwuYmFzZTY0LmVuY29kZShtZXNzYWdlLnJhd0RhdGEsIDAsIG1lc3NhZ2UucmF3RGF0YS5sZW5ndGgpXG4gICAgICAgICAgICA6IG9wdGlvbnMuYnl0ZXMgPT09IEFycmF5XG4gICAgICAgICAgICAgID8gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwobWVzc2FnZS5yYXdEYXRhKVxuICAgICAgICAgICAgICA6IG1lc3NhZ2UucmF3RGF0YTtcbiAgICAgIGlmIChtZXNzYWdlLmRvdWJsZURhdGEgJiYgbWVzc2FnZS5kb3VibGVEYXRhLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZG91YmxlRGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZG91YmxlRGF0YVtqXSA9XG4gICAgICAgICAgICBvcHRpb25zLmpzb24gJiYgIWlzRmluaXRlKG1lc3NhZ2UuZG91YmxlRGF0YVtqXSkgPyBTdHJpbmcobWVzc2FnZS5kb3VibGVEYXRhW2pdKSA6IG1lc3NhZ2UuZG91YmxlRGF0YVtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnVpbnQ2NERhdGEgJiYgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aCkge1xuICAgICAgICBvYmplY3QudWludDY0RGF0YSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UudWludDY0RGF0YVtqXSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICBvYmplY3QudWludDY0RGF0YVtqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLnVpbnQ2NERhdGFbal0pIDogbWVzc2FnZS51aW50NjREYXRhW2pdO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG9iamVjdC51aW50NjREYXRhW2pdID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UudWludDY0RGF0YVtqXSlcbiAgICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS51aW50NjREYXRhW2pdLmxvdyA+Pj4gMCwgbWVzc2FnZS51aW50NjREYXRhW2pdLmhpZ2ggPj4+IDApLnRvTnVtYmVyKHRydWUpXG4gICAgICAgICAgICAgICAgICA6IG1lc3NhZ2UudWludDY0RGF0YVtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKSBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICBpZiAobWVzc2FnZS5leHRlcm5hbERhdGEgJiYgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmV4dGVybmFsRGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZXh0ZXJuYWxEYXRhW2pdID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2pdLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRhdGFMb2NhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RhdGFMb2NhdGlvbicpKVxuICAgICAgICBvYmplY3QuZGF0YUxvY2F0aW9uID1cbiAgICAgICAgICBvcHRpb25zLmVudW1zID09PSBTdHJpbmdcbiAgICAgICAgICAgID8gJHJvb3Qub25ueC5UZW5zb3JQcm90by5EYXRhTG9jYXRpb25bbWVzc2FnZS5kYXRhTG9jYXRpb25dID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyBtZXNzYWdlLmRhdGFMb2NhdGlvblxuICAgICAgICAgICAgICA6ICRyb290Lm9ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uW21lc3NhZ2UuZGF0YUxvY2F0aW9uXVxuICAgICAgICAgICAgOiBtZXNzYWdlLmRhdGFMb2NhdGlvbjtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgVGVuc29yUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBUZW5zb3JQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UZW5zb3JQcm90byc7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERhdGFUeXBlIGVudW0uXG4gICAgICogQG5hbWUgb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVxuICAgICAqIEBlbnVtIHtudW1iZXJ9XG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVOREVGSU5FRD0wIFVOREVGSU5FRCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVD0xIEZMT0FUIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVJTlQ4PTIgVUlOVDggdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UOD0zIElOVDggdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gVUlOVDE2PTQgVUlOVDE2IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IElOVDE2PTUgSU5UMTYgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UMzI9NiBJTlQzMiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJTlQ2ND03IElOVDY0IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNUUklORz04IFNUUklORyB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBCT09MPTkgQk9PTCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVDE2PTEwIEZMT0FUMTYgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRE9VQkxFPTExIERPVUJMRSB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVSU5UMzI9MTIgVUlOVDMyIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVJTlQ2ND0xMyBVSU5UNjQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gQ09NUExFWDY0PTE0IENPTVBMRVg2NCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBDT01QTEVYMTI4PTE1IENPTVBMRVgxMjggdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gQkZMT0FUMTY9MTYgQkZMT0FUMTYgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ4RTRNM0ZOPTE3IEZMT0FUOEU0TTNGTiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVDhFNE0zRk5VWj0xOCBGTE9BVDhFNE0zRk5VWiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVDhFNU0yPTE5IEZMT0FUOEU1TTIgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ4RTVNMkZOVVo9MjAgRkxPQVQ4RTVNMkZOVVogdmFsdWVcbiAgICAgKi9cbiAgICBUZW5zb3JQcm90by5EYXRhVHlwZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LFxuICAgICAgICB2YWx1ZXMgPSBPYmplY3QuY3JlYXRlKHZhbHVlc0J5SWQpO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzBdID0gJ1VOREVGSU5FRCcpXSA9IDA7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMV0gPSAnRkxPQVQnKV0gPSAxO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzJdID0gJ1VJTlQ4JyldID0gMjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFszXSA9ICdJTlQ4JyldID0gMztcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs0XSA9ICdVSU5UMTYnKV0gPSA0O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzVdID0gJ0lOVDE2JyldID0gNTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFs2XSA9ICdJTlQzMicpXSA9IDY7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbN10gPSAnSU5UNjQnKV0gPSA3O1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzhdID0gJ1NUUklORycpXSA9IDg7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbOV0gPSAnQk9PTCcpXSA9IDk7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTBdID0gJ0ZMT0FUMTYnKV0gPSAxMDtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxMV0gPSAnRE9VQkxFJyldID0gMTE7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTJdID0gJ1VJTlQzMicpXSA9IDEyO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzEzXSA9ICdVSU5UNjQnKV0gPSAxMztcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxNF0gPSAnQ09NUExFWDY0JyldID0gMTQ7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTVdID0gJ0NPTVBMRVgxMjgnKV0gPSAxNTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxNl0gPSAnQkZMT0FUMTYnKV0gPSAxNjtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsxN10gPSAnRkxPQVQ4RTRNM0ZOJyldID0gMTc7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMThdID0gJ0ZMT0FUOEU0TTNGTlVaJyldID0gMTg7XG4gICAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMTldID0gJ0ZMT0FUOEU1TTInKV0gPSAxOTtcbiAgICAgIHZhbHVlc1sodmFsdWVzQnlJZFsyMF0gPSAnRkxPQVQ4RTVNMkZOVVonKV0gPSAyMDtcbiAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfSkoKTtcblxuICAgIFRlbnNvclByb3RvLlNlZ21lbnQgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU2VnbWVudC5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgKiBAaW50ZXJmYWNlIElTZWdtZW50XG4gICAgICAgKiBAcHJvcGVydHkge251bWJlcnxMb25nfG51bGx9IFtiZWdpbl0gU2VnbWVudCBiZWdpblxuICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbZW5kXSBTZWdtZW50IGVuZFxuICAgICAgICovXG5cbiAgICAgIC8qKlxuICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBTZWdtZW50LlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFNlZ21lbnQuXG4gICAgICAgKiBAaW1wbGVtZW50cyBJU2VnbWVudFxuICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnQ9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gU2VnbWVudChwcm9wZXJ0aWVzKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbCkgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogU2VnbWVudCBiZWdpbi5cbiAgICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSBiZWdpblxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQucHJvdG90eXBlLmJlZ2luID0gJHV0aWwuTG9uZyA/ICR1dGlsLkxvbmcuZnJvbUJpdHMoMCwgMCwgZmFsc2UpIDogMDtcblxuICAgICAgLyoqXG4gICAgICAgKiBTZWdtZW50IGVuZC5cbiAgICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSBlbmRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBTZWdtZW50LnByb3RvdHlwZS5lbmQgPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLCAwLCBmYWxzZSkgOiAwO1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBuZXcgU2VnbWVudCBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnQ9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IFNlZ21lbnQgaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICByZXR1cm4gbmV3IFNlZ21lbnQocHJvcGVydGllcyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTZWdtZW50IG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudC52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JQcm90by5JU2VnbWVudH0gbWVzc2FnZSBTZWdtZW50IG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuYmVnaW4gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnYmVnaW4nKSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDAgPSovIDgpLmludDY0KG1lc3NhZ2UuYmVnaW4pO1xuICAgICAgICBpZiAobWVzc2FnZS5lbmQgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZW5kJykpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAwID0qLyAxNikuaW50NjQobWVzc2FnZS5lbmQpO1xuICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU2VnbWVudCBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclByb3RvLlNlZ21lbnQudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnR9IG1lc3NhZ2UgU2VnbWVudCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBTZWdtZW50LmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBTZWdtZW50IG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90by5TZWdtZW50fSBTZWdtZW50XG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudCgpO1xuICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICBtZXNzYWdlLmJlZ2luID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZW5kID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBTZWdtZW50IG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IFNlZ21lbnRcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBWZXJpZmllcyBhIFNlZ21lbnQgbWVzc2FnZS5cbiAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2UuYmVnaW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdiZWdpbicpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5iZWdpbikgJiZcbiAgICAgICAgICAgICEobWVzc2FnZS5iZWdpbiAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5iZWdpbi5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmJlZ2luLmhpZ2gpKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHJldHVybiAnYmVnaW46IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLmVuZCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VuZCcpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5lbmQpICYmXG4gICAgICAgICAgICAhKG1lc3NhZ2UuZW5kICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVuZC5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVuZC5oaWdoKSlcbiAgICAgICAgICApXG4gICAgICAgICAgICByZXR1cm4gJ2VuZDogaW50ZWdlcnxMb25nIGV4cGVjdGVkJztcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBTZWdtZW50IG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90by5TZWdtZW50fSBTZWdtZW50XG4gICAgICAgKi9cbiAgICAgIFNlZ21lbnQuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQpIHJldHVybiBvYmplY3Q7XG4gICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudCgpO1xuICAgICAgICBpZiAob2JqZWN0LmJlZ2luICE9IG51bGwpXG4gICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIChtZXNzYWdlLmJlZ2luID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmJlZ2luKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmJlZ2luID09PSAnc3RyaW5nJykgbWVzc2FnZS5iZWdpbiA9IHBhcnNlSW50KG9iamVjdC5iZWdpbiwgMTApO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuYmVnaW4gPT09ICdudW1iZXInKSBtZXNzYWdlLmJlZ2luID0gb2JqZWN0LmJlZ2luO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuYmVnaW4gPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgbWVzc2FnZS5iZWdpbiA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuYmVnaW4ubG93ID4+PiAwLCBvYmplY3QuYmVnaW4uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgaWYgKG9iamVjdC5lbmQgIT0gbnVsbClcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuZW5kID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmVuZCkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5lbmQgPT09ICdzdHJpbmcnKSBtZXNzYWdlLmVuZCA9IHBhcnNlSW50KG9iamVjdC5lbmQsIDEwKTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmVuZCA9PT0gJ251bWJlcicpIG1lc3NhZ2UuZW5kID0gb2JqZWN0LmVuZDtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmVuZCA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmVuZCA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuZW5kLmxvdyA+Pj4gMCwgb2JqZWN0LmVuZC5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgU2VnbWVudCBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JQcm90by5TZWdtZW50fSBtZXNzYWdlIFNlZ21lbnRcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykge1xuICAgICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgICBvYmplY3QuYmVnaW4gPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICAgIH0gZWxzZSBvYmplY3QuYmVnaW4gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAnMCcgOiAwO1xuICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICAgIG9iamVjdC5lbmQgPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICAgIH0gZWxzZSBvYmplY3QuZW5kID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJzAnIDogMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5iZWdpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2JlZ2luJykpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmJlZ2luID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIG9iamVjdC5iZWdpbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmJlZ2luKSA6IG1lc3NhZ2UuYmVnaW47XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgb2JqZWN0LmJlZ2luID1cbiAgICAgICAgICAgICAgb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nXG4gICAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuYmVnaW4pXG4gICAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuYmVnaW4ubG93ID4+PiAwLCBtZXNzYWdlLmJlZ2luLmhpZ2ggPj4+IDApLnRvTnVtYmVyKClcbiAgICAgICAgICAgICAgICAgIDogbWVzc2FnZS5iZWdpbjtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZW5kICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZW5kJykpXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmVuZCA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICBvYmplY3QuZW5kID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZW5kKSA6IG1lc3NhZ2UuZW5kO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG9iamVjdC5lbmQgPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5lbmQpXG4gICAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuZW5kLmxvdyA+Pj4gMCwgbWVzc2FnZS5lbmQuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLmVuZDtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ29udmVydHMgdGhpcyBTZWdtZW50IHRvIEpTT04uXG4gICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgU2VnbWVudFxuICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAqL1xuICAgICAgU2VnbWVudC5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlRlbnNvclByb3RvLlNlZ21lbnQnO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIFNlZ21lbnQ7XG4gICAgfSkoKTtcblxuICAgIC8qKlxuICAgICAqIERhdGFMb2NhdGlvbiBlbnVtLlxuICAgICAqIEBuYW1lIG9ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uXG4gICAgICogQGVudW0ge251bWJlcn1cbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gREVGQVVMVD0wIERFRkFVTFQgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRVhURVJOQUw9MSBFWFRFUk5BTCB2YWx1ZVxuICAgICAqL1xuICAgIFRlbnNvclByb3RvLkRhdGFMb2NhdGlvbiA9IChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LFxuICAgICAgICB2YWx1ZXMgPSBPYmplY3QuY3JlYXRlKHZhbHVlc0J5SWQpO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzBdID0gJ0RFRkFVTFQnKV0gPSAwO1xuICAgICAgdmFsdWVzWyh2YWx1ZXNCeUlkWzFdID0gJ0VYVEVSTkFMJyldID0gMTtcbiAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfSkoKTtcblxuICAgIHJldHVybiBUZW5zb3JQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlNwYXJzZVRlbnNvclByb3RvID0gKGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU3BhcnNlVGVuc29yUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElTcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVGVuc29yUHJvdG98bnVsbH0gW3ZhbHVlc10gU3BhcnNlVGVuc29yUHJvdG8gdmFsdWVzXG4gICAgICogQHByb3BlcnR5IHtvbm54LklUZW5zb3JQcm90b3xudWxsfSBbaW5kaWNlc10gU3BhcnNlVGVuc29yUHJvdG8gaW5kaWNlc1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbZGltc10gU3BhcnNlVGVuc29yUHJvdG8gZGltc1xuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBTcGFyc2VUZW5zb3JQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFNwYXJzZVRlbnNvclByb3RvLlxuICAgICAqIEBpbXBsZW1lbnRzIElTcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JU3BhcnNlVGVuc29yUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBTcGFyc2VUZW5zb3JQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmRpbXMgPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTcGFyc2VUZW5zb3JQcm90byB2YWx1ZXMuXG4gICAgICogQG1lbWJlciB7b25ueC5JVGVuc29yUHJvdG98bnVsbHx1bmRlZmluZWR9IHZhbHVlc1xuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8ucHJvdG90eXBlLnZhbHVlcyA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBTcGFyc2VUZW5zb3JQcm90byBpbmRpY2VzLlxuICAgICAqIEBtZW1iZXIge29ubnguSVRlbnNvclByb3RvfG51bGx8dW5kZWZpbmVkfSBpbmRpY2VzXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5wcm90b3R5cGUuaW5kaWNlcyA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBTcGFyc2VUZW5zb3JQcm90byBkaW1zLlxuICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXJ8TG9uZz59IGRpbXNcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFNwYXJzZVRlbnNvclByb3RvLnByb3RvdHlwZS5kaW1zID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgU3BhcnNlVGVuc29yUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVNwYXJzZVRlbnNvclByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguU3BhcnNlVGVuc29yUHJvdG99IFNwYXJzZVRlbnNvclByb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgU3BhcnNlVGVuc29yUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlNwYXJzZVRlbnNvclByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVNwYXJzZVRlbnNvclByb3RvfSBtZXNzYWdlIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLnZhbHVlcyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICd2YWx1ZXMnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JQcm90by5lbmNvZGUobWVzc2FnZS52YWx1ZXMsIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8gMTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5pbmRpY2VzICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2luZGljZXMnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JQcm90by5lbmNvZGUobWVzc2FnZS5pbmRpY2VzLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZGltcyAhPSBudWxsICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpIHtcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLyAyNikuZm9yaygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltcy5sZW5ndGg7ICsraSkgd3JpdGVyLmludDY0KG1lc3NhZ2UuZGltc1tpXSk7XG4gICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlNwYXJzZVRlbnNvclByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVNwYXJzZVRlbnNvclByb3RvfSBtZXNzYWdlIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguU3BhcnNlVGVuc29yUHJvdG99IFNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVzID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS5pbmRpY2VzID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMzoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5kaW1zICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpKSBtZXNzYWdlLmRpbXMgPSBbXTtcbiAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpIG1lc3NhZ2UuZGltcy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgIH0gZWxzZSBtZXNzYWdlLmRpbXMucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlNwYXJzZVRlbnNvclByb3RvfSBTcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgaWYgKG1lc3NhZ2UudmFsdWVzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWVzJykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS52YWx1ZXMpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAndmFsdWVzLicgKyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmluZGljZXMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdpbmRpY2VzJykpIHtcbiAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS5pbmRpY2VzKTtcbiAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2luZGljZXMuJyArIGVycm9yO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGltcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbXMnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5kaW1zKSkgcmV0dXJuICdkaW1zOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1zW2ldKSAmJlxuICAgICAgICAgICAgIShtZXNzYWdlLmRpbXNbaV0gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbXNbaV0uaGlnaCkpXG4gICAgICAgICAgKVxuICAgICAgICAgICAgcmV0dXJuICdkaW1zOiBpbnRlZ2VyfExvbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5TcGFyc2VUZW5zb3JQcm90b30gU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90bygpO1xuICAgICAgaWYgKG9iamVjdC52YWx1ZXMgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC52YWx1ZXMgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlNwYXJzZVRlbnNvclByb3RvLnZhbHVlczogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UudmFsdWVzID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC52YWx1ZXMpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5pbmRpY2VzICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5kaWNlcyAhPT0gJ29iamVjdCcpIHRocm93IFR5cGVFcnJvcignLm9ubnguU3BhcnNlVGVuc29yUHJvdG8uaW5kaWNlczogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW5kaWNlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QuaW5kaWNlcyk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRpbXMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5kaW1zKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5TcGFyc2VUZW5zb3JQcm90by5kaW1zOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmRpbXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZGltcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuZGltc1tpXSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5kaW1zW2ldKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbXNbaV0gPT09ICdzdHJpbmcnKSBtZXNzYWdlLmRpbXNbaV0gPSBwYXJzZUludChvYmplY3QuZGltc1tpXSwgMTApO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gJ251bWJlcicpIG1lc3NhZ2UuZGltc1tpXSA9IG9iamVjdC5kaW1zW2ldO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmRpbXNbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmRpbXNbaV0ubG93ID4+PiAwLCBvYmplY3QuZGltc1tpXS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguU3BhcnNlVGVuc29yUHJvdG99IG1lc3NhZ2UgU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIFNwYXJzZVRlbnNvclByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LmRpbXMgPSBbXTtcbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC52YWx1ZXMgPSBudWxsO1xuICAgICAgICBvYmplY3QuaW5kaWNlcyA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS52YWx1ZXMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd2YWx1ZXMnKSlcbiAgICAgICAgb2JqZWN0LnZhbHVlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS52YWx1ZXMsIG9wdGlvbnMpO1xuICAgICAgaWYgKG1lc3NhZ2UuaW5kaWNlcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2luZGljZXMnKSlcbiAgICAgICAgb2JqZWN0LmluZGljZXMgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuaW5kaWNlcywgb3B0aW9ucyk7XG4gICAgICBpZiAobWVzc2FnZS5kaW1zICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmRpbXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmRpbXMubGVuZ3RoOyArK2opXG4gICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmRpbXNbal0gPT09ICdudW1iZXInKVxuICAgICAgICAgICAgb2JqZWN0LmRpbXNbal0gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5kaW1zW2pdKSA6IG1lc3NhZ2UuZGltc1tqXTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBvYmplY3QuZGltc1tqXSA9XG4gICAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZ1xuICAgICAgICAgICAgICAgID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLmRpbXNbal0pXG4gICAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICAgID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuZGltc1tqXS5sb3cgPj4+IDAsIG1lc3NhZ2UuZGltc1tqXS5oaWdoID4+PiAwKS50b051bWJlcigpXG4gICAgICAgICAgICAgICAgICA6IG1lc3NhZ2UuZGltc1tqXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgU3BhcnNlVGVuc29yUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgU3BhcnNlVGVuc29yUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBTcGFyc2VUZW5zb3JQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBTcGFyc2VUZW5zb3JQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5TcGFyc2VUZW5zb3JQcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBTcGFyc2VUZW5zb3JQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlRlbnNvclNoYXBlUHJvdG8gPSAoZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgb2YgYSBUZW5zb3JTaGFwZVByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGludGVyZmFjZSBJVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguVGVuc29yU2hhcGVQcm90by5JRGltZW5zaW9uPnxudWxsfSBbZGltXSBUZW5zb3JTaGFwZVByb3RvIGRpbVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3JTaGFwZVByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVGVuc29yU2hhcGVQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yU2hhcGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFRlbnNvclNoYXBlUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgdGhpcy5kaW0gPSBbXTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUZW5zb3JTaGFwZVByb3RvIGRpbS5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb24+fSBkaW1cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by5wcm90b3R5cGUuZGltID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgVGVuc29yU2hhcGVQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JTaGFwZVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90b30gVGVuc29yU2hhcGVQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgIHJldHVybiBuZXcgVGVuc29yU2hhcGVQcm90byhwcm9wZXJ0aWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JTaGFwZVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yU2hhcGVQcm90b30gbWVzc2FnZSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZGltICE9IG51bGwgJiYgbWVzc2FnZS5kaW0ubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltLmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24uZW5jb2RlKFxuICAgICAgICAgICAgbWVzc2FnZS5kaW1baV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvclNoYXBlUHJvdG99IG1lc3NhZ2UgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG99IFRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZGltICYmIG1lc3NhZ2UuZGltLmxlbmd0aCkpIG1lc3NhZ2UuZGltID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmRpbS5wdXNoKCRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvfSBUZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVmVyaWZpZXMgYSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UuXG4gICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRpbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmRpbSkpIHJldHVybiAnZGltOiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kaW0ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLnZlcmlmeShtZXNzYWdlLmRpbVtpXSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2RpbS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvfSBUZW5zb3JTaGFwZVByb3RvXG4gICAgICovXG4gICAgVGVuc29yU2hhcGVQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8pIHJldHVybiBvYmplY3Q7XG4gICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QuZGltKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZGltKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JTaGFwZVByb3RvLmRpbTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5kaW0gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZGltLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZGltW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UZW5zb3JTaGFwZVByb3RvLmRpbTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5kaW1baV0gPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLmZyb21PYmplY3Qob2JqZWN0LmRpbVtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvfSBtZXNzYWdlIFRlbnNvclNoYXBlUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKSBvYmplY3QuZGltID0gW107XG4gICAgICBpZiAobWVzc2FnZS5kaW0gJiYgbWVzc2FnZS5kaW0ubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5kaW0gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmRpbS5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuZGltW2pdID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbi50b09iamVjdChtZXNzYWdlLmRpbVtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGlzIFRlbnNvclNoYXBlUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBUZW5zb3JTaGFwZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIFRlbnNvclNoYXBlUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguVGVuc29yU2hhcGVQcm90byc7XG4gICAgfTtcblxuICAgIFRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogUHJvcGVydGllcyBvZiBhIERpbWVuc2lvbi5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAqIEBpbnRlcmZhY2UgSURpbWVuc2lvblxuICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbZGltVmFsdWVdIERpbWVuc2lvbiBkaW1WYWx1ZVxuICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RpbVBhcmFtXSBEaW1lbnNpb24gZGltUGFyYW1cbiAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkZW5vdGF0aW9uXSBEaW1lbnNpb24gZGVub3RhdGlvblxuICAgICAgICovXG5cbiAgICAgIC8qKlxuICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBEaW1lbnNpb24uXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBEaW1lbnNpb24uXG4gICAgICAgKiBAaW1wbGVtZW50cyBJRGltZW5zaW9uXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb249fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gRGltZW5zaW9uKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBEaW1lbnNpb24gZGltVmFsdWUuXG4gICAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ3xudWxsfHVuZGVmaW5lZH0gZGltVmFsdWVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLnByb3RvdHlwZS5kaW1WYWx1ZSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogRGltZW5zaW9uIGRpbVBhcmFtLlxuICAgICAgICogQG1lbWJlciB7c3RyaW5nfG51bGx8dW5kZWZpbmVkfSBkaW1QYXJhbVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24ucHJvdG90eXBlLmRpbVBhcmFtID0gbnVsbDtcblxuICAgICAgLyoqXG4gICAgICAgKiBEaW1lbnNpb24gZGVub3RhdGlvbi5cbiAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gZGVub3RhdGlvblxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24ucHJvdG90eXBlLmRlbm90YXRpb24gPSAnJztcblxuICAgICAgLy8gT25lT2YgZmllbGQgbmFtZXMgYm91bmQgdG8gdmlydHVhbCBnZXR0ZXJzIGFuZCBzZXR0ZXJzXG4gICAgICB2YXIgJG9uZU9mRmllbGRzO1xuXG4gICAgICAvKipcbiAgICAgICAqIERpbWVuc2lvbiB2YWx1ZS5cbiAgICAgICAqIEBtZW1iZXIge1wiZGltVmFsdWVcInxcImRpbVBhcmFtXCJ8dW5kZWZpbmVkfSB2YWx1ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRGltZW5zaW9uLnByb3RvdHlwZSwgJ3ZhbHVlJywge1xuICAgICAgICBnZXQ6ICR1dGlsLm9uZU9mR2V0dGVyKCgkb25lT2ZGaWVsZHMgPSBbJ2RpbVZhbHVlJywgJ2RpbVBhcmFtJ10pKSxcbiAgICAgICAgc2V0OiAkdXRpbC5vbmVPZlNldHRlcigkb25lT2ZGaWVsZHMpLFxuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIG5ldyBEaW1lbnNpb24gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb249fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9ufSBEaW1lbnNpb24gaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKHByb3BlcnRpZXMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgRGltZW5zaW9uIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbn0gbWVzc2FnZSBEaW1lbnNpb24gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgIGlmIChtZXNzYWdlLmRpbVZhbHVlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RpbVZhbHVlJykpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAwID0qLyA4KS5pbnQ2NChtZXNzYWdlLmRpbVZhbHVlKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZGltUGFyYW0gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZGltUGFyYW0nKSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5zdHJpbmcobWVzc2FnZS5kaW1QYXJhbSk7XG4gICAgICAgIGlmIChtZXNzYWdlLmRlbm90YXRpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZGVub3RhdGlvbicpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8gMjYpLnN0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pO1xuICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgRGltZW5zaW9uIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbn0gbWVzc2FnZSBEaW1lbnNpb24gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBEaW1lbnNpb24gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbn0gRGltZW5zaW9uXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIERpbWVuc2lvbi5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbigpO1xuICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICBtZXNzYWdlLmRpbVZhbHVlID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZGltUGFyYW0gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZGVub3RhdGlvbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhIERpbWVuc2lvbiBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb259IERpbWVuc2lvblxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBEaW1lbnNpb24uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogVmVyaWZpZXMgYSBEaW1lbnNpb24gbWVzc2FnZS5cbiAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIERpbWVuc2lvbi52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZGltVmFsdWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkaW1WYWx1ZScpKSB7XG4gICAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbVZhbHVlKSAmJlxuICAgICAgICAgICAgIShtZXNzYWdlLmRpbVZhbHVlICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbVZhbHVlLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltVmFsdWUuaGlnaCkpXG4gICAgICAgICAgKVxuICAgICAgICAgICAgcmV0dXJuICdkaW1WYWx1ZTogaW50ZWdlcnxMb25nIGV4cGVjdGVkJztcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5kaW1QYXJhbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbVBhcmFtJykpIHtcbiAgICAgICAgICBpZiAocHJvcGVydGllcy52YWx1ZSA9PT0gMSkgcmV0dXJuICd2YWx1ZTogbXVsdGlwbGUgdmFsdWVzJztcbiAgICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZGltUGFyYW0pKSByZXR1cm4gJ2RpbVBhcmFtOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXNzYWdlLmRlbm90YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkZW5vdGF0aW9uJykpXG4gICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pKSByZXR1cm4gJ2Rlbm90YXRpb246IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgRGltZW5zaW9uIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb259IERpbWVuc2lvblxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uKSByZXR1cm4gb2JqZWN0O1xuICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uKCk7XG4gICAgICAgIGlmIChvYmplY3QuZGltVmFsdWUgIT0gbnVsbClcbiAgICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UuZGltVmFsdWUgPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuZGltVmFsdWUpKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltVmFsdWUgPT09ICdzdHJpbmcnKSBtZXNzYWdlLmRpbVZhbHVlID0gcGFyc2VJbnQob2JqZWN0LmRpbVZhbHVlLCAxMCk7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1WYWx1ZSA9PT0gJ251bWJlcicpIG1lc3NhZ2UuZGltVmFsdWUgPSBvYmplY3QuZGltVmFsdWU7XG4gICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1WYWx1ZSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBtZXNzYWdlLmRpbVZhbHVlID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5kaW1WYWx1ZS5sb3cgPj4+IDAsIG9iamVjdC5kaW1WYWx1ZS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICBpZiAob2JqZWN0LmRpbVBhcmFtICE9IG51bGwpIG1lc3NhZ2UuZGltUGFyYW0gPSBTdHJpbmcob2JqZWN0LmRpbVBhcmFtKTtcbiAgICAgICAgaWYgKG9iamVjdC5kZW5vdGF0aW9uICE9IG51bGwpIG1lc3NhZ2UuZGVub3RhdGlvbiA9IFN0cmluZyhvYmplY3QuZGVub3RhdGlvbik7XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBEaW1lbnNpb24gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9ufSBtZXNzYWdlIERpbWVuc2lvblxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSBvYmplY3QuZGVub3RhdGlvbiA9ICcnO1xuICAgICAgICBpZiAobWVzc2FnZS5kaW1WYWx1ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbVZhbHVlJykpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZGltVmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgb2JqZWN0LmRpbVZhbHVlID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZGltVmFsdWUpIDogbWVzc2FnZS5kaW1WYWx1ZTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBvYmplY3QuZGltVmFsdWUgPVxuICAgICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgICA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5kaW1WYWx1ZSlcbiAgICAgICAgICAgICAgICA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlclxuICAgICAgICAgICAgICAgICAgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5kaW1WYWx1ZS5sb3cgPj4+IDAsIG1lc3NhZ2UuZGltVmFsdWUuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgICAgOiBtZXNzYWdlLmRpbVZhbHVlO1xuICAgICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ2RpbVZhbHVlJztcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5kaW1QYXJhbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RpbVBhcmFtJykpIHtcbiAgICAgICAgICBvYmplY3QuZGltUGFyYW0gPSBtZXNzYWdlLmRpbVBhcmFtO1xuICAgICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ2RpbVBhcmFtJztcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZGVub3RhdGlvbicpKSBvYmplY3QuZGVub3RhdGlvbiA9IG1lc3NhZ2UuZGVub3RhdGlvbjtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ29udmVydHMgdGhpcyBEaW1lbnNpb24gdG8gSlNPTi5cbiAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgRGltZW5zaW9uLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBEaW1lbnNpb25cbiAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICovXG4gICAgICBEaW1lbnNpb24uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbic7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gRGltZW5zaW9uO1xuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gVGVuc29yU2hhcGVQcm90bztcbiAgfSkoKTtcblxuICBvbm54LlR5cGVQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIFR5cGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBpbnRlcmZhY2UgSVR5cGVQcm90b1xuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UeXBlUHJvdG8uSVRlbnNvcnxudWxsfSBbdGVuc29yVHlwZV0gVHlwZVByb3RvIHRlbnNvclR5cGVcbiAgICAgKiBAcHJvcGVydHkge29ubnguVHlwZVByb3RvLklTZXF1ZW5jZXxudWxsfSBbc2VxdWVuY2VUeXBlXSBUeXBlUHJvdG8gc2VxdWVuY2VUeXBlXG4gICAgICogQHByb3BlcnR5IHtvbm54LlR5cGVQcm90by5JTWFwfG51bGx9IFttYXBUeXBlXSBUeXBlUHJvdG8gbWFwVHlwZVxuICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsfG51bGx9IFtvcHRpb25hbFR5cGVdIFR5cGVQcm90byBvcHRpb25hbFR5cGVcbiAgICAgKiBAcHJvcGVydHkge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3J8bnVsbH0gW3NwYXJzZVRlbnNvclR5cGVdIFR5cGVQcm90byBzcGFyc2VUZW5zb3JUeXBlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2Rlbm90YXRpb25dIFR5cGVQcm90byBkZW5vdGF0aW9uXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFR5cGVQcm90by5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFR5cGVQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJVHlwZVByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklUeXBlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBUeXBlUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byB0ZW5zb3JUeXBlLlxuICAgICAqIEBtZW1iZXIge29ubnguVHlwZVByb3RvLklUZW5zb3J8bnVsbHx1bmRlZmluZWR9IHRlbnNvclR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLnRlbnNvclR5cGUgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVHlwZVByb3RvIHNlcXVlbmNlVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JU2VxdWVuY2V8bnVsbHx1bmRlZmluZWR9IHNlcXVlbmNlVHlwZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFR5cGVQcm90by5wcm90b3R5cGUuc2VxdWVuY2VUeXBlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byBtYXBUeXBlLlxuICAgICAqIEBtZW1iZXIge29ubnguVHlwZVByb3RvLklNYXB8bnVsbHx1bmRlZmluZWR9IG1hcFR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLm1hcFR5cGUgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVHlwZVByb3RvIG9wdGlvbmFsVHlwZS5cbiAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JT3B0aW9uYWx8bnVsbHx1bmRlZmluZWR9IG9wdGlvbmFsVHlwZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIFR5cGVQcm90by5wcm90b3R5cGUub3B0aW9uYWxUeXBlID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFR5cGVQcm90byBzcGFyc2VUZW5zb3JUeXBlLlxuICAgICAqIEBtZW1iZXIge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3J8bnVsbHx1bmRlZmluZWR9IHNwYXJzZVRlbnNvclR5cGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLnNwYXJzZVRlbnNvclR5cGUgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVHlwZVByb3RvIGRlbm90YXRpb24uXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkZW5vdGF0aW9uXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgVHlwZVByb3RvLnByb3RvdHlwZS5kZW5vdGF0aW9uID0gJyc7XG5cbiAgICAvLyBPbmVPZiBmaWVsZCBuYW1lcyBib3VuZCB0byB2aXJ0dWFsIGdldHRlcnMgYW5kIHNldHRlcnNcbiAgICB2YXIgJG9uZU9mRmllbGRzO1xuXG4gICAgLyoqXG4gICAgICogVHlwZVByb3RvIHZhbHVlLlxuICAgICAqIEBtZW1iZXIge1widGVuc29yVHlwZVwifFwic2VxdWVuY2VUeXBlXCJ8XCJtYXBUeXBlXCJ8XCJvcHRpb25hbFR5cGVcInxcInNwYXJzZVRlbnNvclR5cGVcInx1bmRlZmluZWR9IHZhbHVlXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFR5cGVQcm90by5wcm90b3R5cGUsICd2YWx1ZScsIHtcbiAgICAgIGdldDogJHV0aWwub25lT2ZHZXR0ZXIoXG4gICAgICAgICgkb25lT2ZGaWVsZHMgPSBbJ3RlbnNvclR5cGUnLCAnc2VxdWVuY2VUeXBlJywgJ21hcFR5cGUnLCAnb3B0aW9uYWxUeXBlJywgJ3NwYXJzZVRlbnNvclR5cGUnXSksXG4gICAgICApLFxuICAgICAgc2V0OiAkdXRpbC5vbmVPZlNldHRlcigkb25lT2ZGaWVsZHMpLFxuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBUeXBlUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklUeXBlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIFR5cGVQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBUeXBlUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUeXBlUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSVR5cGVQcm90b30gbWVzc2FnZSBUeXBlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIFR5cGVQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvclR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAndGVuc29yVHlwZScpKVxuICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IuZW5jb2RlKFxuICAgICAgICAgIG1lc3NhZ2UudGVuc29yVHlwZSxcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovIDEwKS5mb3JrKCksXG4gICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5zZXF1ZW5jZVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnc2VxdWVuY2VUeXBlJykpXG4gICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmVuY29kZShcbiAgICAgICAgICBtZXNzYWdlLnNlcXVlbmNlVHlwZSxcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDQsIHdpcmVUeXBlIDIgPSovIDM0KS5mb3JrKCksXG4gICAgICAgICkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5tYXBUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ21hcFR5cGUnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwLmVuY29kZShtZXNzYWdlLm1hcFR5cGUsIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2Rlbm90YXRpb24nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA2LCB3aXJlVHlwZSAyID0qLyA1MCkuc3RyaW5nKG1lc3NhZ2UuZGVub3RhdGlvbik7XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3JUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3NwYXJzZVRlbnNvclR5cGUnKSlcbiAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yLmVuY29kZShcbiAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLyA2NikuZm9yaygpLFxuICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2Uub3B0aW9uYWxUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ29wdGlvbmFsVHlwZScpKVxuICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbC5lbmNvZGUoXG4gICAgICAgICAgbWVzc2FnZS5vcHRpb25hbFR5cGUsXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA5LCB3aXJlVHlwZSAyID0qLyA3NCkuZm9yaygpLFxuICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFR5cGVQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JVHlwZVByb3RvfSBtZXNzYWdlIFR5cGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgVHlwZVByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgVHlwZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90b30gVHlwZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS50ZW5zb3JUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA0OiB7XG4gICAgICAgICAgICBtZXNzYWdlLnNlcXVlbmNlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA1OiB7XG4gICAgICAgICAgICBtZXNzYWdlLm1hcFR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5NYXAuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDk6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3B0aW9uYWxUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNjoge1xuICAgICAgICAgICAgbWVzc2FnZS5kZW5vdGF0aW9uID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBUeXBlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90b30gVHlwZVByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhIFR5cGVQcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcbiAgICAgIGlmIChtZXNzYWdlLnRlbnNvclR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd0ZW5zb3JUeXBlJykpIHtcbiAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IudmVyaWZ5KG1lc3NhZ2UudGVuc29yVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3RlbnNvclR5cGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5zZXF1ZW5jZVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzZXF1ZW5jZVR5cGUnKSkge1xuICAgICAgICBpZiAocHJvcGVydGllcy52YWx1ZSA9PT0gMSkgcmV0dXJuICd2YWx1ZTogbXVsdGlwbGUgdmFsdWVzJztcbiAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TZXF1ZW5jZS52ZXJpZnkobWVzc2FnZS5zZXF1ZW5jZVR5cGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzZXF1ZW5jZVR5cGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5tYXBUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbWFwVHlwZScpKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnZhbHVlID09PSAxKSByZXR1cm4gJ3ZhbHVlOiBtdWx0aXBsZSB2YWx1ZXMnO1xuICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLk1hcC52ZXJpZnkobWVzc2FnZS5tYXBUeXBlKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnbWFwVHlwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm9wdGlvbmFsVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ29wdGlvbmFsVHlwZScpKSB7XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLnZhbHVlID09PSAxKSByZXR1cm4gJ3ZhbHVlOiBtdWx0aXBsZSB2YWx1ZXMnO1xuICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsLnZlcmlmeShtZXNzYWdlLm9wdGlvbmFsVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ29wdGlvbmFsVHlwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzcGFyc2VUZW5zb3JUeXBlJykpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMudmFsdWUgPT09IDEpIHJldHVybiAndmFsdWU6IG11bHRpcGxlIHZhbHVlcyc7XG4gICAgICAgIHByb3BlcnRpZXMudmFsdWUgPSAxO1xuICAgICAgICB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yLnZlcmlmeShtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUpO1xuICAgICAgICAgIGlmIChlcnJvcikgcmV0dXJuICdzcGFyc2VUZW5zb3JUeXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2Rlbm90YXRpb24nKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pKSByZXR1cm4gJ2Rlbm90YXRpb246IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFR5cGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90b30gVHlwZVByb3RvXG4gICAgICovXG4gICAgVHlwZVByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvKSByZXR1cm4gb2JqZWN0O1xuICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8oKTtcbiAgICAgIGlmIChvYmplY3QudGVuc29yVHlwZSAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnRlbnNvclR5cGUgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlR5cGVQcm90by50ZW5zb3JUeXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS50ZW5zb3JUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yLmZyb21PYmplY3Qob2JqZWN0LnRlbnNvclR5cGUpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5zZXF1ZW5jZVR5cGUgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zZXF1ZW5jZVR5cGUgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlR5cGVQcm90by5zZXF1ZW5jZVR5cGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLnNlcXVlbmNlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmZyb21PYmplY3Qob2JqZWN0LnNlcXVlbmNlVHlwZSk7XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0Lm1hcFR5cGUgIT0gbnVsbCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5tYXBUeXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8ubWFwVHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UubWFwVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLk1hcC5mcm9tT2JqZWN0KG9iamVjdC5tYXBUeXBlKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Qub3B0aW9uYWxUeXBlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Qub3B0aW9uYWxUeXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8ub3B0aW9uYWxUeXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vcHRpb25hbFR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbC5mcm9tT2JqZWN0KG9iamVjdC5vcHRpb25hbFR5cGUpO1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5zcGFyc2VUZW5zb3JUeXBlICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlVGVuc29yVHlwZSAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uc3BhcnNlVGVuc29yVHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci5mcm9tT2JqZWN0KG9iamVjdC5zcGFyc2VUZW5zb3JUeXBlKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuZGVub3RhdGlvbiAhPSBudWxsKSBtZXNzYWdlLmRlbm90YXRpb24gPSBTdHJpbmcob2JqZWN0LmRlbm90YXRpb24pO1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFR5cGVQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG99IG1lc3NhZ2UgVHlwZVByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSBvYmplY3QuZGVub3RhdGlvbiA9ICcnO1xuICAgICAgaWYgKG1lc3NhZ2UudGVuc29yVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3RlbnNvclR5cGUnKSkge1xuICAgICAgICBvYmplY3QudGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvci50b09iamVjdChtZXNzYWdlLnRlbnNvclR5cGUsIG9wdGlvbnMpO1xuICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpIG9iamVjdC52YWx1ZSA9ICd0ZW5zb3JUeXBlJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLnNlcXVlbmNlVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NlcXVlbmNlVHlwZScpKSB7XG4gICAgICAgIG9iamVjdC5zZXF1ZW5jZVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TZXF1ZW5jZS50b09iamVjdChtZXNzYWdlLnNlcXVlbmNlVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ3NlcXVlbmNlVHlwZSc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5tYXBUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbWFwVHlwZScpKSB7XG4gICAgICAgIG9iamVjdC5tYXBUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwLnRvT2JqZWN0KG1lc3NhZ2UubWFwVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ21hcFR5cGUnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2Rlbm90YXRpb24nKSkgb2JqZWN0LmRlbm90YXRpb24gPSBtZXNzYWdlLmRlbm90YXRpb247XG4gICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3JUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc3BhcnNlVGVuc29yVHlwZScpKSB7XG4gICAgICAgIG9iamVjdC5zcGFyc2VUZW5zb3JUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yLnRvT2JqZWN0KG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChvcHRpb25zLm9uZW9mcykgb2JqZWN0LnZhbHVlID0gJ3NwYXJzZVRlbnNvclR5cGUnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uub3B0aW9uYWxUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnb3B0aW9uYWxUeXBlJykpIHtcbiAgICAgICAgb2JqZWN0Lm9wdGlvbmFsVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsLnRvT2JqZWN0KG1lc3NhZ2Uub3B0aW9uYWxUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKG9wdGlvbnMub25lb2ZzKSBvYmplY3QudmFsdWUgPSAnb3B0aW9uYWxUeXBlJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoaXMgVHlwZVByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgKi9cbiAgICBUeXBlUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBUeXBlUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAqL1xuICAgIFR5cGVQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UeXBlUHJvdG8nO1xuICAgIH07XG5cbiAgICBUeXBlUHJvdG8uVGVuc29yID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogUHJvcGVydGllcyBvZiBhIFRlbnNvci5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGludGVyZmFjZSBJVGVuc29yXG4gICAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBbZWxlbVR5cGVdIFRlbnNvciBlbGVtVHlwZVxuICAgICAgICogQHByb3BlcnR5IHtvbm54LklUZW5zb3JTaGFwZVByb3RvfG51bGx9IFtzaGFwZV0gVGVuc29yIHNoYXBlXG4gICAgICAgKi9cblxuICAgICAgLyoqXG4gICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFRlbnNvci5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVGVuc29yLlxuICAgICAgICogQGltcGxlbWVudHMgSVRlbnNvclxuICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3I9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gVGVuc29yKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBUZW5zb3IgZWxlbVR5cGUuXG4gICAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGVsZW1UeXBlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgVGVuc29yLnByb3RvdHlwZS5lbGVtVHlwZSA9IDA7XG5cbiAgICAgIC8qKlxuICAgICAgICogVGVuc29yIHNoYXBlLlxuICAgICAgICogQG1lbWJlciB7b25ueC5JVGVuc29yU2hhcGVQcm90b3xudWxsfHVuZGVmaW5lZH0gc2hhcGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBUZW5zb3IucHJvdG90eXBlLnNoYXBlID0gbnVsbDtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgbmV3IFRlbnNvciBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3I9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IFRlbnNvciBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBUZW5zb3IuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZW5zb3IocHJvcGVydGllcyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3IgbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uVGVuc29yLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JVGVuc29yfSBtZXNzYWdlIFRlbnNvciBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBUZW5zb3IuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZWxlbVR5cGUnKSlcbiAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDAgPSovIDgpLmludDMyKG1lc3NhZ2UuZWxlbVR5cGUpO1xuICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdzaGFwZScpKVxuICAgICAgICAgICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5lbmNvZGUobWVzc2FnZS5zaGFwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvciBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5UZW5zb3IudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3J9IG1lc3NhZ2UgVGVuc29yIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgVGVuc29yIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uVGVuc29yfSBUZW5zb3JcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgVGVuc29yLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IoKTtcbiAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgICBtZXNzYWdlLnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBUZW5zb3IgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlRlbnNvcn0gVGVuc29yXG4gICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBWZXJpZmllcyBhIFRlbnNvciBtZXNzYWdlLlxuICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICovXG4gICAgICBUZW5zb3IudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZWxlbVR5cGUnKSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVsZW1UeXBlKSkgcmV0dXJuICdlbGVtVHlwZTogaW50ZWdlciBleHBlY3RlZCc7XG4gICAgICAgIGlmIChtZXNzYWdlLnNoYXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc2hhcGUnKSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by52ZXJpZnkobWVzc2FnZS5zaGFwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3NoYXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIFRlbnNvciBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlRlbnNvcn0gVGVuc29yXG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvcikgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yKCk7XG4gICAgICAgIGlmIChvYmplY3QuZWxlbVR5cGUgIT0gbnVsbCkgbWVzc2FnZS5lbGVtVHlwZSA9IG9iamVjdC5lbGVtVHlwZSB8IDA7XG4gICAgICAgIGlmIChvYmplY3Quc2hhcGUgIT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNoYXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uVGVuc29yLnNoYXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnNoYXBlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVGVuc29yIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IG1lc3NhZ2UgVGVuc29yXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFRlbnNvci50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICBvYmplY3QuZWxlbVR5cGUgPSAwO1xuICAgICAgICAgIG9iamVjdC5zaGFwZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKSBvYmplY3QuZWxlbVR5cGUgPSBtZXNzYWdlLmVsZW1UeXBlO1xuICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3NoYXBlJykpXG4gICAgICAgICAgb2JqZWN0LnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc2hhcGUsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDb252ZXJ0cyB0aGlzIFRlbnNvciB0byBKU09OLlxuICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFRlbnNvci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgVGVuc29yXG4gICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICovXG4gICAgICBUZW5zb3IuZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UeXBlUHJvdG8uVGVuc29yJztcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBUZW5zb3I7XG4gICAgfSkoKTtcblxuICAgIFR5cGVQcm90by5TZXF1ZW5jZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAvKipcbiAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBTZXF1ZW5jZS5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGludGVyZmFjZSBJU2VxdWVuY2VcbiAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVHlwZVByb3RvfG51bGx9IFtlbGVtVHlwZV0gU2VxdWVuY2UgZWxlbVR5cGVcbiAgICAgICAqL1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgU2VxdWVuY2UuXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFNlcXVlbmNlLlxuICAgICAgICogQGltcGxlbWVudHMgSVNlcXVlbmNlXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNlcXVlbmNlPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uIFNlcXVlbmNlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBTZXF1ZW5jZSBlbGVtVHlwZS5cbiAgICAgICAqIEBtZW1iZXIge29ubnguSVR5cGVQcm90b3xudWxsfHVuZGVmaW5lZH0gZWxlbVR5cGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLnByb3RvdHlwZS5lbGVtVHlwZSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIG5ldyBTZXF1ZW5jZSBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNlcXVlbmNlPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU2VxdWVuY2V9IFNlcXVlbmNlIGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2VxdWVuY2UocHJvcGVydGllcyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTZXF1ZW5jZSBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5TZXF1ZW5jZS52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JU2VxdWVuY2V9IG1lc3NhZ2UgU2VxdWVuY2UgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZWxlbVR5cGUnKSlcbiAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS5lbGVtVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFNlcXVlbmNlIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTZXF1ZW5jZX0gbWVzc2FnZSBTZXF1ZW5jZSBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgU2VxdWVuY2UgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNlcXVlbmNlfSBTZXF1ZW5jZVxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLFxuICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UoKTtcbiAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBTZXF1ZW5jZSBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TZXF1ZW5jZX0gU2VxdWVuY2VcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogVmVyaWZpZXMgYSBTZXF1ZW5jZSBtZXNzYWdlLlxuICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VsZW1UeXBlJykpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS5lbGVtVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2VsZW1UeXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIFNlcXVlbmNlIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TZXF1ZW5jZX0gU2VxdWVuY2VcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlR5cGVQcm90by5TZXF1ZW5jZSkgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UoKTtcbiAgICAgICAgaWYgKG9iamVjdC5lbGVtVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZWxlbVR5cGUgIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UuZWxlbVR5cGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5lbGVtVHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFNlcXVlbmNlIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLlNlcXVlbmNlfSBtZXNzYWdlIFNlcXVlbmNlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIFNlcXVlbmNlLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykgb2JqZWN0LmVsZW1UeXBlID0gbnVsbDtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKVxuICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZWxlbVR5cGUsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDb252ZXJ0cyB0aGlzIFNlcXVlbmNlIHRvIEpTT04uXG4gICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICovXG4gICAgICBTZXF1ZW5jZS5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgU2VxdWVuY2VcbiAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAqL1xuICAgICAgU2VxdWVuY2UuZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArICcvb25ueC5UeXBlUHJvdG8uU2VxdWVuY2UnO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIFNlcXVlbmNlO1xuICAgIH0pKCk7XG5cbiAgICBUeXBlUHJvdG8uTWFwID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogUHJvcGVydGllcyBvZiBhIE1hcC5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGludGVyZmFjZSBJTWFwXG4gICAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBba2V5VHlwZV0gTWFwIGtleVR5cGVcbiAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVHlwZVByb3RvfG51bGx9IFt2YWx1ZVR5cGVdIE1hcCB2YWx1ZVR5cGVcbiAgICAgICAqL1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgTWFwLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBNYXAuXG4gICAgICAgKiBAaW1wbGVtZW50cyBJTWFwXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU1hcD19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiBNYXAocHJvcGVydGllcykge1xuICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgfVxuXG4gICAgICAvKipcbiAgICAgICAqIE1hcCBrZXlUeXBlLlxuICAgICAgICogQG1lbWJlciB7bnVtYmVyfSBrZXlUeXBlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgTWFwLnByb3RvdHlwZS5rZXlUeXBlID0gMDtcblxuICAgICAgLyoqXG4gICAgICAgKiBNYXAgdmFsdWVUeXBlLlxuICAgICAgICogQG1lbWJlciB7b25ueC5JVHlwZVByb3RvfG51bGx8dW5kZWZpbmVkfSB2YWx1ZVR5cGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBNYXAucHJvdG90eXBlLnZhbHVlVHlwZSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIG5ldyBNYXAgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JTWFwPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXAgaW5zdGFuY2VcbiAgICAgICAqL1xuICAgICAgTWFwLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWFwKHByb3BlcnRpZXMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgTWFwIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLk1hcC52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU1hcH0gbWVzc2FnZSBNYXAgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgTWFwLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgIGlmIChtZXNzYWdlLmtleVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAna2V5VHlwZScpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki8gOCkuaW50MzIobWVzc2FnZS5rZXlUeXBlKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWVUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3ZhbHVlVHlwZScpKVxuICAgICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShtZXNzYWdlLnZhbHVlVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLyAxOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1hcCBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5NYXAudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklNYXB9IG1lc3NhZ2UgTWFwIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIE1hcC5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGEgTWFwIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXBcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgTWFwLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5NYXAoKTtcbiAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgbWVzc2FnZS5rZXlUeXBlID0gcmVhZGVyLmludDMyKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhIE1hcCBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXBcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgTWFwLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIFZlcmlmaWVzIGEgTWFwIG1lc3NhZ2UuXG4gICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIE1hcC52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2Uua2V5VHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2tleVR5cGUnKSlcbiAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmtleVR5cGUpKSByZXR1cm4gJ2tleVR5cGU6IGludGVnZXIgZXhwZWN0ZWQnO1xuICAgICAgICBpZiAobWVzc2FnZS52YWx1ZVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCd2YWx1ZVR5cGUnKSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnZhbHVlVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ3ZhbHVlVHlwZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBNYXAgbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5NYXB9IE1hcFxuICAgICAgICovXG4gICAgICBNYXAuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlR5cGVQcm90by5NYXApIHJldHVybiBvYmplY3Q7XG4gICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLk1hcCgpO1xuICAgICAgICBpZiAob2JqZWN0LmtleVR5cGUgIT0gbnVsbCkgbWVzc2FnZS5rZXlUeXBlID0gb2JqZWN0LmtleVR5cGUgfCAwO1xuICAgICAgICBpZiAob2JqZWN0LnZhbHVlVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudmFsdWVUeXBlICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5UeXBlUHJvdG8uTWFwLnZhbHVlVHlwZTogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS52YWx1ZVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC52YWx1ZVR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBNYXAgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLk1hcH0gbWVzc2FnZSBNYXBcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgTWFwLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgIG9iamVjdC5rZXlUeXBlID0gMDtcbiAgICAgICAgICBvYmplY3QudmFsdWVUeXBlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5rZXlUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgna2V5VHlwZScpKSBvYmplY3Qua2V5VHlwZSA9IG1lc3NhZ2Uua2V5VHlwZTtcbiAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWVUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmFsdWVUeXBlJykpXG4gICAgICAgICAgb2JqZWN0LnZhbHVlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudmFsdWVUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ29udmVydHMgdGhpcyBNYXAgdG8gSlNPTi5cbiAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICovXG4gICAgICBNYXAucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIE1hcFxuICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAqL1xuICAgICAgTWFwLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSAndHlwZS5nb29nbGVhcGlzLmNvbSc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyAnL29ubnguVHlwZVByb3RvLk1hcCc7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gTWFwO1xuICAgIH0pKCk7XG5cbiAgICBUeXBlUHJvdG8uT3B0aW9uYWwgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBQcm9wZXJ0aWVzIG9mIGFuIE9wdGlvbmFsLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgKiBAaW50ZXJmYWNlIElPcHRpb25hbFxuICAgICAgICogQHByb3BlcnR5IHtvbm54LklUeXBlUHJvdG98bnVsbH0gW2VsZW1UeXBlXSBPcHRpb25hbCBlbGVtVHlwZVxuICAgICAgICovXG5cbiAgICAgIC8qKlxuICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBPcHRpb25hbC5cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGFuIE9wdGlvbmFsLlxuICAgICAgICogQGltcGxlbWVudHMgSU9wdGlvbmFsXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uIE9wdGlvbmFsKHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKSB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBPcHRpb25hbCBlbGVtVHlwZS5cbiAgICAgICAqIEBtZW1iZXIge29ubnguSVR5cGVQcm90b3xudWxsfHVuZGVmaW5lZH0gZWxlbVR5cGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLnByb3RvdHlwZS5lbGVtVHlwZSA9IG51bGw7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIG5ldyBPcHRpb25hbCBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uT3B0aW9uYWx9IE9wdGlvbmFsIGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgT3B0aW9uYWwocHJvcGVydGllcyk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBPcHRpb25hbCBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5PcHRpb25hbC52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JT3B0aW9uYWx9IG1lc3NhZ2UgT3B0aW9uYWwgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgT3B0aW9uYWwuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAnZWxlbVR5cGUnKSlcbiAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS5lbGVtVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE9wdGlvbmFsIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklPcHRpb25hbH0gbWVzc2FnZSBPcHRpb25hbCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICovXG4gICAgICBPcHRpb25hbC5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGFuIE9wdGlvbmFsIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5PcHRpb25hbH0gT3B0aW9uYWxcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgT3B0aW9uYWwuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsKCk7XG4gICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBEZWNvZGVzIGFuIE9wdGlvbmFsIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLk9wdGlvbmFsfSBPcHRpb25hbFxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBPcHRpb25hbC5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBWZXJpZmllcyBhbiBPcHRpb25hbCBtZXNzYWdlLlxuICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcgfHwgbWVzc2FnZSA9PT0gbnVsbCkgcmV0dXJuICdvYmplY3QgZXhwZWN0ZWQnO1xuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VsZW1UeXBlJykpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS5lbGVtVHlwZSk7XG4gICAgICAgICAgaWYgKGVycm9yKSByZXR1cm4gJ2VsZW1UeXBlLicgKyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhbiBPcHRpb25hbCBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uT3B0aW9uYWx9IE9wdGlvbmFsXG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwpIHJldHVybiBvYmplY3Q7XG4gICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsKCk7XG4gICAgICAgIGlmIChvYmplY3QuZWxlbVR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmVsZW1UeXBlICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguVHlwZVByb3RvLk9wdGlvbmFsLmVsZW1UeXBlOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmVsZW1UeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZWxlbVR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYW4gT3B0aW9uYWwgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uT3B0aW9uYWx9IG1lc3NhZ2UgT3B0aW9uYWxcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgT3B0aW9uYWwudG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSBvYmplY3QuZWxlbVR5cGUgPSBudWxsO1xuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VsZW1UeXBlJykpXG4gICAgICAgICAgb2JqZWN0LmVsZW1UeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udG9PYmplY3QobWVzc2FnZS5lbGVtVHlwZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnZlcnRzIHRoaXMgT3B0aW9uYWwgdG8gSlNPTi5cbiAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgKi9cbiAgICAgIE9wdGlvbmFsLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBPcHRpb25hbFxuICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICovXG4gICAgICBPcHRpb25hbC5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlR5cGVQcm90by5PcHRpb25hbCc7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gT3B0aW9uYWw7XG4gICAgfSkoKTtcblxuICAgIFR5cGVQcm90by5TcGFyc2VUZW5zb3IgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU3BhcnNlVGVuc29yLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgKiBAaW50ZXJmYWNlIElTcGFyc2VUZW5zb3JcbiAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfG51bGx9IFtlbGVtVHlwZV0gU3BhcnNlVGVuc29yIGVsZW1UeXBlXG4gICAgICAgKiBAcHJvcGVydHkge29ubnguSVRlbnNvclNoYXBlUHJvdG98bnVsbH0gW3NoYXBlXSBTcGFyc2VUZW5zb3Igc2hhcGVcbiAgICAgICAqL1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgU3BhcnNlVGVuc29yLlxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBTcGFyc2VUZW5zb3IuXG4gICAgICAgKiBAaW1wbGVtZW50cyBJU3BhcnNlVGVuc29yXG4gICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNwYXJzZVRlbnNvcj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiBTcGFyc2VUZW5zb3IocHJvcGVydGllcykge1xuICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgfVxuXG4gICAgICAvKipcbiAgICAgICAqIFNwYXJzZVRlbnNvciBlbGVtVHlwZS5cbiAgICAgICAqIEBtZW1iZXIge251bWJlcn0gZWxlbVR5cGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICovXG4gICAgICBTcGFyc2VUZW5zb3IucHJvdG90eXBlLmVsZW1UeXBlID0gMDtcblxuICAgICAgLyoqXG4gICAgICAgKiBTcGFyc2VUZW5zb3Igc2hhcGUuXG4gICAgICAgKiBAbWVtYmVyIHtvbm54LklUZW5zb3JTaGFwZVByb3RvfG51bGx8dW5kZWZpbmVkfSBzaGFwZVxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5wcm90b3R5cGUuc2hhcGUgPSBudWxsO1xuXG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBuZXcgU3BhcnNlVGVuc29yIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNwYXJzZVRlbnNvcj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcn0gU3BhcnNlVGVuc29yIGluc3RhbmNlXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICByZXR1cm4gbmV3IFNwYXJzZVRlbnNvcihwcm9wZXJ0aWVzKTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFNwYXJzZVRlbnNvciBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3J9IG1lc3NhZ2UgU3BhcnNlVGVuc29yIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgIGlmICghd3JpdGVyKSB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdlbGVtVHlwZScpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki8gOCkuaW50MzIobWVzc2FnZS5lbGVtVHlwZSk7XG4gICAgICAgIGlmIChtZXNzYWdlLnNoYXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ3NoYXBlJykpXG4gICAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmVuY29kZShtZXNzYWdlLnNoYXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovIDE4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU3BhcnNlVGVuc29yIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNwYXJzZVRlbnNvcn0gbWVzc2FnZSBTcGFyc2VUZW5zb3IgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIERlY29kZXMgYSBTcGFyc2VUZW5zb3IgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAqIEBzdGF0aWNcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3J9IFNwYXJzZVRlbnNvclxuICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICovXG4gICAgICBTcGFyc2VUZW5zb3IuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgICBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcigpO1xuICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICBtZXNzYWdlLmVsZW1UeXBlID0gcmVhZGVyLmludDMyKCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgIG1lc3NhZ2Uuc2hhcGUgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH07XG5cbiAgICAgIC8qKlxuICAgICAgICogRGVjb2RlcyBhIFNwYXJzZVRlbnNvciBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICogQHN0YXRpY1xuICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yfSBTcGFyc2VUZW5zb3JcbiAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIFZlcmlmaWVzIGEgU3BhcnNlVGVuc29yIG1lc3NhZ2UuXG4gICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdlbGVtVHlwZScpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZWxlbVR5cGUpKSByZXR1cm4gJ2VsZW1UeXBlOiBpbnRlZ2VyIGV4cGVjdGVkJztcbiAgICAgICAgaWYgKG1lc3NhZ2Uuc2hhcGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdzaGFwZScpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLnZlcmlmeShtZXNzYWdlLnNoYXBlKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnc2hhcGUuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgU3BhcnNlVGVuc29yIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yfSBTcGFyc2VUZW5zb3JcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yKSByZXR1cm4gb2JqZWN0O1xuICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IoKTtcbiAgICAgICAgaWYgKG9iamVjdC5lbGVtVHlwZSAhPSBudWxsKSBtZXNzYWdlLmVsZW1UeXBlID0gb2JqZWN0LmVsZW1UeXBlIHwgMDtcbiAgICAgICAgaWYgKG9iamVjdC5zaGFwZSAhPSBudWxsKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc2hhcGUgIT09ICdvYmplY3QnKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3Iuc2hhcGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2Uuc2hhcGUgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3Quc2hhcGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBTcGFyc2VUZW5zb3IgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcn0gbWVzc2FnZSBTcGFyc2VUZW5zb3JcbiAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9IDA7XG4gICAgICAgICAgb2JqZWN0LnNoYXBlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2VsZW1UeXBlJykpIG9iamVjdC5lbGVtVHlwZSA9IG1lc3NhZ2UuZWxlbVR5cGU7XG4gICAgICAgIGlmIChtZXNzYWdlLnNoYXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnc2hhcGUnKSlcbiAgICAgICAgICBvYmplY3Quc2hhcGUgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8udG9PYmplY3QobWVzc2FnZS5zaGFwZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbnZlcnRzIHRoaXMgU3BhcnNlVGVuc29yIHRvIEpTT04uXG4gICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAqL1xuICAgICAgU3BhcnNlVGVuc29yLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBTcGFyc2VUZW5zb3JcbiAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgKiBAc3RhdGljXG4gICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgKi9cbiAgICAgIFNwYXJzZVRlbnNvci5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gJ3R5cGUuZ29vZ2xlYXBpcy5jb20nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3InO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIFNwYXJzZVRlbnNvcjtcbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuIFR5cGVQcm90bztcbiAgfSkoKTtcblxuICBvbm54Lk9wZXJhdG9yU2V0SWRQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhbiBPcGVyYXRvclNldElkUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElPcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9tYWluXSBPcGVyYXRvclNldElkUHJvdG8gZG9tYWluXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbdmVyc2lvbl0gT3BlcmF0b3JTZXRJZFByb3RvIHZlcnNpb25cbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgT3BlcmF0b3JTZXRJZFByb3RvLlxuICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGFuIE9wZXJhdG9yU2V0SWRQcm90by5cbiAgICAgKiBAaW1wbGVtZW50cyBJT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklPcGVyYXRvclNldElkUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBPcGVyYXRvclNldElkUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wZXJhdG9yU2V0SWRQcm90byBkb21haW4uXG4gICAgICogQG1lbWJlciB7c3RyaW5nfSBkb21haW5cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8ucHJvdG90eXBlLmRvbWFpbiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogT3BlcmF0b3JTZXRJZFByb3RvIHZlcnNpb24uXG4gICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IHZlcnNpb25cbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8ucHJvdG90eXBlLnZlcnNpb24gPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLCAwLCBmYWxzZSkgOiAwO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBPcGVyYXRvclNldElkUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklPcGVyYXRvclNldElkUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90byBpbnN0YW5jZVxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBPcGVyYXRvclNldElkUHJvdG8ocHJvcGVydGllcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5PcGVyYXRvclNldElkUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSU9wZXJhdG9yU2V0SWRQcm90b30gbWVzc2FnZSBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICBpZiAoIXdyaXRlcikgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb21haW4nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UuZG9tYWluKTtcbiAgICAgIGlmIChtZXNzYWdlLnZlcnNpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCAndmVyc2lvbicpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDAgPSovIDE2KS5pbnQ2NChtZXNzYWdlLnZlcnNpb24pO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54Lk9wZXJhdG9yU2V0SWRQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvfSBtZXNzYWdlIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGFuIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCxcbiAgICAgICAgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90bygpO1xuICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgbWVzc2FnZS52ZXJzaW9uID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRGVjb2RlcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEByZXR1cm5zIHtvbm54Lk9wZXJhdG9yU2V0SWRQcm90b30gT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgKi9cbiAgICBPcGVyYXRvclNldElkUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmllcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZS5cbiAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09ICdvYmplY3QnIHx8IG1lc3NhZ2UgPT09IG51bGwpIHJldHVybiAnb2JqZWN0IGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvbWFpbicpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9tYWluKSkgcmV0dXJuICdkb21haW46IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS52ZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgndmVyc2lvbicpKVxuICAgICAgICBpZiAoXG4gICAgICAgICAgISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnZlcnNpb24pICYmXG4gICAgICAgICAgIShtZXNzYWdlLnZlcnNpb24gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudmVyc2lvbi5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnZlcnNpb24uaGlnaCkpXG4gICAgICAgIClcbiAgICAgICAgICByZXR1cm4gJ3ZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZCc7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvKCk7XG4gICAgICBpZiAob2JqZWN0LmRvbWFpbiAhPSBudWxsKSBtZXNzYWdlLmRvbWFpbiA9IFN0cmluZyhvYmplY3QuZG9tYWluKTtcbiAgICAgIGlmIChvYmplY3QudmVyc2lvbiAhPSBudWxsKVxuICAgICAgICBpZiAoJHV0aWwuTG9uZykgKG1lc3NhZ2UudmVyc2lvbiA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC52ZXJzaW9uKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC52ZXJzaW9uID09PSAnc3RyaW5nJykgbWVzc2FnZS52ZXJzaW9uID0gcGFyc2VJbnQob2JqZWN0LnZlcnNpb24sIDEwKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC52ZXJzaW9uID09PSAnbnVtYmVyJykgbWVzc2FnZS52ZXJzaW9uID0gb2JqZWN0LnZlcnNpb247XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudmVyc2lvbiA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgbWVzc2FnZS52ZXJzaW9uID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC52ZXJzaW9uLmxvdyA+Pj4gMCwgb2JqZWN0LnZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYW4gT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54Lk9wZXJhdG9yU2V0SWRQcm90b30gbWVzc2FnZSBPcGVyYXRvclNldElkUHJvdG9cbiAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgb2JqZWN0LmRvbWFpbiA9ICcnO1xuICAgICAgICBpZiAoJHV0aWwuTG9uZykge1xuICAgICAgICAgIHZhciBsb25nID0gbmV3ICR1dGlsLkxvbmcoMCwgMCwgZmFsc2UpO1xuICAgICAgICAgIG9iamVjdC52ZXJzaW9uID1cbiAgICAgICAgICAgIG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgIH0gZWxzZSBvYmplY3QudmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICcwJyA6IDA7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb21haW4nKSkgb2JqZWN0LmRvbWFpbiA9IG1lc3NhZ2UuZG9tYWluO1xuICAgICAgaWYgKG1lc3NhZ2UudmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3ZlcnNpb24nKSlcbiAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLnZlcnNpb24gPT09ICdudW1iZXInKVxuICAgICAgICAgIG9iamVjdC52ZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UudmVyc2lvbikgOiBtZXNzYWdlLnZlcnNpb247XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBvYmplY3QudmVyc2lvbiA9XG4gICAgICAgICAgICBvcHRpb25zLmxvbmdzID09PSBTdHJpbmdcbiAgICAgICAgICAgICAgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UudmVyc2lvbilcbiAgICAgICAgICAgICAgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXJcbiAgICAgICAgICAgICAgICA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLnZlcnNpb24ubG93ID4+PiAwLCBtZXNzYWdlLnZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKVxuICAgICAgICAgICAgICAgIDogbWVzc2FnZS52ZXJzaW9uO1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBPcGVyYXRvclNldElkUHJvdG8gdG8gSlNPTi5cbiAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAqL1xuICAgIE9wZXJhdG9yU2V0SWRQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICovXG4gICAgT3BlcmF0b3JTZXRJZFByb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54Lk9wZXJhdG9yU2V0SWRQcm90byc7XG4gICAgfTtcblxuICAgIHJldHVybiBPcGVyYXRvclNldElkUHJvdG87XG4gIH0pKCk7XG5cbiAgLyoqXG4gICAqIE9wZXJhdG9yU3RhdHVzIGVudW0uXG4gICAqIEBuYW1lIG9ubnguT3BlcmF0b3JTdGF0dXNcbiAgICogQGVudW0ge251bWJlcn1cbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IEVYUEVSSU1FTlRBTD0wIEVYUEVSSU1FTlRBTCB2YWx1ZVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gU1RBQkxFPTEgU1RBQkxFIHZhbHVlXG4gICAqL1xuICBvbm54Lk9wZXJhdG9yU3RhdHVzID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LFxuICAgICAgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMF0gPSAnRVhQRVJJTUVOVEFMJyldID0gMDtcbiAgICB2YWx1ZXNbKHZhbHVlc0J5SWRbMV0gPSAnU1RBQkxFJyldID0gMTtcbiAgICByZXR1cm4gdmFsdWVzO1xuICB9KSgpO1xuXG4gIG9ubnguRnVuY3Rpb25Qcm90byA9IChmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogUHJvcGVydGllcyBvZiBhIEZ1bmN0aW9uUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAaW50ZXJmYWNlIElGdW5jdGlvblByb3RvXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW25hbWVdIEZ1bmN0aW9uUHJvdG8gbmFtZVxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW2lucHV0XSBGdW5jdGlvblByb3RvIGlucHV0XG4gICAgICogQHByb3BlcnR5IHtBcnJheS48c3RyaW5nPnxudWxsfSBbb3V0cHV0XSBGdW5jdGlvblByb3RvIG91dHB1dFxuICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW2F0dHJpYnV0ZV0gRnVuY3Rpb25Qcm90byBhdHRyaWJ1dGVcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklBdHRyaWJ1dGVQcm90bz58bnVsbH0gW2F0dHJpYnV0ZVByb3RvXSBGdW5jdGlvblByb3RvIGF0dHJpYnV0ZVByb3RvXG4gICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JTm9kZVByb3RvPnxudWxsfSBbbm9kZV0gRnVuY3Rpb25Qcm90byBub2RlXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gRnVuY3Rpb25Qcm90byBkb2NTdHJpbmdcbiAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklPcGVyYXRvclNldElkUHJvdG8+fG51bGx9IFtvcHNldEltcG9ydF0gRnVuY3Rpb25Qcm90byBvcHNldEltcG9ydFxuICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb21haW5dIEZ1bmN0aW9uUHJvdG8gZG9tYWluXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEZ1bmN0aW9uUHJvdG8uXG4gICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBGdW5jdGlvblByb3RvLlxuICAgICAqIEBpbXBsZW1lbnRzIElGdW5jdGlvblByb3RvXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtvbm54LklGdW5jdGlvblByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICovXG4gICAgZnVuY3Rpb24gRnVuY3Rpb25Qcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmlucHV0ID0gW107XG4gICAgICB0aGlzLm91dHB1dCA9IFtdO1xuICAgICAgdGhpcy5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgIHRoaXMuYXR0cmlidXRlUHJvdG8gPSBbXTtcbiAgICAgIHRoaXMubm9kZSA9IFtdO1xuICAgICAgdGhpcy5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gbmFtZS5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUubmFtZSA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBpbnB1dC5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48c3RyaW5nPn0gaW5wdXRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUuaW5wdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBvdXRwdXQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPHN0cmluZz59IG91dHB1dFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5vdXRwdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBhdHRyaWJ1dGUuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPHN0cmluZz59IGF0dHJpYnV0ZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5hdHRyaWJ1dGUgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb25Qcm90byBhdHRyaWJ1dGVQcm90by5cbiAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fSBhdHRyaWJ1dGVQcm90b1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5hdHRyaWJ1dGVQcm90byA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvblByb3RvIG5vZGUuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSU5vZGVQcm90bz59IG5vZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUubm9kZSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvblByb3RvIGRvY1N0cmluZy5cbiAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gb3BzZXRJbXBvcnQuXG4gICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSU9wZXJhdG9yU2V0SWRQcm90bz59IG9wc2V0SW1wb3J0XG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLm9wc2V0SW1wb3J0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uUHJvdG8gZG9tYWluLlxuICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9tYWluXG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBpbnN0YW5jZVxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLmRvbWFpbiA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBGdW5jdGlvblByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguSUZ1bmN0aW9uUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgKiBAcmV0dXJucyB7b25ueC5GdW5jdGlvblByb3RvfSBGdW5jdGlvblByb3RvIGluc3RhbmNlXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvblByb3RvKHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgRnVuY3Rpb25Qcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LkZ1bmN0aW9uUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtvbm54LklGdW5jdGlvblByb3RvfSBtZXNzYWdlIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAqL1xuICAgIEZ1bmN0aW9uUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgaWYgKCF3cml0ZXIpIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ25hbWUnKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLyAxMCkuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLyAzNCkuc3RyaW5nKG1lc3NhZ2UuaW5wdXRbaV0pO1xuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki8gNDIpLnN0cmluZyhtZXNzYWdlLm91dHB1dFtpXSk7XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgIT0gbnVsbCAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpXG4gICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA2LCB3aXJlVHlwZSAyID0qLyA1MCkuc3RyaW5nKG1lc3NhZ2UuYXR0cmlidXRlW2ldKTtcbiAgICAgIGlmIChtZXNzYWdlLm5vZGUgIT0gbnVsbCAmJiBtZXNzYWdlLm5vZGUubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAkcm9vdC5vbm54Lk5vZGVQcm90by5lbmNvZGUobWVzc2FnZS5ub2RlW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDcsIHdpcmVUeXBlIDIgPSovIDU4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgJ2RvY1N0cmluZycpKVxuICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDgsIHdpcmVUeXBlIDIgPSovIDY2KS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmVuY29kZShcbiAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnRbaV0sXG4gICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDksIHdpcmVUeXBlIDIgPSovIDc0KS5mb3JrKCksXG4gICAgICAgICAgKS5sZGVsaW0oKTtcbiAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsICdkb21haW4nKSlcbiAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMCwgd2lyZVR5cGUgMiA9Ki8gODIpLnN0cmluZyhtZXNzYWdlLmRvbWFpbik7XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGVQcm90byAhPSBudWxsICYmIG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoKVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoOyArK2kpXG4gICAgICAgICAgJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5lbmNvZGUoXG4gICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvW2ldLFxuICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMSwgd2lyZVR5cGUgMiA9Ki8gOTApLmZvcmsoKSxcbiAgICAgICAgICApLmxkZWxpbSgpO1xuICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5GdW5jdGlvblByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7b25ueC5JRnVuY3Rpb25Qcm90b30gbWVzc2FnZSBGdW5jdGlvblByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGVzIGEgRnVuY3Rpb25Qcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICogQHJldHVybnMge29ubnguRnVuY3Rpb25Qcm90b30gRnVuY3Rpb25Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKSByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsXG4gICAgICAgIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5GdW5jdGlvblByb3RvKCk7XG4gICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkpIG1lc3NhZ2UuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXQucHVzaChyZWFkZXIuc3RyaW5nKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSkgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0LnB1c2gocmVhZGVyLnN0cmluZygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuYXR0cmlidXRlICYmIG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aCkpIG1lc3NhZ2UuYXR0cmlidXRlID0gW107XG4gICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZS5wdXNoKHJlYWRlci5zdHJpbmcoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSAxMToge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5hdHRyaWJ1dGVQcm90byAmJiBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvLmxlbmd0aCkpIG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ucHVzaCgkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgNzoge1xuICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpKSBtZXNzYWdlLm5vZGUgPSBbXTtcbiAgICAgICAgICAgIG1lc3NhZ2Uubm9kZS5wdXNoKCRyb290Lm9ubnguTm9kZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgODoge1xuICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSA5OiB7XG4gICAgICAgICAgICBpZiAoIShtZXNzYWdlLm9wc2V0SW1wb3J0ICYmIG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoKSkgbWVzc2FnZS5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydC5wdXNoKCRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgMTA6IHtcbiAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZXMgYSBGdW5jdGlvblByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICogQHJldHVybnMge29ubnguRnVuY3Rpb25Qcm90b30gRnVuY3Rpb25Qcm90b1xuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSkgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFZlcmlmaWVzIGEgRnVuY3Rpb25Qcm90byBtZXNzYWdlLlxuICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSAnb2JqZWN0JyB8fCBtZXNzYWdlID09PSBudWxsKSByZXR1cm4gJ29iamVjdCBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbmFtZScpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpIHJldHVybiAnbmFtZTogc3RyaW5nIGV4cGVjdGVkJztcbiAgICAgIGlmIChtZXNzYWdlLmlucHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnaW5wdXQnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnB1dCkpIHJldHVybiAnaW5wdXQ6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5pbnB1dFtpXSkpIHJldHVybiAnaW5wdXQ6IHN0cmluZ1tdIGV4cGVjdGVkJztcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ291dHB1dCcpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm91dHB1dCkpIHJldHVybiAnb3V0cHV0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm91dHB1dFtpXSkpIHJldHVybiAnb3V0cHV0OiBzdHJpbmdbXSBleHBlY3RlZCc7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdhdHRyaWJ1dGUnKSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5hdHRyaWJ1dGUpKSByZXR1cm4gJ2F0dHJpYnV0ZTogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5hdHRyaWJ1dGVbaV0pKSByZXR1cm4gJ2F0dHJpYnV0ZTogc3RyaW5nW10gZXhwZWN0ZWQnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdhdHRyaWJ1dGVQcm90bycpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmF0dHJpYnV0ZVByb3RvKSkgcmV0dXJuICdhdHRyaWJ1dGVQcm90bzogYXJyYXkgZXhwZWN0ZWQnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLnZlcmlmeShtZXNzYWdlLmF0dHJpYnV0ZVByb3RvW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnYXR0cmlidXRlUHJvdG8uJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5ub2RlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnbm9kZScpKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm5vZGUpKSByZXR1cm4gJ25vZGU6IGFycmF5IGV4cGVjdGVkJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm5vZGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54Lk5vZGVQcm90by52ZXJpZnkobWVzc2FnZS5ub2RlW2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnbm9kZS4nICsgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ2RvY1N0cmluZycpKVxuICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSkgcmV0dXJuICdkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZCc7XG4gICAgICBpZiAobWVzc2FnZS5vcHNldEltcG9ydCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ29wc2V0SW1wb3J0JykpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3BzZXRJbXBvcnQpKSByZXR1cm4gJ29wc2V0SW1wb3J0OiBhcnJheSBleHBlY3RlZCc7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeShtZXNzYWdlLm9wc2V0SW1wb3J0W2ldKTtcbiAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiAnb3BzZXRJbXBvcnQuJyArIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb21haW4nKSlcbiAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvbWFpbikpIHJldHVybiAnZG9tYWluOiBzdHJpbmcgZXhwZWN0ZWQnO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGdW5jdGlvblByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtvbm54LkZ1bmN0aW9uUHJvdG99IEZ1bmN0aW9uUHJvdG9cbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguRnVuY3Rpb25Qcm90bykgcmV0dXJuIG9iamVjdDtcbiAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguRnVuY3Rpb25Qcm90bygpO1xuICAgICAgaWYgKG9iamVjdC5uYW1lICE9IG51bGwpIG1lc3NhZ2UubmFtZSA9IFN0cmluZyhvYmplY3QubmFtZSk7XG4gICAgICBpZiAob2JqZWN0LmlucHV0KSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW5wdXQpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkZ1bmN0aW9uUHJvdG8uaW5wdXQ6IGFycmF5IGV4cGVjdGVkJyk7XG4gICAgICAgIG1lc3NhZ2UuaW5wdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW5wdXQubGVuZ3RoOyArK2kpIG1lc3NhZ2UuaW5wdXRbaV0gPSBTdHJpbmcob2JqZWN0LmlucHV0W2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Qub3V0cHV0KSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qub3V0cHV0KSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLm91dHB1dDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qub3V0cHV0Lmxlbmd0aDsgKytpKSBtZXNzYWdlLm91dHB1dFtpXSA9IFN0cmluZyhvYmplY3Qub3V0cHV0W2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuYXR0cmlidXRlKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuYXR0cmlidXRlKSkgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLmF0dHJpYnV0ZTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuYXR0cmlidXRlLmxlbmd0aDsgKytpKSBtZXNzYWdlLmF0dHJpYnV0ZVtpXSA9IFN0cmluZyhvYmplY3QuYXR0cmlidXRlW2ldKTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3QuYXR0cmlidXRlUHJvdG8pIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5hdHRyaWJ1dGVQcm90bykpXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLmF0dHJpYnV0ZVByb3RvOiBhcnJheSBleHBlY3RlZCcpO1xuICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmF0dHJpYnV0ZVByb3RvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuYXR0cmlidXRlUHJvdG9baV0gIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLmF0dHJpYnV0ZVByb3RvOiBvYmplY3QgZXhwZWN0ZWQnKTtcbiAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvW2ldID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5hdHRyaWJ1dGVQcm90b1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3Qubm9kZSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm5vZGUpKSB0aHJvdyBUeXBlRXJyb3IoJy5vbm54LkZ1bmN0aW9uUHJvdG8ubm9kZTogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5ub2RlID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm5vZGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5ub2RlW2ldICE9PSAnb2JqZWN0JykgdGhyb3cgVHlwZUVycm9yKCcub25ueC5GdW5jdGlvblByb3RvLm5vZGU6IG9iamVjdCBleHBlY3RlZCcpO1xuICAgICAgICAgIG1lc3NhZ2Uubm9kZVtpXSA9ICRyb290Lm9ubnguTm9kZVByb3RvLmZyb21PYmplY3Qob2JqZWN0Lm5vZGVbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKSBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgIGlmIChvYmplY3Qub3BzZXRJbXBvcnQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5vcHNldEltcG9ydCkpIHRocm93IFR5cGVFcnJvcignLm9ubnguRnVuY3Rpb25Qcm90by5vcHNldEltcG9ydDogYXJyYXkgZXhwZWN0ZWQnKTtcbiAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm9wc2V0SW1wb3J0W2ldICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcignLm9ubnguRnVuY3Rpb25Qcm90by5vcHNldEltcG9ydDogb2JqZWN0IGV4cGVjdGVkJyk7XG4gICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydFtpXSA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmZyb21PYmplY3Qob2JqZWN0Lm9wc2V0SW1wb3J0W2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9iamVjdC5kb21haW4gIT0gbnVsbCkgbWVzc2FnZS5kb21haW4gPSBTdHJpbmcob2JqZWN0LmRvbWFpbik7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgRnVuY3Rpb25Qcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcGFyYW0ge29ubnguRnVuY3Rpb25Qcm90b30gbWVzc2FnZSBGdW5jdGlvblByb3RvXG4gICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICBvYmplY3QuYXR0cmlidXRlID0gW107XG4gICAgICAgIG9iamVjdC5ub2RlID0gW107XG4gICAgICAgIG9iamVjdC5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICBvYmplY3QuYXR0cmlidXRlUHJvdG8gPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgIG9iamVjdC5uYW1lID0gJyc7XG4gICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSAnJztcbiAgICAgICAgb2JqZWN0LmRvbWFpbiA9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ25hbWUnKSkgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICBpZiAobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytqKSBvYmplY3QuaW5wdXRbal0gPSBtZXNzYWdlLmlucHV0W2pdO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aCkge1xuICAgICAgICBvYmplY3Qub3V0cHV0ID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2opIG9iamVjdC5vdXRwdXRbal0gPSBtZXNzYWdlLm91dHB1dFtqXTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZSAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aDsgKytqKSBvYmplY3QuYXR0cmlidXRlW2pdID0gbWVzc2FnZS5hdHRyaWJ1dGVbal07XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0Lm5vZGUgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm5vZGUubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0Lm5vZGVbal0gPSAkcm9vdC5vbm54Lk5vZGVQcm90by50b09iamVjdChtZXNzYWdlLm5vZGVbal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgnZG9jU3RyaW5nJykpIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgIGlmIChtZXNzYWdlLm9wc2V0SW1wb3J0ICYmIG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdC5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoOyArK2opXG4gICAgICAgICAgb2JqZWN0Lm9wc2V0SW1wb3J0W2pdID0gJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8udG9PYmplY3QobWVzc2FnZS5vcHNldEltcG9ydFtqXSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KCdkb21haW4nKSkgb2JqZWN0LmRvbWFpbiA9IG1lc3NhZ2UuZG9tYWluO1xuICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gJiYgbWVzc2FnZS5hdHRyaWJ1dGVQcm90by5sZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZVByb3RvID0gW107XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5hdHRyaWJ1dGVQcm90by5sZW5ndGg7ICsrailcbiAgICAgICAgICBvYmplY3QuYXR0cmlidXRlUHJvdG9bal0gPSAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuYXR0cmlidXRlUHJvdG9bal0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhpcyBGdW5jdGlvblByb3RvIHRvIEpTT04uXG4gICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICovXG4gICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIEZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgKiBAc3RhdGljXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgKi9cbiAgICBGdW5jdGlvblByb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHlwZVVybFByZWZpeCA9ICd0eXBlLmdvb2dsZWFwaXMuY29tJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgJy9vbm54LkZ1bmN0aW9uUHJvdG8nO1xuICAgIH07XG5cbiAgICByZXR1cm4gRnVuY3Rpb25Qcm90bztcbiAgfSkoKTtcblxuICByZXR1cm4gb25ueDtcbn0pKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gJHJvb3Q7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCBMb25nIGZyb20gJ2xvbmcnO1xuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0ICogYXMgb3J0RmJzIGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7IG9ubnggfSBmcm9tICcuL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5cbi8vIGNoZWNrIHRoZSBpbnB1dHMgc2hhcGUgYmVmb3JlIHJ1bm5pbmcgYW4gT1AuXG4vLyByZXR1cm4gdHJ1ZSB3aGVuIHRoZSBpbnB1dHMgcGFzcyB0aGUgY2hlY2tcbi8vIHJldHVybiBmYWxzZSB3aGVuIHRoZSBpbnB1dHMgZG8gbm90IGZpdCB0aGUgcmVxdWlyZW1lbnRcbi8vIHRocm93IGV4Y2VwdGlvbiB3aGVuIGZhdGFsIGVycm9yIG9yIG5vdCBpbXBsZW1lbnRlZFxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrSW5wdXRzU2hhcGUoaW5wdXRzOiBUZW5zb3JbXSwgLi4uZXhwZWN0ZWREaW1lbnNpb25zOiBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSBleHBlY3RlZERpbWVuc2lvbnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFpbnB1dHNbaV0uZGltcyB8fCBpbnB1dHNbaV0uZGltcy5sZW5ndGggIT09IGV4cGVjdGVkRGltZW5zaW9uc1tpXSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8gRXZhbHVhdGVzIHRoZSBnaXZlbiBleHByZXNzaW9uIGFuZCBhc3NlcnRzIGVycm9yIG1lc3NhZ2UgaWYgY29uZGl0aW9uIGlzIHVubWV0LlxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydChleHByOiBib29sZWFuLCBtc2c6ICgpID0+IHN0cmluZykge1xuICBpZiAoIWV4cHIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodHlwZW9mIG1zZyA9PT0gJ3N0cmluZycgPyBtc2cgOiBtc2coKSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEFycmF5VXRpbCB7XG4gIC8qKlxuICAgKiBWZXJpZmllcyBpZiAyIGlucHV0IGFycmF5cyBjb250YWluIHRoZSBzYW1lIGVsZW1lbnRzLlxuICAgKiBAcGFyYW0gbjEgQXJyYXkgMVxuICAgKiBAcGFyYW0gbjIgQXJyYXkgMlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZXNlIDIgYXJlIGVxdWFsXG4gICAqL1xuICBzdGF0aWMgYXJyYXlzRXF1YWwoXG4gICAgbjE6XG4gICAgICB8IHJlYWRvbmx5IG51bWJlcltdXG4gICAgICB8IEludDhBcnJheVxuICAgICAgfCBVaW50OEFycmF5XG4gICAgICB8IEludDE2QXJyYXlcbiAgICAgIHwgVWludDE2QXJyYXlcbiAgICAgIHwgSW50MzJBcnJheVxuICAgICAgfCBVaW50MzJBcnJheVxuICAgICAgfCBVaW50OENsYW1wZWRBcnJheVxuICAgICAgfCBGbG9hdDMyQXJyYXlcbiAgICAgIHwgRmxvYXQ2NEFycmF5LFxuICAgIG4yOlxuICAgICAgfCByZWFkb25seSBudW1iZXJbXVxuICAgICAgfCBJbnQ4QXJyYXlcbiAgICAgIHwgVWludDhBcnJheVxuICAgICAgfCBJbnQxNkFycmF5XG4gICAgICB8IFVpbnQxNkFycmF5XG4gICAgICB8IEludDMyQXJyYXlcbiAgICAgIHwgVWludDMyQXJyYXlcbiAgICAgIHwgVWludDhDbGFtcGVkQXJyYXlcbiAgICAgIHwgRmxvYXQzMkFycmF5XG4gICAgICB8IEZsb2F0NjRBcnJheSxcbiAgKSB7XG4gICAgaWYgKG4xLmxlbmd0aCAhPT0gbjIubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChuMVtpXSAhPT0gbjJbaV0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTWF0TXVsVXRpbCB7XG4gIC8qKlxuICAgKiBGaXggdGhlIGlucHV0IHNoYXBlcyBmb3IgTWF0TXVsIG9wZXJhdGlvbiBpZiB0aGV5IG5lZWQgZml4aW5nXG4gICAqIEBwYXJhbSBkaW1zQSBUaGUgc2hhcGUgb2YgdGVuc29yIEEuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gZGltc0IgVGhlIHNoYXBlIG9mIHRlbnNvciBCLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHJldHVybnMgQSB0dXBsZSBjb250YWluaW5nIHRoZSBwcmVwcm9jZXNzZWQgaW5wdXQgc2hhcGVzIGFzIHJlcXVpcmVkIGJ5IE9OTlggc3BlY2lmaWNhdGlvbnNcbiAgICovXG4gIHN0YXRpYyBwcmVwcm9jZXNzSW5wdXRTaGFwZXMoXG4gICAgZGltc0E6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbXNCOiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogW3JlYWRvbmx5IG51bWJlcltdLCByZWFkb25seSBudW1iZXJbXV0ge1xuICAgIC8vIElmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyAxLUQsIGl0IGlzIHByb21vdGVkIHRvIGEgbWF0cml4IGJ5IHByZXBlbmRpbmdcbiAgICAvLyBhIDEgdG8gaXRzIGRpbWVuc2lvbnMuIEFmdGVyIG1hdHJpeCBtdWx0aXBsaWNhdGlvbiB0aGUgcHJlcGVuZGVkIDEgaXNcbiAgICAvLyByZW1vdmVkLlxuICAgIGNvbnN0IGEgPSBkaW1zQS5sZW5ndGggPT09IDEgPyBbMSwgZGltc0FbMF1dIDogZGltc0E7XG5cbiAgICAvLyBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIDEtRCwgaXQgaXMgcHJvbW90ZWQgdG8gYSBtYXRyaXggYnkgYXBwZW5kaW5nXG4gICAgLy8gYSAxIHRvIGl0cyBkaW1lbnNpb25zLiBBZnRlciBtYXRyaXggbXVsdGlwbGljYXRpb24gdGhlIGFwcGVuZGVkIDEgaXNcbiAgICAvLyByZW1vdmVkLlxuICAgIGNvbnN0IGIgPSBkaW1zQi5sZW5ndGggPT09IDEgPyBbZGltc0JbMF0sIDFdIDogZGltc0I7XG5cbiAgICByZXR1cm4gW2EsIGJdO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpeCB0aGUgb3V0cHV0IHNoYXBlIGNvbXB1dGVkIGZvciBNYXRNdWwgb3BlcmF0aW9uIGlmIGl0IG5lZWRzIGZpeGluZ1xuICAgKiBAcGFyYW0gb3V0cHV0U2hhcGUgVGhlIGNvbXB1dGVkIG91dHB1dFNoYXBlLiBTaG91bGQgYmUgYW4gYXJyYXkgKGF0IGxlYXN0IG9mIGxlbmd0aCAyKSBvZiBwb3NpdGl2ZSBpbnRlZ2Vycy5cbiAgICogVGhpcyB3aWxsIGJlIG11dGF0ZWQuXG4gICAqIEBwYXJhbSBhUmFuayBUaGUgcmFuayBvZiB0ZW5zb3IgQS5cbiAgICogQHBhcmFtIGJSYW5rIFRoZSByYW5rIG9mIHRlbnNvciBCLlxuICAgKi9cbiAgc3RhdGljIHBvc3Rwcm9jZXNzT3V0cHV0U2hhcGUob3V0cHV0U2hhcGU6IG51bWJlcltdLCBhUmFuazogbnVtYmVyLCBiUmFuazogbnVtYmVyKSB7XG4gICAgLy8gUmVtb3ZlIHByZXBlbmRlZCBkaW1lbnNpb24gaWYgZmlyc3QgaW5wdXQgaXMgMWRcbiAgICBpZiAoYVJhbmsgPT09IDEpIHtcbiAgICAgIC8vIG91dHB1dFNoYXBlID0gb3V0cHV0U2hhcGUuc2xpY2UoMCwgb3V0cHV0U2hhcGUubGVuZ3RoIC0gMikuY29uY2F0KG91dHB1dFNoYXBlLnNsaWNlKG91dHB1dFNoYXBlLmxlbmd0aCAtIDEpKTtcbiAgICAgIG91dHB1dFNoYXBlLnNwbGljZShvdXRwdXRTaGFwZS5sZW5ndGggLSAyLCAxKTtcbiAgICB9XG4gICAgLy8gUmVtb3ZlIGFwcGVuZGVkIGRpbWVuc2lvbiBpZiBzZWNvbmQgaW5wdXQgaXMgMWRcbiAgICBpZiAoYlJhbmsgPT09IDEpIHtcbiAgICAgIG91dHB1dFNoYXBlLnBvcCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlIHdoZW4gbWF0cml4IG11bHRpcGxpY2F0aW9uXG4gICAqIEBwYXJhbSBhIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQS4gU2hvdWxkIGJlIGEgdHVwbGUgb2YgMiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gYiBUaGUgc2hhcGUgb2YgdGVuc29yIEIuIFNob3VsZCBiZSBhIHR1cGxlIG9mIDIgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHJldHVybnMgVGhlIGV4cGVjdGVkIHNoYXBlIG9mIHRoZSByZXN1bHQsIG9yIHVuZGVmaW5lZCBpZiBOL0FcbiAgICovXG4gIHN0YXRpYyBjYWxjTWF0TXVsU2hhcGUoYTogW251bWJlciwgbnVtYmVyXSwgYjogW251bWJlciwgbnVtYmVyXSk6IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBhWzFdICE9PSBiWzBdID8gdW5kZWZpbmVkIDogW2FbMF0sIGJbMV1dO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCcm9hZGNhc3RVdGlsIHtcbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgc2hhcGUgd2hlbiBicm9hZGNhc3RpbmcgMiB0ZW5zb3JzXG4gICAqIEBwYXJhbSBhIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQS4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBiIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQi4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBpc01hdE11bCBXaGV0aGVyIHRoZSBvcGVyYXRpb24gaXMgTWF0TXVsXG4gICAqIEByZXR1cm5zIFRoZSBleHBlY3RlZCBzaGFwZSBvZiB0aGUgcmVzdWx0LCBvciB1bmRlZmluZWQgaWYgTi9BXG4gICAqL1xuICBzdGF0aWMgY2FsY1NoYXBlKFxuICAgIGFkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBiZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgaXNNYXRNdWwgPSBmYWxzZSxcbiAgKTogcmVhZG9ubHkgbnVtYmVyW10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGFyYW5rID0gYWRpbXMubGVuZ3RoO1xuICAgIGNvbnN0IGJyYW5rID0gYmRpbXMubGVuZ3RoO1xuICAgIGlmIChhcmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIGJkaW1zO1xuICAgIH1cbiAgICBpZiAoYnJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBhZGltcztcbiAgICB9XG4gICAgY29uc3QgY3JhbmsgPSBNYXRoLm1heChhZGltcy5sZW5ndGgsIGJkaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgY2RpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihjcmFuayk7XG5cbiAgICAvLyBjYWxjdWxhdGUgdGhlIGxhc3QgMiBkaW1lbnNpb24gaWYgaXQgaXMgTWF0TXVsXG4gICAgaWYgKGlzTWF0TXVsKSB7XG4gICAgICBpZiAoYXJhbmsgPCAyIHx8IGJyYW5rIDwgMikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY29uc3QgY1NoYXBlTWF0TXVsID0gTWF0TXVsVXRpbC5jYWxjTWF0TXVsU2hhcGUoXG4gICAgICAgIFthZGltc1thcmFuayAtIDJdLCBhZGltc1thcmFuayAtIDFdXSxcbiAgICAgICAgW2JkaW1zW2JyYW5rIC0gMl0sIGJkaW1zW2JyYW5rIC0gMV1dLFxuICAgICAgKTtcbiAgICAgIGlmIChjU2hhcGVNYXRNdWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgW2NkaW1zW2NyYW5rIC0gMl0sIGNkaW1zW2NyYW5rIC0gMV1dID0gY1NoYXBlTWF0TXVsO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSBpc01hdE11bCA/IDMgOiAxOyBpIDw9IGNyYW5rOyBpKyspIHtcbiAgICAgIGNvbnN0IGFMZW4gPSBhcmFuayAtIGkgPCAwID8gMSA6IGFkaW1zW2FyYW5rIC0gaV07XG4gICAgICBjb25zdCBiTGVuID0gYnJhbmsgLSBpIDwgMCA/IDEgOiBiZGltc1ticmFuayAtIGldO1xuXG4gICAgICBpZiAoYUxlbiAhPT0gYkxlbiAmJiBhTGVuID4gMSAmJiBiTGVuID4gMSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY2RpbXNbY3JhbmsgLSBpXSA9IE1hdGgubWF4KGFMZW4sIGJMZW4pO1xuICAgIH1cblxuICAgIHJldHVybiBjZGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiB0aGUgaW5kaWNlcyBvZiBhIGJyb2FkY2FzdGVkIHRlbnNvciwgY2FsY3VsYXRlIHRoZSBvcmlnaW5hbCBpbmRpY2VzXG4gICAqIEBwYXJhbSBicm9hZGNhc3RlZEluZGljZXMgVGhlIGdpdmVuIGluZGljZXMgb2YgdGhlIGJyb2FkY2FzdGVkIHRlbnNvci5cbiAgICogQHBhcmFtIG9yaWdpbmFsU2hhcGUgVGhlIG9yaWdpbmFsIHNoYXBlIG9mIHRoZSB0ZW5zb3IgYmVmb3JlIGJyb2FkY2FzdFxuICAgKiBAcmV0dXJucyBUaGUgY2FsY3VsYXRlZCBpbmRpY2VzIHRoYXQgbWFwcyB0byB0aGUgb3JpZ2luYWwgdGVuc29yLlxuICAgKi9cbiAgc3RhdGljIGluZGV4KGJyb2FkY2FzdGVkSW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIG9yaWdpbmFsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyW10ge1xuICAgIC8vIE5PVEUgMTogd2UgYXNzdW1lIHRoZSBwYXJhbWV0ZXIgYnJvYWRjYXN0ZWRJbmRpY2VzIGlzIHZhbGlkLiBpZS4gaXQgc2hvdWxkIGhhdmUgdGhlIHNhbWVcbiAgICAvLyBsZW5ndGggYXMgdGhlIGJyb2FkY2FzdGVkIHNoYXBlLCBhbmQgZm9yIGVhY2ggZGltZW5zaW9uIHRoZSBpbmRleCBzaG91bGRcbiAgICAvLyBub3QgYmUgb3V0IG9mIHJhbmdlLlxuICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlcyA9IG5ldyBBcnJheShvcmlnaW5hbFNoYXBlLmxlbmd0aCk7XG4gICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgoYnJvYWRjYXN0ZWRJbmRpY2VzLCBvcmlnaW5hbFNoYXBlLCBvcmlnaW5hbEluZGljZXMpO1xuICAgIHJldHVybiBvcmlnaW5hbEluZGljZXM7XG4gIH1cblxuICAvKipcbiAgICogR2l2ZW4gdGhlIGluZGljZXMgb2YgYSBicm9hZGNhc3RlZCB0ZW5zb3IsIGNhbGN1bGF0ZSB0aGUgb3JpZ2luYWwgaW5kaWNlc1xuICAgKiBAcGFyYW0gYnJvYWRjYXN0ZWRJbmRpY2VzIFRoZSBnaXZlbiBpbmRpY2VzIG9mIHRoZSBicm9hZGNhc3RlZCB0ZW5zb3IuXG4gICAqIEBwYXJhbSBvcmlnaW5hbFNoYXBlIFRoZSBvcmlnaW5hbCBzaGFwZSBvZiB0aGUgdGVuc29yIGJlZm9yZSBicm9hZGNhc3RcbiAgICogQHBhcmFtIG9yaWdpbmFsSW5kaWNlcyBUaGUgbWFwcGluZyBvZiBicm9hZGNhc3RlZEluZGljZXMgdG8gdGhlIG9yaWdpbmFsSW5kaWNlcyAob3V0cHV0IHBhcmFtZXRlciAtIHdpbGwgYmVcbiAgICogICAgIG11dGF0ZWQpLlxuICAgKi9cbiAgc3RhdGljIGZpbGxJbmRleChicm9hZGNhc3RlZEluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdLCBvcmlnaW5hbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgb3JpZ2luYWxJbmRpY2VzOiBudW1iZXJbXSkge1xuICAgIC8vIE5PVEUgMTogd2UgYXNzdW1lIHRoZSBwYXJhbWV0ZXIgYnJvYWRjYXN0ZWRJbmRpY2VzIGlzIHZhbGlkLiBpZS4gaXQgc2hvdWxkIGhhdmUgdGhlIHNhbWUgbGVuZ3RoIGFzIHRoZVxuICAgIC8vIGJyb2FkY2FzdGVkIHNoYXBlLCBhbmQgZm9yIGVhY2ggZGltZW5zaW9uIHRoZSBpbmRleCBzaG91bGQgbm90IGJlIG91dCBvZiByYW5nZS5cbiAgICAvLyBOT1RFIDI6IHdlIGFzc3VtZSB0aGUgcGFyYW1ldGVyIG9yaWdpbmFsSW5kaWNlcyBoYXMgdGhlIHNhbWUgbGVuZ3RoIGFzIHRoZSBvcmlnaW5hbFNoYXBlXG4gICAgY29uc3QgZGltT2Zmc2V0ID0gYnJvYWRjYXN0ZWRJbmRpY2VzLmxlbmd0aCAtIG9yaWdpbmFsU2hhcGUubGVuZ3RoO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JpZ2luYWxTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgICAgb3JpZ2luYWxJbmRpY2VzW2ldID0gYnJvYWRjYXN0ZWRJbmRpY2VzW2RpbU9mZnNldCArIGldICUgb3JpZ2luYWxTaGFwZVtpXTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSB0aGUgYnJvYWRjYXN0aW5nIG9wZXJhdGlvbiBvbiB0aGUgc3BlY2lmaWMgb3BlcmF0b3JcbiAgICogQHBhcmFtIGEgVGhlIGlucHV0IHRlbnNvciBBXG4gICAqIEBwYXJhbSBiIFRoZSBpbnB1dCB0ZW5zb3IgQlxuICAgKiBAcGFyYW0gb3AgVGhlIG9wZXJhdG9yIGxhbWJkYSBmdW5jdGlvblxuICAgKiBAcGFyYW0gaW5wbGFjZSBXaGV0aGVyIHRvIHdyaXRlIHRoZSByZXN1bHQgYmFjayB0byBBLlxuICAgKiBAcmV0dXJucyBUaGUgcmVzdWx0IHRlbnNvciwgb3IgdW5kZWZpbmVkIGlmIGlucHV0IG5vdCBicm9hZGNhc3RhYmxlLlxuICAgKi9cbiAgc3RhdGljIGNhbGMoXG4gICAgYTogVGVuc29yLFxuICAgIGI6IFRlbnNvcixcbiAgICBvcDogKGE6IHN0cmluZyB8IG51bWJlciwgYjogc3RyaW5nIHwgbnVtYmVyKSA9PiBzdHJpbmcgfCBudW1iZXIsXG4gICAgaW5wbGFjZTogYm9vbGVhbixcbiAgICByZXN1bHRUeXBlPzogVGVuc29yLkRhdGFUeXBlLFxuICApOiBUZW5zb3IgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG91dHB1dFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoYS5kaW1zLCBiLmRpbXMpO1xuXG4gICAgaWYgKG91dHB1dFNoYXBlKSB7XG4gICAgICBpZiAoaW5wbGFjZSAmJiAhU2hhcGVVdGlsLmFyZUVxdWFsKG91dHB1dFNoYXBlLCBhLmRpbXMpKSB7XG4gICAgICAgIC8vIEIgaXMgbm90IGJyb2FkY2FzdGFibGUgdG8gQSwgZmFpbGVkIHRvIGNhbGN1bGF0ZSBpbnBsYWNlLlxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICAgICAgY29uc3QgYyA9IGlucGxhY2UgPyBhIDogbmV3IFRlbnNvcihvdXRwdXRTaGFwZSwgcmVzdWx0VHlwZSB8fCBhLnR5cGUpO1xuXG4gICAgICAvLyBib3RoIGlucHV0cyBhcmUgc2NhbGFyc1xuICAgICAgaWYgKG91dHB1dFNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjLnNldChbXSwgb3AoYS5nZXQoW10pIGFzIG51bWJlciwgYi5nZXQoW10pIGFzIG51bWJlcikpO1xuICAgICAgfVxuXG4gICAgICAvLyBhdCBsZWFzdCBvbmUgaW5wdXQgaXMgYSBub24tc2NhbGFyXG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0EgPSBuZXcgQXJyYXkoYS5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0IgPSBuZXcgQXJyYXkoYi5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGxldCB2YWxBOiBzdHJpbmcgfCBudW1iZXIgPSAwO1xuICAgICAgICBsZXQgdmFsQjogc3RyaW5nIHwgbnVtYmVyID0gMDtcbiAgICAgICAgbGV0IGlzQVNjYWxhciA9IGZhbHNlO1xuICAgICAgICBsZXQgaXNCU2NhbGFyID0gZmFsc2U7XG4gICAgICAgIGlmIChhLmRpbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdmFsQSA9IGEuZ2V0KFtdKSBhcyBudW1iZXI7XG4gICAgICAgICAgaXNBU2NhbGFyID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYi5kaW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHZhbEIgPSBiLmdldChbXSkgYXMgbnVtYmVyO1xuICAgICAgICAgIGlzQlNjYWxhciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc3Q6IG51bWJlcjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgICAgICAvLyB0cmF2ZXJzYWwgaW5kaWNlc1xuICAgICAgICAgIHJlc3QgPSBpO1xuICAgICAgICAgIGZvciAobGV0IGogPSBvdXRwdXRTaGFwZS5sZW5ndGggLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgICAgICAgb3V0cHV0SW5kaWNlc1tqXSA9IHJlc3QgJSBvdXRwdXRTaGFwZVtqXTtcbiAgICAgICAgICAgIHJlc3QgPSBNYXRoLmZsb29yKHJlc3QgLyBvdXRwdXRTaGFwZVtqXSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFpc0FTY2FsYXIpIHtcbiAgICAgICAgICAgIC8vIG1hcCBvdXRwdXRJbmRpY2VzICh3aGljaCBpcyBhY3R1YWxseSBicm9hZGNhc3RlZCkgdG8gdGhlIG9yaWdpbmFsSW5kaWNlc1xuICAgICAgICAgICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgob3V0cHV0SW5kaWNlcywgYS5kaW1zLCBvcmlnaW5hbEluZGljZXNBKTtcbiAgICAgICAgICAgIHZhbEEgPSBhLmdldChvcmlnaW5hbEluZGljZXNBKSBhcyBudW1iZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghaXNCU2NhbGFyKSB7XG4gICAgICAgICAgICBCcm9hZGNhc3RVdGlsLmZpbGxJbmRleChvdXRwdXRJbmRpY2VzLCBiLmRpbXMsIG9yaWdpbmFsSW5kaWNlc0IpO1xuICAgICAgICAgICAgdmFsQiA9IGIuZ2V0KG9yaWdpbmFsSW5kaWNlc0IpIGFzIG51bWJlcjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjLnNldChvdXRwdXRJbmRpY2VzLCBvcCh2YWxBLCB2YWxCKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgaWYgYSBzaGFwZSBpcyB1bmlkaXJlY3Rpb25hbCBicm9hZGNhc3RhYmxlIHRvIGFub3RoZXIgc2hhcGVcbiAgICogQHBhcmFtIHNoYXBlIFRoZSBpbnB1dCBzaGFwZVxuICAgKiBAcGFyYW0gZmluYWxTaGFwZSBUaGUgZGVzaXJlZCBzaGFwZSBhZnRlciBicm9hZGNhc3RpbmdcbiAgICovXG4gIHN0YXRpYyBpc1ZhbGlkQnJvYWRjYXN0KHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZmluYWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBib29sZWFuIHtcbiAgICAvLyBhbGlnbiBzaGFwZSB0byB0aGUgcmlnaHRcbiAgICBjb25zdCBpbnB1dFJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgZmluYWxSYW5rID0gZmluYWxTaGFwZS5sZW5ndGg7XG4gICAgaWYgKGlucHV0UmFuayA+IGZpbmFsUmFuaykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBpbnB1dFJhbms7IGkrKykge1xuICAgICAgaWYgKHNoYXBlW2lucHV0UmFuayAtIGldICE9PSAxICYmIHNoYXBlW2lucHV0UmFuayAtIGldICE9PSBmaW5hbFNoYXBlW2ZpbmFsUmFuayAtIGldKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIHRoZSBicm9hZGNhc3RlZCBkaW1zIGluIGlucHV0IHNoYXBlIGJhc2VkIG9uIHRoZSBnaXZlbiBvdXRwdXQgc2hhcGUuXG4gICAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIG9ubHkgcmV0dXJucyB0aGUgYnJvYWRjYXN0ZWQgZGltcy5cbiAgICogQHBhcmFtIGlucHV0U2hhcGUgVGhlIGlucHV0IHNoYXBlXG4gICAqIEBwYXJhbSBvdXRwdXRTaGFwZSBUaGUgb3V0cHV0IHNoYXBlXG4gICAqIEByZXR1cm5zIFRoZSBicm9hZGNhc3RlZCBkaW1zIGluIGlucHV0IHNoYXBlLlxuICAgKi9cbiAgc3RhdGljIGdldEJyb2FkY2FzdERpbXMoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgICBjb25zdCBpblJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBkaW1zOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5SYW5rOyBpKyspIHtcbiAgICAgIGNvbnN0IGRpbSA9IGluUmFuayAtIDEgLSBpO1xuICAgICAgY29uc3QgYSA9IGlucHV0U2hhcGVbZGltXSB8fCAxO1xuICAgICAgY29uc3QgYiA9IG91dHB1dFNoYXBlW291dHB1dFNoYXBlLmxlbmd0aCAtIDEgLSBpXSB8fCAxO1xuICAgICAgaWYgKGIgPiAxICYmIGEgPT09IDEpIHtcbiAgICAgICAgZGltcy51bnNoaWZ0KGRpbSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkaW1zO1xuICB9XG59XG5cbi8vIGNvcHkgYXJyYXkgaGVscGVyXG4vLyBtaW1pY3MgbWVtY3B5IGFzIG11Y2ggYXMgcG9zc2libGVcbmV4cG9ydCBmdW5jdGlvbiBhcnJheUNvcHlIZWxwZXIoXG4gIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgc291cmNlOiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICB0YXJnZXRJbmRleDogbnVtYmVyLFxuICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICBibG9ja1NpemU6IG51bWJlcixcbikge1xuICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gIH1cbiAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICB9XG5cbiAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBHZW1tVXRpbCB7XG4gIC8vIHdpbGwgbWFrZSBzdXJlIGlucHV0IHNoYXBlcyBhcmUgY29tcGF0aWJsZSBmb3IgdGhpcyBvcFxuICAvLyBhbmQgcmV0dXJuIGJhY2sgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgaW4gdGhlIGZvcm0gb2YgYSB0dXBsZVxuICAvLyB3aWxsIHRocm93IGV4Y2VwdGlvbiBpZiB0aGUgaW5wdXQgc2hhcGVzIGFyZSBub3QgY29tcGF0aWJsZVxuICBzdGF0aWMgZ2V0U2hhcGVPZkdlbW1SZXN1bHQoXG4gICAgbGVmdFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICB0cmFuc0xlZnQ6IGJvb2xlYW4sXG4gICAgcmlnaHRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgdHJhbnNSaWdodDogYm9vbGVhbixcbiAgICBiaWFzU2hhcGU/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChsZWZ0U2hhcGUubGVuZ3RoICE9PSAyIHx8IHJpZ2h0U2hhcGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NoYXBlIG5lZWQgdG8gYmUgb2Ygc2l6ZSAyJyk7XG4gICAgfVxuXG4gICAgbGV0IE06IG51bWJlcjtcbiAgICBsZXQgSzogbnVtYmVyO1xuICAgIGxldCBOOiBudW1iZXI7XG5cbiAgICBpZiAodHJhbnNMZWZ0KSB7XG4gICAgICBNID0gbGVmdFNoYXBlWzFdO1xuICAgICAgSyA9IGxlZnRTaGFwZVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgTSA9IGxlZnRTaGFwZVswXTtcbiAgICAgIEsgPSBsZWZ0U2hhcGVbMV07XG4gICAgfVxuXG4gICAgbGV0IGtEaW0gPSAtMTtcblxuICAgIGlmICh0cmFuc1JpZ2h0KSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVswXTtcbiAgICAgIGtEaW0gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVsxXTtcbiAgICAgIGtEaW0gPSAwO1xuICAgIH1cblxuICAgIGlmIChyaWdodFNoYXBlW2tEaW1dICE9PSBLKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RpbWVuc2lvbiBtaXNtYXRjaCcpO1xuICAgIH1cblxuICAgIGlmIChNIDw9IDAgfHwgTiA8PSAwIHx8IEsgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNoYXBlIHNwZWNpZmllZCcpO1xuICAgIH1cblxuICAgIGlmIChiaWFzU2hhcGUgJiYgIUJyb2FkY2FzdFV0aWwuaXNWYWxpZEJyb2FkY2FzdChiaWFzU2hhcGUsIFtNLCBOXSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ2VtbTogaW52YWxpZCBiaWFzIHNoYXBlIGZvciBicm9hZGNhc3QnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW00sIE4sIEtdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQcm90b1V0aWwge1xuICBzdGF0aWMgdGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odHlwZVByb3RvOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHwgb3J0RmJzLlRlbnNvckRhdGFUeXBlKTogVGVuc29yLkRhdGFUeXBlIHtcbiAgICBzd2l0Y2ggKHR5cGVQcm90bykge1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgICAgIHJldHVybiAnaW50OCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgICAgIHJldHVybiAndWludDgnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgICAgIHJldHVybiAnYm9vbCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY6XG4gICAgICAgIHJldHVybiAnaW50MTYnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICAgICAgcmV0dXJuICd1aW50MTYnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyOlxuICAgICAgICByZXR1cm4gJ2ludDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICAgIHJldHVybiAndWludDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuICdmbG9hdDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgICAgIHJldHVybiAnZmxvYXQ2NCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gJ3N0cmluZyc7XG5cbiAgICAgIC8vIEZvciBJTlQ2NC9VSU5UNjQsIHJlZHVjZSB0aGVpciB2YWx1ZSB0byAzMi1iaXRzLlxuICAgICAgLy8gU2hvdWxkIHRocm93IGV4Y2VwdGlvbiB3aGVuIG92ZXJmbG93XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgICAgIHJldHVybiAnaW50MzInO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgICAgcmV0dXJuICd1aW50MzInO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHtvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlW3R5cGVQcm90b119YCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtKHR5cGU6IHN0cmluZyk6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4O1xuICAgICAgY2FzZSAnYm9vbCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2O1xuICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2O1xuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjtcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjtcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDtcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU7XG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5TVFJJTkc7XG4gICAgICBjYXNlICdpbnQ2NCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0O1xuICAgICAgY2FzZSAndWludDY0JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0O1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHt0eXBlfWApO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB0ZW5zb3JEaW1zRnJvbVByb3RvKGRpbXM6IEFycmF5PG51bWJlciB8IExvbmc+KTogbnVtYmVyW10ge1xuICAgIC8vIGdldCByaWQgb2YgTG9uZyB0eXBlIGZvciBkaW1zXG4gICAgcmV0dXJuIGRpbXMubWFwKChkKSA9PiAoTG9uZy5pc0xvbmcoZCkgPyBkLnRvTnVtYmVyKCkgOiBkKSk7XG4gIH1cblxuICBzdGF0aWMgdGVuc29yVmFsdWVUeXBlRnJvbVByb3RvKHZhbHVlVHlwZTogb25ueC5UeXBlUHJvdG8uSVRlbnNvcik6IEdyYXBoLlZhbHVlVHlwZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRlbnNvclR5cGU6IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byh2YWx1ZVR5cGUuZWxlbVR5cGUhKSxcbiAgICAgIHNoYXBlOiB7IGRpbXM6IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKHZhbHVlVHlwZS5zaGFwZSEuZGltIS5tYXAoKGQpID0+IGQuZGltVmFsdWUhKSkgfSxcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHRlbnNvckRpbXNGcm9tT1JURm9ybWF0KHRlbnNvcjogb3J0RmJzLlRlbnNvcikge1xuICAgIGNvbnN0IGRpbXMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRlbnNvci5kaW1zTGVuZ3RoKCk7IGkrKykge1xuICAgICAgZGltcy5wdXNoKExvbmdVdGlsLmxvbmdUb051bWJlcih0ZW5zb3IuZGltcyhpKSEpKTtcbiAgICB9XG4gICAgcmV0dXJuIGRpbXM7XG4gIH1cblxuICBzdGF0aWMgdGVuc29yQXR0cmlidXRlc0Zyb21PUlRGb3JtYXQobm9kZTogb3J0RmJzLk5vZGUpIHtcbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2RlLmF0dHJpYnV0ZXNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBhdHRyaWJ1dGVzLnB1c2gobm9kZS5hdHRyaWJ1dGVzKGkpISk7XG4gICAgfVxuICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBMb25nVXRpbCB7XG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHRvIGdldCBhIG51bWJlciBmcm9tIGxvbmcgdHlwZSBvZiBkYXRhIGZvciBhdHRyaWJ1dGUsIGRpbSwgYW5kIGlyIHZlcnNpb24sXG4gIC8vIHdoaWNoIHZhbHVlcyBhcmUgc2lnbmVkIGludGVnZXJzLlxuICAvLyBUbyBtYWtlIGl0IG1vcmUgZ2VuZXJpYywgYWRkIGFuIG9wdGlvbmFsIHBhcmFtZXRlciB0byBjb252ZXJ0IHRvIGEgdW5zaWduZWQgbnVtYmVyLlxuICBzdGF0aWMgbG9uZ1RvTnVtYmVyKG46IExvbmcgfCBiaWdpbnQgfCBudW1iZXIpIHtcbiAgICBpZiAoTG9uZy5pc0xvbmcobikpIHtcbiAgICAgIHJldHVybiBuLnRvTnVtYmVyKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbiA9PT0gJ2JpZ2ludCcpIHtcbiAgICAgIHJldHVybiBOdW1iZXIobik7XG4gICAgfVxuICAgIHJldHVybiBuO1xuICB9XG4gIHN0YXRpYyBpc0xvbmcobjogdW5rbm93bikge1xuICAgIHJldHVybiBMb25nLmlzTG9uZyhuKSB8fCB0eXBlb2YgbiA9PT0gJ2JpZ2ludCc7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNoYXBlVXRpbCB7XG4gIHN0YXRpYyBzaXplKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgMCwgZGltcy5sZW5ndGgpO1xuICB9XG5cbiAgLy8gYGF4aXNgIGluY2x1c2l2ZVxuICBzdGF0aWMgc2l6ZUZyb21EaW1lbnNpb24oZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAwIHx8IGF4aXMgPiBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGRpbWVuc2lvbiBvZiAke2F4aXN9IGZvciBzaXplRnJvbURpbWVuc2lvbiBhcyBUZW5zb3IgaGFzICR7ZGltcy5sZW5ndGh9IGRpbWVuc2lvbnMuYCk7XG4gICAgfVxuICAgIHJldHVybiBTaGFwZVV0aWwuZ2V0U2l6ZUZyb21EaW1lbnNpb25SYW5nZShkaW1zLCBheGlzLCBkaW1zLmxlbmd0aCk7XG4gIH1cblxuICAvLyBgYXhpc2AgZXhjbHVzaXZlXG4gIHN0YXRpYyBzaXplVG9EaW1lbnNpb24oZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAwIHx8IGF4aXMgPiBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGRpbWVuc2lvbiBvZiAke2F4aXN9IGZvciBzaXplVG9EaW1lbnNpb24gYXMgVGVuc29yIGhhcyAke2RpbXMubGVuZ3RofSBkaW1lbnNpb25zLmApO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgMCwgYXhpcyk7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZUZyb21EaW1lbnNpb25SYW5nZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBzaXplID0gMTtcbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgLy8gc2FmZXR5IGNoZWNrIGFzIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBtdWx0aXBsZSBvdGhlciBtZXRob2RzIHJlcXVpcmluZyBzaXplLlxuICAgICAgLy8gc2l6ZSBjYW5ub3QgYmUgMCBvciBuZWdhdGl2ZS5cbiAgICAgIGlmIChkaW1zW2ldIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdjYW5ub3QgZ2V0IHZhbGlkIHNpemUgZnJvbSBzcGVjaWZpZWQgZGltZW5zaW9uIHJhbmdlLiBNb3N0IGxpa2VseSB0aGUgcmFuZ2UgY29udGFpbnMgMCBvciBuZWdhdGl2ZSB2YWx1ZXMgaW4gdGhlbS4nLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgc2l6ZSAqPSBkaW1zW2ldO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZTtcbiAgfVxuXG4gIHN0YXRpYyBjb21wdXRlU3RyaWRlcyhkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gZGltcy5sZW5ndGg7XG4gICAgaWYgKHJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2UgaWYgKHJhbmsgPT09IDEpIHtcbiAgICAgIHJldHVybiBbMV07XG4gICAgfVxuICAgIGNvbnN0IHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMV0gPSAxO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gZGltc1tyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogZGltc1tpICsgMV07XG4gICAgfVxuICAgIHJldHVybiBzdHJpZGVzO1xuICB9XG5cbiAgc3RhdGljIHRyYW5zcG9zZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCBjb3B5ID0gZGltcy5zbGljZSgpO1xuICAgIHJldHVybiBjb3B5LnJldmVyc2UoKTtcbiAgfVxuXG4gIHN0YXRpYyBpbmRpY2VzVG9PZmZzZXQoaW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzPzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoYXhpcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBheGlzID0gaW5kaWNlcy5sZW5ndGg7XG4gICAgfVxuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhpczsgKytpKSB7XG4gICAgICBvZmZzZXQgKz0gc3RyaWRlc1tpXSAqIGluZGljZXNbaV07XG4gICAgfVxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgb2Zmc2V0VG9JbmRpY2VzKG9mZnNldDogbnVtYmVyLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gc3RyaWRlcy5sZW5ndGg7XG4gICAgaWYgKHJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2UgaWYgKHJhbmsgPT09IDEpIHtcbiAgICAgIHJldHVybiBbb2Zmc2V0ICogc3RyaWRlc1swXV07XG4gICAgfVxuICAgIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gbmV3IEFycmF5KHN0cmlkZXMubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoIC0gMTsgKytpKSB7XG4gICAgICBpbmRpY2VzW2ldID0gTWF0aC5mbG9vcihvZmZzZXQgLyBzdHJpZGVzW2ldKTtcbiAgICAgIG9mZnNldCAtPSBpbmRpY2VzW2ldICogc3RyaWRlc1tpXTtcbiAgICB9XG4gICAgaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdID0gb2Zmc2V0O1xuICAgIHJldHVybiBpbmRpY2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIG5vcm1hbGl6ZSBheGlzIG9mIHJhbmdlIFstciwgcikgaW50byBbMCwgcikuXG4gICAqL1xuICBzdGF0aWMgbm9ybWFsaXplQXhpcyhheGlzOiBudW1iZXIsIHRlbnNvclJhbms6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAtdGVuc29yUmFuayAmJiBheGlzID49IHRlbnNvclJhbmspIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5zdXBwb3J0ZWQgYXhpcyBmb3IgdGhpcyBvcGVyYXRpb24uJyk7XG4gICAgfVxuICAgIHJldHVybiBheGlzIDwgMCA/IGF4aXMgKyB0ZW5zb3JSYW5rIDogYXhpcztcbiAgfVxuXG4gIHN0YXRpYyBub3JtYWxpemVBeGVzKGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdLCB0ZW5zb3JSYW5rOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIGF4ZXMubWFwKCh4KSA9PiB0aGlzLm5vcm1hbGl6ZUF4aXMoeCwgdGVuc29yUmFuaykpO1xuICB9XG5cbiAgLy8gSW5jcmVtZW50IGFuIGluZGV4IGludG8gYSB0ZW5zb3IgKGluIGxleGljb2dyYXBoaWNcbiAgLy8gb3JkZXJpbmcpLCB3cmFwcGluZyBhcm91bmQgdGhlIHNwZWNpZmllZCB1cHBlcl9ib3VuZC5cbiAgLyoqXG4gICAqIEluY3JlbWVudCBhbiBpbmRleCBpbnRvIGEgdGVuc29yIChpbiBsZXhpY29ncmFwaGljIG9yZGVyaW5nKSwgd3JhcHBpbmcgYXJvdW5kIHRoZSBzcGVjaWZpZWQgdXBwZXJfYm91bmQuXG4gICAqIEBwYXJhbSBpbmRleCBHaXZlbiBpbmRleCB0byBpbmNyZW1lbnQgKFdpbGwgYmUgbXV0YXRlZClcbiAgICogQHBhcmFtIGRpbXMgVGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvciBmb3Igd2hpY2ggdGhlIGdpdmVuIGluZGV4IGNvcnJlc3BvbmRzIHRvXG4gICAqIEBwYXJhbSBheGlzVG9JbmNyZW1lbnRPbiBUaGUgMS1pbmRleGVkIGF4aXMgdG8gaW5jcmVtZW50IG9uLiBJZiB1bmRlZmluZWQsIGF4aXNUb0luY3JlbWVudE9uID09IHJhbmtcbiAgICovXG4gIHN0YXRpYyBpbmNyZW1lbnRJbmRleChpbmRleDogbnVtYmVyW10sIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzVG9JbmNyZW1lbnRPbj86IG51bWJlcikge1xuICAgIGlmIChkaW1zLmxlbmd0aCA9PT0gMCB8fCBpbmRleC5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5kZXggaW5jcmVtZW50aW5nIHVuc3VwcG9ydGVkIGZvciBzY2FsYXIgVGVuc29yJyk7XG4gICAgfVxuICAgIGlmIChheGlzVG9JbmNyZW1lbnRPbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBheGlzVG9JbmNyZW1lbnRPbiA9IGRpbXMubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoYXhpc1RvSW5jcmVtZW50T24gPD0gMCB8fCBheGlzVG9JbmNyZW1lbnRPbiA+IGRpbXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5jb3JyZWN0IGF4aXMgdG8gaW5jcmVtZW50IG9uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgayA9IGF4aXNUb0luY3JlbWVudE9uIC0gMTsgayA+PSAwOyAtLWspIHtcbiAgICAgIGluZGV4W2tdKys7XG4gICAgICBpZiAoaW5kZXhba10gPCBkaW1zW2tdKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaW5kZXhba10gPSAwO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIG5ldyBkaW1lbnNpb25zIGFycmF5IGJhc2VkIG9uIHRoZSB2YWx1ZXMgaW4gdGhlICdvcmlnaW5hbERpbWVuc2lvbnMnIGFuZCAnc2hhcGUnIGFycmF5XG4gICAqIFVzZWQgaW4gUmVzaGFwZVxuICAgKiBAcGFyYW0gb3JpZ2luYWxEaW1zIE9yaWdpbmFsIFNoYXBlIGFycmF5XG4gICAqIEBwYXJhbSBzaGFwZUhpbnRzIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIHRvIGNvbXB1dGUgdGhlIG5ldyBkaW1lbnNpb25zXG4gICAqIEZvciBleGFtcGxlOlxuICAgKiBvcmlnaW5hbERpbXMgPSBbMiwyXSBhbmQgc2hhcGVIaW50cyA9IFswLC0xXSB3aWxsIHJldHVybiBbMiwyXVxuICAgKiBvcmlnaW5hbERpbXMgPSBbMiwyXSBhbmQgc2hhcGVIaW50cyA9IFs0XSB3aWxsIHJldHVybiBbNF1cbiAgICogb3JpZ2luYWxEaW1zID0gWzIsMl0gYW5kIHNoYXBlSGludHMgPSBbNV0gd2lsbCB0aHJvdyBhbiBleGNlcHRpb25cbiAgICogaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjUmVzaGFwZVxuICAgKi9cblxuICBzdGF0aWMgY2FsY3VsYXRlUmVzaGFwZWREaW1zKG9yaWdpbmFsRGltczogcmVhZG9ubHkgbnVtYmVyW10sIHNoYXBlSGludHM6IEFycmF5TGlrZTxudW1iZXI+KTogbnVtYmVyW10ge1xuICAgIC8vIHJlc2hhcGUgdG8gYSBTY2FsYXIgVGVuc29yXG4gICAgaWYgKHNoYXBlSGludHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZiAob3JpZ2luYWxEaW1zLmxlbmd0aCA9PT0gMCB8fCBTaGFwZVV0aWwuc2l6ZShvcmlnaW5hbERpbXMpID09PSAxKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IHJlc2hhcGUgdG8gYSBzY2FsYXIgVGVuc29yJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbkRpbXMgPSBzaGFwZUhpbnRzLmxlbmd0aDtcbiAgICBjb25zdCByZXNoYXBlZERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihuRGltcyk7XG4gICAgbGV0IHVua25vd25EaW1lbnNpb24gPSAtMTtcbiAgICBsZXQgbmV3VGVuc29yU2l6ZSA9IDE7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuRGltczsgaSsrKSB7XG4gICAgICBpZiAoc2hhcGVIaW50c1tpXSA8IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYSBkaW1lbnNpb24gaW4gc2hhcGUgaGludHMgY2Fubm90IGJlIGxlc3MgdGhhbiAtMScpO1xuICAgICAgfVxuICAgICAgaWYgKHNoYXBlSGludHNbaV0gPT09IC0xKSB7XG4gICAgICAgIGlmICh1bmtub3duRGltZW5zaW9uICE9PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYXQgbW9zdCBvbmUgZGltZW5zaW9uIGluIHNoYXBlIGhpbnRzIGNhbiBiZSAtMScpO1xuICAgICAgICB9XG4gICAgICAgIHVua25vd25EaW1lbnNpb24gPSBpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNoYXBlSGludHNbaV0gPT09IDApIHtcbiAgICAgICAgICBpZiAoaSA+PSBvcmlnaW5hbERpbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBkaW1lbnNpb24gd2l0aCB2YWx1ZSB6ZXJvIGV4Y2VlZHMgdGhlIGRpbWVuc2lvbiBzaXplIG9mIHRoZSBpbnB1dCB0ZW5zb3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzaGFwZWREaW1zW2ldID0gb3JpZ2luYWxEaW1zW2ldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc2hhcGVkRGltc1tpXSA9IHNoYXBlSGludHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgbmV3VGVuc29yU2l6ZSAqPSByZXNoYXBlZERpbXNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgb2xkVGVuc29yU2l6ZSA9IFNoYXBlVXRpbC5zaXplKG9yaWdpbmFsRGltcyk7XG4gICAgaWYgKHVua25vd25EaW1lbnNpb24gIT09IC0xKSB7XG4gICAgICBpZiAob2xkVGVuc29yU2l6ZSAlIG5ld1RlbnNvclNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGB0aGUgaW5wdXQgdGVuc29yIGNhbm5vdCBiZSByZXNoYXBlZCB0byB0aGUgcmVxdWVzdGVkIHNoYXBlLiBJbnB1dCBzaGFwZTogWyR7XG4gICAgICAgICAgICBvcmlnaW5hbERpbXNcbiAgICAgICAgICB9XSBPdXRwdXQgc2hhcGU6IFske3NoYXBlSGludHN9XWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXNoYXBlZERpbXNbdW5rbm93bkRpbWVuc2lvbl0gPSBvbGRUZW5zb3JTaXplIC8gbmV3VGVuc29yU2l6ZTtcbiAgICB9XG4gICAgLy8gdmFsaWRhdGUgc2l6ZXMgZnJvbSBvcmlnaW5hbERpbXMgYW5kIHJlc2hhcGVkRGltcyBtYXRjaFxuICAgIGVsc2Uge1xuICAgICAgaWYgKG5ld1RlbnNvclNpemUgIT09IG9sZFRlbnNvclNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwicmVzaGFwZWREaW1zIGFuZCBvcmlnaW5hbERpbXMgZG9uJ3QgaGF2ZSBtYXRjaGluZyBzaXplc1wiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc2hhcGVkRGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTb3J0cyBhIGdpdmVuIGFycmF5IGJhc2VkIG9uIHRoZSBpbmRpY2VzIGluIHRoZSBQZXJtIGFycmF5XG4gICAqIFVzZWQgaW4gVHJhbnNwb3NlXG4gICAqIEBwYXJhbSBhIEFycmF5IHRvIGJlIHNvcnRlZCBzdWNoIGFzIGRpbXMgb3Igc3RyaWRlc1xuICAgKiBAcGFyYW0gcGVybSBQZXJtIGdpdmVuOyBpZiBudWxsIGEgd2lsbCBiZSByZXZlcnNlZFxuICAgKi9cbiAgc3RhdGljIHNvcnRCYXNlZE9uUGVybShhOiByZWFkb25seSBudW1iZXJbXSwgcGVybT86IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChwZXJtKSB7XG4gICAgICByZXR1cm4gcGVybS5tYXAoKHYpID0+IGFbdl0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYS5zbGljZSgpLnJldmVyc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFkcyBhIGdpdmVuIHNoYXBlIGFjY29yZGluZyB0byB0aGUgcGFkZGluZyB2YWx1ZXNcbiAgICogQHBhcmFtIGRpbXMgc2hhcGUgb2YgdGhlIFRlbnNvciB0byBiZSBwYWRkZWRcbiAgICogQHBhcmFtIHBhZCBwYWQgdmFsdWVzXG4gICAqL1xuICBzdGF0aWMgcGFkU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHBhZDogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3QgcmFuayA9IGRpbXMubGVuZ3RoO1xuICAgIHJldHVybiBkaW1zLm1hcCgodiwgaSkgPT4gdiArIHBhZFtpXSArIHBhZFtpICsgcmFua10pO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgdGhlIHR3byBzaGFwZXMgYXJlIGlkZW50aWNhbFxuICAgKiBAcGFyYW0gc2hhcGUxXG4gICAqIEBwYXJhbSBzaGFwZTJcbiAgICovXG4gIHN0YXRpYyBhcmVFcXVhbChzaGFwZTE6IHJlYWRvbmx5IG51bWJlcltdLCBzaGFwZTI6IHJlYWRvbmx5IG51bWJlcltdKTogYm9vbGVhbiB7XG4gICAgaWYgKHNoYXBlMS5sZW5ndGggIT09IHNoYXBlMi5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHNoYXBlMS5ldmVyeSgodiwgaSkgPT4gdiA9PT0gc2hhcGUyW2ldKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgaWYgdGhlIGdpdmVuIGBkaW1zYCBvciBgc2hhcGVgIGlzIHZhbGlkIGluIE9OTlguanMgY29udGV4dCBhbmQgcmV0dXJucyBkYXRhIHNpemVcbiAgICogQHBhcmFtIGRpbXMgLSBpbnB1dCBgZGltc2AgdGhhdCBuZWVkcyB0byBiZSBjaGVja2VkXG4gICAqL1xuICBzdGF0aWMgdmFsaWRhdGVEaW1zQW5kQ2FsY1NpemUoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXIge1xuICAgIGlmIChkaW1zLmxlbmd0aCA+IDYpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ09ubHkgcmFuayAwIHRvIDYgaXMgc3VwcG9ydGVkIGZvciB0ZW5zb3Igc2hhcGUuJyk7XG4gICAgfVxuICAgIGxldCBzaXplID0gMTtcbiAgICBmb3IgKGNvbnN0IG4gb2YgZGltcykge1xuICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKG4pKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgc2hhcGU6ICR7bn0gaXMgbm90IGFuIGludGVnZXJgKTtcbiAgICAgIH1cbiAgICAgIGlmIChuIDwgMCB8fCBuID4gMjE0NzQ4MzY0Nykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIHNoYXBlOiBsZW5ndGggJHtufSBpcyBub3QgYWxsb3dlZGApO1xuICAgICAgfVxuICAgICAgc2l6ZSAqPSBuO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHRoZSBzaGFwZSBvZiBvdXRwdXQgdGVuc29yIHkgPSBmbGF0dGVuKHgsIGF4aXMpXG4gICAqIEBwYXJhbSBkaW1zIC0gc2hhcGUgb2YgaW5wdXQgdGVuc29yXG4gICAqIEBwYXJhbSBheGlzIC0gZmxhdHRlbiBheGlzLCBpbiB0aGUgcmFuZ2UgWy1yLCByXVxuICAgKi9cbiAgc3RhdGljIGZsYXR0ZW5TaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhpczogbnVtYmVyKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChheGlzIDwgMCkge1xuICAgICAgYXhpcyArPSBkaW1zLmxlbmd0aDtcbiAgICB9XG4gICAgY29uc3QgdG90YWwgPSBkaW1zLnJlZHVjZSgoeCwgeSkgPT4geCAqIHksIDEpO1xuICAgIGNvbnN0IHJpZ2h0ID0gZGltcy5zbGljZShheGlzKS5yZWR1Y2UoKHgsIHkpID0+IHggKiB5LCAxKTtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW3RvdGFsIC8gcmlnaHQsIHJpZ2h0XTtcblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgdGhlIHNoYXBlIG9mIG91dHB1dCB0ZW5zb3IgeSA9IHNxdWVlemUoeCwgYXhlcylcbiAgICogQHBhcmFtIGRpbXMgLSBzaGFwZSBvZiBpbnB1dCB0ZW5zb3JcbiAgICogQHBhcmFtIGF4ZXMgLSBzcXVlZXplIGF4ZXNcbiAgICovXG4gIHN0YXRpYyBzcXVlZXplU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXG4gICAgLy8gc2FuaXR5IGNoZWNrXG4gICAgYXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF4ZXMsIGRpbXMubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgaW5TcXVlZXplTGlzdCA9IGF4ZXMuaW5kZXhPZihpKSA+PSAwO1xuICAgICAgaWYgKGluU3F1ZWV6ZUxpc3QgJiYgZGltc1tpXSAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NxdWVlemUgYW4gYXhpcyBvZiBzaXplIGRpZmZlcmVudCB0aGFuIDEnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKChheGVzLmxlbmd0aCA9PT0gMCAmJiBkaW1zW2ldID4gMSkgfHwgKGF4ZXMubGVuZ3RoID4gMCAmJiAhaW5TcXVlZXplTGlzdCkpIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKGRpbXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgdGhlIHNoYXBlIG9mIG91dHB1dCB0ZW5zb3IgeSA9IHVuc3F1ZWV6ZSh4LCBheGVzKVxuICAgKiBAcGFyYW0gZGltcyAtIHNoYXBlIG9mIGlucHV0IHRlbnNvclxuICAgKiBAcGFyYW0gYXhlcyAtIHVuc3F1ZWV6ZSBheGVzXG4gICAqL1xuICBzdGF0aWMgdW5zcXVlZXplU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihkaW1zLmxlbmd0aCArIGF4ZXMubGVuZ3RoKTtcblxuICAgIC8vIGluaXRpYWxpemUgdGhlIGFycmF5IGVsZW1lbnRzIHRvIDBcbiAgICBvdXRwdXREaW1zLmZpbGwoMCk7XG5cbiAgICAvLyBzZXQgYWxsIGF4ZXMgaW5kaWNlcyB0byAxIGluIG91dHB1dERpbXMgYW5kIGNoZWNrIGZvciBkdXBsaWNhdGVzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBheGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXhlc1tpXSwgb3V0cHV0RGltcy5sZW5ndGgpO1xuICAgICAgaWYgKGF4aXMgPj0gb3V0cHV0RGltcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiJ2F4ZXMnIGhhcyBhbiBvdXQgb2YgcmFuZ2UgYXhpc1wiKTtcbiAgICAgIH1cbiAgICAgIGlmIChvdXRwdXREaW1zW2F4aXNdICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIidheGVzJyBoYXMgYSBkdXBsaWNhdGUgYXhpc1wiKTtcbiAgICAgIH1cblxuICAgICAgb3V0cHV0RGltc1theGlzXSA9IDE7XG4gICAgfVxuXG4gICAgLy8gZmlsbCBpbiB0aGUgemVybyBlbnRyaWVzIG9mIG91dHB1dERpbXMgd2l0aCB0aGUgaW5wdXQgdGVuc29yJ3Mgc2hhcGVcbiAgICBsZXQgaW5wdXREaW1zSXRlcmF0b3IgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0RGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG91dHB1dERpbXNbaV0gPT09IDApIHtcbiAgICAgICAgb3V0cHV0RGltc1tpXSA9IGRpbXNbaW5wdXREaW1zSXRlcmF0b3IrK107XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2FuaXR5IGNoZWNrIGFzc2VydGlvbi4gJ2lucHV0RGltc0l0ZXJhdG9yJ1xuICAgIC8vIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mICdkaW1zJ1xuICAgIGlmIChpbnB1dERpbXNJdGVyYXRvciAhPT0gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHVuc3F1ZWV6ZWQgZGltZW5zaW9uIGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG59XG5cbi8vIGJ1bmNoIG9mIGhlbHBlciBtZXRob2RzIHRoYXQgZG8gYSB2YXJpZXR5IG9mIG1hdGggb3BlcmF0aW9uc1xuZXhwb3J0IGNsYXNzIE1hdGhVdGlsIHtcbiAgLy8geSA9ICh4KngpICsgeVxuICBzdGF0aWMgc3FyKFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICApIHtcbiAgICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlSW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0SW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBpbmRpY2VzIHRvIGJlIGNvcGllZCBhcmUgb3V0c2lkZSBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXQgYXJyYXkgaXMgdG9vIHNtYWxsIHRvIGhvbGQgcmVzdWx0Jyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgICAgdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSArPSBNYXRoLnBvdyhzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdLCAyKTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0gYXggKyB5XG4gIHN0YXRpYyBheHB5KFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICAgIGFscGhhOiBudW1iZXIsXG4gICkge1xuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdICs9IGFscGhhICogc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0gcG93KHgsIGIpXG4gIHN0YXRpYyBwb3d4KFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICAgIGI6IG51bWJlcixcbiAgKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBNYXRoLnBvdyhzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdLCBiKTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0geCAqIHlcbiAgc3RhdGljIG11bChcbiAgICB0YXJnZXQ6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgc291cmNlOiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRhcmdldEluZGV4OiBudW1iZXIsXG4gICAgc291cmNlSW5kZXg6IG51bWJlcixcbiAgICBibG9ja1NpemU6IG51bWJlcixcbiAgKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdICogdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNwbGl0VXRpbCB7XG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIG5ldyBTaGFwZXMgZnJvbSBleGlzdGluZyBvbmUgYW5kIHRoZSBzcGxpdHMgZ2l2ZW4gYWxvbmcgdGhlIGF4aXMgcHJvdmlkZXNcbiAgICogQHBhcmFtIGRpbXMgU2hhcGUgb2YgdGhlIFRlbnNvciB0byBiZSBzcGxpdHRlZCBpbnRvIHR3byBvciBtb3JlIFNoYXBlc1xuICAgKiBAcGFyYW0gYXhpcyBUaGUgZGltZW5zaW9uIGFsb25nIHdoaWNoIHRoZSBUZW5zb3Igd2lsbCBiZSBzcGxpdFxuICAgKiBAcGFyYW0gc3BsaXRzIE9mZnNldHMgZm9yIHRoZSBzdGFydCBvZiBlYWNoIHNwbGl0XG4gICAqL1xuICBzdGF0aWMgc3BsaXRTaGFwZShcbiAgICBkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBheGlzOiBudW1iZXIsXG4gICAgc3BsaXQ6IG51bWJlcltdLFxuICAgIG51bU91dHB1dHM/OiBudW1iZXIsXG4gICk6IFtudW1iZXJbXVtdLCBudW1iZXJbXV0ge1xuICAgIGlmIChzcGxpdC5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmICghbnVtT3V0cHV0cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJuZWVkIHRvIGtub3cgbnVtYmVyIG9mIG91dHB1dHMgd2hlbiB0aGUgJ3NwbGl0JyBhdHRyaWJ1dGUgaXMgbm90IHNwZWNpZmllZFwiKTtcbiAgICAgIH1cbiAgICAgIFNwbGl0VXRpbC5kZXRlcm1pbmVTcGxpdChkaW1zW2F4aXNdLCBudW1PdXRwdXRzLCBzcGxpdCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2hhcGVzOiBudW1iZXJbXVtdID0gW107XG4gICAgY29uc3Qgb2Zmc2V0cyA9IFswXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNwbGl0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAoaSAhPT0gMCkge1xuICAgICAgICBvZmZzZXRzLnB1c2gob2Zmc2V0c1tpIC0gMV0gKyBzcGxpdFtpIC0gMV0pO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2hhcGUgPSBkaW1zLnNsaWNlKCk7XG4gICAgICBzaGFwZVtheGlzXSA9IHNwbGl0W2ldO1xuICAgICAgc2hhcGVzLnB1c2goc2hhcGUpO1xuICAgIH1cbiAgICByZXR1cm4gW3NoYXBlcywgb2Zmc2V0c107XG4gIH1cblxuICBzdGF0aWMgZGV0ZXJtaW5lU3BsaXQobnVtRWxlbWVudHNBbG9uZ0F4aXM6IG51bWJlciwgbnVtT3V0cHV0czogbnVtYmVyLCBzcGxpdDogbnVtYmVyW10pIHtcbiAgICAvLyBJZiAnc3BsaXQnIGlzIG5vdCBzcGVjaWZpZWQgYnkgdGhlIHVzZXIsIHdlIG5lZWQgdG8gcGFydGl0aW9uIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgZXF1YWxseSBhbW9uZyB0aGUgb3V0cHV0c1xuICAgIGlmIChudW1FbGVtZW50c0Fsb25nQXhpcyAlIG51bU91dHB1dHMgIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IHNwbGl0IHRlbnNvciB0byBlcXVhbCBzaXplZCBwYXJ0cycpO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bU91dHB1dHM7ICsraSkge1xuICAgICAgc3BsaXQucHVzaChudW1FbGVtZW50c0Fsb25nQXhpcyAvIG51bU91dHB1dHMpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUmVkdWNlVXRpbCB7XG4gIC8qKlxuICAgKiBQZXJmb3JtIHJlZHVjZSBvcGVyYXRpb25zIG9uIHRoZSBzcGVjaWZpYyBvcGVyYXRvclxuICAgKiBAcGFyYW0gYSBJbnB1dCB0ZW5zb3IgZGF0YVxuICAgKiBAcGFyYW0gYXhlcyBUaGUgZGltZW5zaW9ucyBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0ga2VlcGRpbXMgSWYgc2V0IHRvIHRydWUsIHRoZSBheGVzIHdoaWNoIGFyZSByZWR1Y2VkIGFyZSBsZWZ0IGluIHRoZVxuICAgKiAgICByZXN1bHQgYXMgZGltZW5zaW9ucyB3aXRoIHNpemUgb25lLlxuICAgKiBAcGFyYW0gb3AxIFRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkIG9uIGVhY2ggZWxlbWVudCBpbiB0aGUgdGVuc29yXG4gICAqIEBwYXJhbSBvcDIgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgYmV0d2VlbiBlbGVtZW50cyBpbiB0aGUgdGVuc29yXG4gICAqL1xuICBzdGF0aWMgY2FsY1JlZHVjZShcbiAgICBhOiBUZW5zb3IsXG4gICAgYXhlczogbnVtYmVyW10sXG4gICAga2VlcGRpbXM6IGJvb2xlYW4sXG4gICAgb3AxOiAoYjogbnVtYmVyKSA9PiBudW1iZXIsXG4gICAgb3AyOiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IG51bWJlcixcbiAgKTogVGVuc29yIHtcbiAgICBjb25zdCBkaW1zID0gYS5kaW1zLnNsaWNlKDApO1xuICAgIC8vIGlmIGF4ZXMgaXMgbm90IHNldCwgcGVyZm9ybSByZWR1Y2Ugb24gYWxsIGF4ZXNcbiAgICBpZiAoYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGRpbXMuZm9yRWFjaCgoX2QsIGluZCkgPT4gYXhlcy5wdXNoKGluZCkpO1xuICAgIH1cbiAgICAvLyBnZXQgYSB0ZW1wb3JhcnkgYnJvYWRjYXN0YWJsZSBvdXRwdXQgc2hhcGVcbiAgICBjb25zdCBvdXRwdXREaW1zID0gUmVkdWNlVXRpbC5jYWxjUmVkdWNlU2hhcGUoZGltcywgYXhlcywgdHJ1ZSk7XG5cbiAgICAvLyBsb29wIHRocm91Z2ggdGhlIG91dHB1dCBhbmQgY2FsY3VsYXRlIHJlc3VsdCBvbmUgYnkgb25lXG4gICAgY29uc3Qgc2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dERpbXMpO1xuICAgIGNvbnN0IHkgPSBuZXcgVGVuc29yKG91dHB1dERpbXMsIGEudHlwZSk7XG4gICAgY29uc3Qgc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhvdXRwdXREaW1zKTtcbiAgICBjb25zdCBpbnB1dFN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoZGltcyk7XG4gICAgY29uc3QgaW5kaWNlc1kgPSBuZXcgQXJyYXkoZGltcy5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRpY2VzID0gU2hhcGVVdGlsLm9mZnNldFRvSW5kaWNlcyhpLCBzdHJpZGVzKTtcbiAgICAgIC8vIG1hcCBpbmRleFxuICAgICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgoaW5kaWNlcywgZGltcywgaW5kaWNlc1kpO1xuICAgICAgeS5zZXQoXG4gICAgICAgIGluZGljZXMsXG4gICAgICAgIFJlZHVjZVV0aWwuY2FsY1JlZHVjZUJ5QXhpcyhcbiAgICAgICAgICBhLm51bWJlckRhdGEsXG4gICAgICAgICAgYXhlcyxcbiAgICAgICAgICBkaW1zLFxuICAgICAgICAgIDAsXG4gICAgICAgICAgU2hhcGVVdGlsLmluZGljZXNUb09mZnNldChpbmRpY2VzWSwgaW5wdXRTdHJpZGVzKSxcbiAgICAgICAgICBvcDEsXG4gICAgICAgICAgb3AyLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoa2VlcGRpbXMpIHtcbiAgICAgIHJldHVybiB5O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBrZWVwZGltcyA9PSAwLCBjYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlXG4gICAgICByZXR1cm4gbmV3IFRlbnNvcihcbiAgICAgICAgUmVkdWNlVXRpbC5jYWxjUmVkdWNlU2hhcGUoZGltcywgYXhlcywga2VlcGRpbXMpLFxuICAgICAgICB5LnR5cGUsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICB5LmRhdGEsXG4gICAgICAgIHkuZGF0YUlkLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSByZWR1Y2Ugb3BlcmF0aW9ucyBvbiB0aGUgc3BlY2lmaWMgb3BlcmF0b3Igb24gc3BlY2lmaWMgYXhlc1xuICAgKiBAcGFyYW0gYSBJbnB1dCB0ZW5zb3IgZGF0YVxuICAgKiBAcGFyYW0gYXhlcyBUaGUgZGltZW5zaW9ucyBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0gZGltcyBUaGUgaW5wdXQgZGltZW5zaW9uLlxuICAgKiBAcGFyYW0gY3VyQXhpc0luZCBJbmRleCBpbiBheGVzIHNwZWNpZnlpbmcgdGhlIGN1cnJlbnQgZGltZW5zaW9uIGFsb25nXG4gICAqICAgICAgd2hpY2ggdGhlIHRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIHBvcyBUaGUgY3VycmVudCBpbmRleCBvZiBlbGVtZW50IHRvIHBlcmZvcm0gb3BlcmF0aW9uXG4gICAqIEBwYXJhbSBvcDEgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgb24gZWFjaCBlbGVtZW50IGluIHRoZSB0ZW5zb3JcbiAgICogQHBhcmFtIG9wMiBUaGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZCBiZXR3ZWVuIGVsZW1lbnRzIGluIHRoZSB0ZW5zb3JcbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlQnlBeGlzKFxuICAgIGlucHV0OiBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBheGVzOiBudW1iZXJbXSxcbiAgICBkaW1zOiBudW1iZXJbXSxcbiAgICBjdXJBeGlzSW5kOiBudW1iZXIsXG4gICAgcG9zOiBudW1iZXIsXG4gICAgb3AxOiAoYjogbnVtYmVyKSA9PiBudW1iZXIsXG4gICAgb3AyOiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IG51bWJlcixcbiAgKTogbnVtYmVyIHtcbiAgICBsZXQgcmVzID0gMDtcbiAgICBpZiAoY3VyQXhpc0luZCA+PSBheGVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIG9wMShpbnB1dFtwb3NdKTtcbiAgICB9XG4gICAgY29uc3QgYXhpcyA9IGF4ZXNbY3VyQXhpc0luZF07XG4gICAgY29uc3Qgc3RlcCA9IGF4aXMgPj0gZGltcy5sZW5ndGggPyAxIDogU2hhcGVVdGlsLnNpemUoZGltcy5zbGljZShheGlzICsgMSkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGltc1theGlzXTsgaSsrKSB7XG4gICAgICByZXMgPVxuICAgICAgICBpID09PSAwXG4gICAgICAgICAgPyBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VCeUF4aXMoaW5wdXQsIGF4ZXMsIGRpbXMsIGN1ckF4aXNJbmQgKyAxLCBwb3MsIG9wMSwgb3AyKVxuICAgICAgICAgIDogb3AyKHJlcywgUmVkdWNlVXRpbC5jYWxjUmVkdWNlQnlBeGlzKGlucHV0LCBheGVzLCBkaW1zLCBjdXJBeGlzSW5kICsgMSwgcG9zLCBvcDEsIG9wMikpO1xuICAgICAgcG9zICs9IHN0ZXA7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZSBvZiBhIHJlZHVjZSBvcGVyYXRpb25cbiAgICogQHBhcmFtIGRpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb25cbiAgICogQHBhcmFtIGF4ZXMgVGhlIGRpbWVuc2lvbnMgYWxvbmcgd2hpY2ggdGhlIFRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIGtlZXBkaW1zIElmIHNldCB0byB0cnVlLCB0aGUgYXhlcyB3aGljaCBhcmUgcmVkdWNlZCBhcmUgbGVmdCBpbiB0aGVcbiAgICogICAgcmVzdWx0IGFzIGRpbWVuc2lvbnMgd2l0aCBzaXplIG9uZS5cbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdLCBrZWVwRGltczogYm9vbGVhbik6IG51bWJlcltdIHtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gZGltcy5zbGljZSgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGtlZXBEaW1zKSB7XG4gICAgICAgIG91dHB1dERpbXNbYXhlc1tpXV0gPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0RGltc1theGVzW2ldXSA9IDA7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXREaW1zLmZpbHRlcigoZGltKSA9PiBkaW0gIT09IDApO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQb29sQ29udlV0aWwge1xuICAvKipcbiAgICogQWRqdXN0IHRoZSBrZXJuZWwsIHN0cmlkZXMsIHBhZHMgdG8gY29ycmVjdCByYW5rLiBTZXQgdG8gZGVmYXVsdCB2YWx1ZSBpZiBub3QgcHJlc2VudFxuICAgKiBAcGFyYW0gaXNHbG9iYWxPcGVyYXRvciBJZiB0cnVlLCBwZXJmb3JtIGdsb2JhbCBwb29saW5nLlxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBkaWxhdGlvbnMgRGlsYXRpb24gYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKi9cbiAgc3RhdGljIGFkanVzdFBvb2xBdHRyaWJ1dGVzKFxuICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sXG4gICAgc3RyaWRlczogbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgKSB7XG4gICAgaWYgKCFpc0dsb2JhbE9wZXJhdG9yICYmIGtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHNwZWNpZmllZCBrZXJuZWwgc2hhcGVzIHNob3VsZCBiZSAyIGxlc3MgdGhhbiBsZW5ndGggb2YgaW5wdXQgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChpc0dsb2JhbE9wZXJhdG9yKSB7XG4gICAgICAvLyBhZGp1c3Qga2VybmVsIHNoYXBlIHRvIGNvdmVyIHRoZSBpbnB1dCBkaW1zXG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgaWYgKGRpbSA+PSBrZXJuZWxTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0RGltc1tkaW0gKyAyXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2VybmVsU2hhcGVbZGltXSA9IGlucHV0RGltc1tkaW0gKyAyXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkanVzdCBzdHJpZGVzIGxlbmd0aCB0byBtYXRjaCBrZXJuZWwgc2hhcGUgbGVuZ3RoXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IHN0cmlkZXMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChzdHJpZGVzW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpZGVzIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJpZGVzLnB1c2goMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRqdXN0IGRpbGF0aW9uIHZhbHVlXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IGRpbGF0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGRpbGF0aW9uc1tkaW1dIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZGlsYXRpb25zIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaWxhdGlvbnMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGp1c3QgcGFkcyBsZW5ndGggdG8gbWF0Y2ggMiAqIGtlcm5lbCBzaGFwZSBsZW5ndGhcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGggKiAyOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IHBhZHMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChwYWRzW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYWQgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhZHMucHVzaCgwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzYW5pdHkgY2hlY2tzIGZvciB2YWx1ZXMgaW4ga2VybmVsIHNoYXBlcyBhbmQgcGFkc1xuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aDsgZGltKyspIHtcbiAgICAgIGlmIChrZXJuZWxTaGFwZVtkaW1dIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZXJuZWwgc2hhcGVzIG5lZWQgdG8gYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhZHNbZGltXSA+PSBrZXJuZWxTaGFwZVtkaW1dIHx8IHBhZHNbZGltICsga2VybmVsU2hhcGUubGVuZ3RoXSA+PSBrZXJuZWxTaGFwZVtkaW1dKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncGFkcyBzaG91bGQgYmUgc21hbGxlciB0aGFuIGtlcm5lbCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGFkanVzdCBwYWQgdmFsdWVzIGJhc2VkIG9uICdhdXRvUGFkJyBhdHRyaWJ1dGVcbiAgc3RhdGljIGFkanVzdFBhZHNCYXNlZE9uQXV0b1BhZChcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICkge1xuICAgIGlmICghYXV0b1BhZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYWRzLmxlbmd0aCAhPT0gMiAqIChpbnB1dERpbXMubGVuZ3RoIC0gMikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHBhZHMgc2hvdWxkIGJlIHR3aWNlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKHN0cmlkZXMubGVuZ3RoICE9PSBpbnB1dERpbXMubGVuZ3RoIC0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Ygc3RyaWRlcyBzaG91bGQgYmUgdGhlIGxlbmd0aCBvZiBkYXRhIGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAoa2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dERpbXMubGVuZ3RoIC0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Yga2VybmVsIHNoYXBlcyBzaG91bGQgYmUgdGhlIGxlbmd0aCBvZiBkYXRhIGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgIFBvb2xDb252VXRpbC5hZGp1c3RQYWRBbmRSZXR1cm5TaGFwZShcbiAgICAgICAgaW5wdXREaW1zW2RpbSArIDJdLFxuICAgICAgICBzdHJpZGVzW2RpbV0sXG4gICAgICAgIGRpbGF0aW9uc1tkaW1dLFxuICAgICAgICBrZXJuZWxTaGFwZVtkaW1dLFxuICAgICAgICBwYWRzLFxuICAgICAgICBkaW0sXG4gICAgICAgIGRpbSArIGlucHV0RGltcy5sZW5ndGggLSAyLFxuICAgICAgICBhdXRvUGFkLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBvdXRwdXQgc2hhcGUgZm9yIFBvb2wgb3BzIGJhc2VkIG9uIGlucHV0IGF0dHJpYnV0ZXMuIChTaG91bGQgYmUgdXNlZCBvbmx5IGZvciBQb29sIG9wcylcbiAgICogQHBhcmFtIGlzR2xvYmFsT3BlcmF0b3IgSWYgdHJ1ZSwgcGVyZm9ybSBnbG9iYWwgcG9vbGluZy5cbiAgICogQHBhcmFtIGlucHV0RGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1swXS5kaW1zKVxuICAgKiBAcGFyYW0gc3RyaWRlcyBTdHJpZGUgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gZGlsYXRpb25zIERpbGF0aW9uIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGtlcm5lbFNoYXBlIFRoZSBzaXplIG9mIHRoZSBrZXJuZWwgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gYXV0b1BhZCBERVBSRUNBVEVEIGF0dHJpYnV0ZSBzdXBwb3J0ZWQgZm9yIGxlZ2FjeSBtb2RlbHMuIFNwZWNpZmllcyBob3cgdG8gaW1wbGljaXRseSBjYWxjdWxhdGUgcGFkcyBpbiBlYWNoXG4gICAqICAgICBkaW1lbnNpb24uIENhbiB0YWtlIHZhbHVlcyBOT1RTRVQsIFNBTUVfVVBQRVIsIFNBTUVfTE9XRVIsIG9yIFZBTElELlxuICAgKiBAcGFyYW0gY2VpbE1vZGUgV2hlbiBzZXQgdG8gMSwgdXNlIGNlaWwoKSBpbnN0ZWFkIG9mIGZsb29yKCkgdG8gY29tcHV0ZSB0aGUgb3V0cHV0IHNwYXRpYWwgc2l6ZSAoYW5kIGFwcGx5IHRoZVxuICAgKiAgICAgXCJzaHJpbmsgdGhlIGxhc3Qgd2luZG93IGlmIGl0IHN0YXJ0cyBlbnRpcmVseSBpbiBwYWRkaW5nXCIgcnVsZSkuIERlZmF1bHRzIHRvIDAgKGZsb29yKS5cbiAgICovXG4gIHN0YXRpYyBjb21wdXRlUG9vbE91dHB1dFNoYXBlKFxuICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICAgIGNlaWxNb2RlID0gMCxcbiAgKTogbnVtYmVyW10ge1xuICAgIGlmIChpbnB1dERpbXMubGVuZ3RoIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hhcGUgbXVzdCBiZSBvZiBzaXplIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJhdGNoIHNpemUgYW5kIG51bWJlciBvZiBjaGFubmVscyBvZiBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW2lucHV0RGltc1swXSwgaW5wdXREaW1zWzFdXTtcblxuICAgIFBvb2xDb252VXRpbC5jb21wdXRlU2hhcGVIZWxwZXIoXG4gICAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICAgICAgaW5wdXREaW1zLFxuICAgICAgb3V0cHV0RGltcyxcbiAgICAgIHN0cmlkZXMsXG4gICAgICBkaWxhdGlvbnMsXG4gICAgICBrZXJuZWxTaGFwZSxcbiAgICAgIHBhZHMsXG4gICAgICBhdXRvUGFkLFxuICAgICAgY2VpbE1vZGUsXG4gICAgKTtcbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIG91dHB1dCBzaGFwZSBmb3IgQ29udiBvcCBiYXNlZCBvbiBpbnB1dCBhdHRyaWJ1dGVzLiAoU2hvdWxkIGJlIHVzZWQgb25seSBmb3IgQ29udiBvcClcbiAgICogQHBhcmFtIGlucHV0RGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1swXS5kaW1zKVxuICAgKiBAcGFyYW0gZmlsdGVyRGltcyBUaGUgZmlsdGVyIHRlbnNvciBkaW1lbnNpb24uIChpbnB1dHNbMV0uZGltcylcbiAgICogQHBhcmFtIHN0cmlkZXMgU3RyaWRlIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGtlcm5lbFNoYXBlIFRoZSBzaXplIG9mIHRoZSBrZXJuZWwgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gYXV0b1BhZCBERVBSRUNBVEVEIGF0dHJpYnV0ZSBzdXBwb3J0ZWQgZm9yIGxlZ2FjeSBtb2RlbHMuIFNwZWNpZmllcyBob3cgdG8gaW1wbGljaXRseSBjYWxjdWxhdGUgcGFkcyBpbiBlYWNoXG4gICAqICAgICBkaW1lbnNpb24uIENhbiB0YWtlIHZhbHVlcyBOT1RTRVQsIFNBTUVfVVBQRVIsIFNBTUVfTE9XRVIsIG9yIFZBTElELlxuICAgKi9cbiAgc3RhdGljIGNvbXB1dGVDb252T3V0cHV0U2hhcGUoXG4gICAgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBmaWx0ZXJEaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiBudW1iZXJbXSxcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApOiBudW1iZXJbXSB7XG4gICAgaWYgKGlucHV0RGltcy5sZW5ndGggPD0gMCB8fCBmaWx0ZXJEaW1zLmxlbmd0aCA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgdGVuc29yIGRpbXMgb3IgaW52YWxpZCBmaWx0ZXIgdGVuc29yIGRpbXMnKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgYmF0Y2ggc2l6ZSBhbmQgbnVtYmVyIG9mIGNoYW5uZWxzIG9mIG91dHB1dFxuICAgIGNvbnN0IG91dHB1dERpbXMgPSBbaW5wdXREaW1zWzBdLCBmaWx0ZXJEaW1zWzBdXTtcblxuICAgIFBvb2xDb252VXRpbC5jb21wdXRlU2hhcGVIZWxwZXIoZmFsc2UsIGlucHV0RGltcywgb3V0cHV0RGltcywgc3RyaWRlcywgZGlsYXRpb25zLCBrZXJuZWxTaGFwZSwgcGFkcywgYXV0b1BhZCk7XG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvLyB3aWxsIGNvbXB1dGUgb3V0cHV0IHNoYXBlcyBmb3IgZGF0YSBkaW1lbnNpb25zIE9OTFkgKGkuZS4pIG5vIGJhdGNoIHNpemUgYW5kIGNoYW5uZWxzXG4gIC8vIGNhbGxlZCBieSBjb21wdXRlUG9vbE91dHB1dFNoYXBlKCkgYW5kIGNvbXB1dGVDb252T3V0cHV0U2hhcGUoKVxuICAvLyBhZGp1c3QgcGFkcyBiYXNlZCBvbiAnYXV0b1BhZCcgYXR0cmlidXRlIHByaW9yIHRvIHNoYXBlIGNvbXB1dGF0aW9uXG4gIHByaXZhdGUgc3RhdGljIGNvbXB1dGVTaGFwZUhlbHBlcihcbiAgICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgb3V0cHV0RGltczogbnVtYmVyW10sXG4gICAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgICBjZWlsTW9kZSA9IDAsXG4gICkge1xuICAgIGlmIChpc0dsb2JhbE9wZXJhdG9yKSB7XG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKDEpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKFxuICAgICAgICAgIFBvb2xDb252VXRpbC5hZGp1c3RQYWRBbmRSZXR1cm5TaGFwZShcbiAgICAgICAgICAgIGlucHV0RGltc1tkaW0gKyAyXSxcbiAgICAgICAgICAgIHN0cmlkZXNbZGltXSxcbiAgICAgICAgICAgIGRpbGF0aW9uc1tkaW1dLFxuICAgICAgICAgICAga2VybmVsU2hhcGVbZGltXSxcbiAgICAgICAgICAgIHBhZHMsXG4gICAgICAgICAgICBkaW0sXG4gICAgICAgICAgICBkaW0gKyBpbnB1dERpbXMubGVuZ3RoIC0gMixcbiAgICAgICAgICAgIGF1dG9QYWQsXG4gICAgICAgICAgICBjZWlsTW9kZSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIENvbXB1dGVzIHRoZSBvdXRwdXQgc3BhdGlhbCBzaXplIGZvciBhIHNpbmdsZSBkaW1lbnNpb24uXG4gIC8vIFByb2R1Y2VzIHJlc3VsdHMgaWRlbnRpY2FsIHRvIHRoZSBDKysgUG9vbEF0dHJpYnV0ZXM6OkNvbXB1dGVPdXRwdXRTaXplXG4gIC8vIChvbm54cnVudGltZS9jb3JlL3Byb3ZpZGVycy9jcHUvbm4vcG9vbF9hdHRyaWJ1dGVzLmgpLCBpbmNsdWRpbmcgdGhlIGNlaWxfbW9kZVxuICAvLyBcInNocmluayB0aGUgbGFzdCB3aW5kb3cgaWYgaXQgc3RhcnRzIGVudGlyZWx5IGluIHRoZSB0cmFpbGluZyBwYWRkaW5nXCIgcnVsZS4gVGhlIEpTXG4gIC8vIHNpZ25hdHVyZSB0YWtlcyBhIHByZS1jb21wdXRlZCBgbnVtZXJhdG9yYCAoZXF1YWwgdG8gYGluU2l6ZSArIHBhZEhlYWQgKyBwYWRUYWlsIC0gZGtlcm5lbGAsXG4gIC8vIG1hdGNoaW5nIHRoZSBDKysgYGluX3NpemUgKyBwYWRfaGVhZCArIHBhZF90YWlsIC0gZGlsYXRpb24gKiAoa2VybmVsIC0gMSkgLSAxYCkgaW5zdGVhZCBvZlxuICAvLyB0aGUgcmF3IHBvb2xpbmcgYXR0cmlidXRlcywgYnV0IHRoZSBjb21wdXRlZCBvdXRwdXQgc2l6ZSBpcyB0aGUgc2FtZS5cbiAgLy8gS2VlcCBpbiBzeW5jIHdpdGggdGhlIG9ubnhqcy9qc2VwIGNvcHkuXG4gIC8vIE5PVEU6IEluIHRoaXMgb25ueGpzIGNvcHkgdGhlIGNlaWxNb2RlIHBhdGggZXhpc3RzIGZvciBzaGFwZS10ZXN0IHBhcml0eSB3aXRoIHRoZSBqc2VwIGNvcHk7XG4gIC8vIHRoZSBvbm54anMgV2ViR0wgcG9vbGluZyBjYWxsZXIgKGJhY2tlbmRzL3dlYmdsL29wcy9wb29sLnRzKSBpbnRlbnRpb25hbGx5IGRvZXMgTk9UIHBhc3NcbiAgLy8gY2VpbE1vZGUgKGxlZ2FjeSBwYXRoIHN0aWxsIHRocm93cyBvbiBjZWlsX21vZGUgIT0gMCksIHNvIGl0IGFsd2F5cyB1c2VzIHRoZSBmbG9vciBkZWZhdWx0LlxuICBwcml2YXRlIHN0YXRpYyBjb21wdXRlT3V0cHV0U2l6ZShcbiAgICBudW1lcmF0b3I6IG51bWJlcixcbiAgICBzdHJpZGU6IG51bWJlcixcbiAgICBpblNpemU6IG51bWJlcixcbiAgICBwYWRIZWFkOiBudW1iZXIsXG4gICAgY2VpbE1vZGU6IG51bWJlcixcbiAgKTogbnVtYmVyIHtcbiAgICBsZXQgb3V0U2l6ZSA9IE1hdGguZmxvb3IobnVtZXJhdG9yIC8gc3RyaWRlKSArIDE7XG4gICAgLy8gTWF0Y2ggQysrIGBjZWlsX21vZGUgPT0gMWAgZXhhY3RseSBzbyBvdXQtb2Ytc3BlYyBjZWlsX21vZGUgdmFsdWVzIGRvIG5vdCBkaXZlcmdlLlxuICAgIGlmIChjZWlsTW9kZSA9PT0gMSkge1xuICAgICAgb3V0U2l6ZSA9IE1hdGguY2VpbChudW1lcmF0b3IgLyBzdHJpZGUpICsgMTtcbiAgICAgIC8vIEVuc3VyZSB0aGUgbGFzdCBwb29saW5nIHdpbmRvdyBzdGFydHMgaW5zaWRlIHRoZSBpbWFnZSAocmVmOiBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L3B1bGwvNTc0MSkuXG4gICAgICAvLyBpblNpemUgYW5kIHBhZEhlYWQgYXJlIG5lZWRlZCBoZXJlIHRvIHJlY29uc3RydWN0IHRoZSBsYXN0IHdpbmRvdydzIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAgaWYgKChvdXRTaXplIC0gMSkgKiBzdHJpZGUgPj0gaW5TaXplICsgcGFkSGVhZCkge1xuICAgICAgICBvdXRTaXplIC09IDE7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXRTaXplO1xuICB9XG5cbiAgLy8gaGVscGVyIGZvciBjb21wdXRlU2hhcGVIZWxwZXIoKSBhbmQgYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKClcbiAgLy8gYWRqdXN0cyBwYWQgdmFsdWUgZm9yIGdpdmVuICdhdXRvUGFkJyBzdHJpbmcgYW5kIGNvbXB1dGVzIG91dHB1dCBzaGFwZSBhbG9uZyBhIHBhcnRpY3VsYXIgZGltZW5zaW9uXG4gIHByaXZhdGUgc3RhdGljIGFkanVzdFBhZEFuZFJldHVyblNoYXBlKFxuICAgIGluU2l6ZTogbnVtYmVyLFxuICAgIHN0cmlkZTogbnVtYmVyLFxuICAgIGRpbGF0aW9uOiBudW1iZXIsXG4gICAga2VybmVsOiBudW1iZXIsXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgcGFkSGVhZEluZGV4OiBudW1iZXIsXG4gICAgcGFkVGFpbEluZGV4OiBudW1iZXIsXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgICBjZWlsTW9kZSA9IDAsXG4gICk6IG51bWJlciB7XG4gICAgY29uc3QgZGtlcm5lbCA9IGRpbGF0aW9uICogKGtlcm5lbCAtIDEpICsgMTtcbiAgICBpZiAoYXV0b1BhZCAmJiBhdXRvUGFkICE9PSAnTk9UU0VUJykge1xuICAgICAgc3dpdGNoIChhdXRvUGFkKSB7XG4gICAgICAgIGNhc2UgJ1ZBTElEJzpcbiAgICAgICAgICBwYWRzW3BhZEhlYWRJbmRleF0gPSAwO1xuICAgICAgICAgIHBhZHNbcGFkVGFpbEluZGV4XSA9IDA7XG4gICAgICAgICAgcmV0dXJuIFBvb2xDb252VXRpbC5jb21wdXRlT3V0cHV0U2l6ZShpblNpemUgLSBka2VybmVsLCBzdHJpZGUsIGluU2l6ZSwgMCwgY2VpbE1vZGUpO1xuICAgICAgICBjYXNlICdTQU1FX0xPV0VSJzpcbiAgICAgICAgY2FzZSAnU0FNRV9VUFBFUic6XG4gICAgICAgICAgaWYgKGRpbGF0aW9uICE9PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbGF0aW9uIG5vdCBzdXBwb3J0ZWQgZm9yIFNBTUVfVVBQRVIgb3IgU0FNRV9MT1dFUicpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBJbnRlZ2VyIGRpdmlzaW9uIHRvIG1hdGNoIEMrKyBwb29sX2F0dHJpYnV0ZXMuaCBDb21wdXRlU2l6ZVBhZERpbGF0aW9uczsgZmxvYXQgZGl2aXNpb24gbWlzLXJvdW5kcyBTQU1FXyogcGFkcy5cbiAgICAgICAgICAgIGNvbnN0IGxlZ2FjeVRhcmdldFNpemUgPSBNYXRoLmZsb29yKChpblNpemUgKyBzdHJpZGUgLSAxKSAvIHN0cmlkZSk7XG4gICAgICAgICAgICBjb25zdCBwYWROZWVkZWQgPSAobGVnYWN5VGFyZ2V0U2l6ZSAtIDEpICogc3RyaWRlICsga2VybmVsIC0gaW5TaXplO1xuICAgICAgICAgICAgcGFkc1twYWRIZWFkSW5kZXhdID0gYXV0b1BhZCA9PT0gJ1NBTUVfTE9XRVInID8gTWF0aC5mbG9vcigocGFkTmVlZGVkICsgMSkgLyAyKSA6IE1hdGguZmxvb3IocGFkTmVlZGVkIC8gMik7XG4gICAgICAgICAgICBwYWRzW3BhZFRhaWxJbmRleF0gPSBwYWROZWVkZWQgLSBwYWRzW3BhZEhlYWRJbmRleF07XG4gICAgICAgICAgICByZXR1cm4gUG9vbENvbnZVdGlsLmNvbXB1dGVPdXRwdXRTaXplKFxuICAgICAgICAgICAgICBpblNpemUgKyBwYWRzW3BhZEhlYWRJbmRleF0gKyBwYWRzW3BhZFRhaWxJbmRleF0gLSBka2VybmVsLFxuICAgICAgICAgICAgICBzdHJpZGUsXG4gICAgICAgICAgICAgIGluU2l6ZSxcbiAgICAgICAgICAgICAgcGFkc1twYWRIZWFkSW5kZXhdLFxuICAgICAgICAgICAgICBjZWlsTW9kZSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgQXV0b1BhZCB0eXBlJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBQb29sQ29udlV0aWwuY29tcHV0ZU91dHB1dFNpemUoXG4gICAgICAgIGluU2l6ZSArIHBhZHNbcGFkSGVhZEluZGV4XSArIHBhZHNbcGFkVGFpbEluZGV4XSAtIGRrZXJuZWwsXG4gICAgICAgIHN0cmlkZSxcbiAgICAgICAgaW5TaXplLFxuICAgICAgICBwYWRzW3BhZEhlYWRJbmRleF0sXG4gICAgICAgIGNlaWxNb2RlLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IE1JTl9DTElQID0gLTMuNDAyODIzNDY2Mzg1Mjg4NmUzODtcbmV4cG9ydCBjb25zdCBNQVhfQ0xJUCA9IDMuNDAyODIzNDY2Mzg1Mjg4NmUzODtcblxuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVV0ZjhTdHJpbmcoYnVmZmVyOiBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShidWZmZXIpO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHdWlkIH0gZnJvbSAnZ3VpZC10eXBlc2NyaXB0JztcbmltcG9ydCBMb25nIGZyb20gJ2xvbmcnO1xuXG5pbXBvcnQgKiBhcyBvcnRGYnMgZnJvbSAnLi9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ydC1nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgb25ueCB9IGZyb20gJy4vb3J0LXNjaGVtYS9wcm90b2J1Zi9vbm54JztcbmltcG9ydCB7IGRlY29kZVV0ZjhTdHJpbmcsIFByb3RvVXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFRlbnNvciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgRGF0YVR5cGVNYXAge1xuICAgIGJvb2w6IFVpbnQ4QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuICAgIGZsb2F0NjQ6IEZsb2F0NjRBcnJheTtcbiAgICBzdHJpbmc6IHN0cmluZ1tdO1xuICAgIGludDg6IEludDhBcnJheTtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcbiAgICB1aW50MTY6IFVpbnQxNkFycmF5O1xuICAgIGludDMyOiBJbnQzMkFycmF5O1xuICAgIHVpbnQzMjogVWludDMyQXJyYXk7XG4gICAgaW50NjQ6IEJpZ0ludDY0QXJyYXk7XG4gIH1cblxuICBleHBvcnQgdHlwZSBEYXRhVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xuXG4gIGV4cG9ydCB0eXBlIFN0cmluZ1R5cGUgPSBUZW5zb3IuRGF0YVR5cGVNYXBbJ3N0cmluZyddO1xuICBleHBvcnQgdHlwZSBCb29sZWFuVHlwZSA9IFRlbnNvci5EYXRhVHlwZU1hcFsnYm9vbCddO1xuICBleHBvcnQgdHlwZSBJbnRlZ2VyVHlwZSA9XG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ2ludDgnXVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWyd1aW50OCddXG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ2ludDE2J11cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsndWludDE2J11cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsnaW50MzInXVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWyd1aW50MzInXTtcbiAgZXhwb3J0IHR5cGUgRmxvYXRUeXBlID0gVGVuc29yLkRhdGFUeXBlTWFwWydmbG9hdDMyJ10gfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ2Zsb2F0NjQnXTtcbiAgZXhwb3J0IHR5cGUgTnVtYmVyVHlwZSA9IEJvb2xlYW5UeXBlIHwgSW50ZWdlclR5cGUgfCBGbG9hdFR5cGU7XG5cbiAgZXhwb3J0IHR5cGUgSWQgPSBHdWlkO1xufVxuXG50eXBlIFRlbnNvckRhdGEgPSBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXTtcblxudHlwZSBEYXRhUHJvdmlkZXIgPSAoaWQ6IFRlbnNvci5JZCkgPT4gVGVuc29yRGF0YTtcbnR5cGUgQXN5bmNEYXRhUHJvdmlkZXIgPSAoaWQ6IFRlbnNvci5JZCkgPT4gUHJvbWlzZTxUZW5zb3JEYXRhPjtcblxuZXhwb3J0IGNsYXNzIFRlbnNvciB7XG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgdGVuc29yIGRhdGFcbiAgICovXG4gIGdldCBkYXRhKCk6IFRlbnNvckRhdGEge1xuICAgIGlmICh0aGlzLmNhY2hlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGFQcm92aWRlciEodGhpcy5kYXRhSWQpO1xuICAgICAgaWYgKGRhdGEubGVuZ3RoICE9PSB0aGlzLnNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMZW5ndGggb2YgZGF0YSBwcm92aWRlZCBieSB0aGUgRGF0YSBQcm92aWRlciBpcyBpbmNvbnNpc3RlbnQgd2l0aCB0aGUgZGltcyBvZiB0aGlzIFRlbnNvci4nKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2FjaGUgPSBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgc3RyaW5nIHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIFNUUklOR1xuICAgKi9cbiAgZ2V0IHN0cmluZ0RhdGEoKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2RhdGEgdHlwZSBpcyBub3Qgc3RyaW5nJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuU3RyaW5nVHlwZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgaW50ZWdlciB0ZW5zb3IgZGF0YS4gU2hvdWxkIG9ubHkgdXNlIHdoZW4gdHlwZSBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzogKFVJTlQ4LCBJTlQ4LCBVSU5UMTYsXG4gICAqIElOVDE2LCBJTlQzMiwgVUlOVDMyLCBCT09MKVxuICAgKi9cbiAgZ2V0IGludGVnZXJEYXRhKCkge1xuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgY2FzZSAnYm9vbCc6XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEgYXMgVGVuc29yLkludGVnZXJUeXBlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIHR5cGUgaXMgbm90IGludGVnZXIgKHVpbnQ4LCBpbnQ4LCB1aW50MTYsIGludDE2LCBpbnQzMiwgdWludDMyLCBib29sKScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgZmxvYXQgdGVuc29yIGRhdGEuIFNob3VsZCBvbmx5IHVzZSB3aGVuIHR5cGUgaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6IChGTE9BVCwgRE9VQkxFKVxuICAgKi9cbiAgZ2V0IGZsb2F0RGF0YSgpIHtcbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuRmxvYXRUeXBlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIHR5cGUgaXMgbm90IGZsb2F0IChmbG9hdDMyLCBmbG9hdDY0KScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgbnVtYmVyIHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nOiAoVUlOVDgsIElOVDgsIFVJTlQxNixcbiAgICogSU5UMTYsIElOVDMyLCBVSU5UMzIsIEJPT0wsIEZMT0FULCBET1VCTEUpXG4gICAqL1xuICBnZXQgbnVtYmVyRGF0YSgpIHtcbiAgICBpZiAodGhpcy50eXBlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuTnVtYmVyVHlwZTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndHlwZSBjYW5ub3QgYmUgbm9uLW51bWJlciAoc3RyaW5nKScpO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB2YWx1ZSBvZiBhbiBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRpY2VzXG4gICAqL1xuICBnZXQoaW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXVtudW1iZXJdIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhW1NoYXBlVXRpbC5pbmRpY2VzVG9PZmZzZXQoaW5kaWNlcywgdGhpcy5zdHJpZGVzKV07XG4gIH1cblxuICAvKipcbiAgICogc2V0IHZhbHVlIG9mIGFuIGVsZW1lbnQgYXQgdGhlIGdpdmVuIGluZGljZXNcbiAgICovXG4gIHNldChpbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSwgdmFsdWU6IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdW251bWJlcl0pIHtcbiAgICB0aGlzLmRhdGFbU2hhcGVVdGlsLmluZGljZXNUb09mZnNldChpbmRpY2VzLCB0aGlzLnN0cmlkZXMpXSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyB0ZW5zb3IgZGF0YSBhc3luY2hyb25vdXNseVxuICAgKi9cbiAgYXN5bmMgZ2V0RGF0YSgpOiBQcm9taXNlPFRlbnNvckRhdGE+IHtcbiAgICBpZiAodGhpcy5jYWNoZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmNhY2hlID0gYXdhaXQgdGhpcy5hc3luY0RhdGFQcm92aWRlciEodGhpcy5kYXRhSWQpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgdGVuc29yXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2l6ZTogbnVtYmVyO1xuXG4gIHByaXZhdGUgX3N0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogZ2V0IHRoZSBzdHJpZGVzIGZvciBlYWNoIGRpbWVuc2lvblxuICAgKi9cbiAgZ2V0IHN0cmlkZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmICghdGhpcy5fc3RyaWRlcykge1xuICAgICAgdGhpcy5fc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyh0aGlzLmRpbXMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3RyaWRlcztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgICAqIGdldCB0aGUgZGltZW5zaW9ucyBvZiB0aGUgdGVuc29yXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIC8qKlxuICAgICAqIGdldCB0aGUgdHlwZSBvZiB0aGUgdGVuc29yXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHR5cGU6IFRlbnNvci5EYXRhVHlwZSxcbiAgICBwcml2YXRlIGRhdGFQcm92aWRlcj86IERhdGFQcm92aWRlcixcbiAgICBwcml2YXRlIGFzeW5jRGF0YVByb3ZpZGVyPzogQXN5bmNEYXRhUHJvdmlkZXIsXG4gICAgcHJpdmF0ZSBjYWNoZT86IFRlbnNvckRhdGEsXG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSBkYXRhIElEIHRoYXQgdXNlZCB0byBtYXAgdG8gYSB0ZW5zb3IgZGF0YVxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBkYXRhSWQ6IEd1aWQgPSBHdWlkLmNyZWF0ZSgpLFxuICApIHtcbiAgICB0aGlzLnNpemUgPSBTaGFwZVV0aWwudmFsaWRhdGVEaW1zQW5kQ2FsY1NpemUoZGltcyk7XG4gICAgY29uc3Qgc2l6ZSA9IHRoaXMuc2l6ZTtcbiAgICBjb25zdCBlbXB0eSA9IGRhdGFQcm92aWRlciA9PT0gdW5kZWZpbmVkICYmIGFzeW5jRGF0YVByb3ZpZGVyID09PSB1bmRlZmluZWQgJiYgY2FjaGUgPT09IHVuZGVmaW5lZDtcblxuICAgIGlmIChjYWNoZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoY2FjaGUubGVuZ3RoICE9PSBzaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW5wdXQgZGltcyBkb2Vzbid0IG1hdGNoIGRhdGEgbGVuZ3RoLlwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChjYWNoZSAhPT0gdW5kZWZpbmVkICYmICghQXJyYXkuaXNBcnJheShjYWNoZSkgfHwgIWNhY2hlLmV2ZXJ5KChpKSA9PiB0eXBlb2YgaSA9PT0gJ3N0cmluZycpKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjYWNoZSBzaG91bGQgYmUgYSBzdHJpbmcgYXJyYXknKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVtcHR5KSB7XG4gICAgICAgIHRoaXMuY2FjaGUgPSBuZXcgQXJyYXk8c3RyaW5nPihzaXplKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGNhY2hlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgY29uc3RydWN0b3IgPSBkYXRhdmlld0NvbnN0cnVjdG9yKHR5cGUpO1xuICAgICAgICBpZiAoIShjYWNoZSBpbnN0YW5jZW9mIGNvbnN0cnVjdG9yKSkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGNhY2hlIHNob3VsZCBiZSB0eXBlICR7Y29uc3RydWN0b3IubmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZW1wdHkpIHtcbiAgICAgICAgY29uc3QgYnVmID0gbmV3IEFycmF5QnVmZmVyKHNpemUgKiBzaXplb2YodHlwZSkpO1xuICAgICAgICB0aGlzLmNhY2hlID0gY3JlYXRlVmlldyhidWYsIHR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgbmV3IFRlbnNvciBmcm9tIGEgT05OWCBUZW5zb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB0ZW5zb3JQcm90byB0aGUgT05OWCBUZW5zb3JcbiAgICovXG4gIHN0YXRpYyBmcm9tUHJvdG8odGVuc29yUHJvdG86IG9ubnguSVRlbnNvclByb3RvKTogVGVuc29yIHtcbiAgICBpZiAoIXRlbnNvclByb3RvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBjb25zdHJ1Y3QgVmFsdWUgZnJvbSBhbiBlbXB0eSB0ZW5zb3InKTtcbiAgICB9XG4gICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byh0ZW5zb3JQcm90by5kYXRhVHlwZSEpO1xuICAgIGNvbnN0IGRpbXMgPSBQcm90b1V0aWwudGVuc29yRGltc0Zyb21Qcm90byh0ZW5zb3JQcm90by5kaW1zISk7XG5cbiAgICBjb25zdCB2YWx1ZSA9IG5ldyBUZW5zb3IoZGltcywgdHlwZSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFdoZW4gaXQncyBTVFJJTkcgdHlwZSwgdGhlIHZhbHVlIHNob3VsZCBhbHdheXMgYmUgc3RvcmVkIGluIGZpZWxkXG4gICAgICAvLyAnc3RyaW5nRGF0YSdcbiAgICAgIHRlbnNvclByb3RvLnN0cmluZ0RhdGEhLmZvckVhY2goKHN0ciwgaSkgPT4ge1xuICAgICAgICB2YWx1ZS5kYXRhW2ldID0gZGVjb2RlVXRmOFN0cmluZyhzdHIpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEgJiZcbiAgICAgIHR5cGVvZiB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGggPT09ICdudW1iZXInICYmXG4gICAgICB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICAvLyBOT1QgY29uc2lkZXJpbmcgc2VnbWVudCBmb3Igbm93IChJTVBPUlRBTlQpXG5cbiAgICAgIC8vIHBvcHVsYXRlIHZhbHVlIGZyb20gcmF3RGF0YVxuICAgICAgY29uc3QgZGF0YURlc3QgPSB2YWx1ZS5kYXRhO1xuICAgICAgY29uc3QgZGF0YVNvdXJjZSA9IG5ldyBEYXRhVmlldyhcbiAgICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YS5idWZmZXIsXG4gICAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZU9mZnNldCxcbiAgICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGVsZW1lbnRTaXplID0gc2l6ZW9mUHJvdG8odGVuc29yUHJvdG8uZGF0YVR5cGUhKTtcbiAgICAgIGNvbnN0IGxlbmd0aCA9IHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCAvIGVsZW1lbnRTaXplO1xuXG4gICAgICBpZiAodGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoICUgZWxlbWVudFNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJ1ZmZlciBsZW5ndGgnKTtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhRGVzdC5sZW5ndGggIT09IGxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1ZmZlciBsZW5ndGggbWlzbWF0Y2gnKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBuID0gcmVhZFByb3RvKGRhdGFTb3VyY2UsIHRlbnNvclByb3RvLmRhdGFUeXBlISwgaSAqIGVsZW1lbnRTaXplKTtcbiAgICAgICAgZGF0YURlc3RbaV0gPSBuO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBwb3B1bGF0ZSB2YWx1ZSBmcm9tIGFycmF5XG4gICAgICBsZXQgYXJyYXk6IEFycmF5PG51bWJlciB8IExvbmc+O1xuICAgICAgc3dpdGNoICh0ZW5zb3JQcm90by5kYXRhVHlwZSkge1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5mbG9hdERhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5pbnQzMkRhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5pbnQ2NERhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8uZG91YmxlRGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by51aW50NjREYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgcnVuIGhlcmVcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3BlY2lmaWMgZXJyb3InKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFycmF5ID09PSBudWxsIHx8IGFycmF5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdmYWlsZWQgdG8gcG9wdWxhdGUgZGF0YSBmcm9tIGEgdGVuc29ycHJvdG8gdmFsdWUnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGF0YSA9IHZhbHVlLmRhdGE7XG4gICAgICBpZiAoZGF0YS5sZW5ndGggIT09IGFycmF5Lmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FycmF5IGxlbmd0aCBtaXNtYXRjaCcpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhcnJheVtpXTtcbiAgICAgICAgaWYgKExvbmcuaXNMb25nKGVsZW1lbnQpKSB7XG4gICAgICAgICAgZGF0YVtpXSA9IGxvbmdUb051bWJlcihlbGVtZW50LCB0ZW5zb3JQcm90by5kYXRhVHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGF0YVtpXSA9IGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IG5ldyBUZW5zb3IgZnJvbSByYXcgZGF0YVxuICAgKiBAcGFyYW0gZGF0YSB0aGUgcmF3IGRhdGEgb2JqZWN0LiBTaG91bGQgYmUgYSBzdHJpbmcgYXJyYXkgZm9yICdzdHJpbmcnIHRlbnNvciwgYW5kIHRoZSBjb3JyZXNwb25kaW5nIHR5cGVkIGFycmF5XG4gICAqIGZvciBvdGhlciB0eXBlcyBvZiB0ZW5zb3IuXG4gICAqIEBwYXJhbSBkaW1zIHRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3JcbiAgICogQHBhcmFtIHR5cGUgdGhlIHR5cGUgb2YgdGhlIHRlbnNvclxuICAgKi9cbiAgc3RhdGljIGZyb21EYXRhKGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSwgdHlwZTogVGVuc29yLkRhdGFUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBUZW5zb3IoZGltcywgdHlwZSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGRhdGEpO1xuICB9XG5cbiAgc3RhdGljIGZyb21PcnRUZW5zb3Iob3J0VGVuc29yOiBvcnRGYnMuVGVuc29yKSB7XG4gICAgaWYgKCFvcnRUZW5zb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGNvbnN0cnVjdCBWYWx1ZSBmcm9tIGFuIGVtcHR5IHRlbnNvcicpO1xuICAgIH1cbiAgICBjb25zdCBkaW1zID0gUHJvdG9VdGlsLnRlbnNvckRpbXNGcm9tT1JURm9ybWF0KG9ydFRlbnNvcik7XG4gICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhvcnRUZW5zb3IuZGF0YVR5cGUoKSk7XG5cbiAgICBjb25zdCB2YWx1ZSA9IG5ldyBUZW5zb3IoZGltcywgdHlwZSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFdoZW4gaXQncyBTVFJJTkcgdHlwZSwgdGhlIHZhbHVlIHNob3VsZCBhbHdheXMgYmUgc3RvcmVkIGluIGZpZWxkXG4gICAgICAvLyAnc3RyaW5nRGF0YSdcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3J0VGVuc29yLnN0cmluZ0RhdGFMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgIHZhbHVlLmRhdGFbaV0gPSBvcnRUZW5zb3Iuc3RyaW5nRGF0YShpKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgb3J0VGVuc29yLnJhd0RhdGFBcnJheSgpICYmXG4gICAgICB0eXBlb2Ygb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSA9PT0gJ251bWJlcicgJiZcbiAgICAgIG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkgPiAwXG4gICAgKSB7XG4gICAgICAvLyBOT1QgY29uc2lkZXJpbmcgc2VnbWVudCBmb3Igbm93IChJTVBPUlRBTlQpXG5cbiAgICAgIC8vIHBvcHVsYXRlIHZhbHVlIGZyb20gcmF3RGF0YVxuICAgICAgY29uc3QgZGF0YURlc3QgPSB2YWx1ZS5kYXRhO1xuICAgICAgY29uc3QgZGF0YVNvdXJjZSA9IG5ldyBEYXRhVmlldyhcbiAgICAgICAgb3J0VGVuc29yLnJhd0RhdGFBcnJheSgpIS5idWZmZXIsXG4gICAgICAgIG9ydFRlbnNvci5yYXdEYXRhQXJyYXkoKSEuYnl0ZU9mZnNldCxcbiAgICAgICAgb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBlbGVtZW50U2l6ZSA9IHNpemVvZlByb3RvKG9ydFRlbnNvci5kYXRhVHlwZSgpKTtcbiAgICAgIGNvbnN0IGxlbmd0aCA9IG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkgLyBlbGVtZW50U2l6ZTtcblxuICAgICAgaWYgKG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkgJSBlbGVtZW50U2l6ZSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYnVmZmVyIGxlbmd0aCcpO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGFEZXN0Lmxlbmd0aCAhPT0gbGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYnVmZmVyIGxlbmd0aCBtaXNtYXRjaCcpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG4gPSByZWFkUHJvdG8oZGF0YVNvdXJjZSwgb3J0VGVuc29yLmRhdGFUeXBlKCksIGkgKiBlbGVtZW50U2l6ZSk7XG4gICAgICAgIGRhdGFEZXN0W2ldID0gbjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNpemVvZih0eXBlOiBUZW5zb3IuRGF0YVR5cGUpOiBudW1iZXIge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdib29sJzpcbiAgICBjYXNlICdpbnQ4JzpcbiAgICBjYXNlICd1aW50OCc6XG4gICAgICByZXR1cm4gMTtcbiAgICBjYXNlICdpbnQxNic6XG4gICAgY2FzZSAndWludDE2JzpcbiAgICAgIHJldHVybiAyO1xuICAgIGNhc2UgJ2ludDMyJzpcbiAgICBjYXNlICd1aW50MzInOlxuICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgcmV0dXJuIDQ7XG4gICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICByZXR1cm4gODtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgY2FsY3VsYXRlIHNpemVvZigpIG9uIHR5cGUgJHt0eXBlfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNpemVvZlByb3RvKHR5cGU6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUgfCBvcnRGYnMuVGVuc29yRGF0YVR5cGUpOiBudW1iZXIge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgICByZXR1cm4gMTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2OlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgIHJldHVybiAyO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjpcbiAgICAgIHJldHVybiA0O1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICByZXR1cm4gODtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgY2FsY3VsYXRlIHNpemVvZigpIG9uIHR5cGUgJHtvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlW3R5cGVdfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpZXcoZGF0YUJ1ZmZlcjogQXJyYXlCdWZmZXIsIHR5cGU6IFRlbnNvci5EYXRhVHlwZSkge1xuICByZXR1cm4gbmV3IChkYXRhdmlld0NvbnN0cnVjdG9yKHR5cGUpKShkYXRhQnVmZmVyKTtcbn1cblxuZnVuY3Rpb24gZGF0YXZpZXdDb25zdHJ1Y3Rvcih0eXBlOiBUZW5zb3IuRGF0YVR5cGUpIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnYm9vbCc6XG4gICAgY2FzZSAndWludDgnOlxuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXk7XG4gICAgY2FzZSAnaW50OCc6XG4gICAgICByZXR1cm4gSW50OEFycmF5O1xuICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgIHJldHVybiBJbnQxNkFycmF5O1xuICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICByZXR1cm4gVWludDE2QXJyYXk7XG4gICAgY2FzZSAnaW50MzInOlxuICAgICAgcmV0dXJuIEludDMyQXJyYXk7XG4gICAgY2FzZSAndWludDMyJzpcbiAgICAgIHJldHVybiBVaW50MzJBcnJheTtcbiAgICBjYXNlICdpbnQ2NCc6XG4gICAgICByZXR1cm4gQmlnSW50NjRBcnJheTtcbiAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIHJldHVybiBGbG9hdDMyQXJyYXk7XG4gICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICByZXR1cm4gRmxvYXQ2NEFycmF5O1xuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBzaG91bGQgbmV2ZXIgcnVuIHRvIGhlcmVcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5zcGVjaWZpZWQgZXJyb3InKTtcbiAgfVxufVxuXG4vLyBjb252ZXJ0IGEgbG9uZyBudW1iZXIgdG8gYSAzMi1iaXQgaW50ZWdlciAoY2FzdC1kb3duKVxuZnVuY3Rpb24gbG9uZ1RvTnVtYmVyKGk6IExvbmcsIHR5cGU6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUgfCBvcnRGYnMuVGVuc29yRGF0YVR5cGUpOiBudW1iZXIge1xuICAvLyBJTlQ2NCwgVUlOVDMyLCBVSU5UNjRcbiAgaWYgKHR5cGUgPT09IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQgfHwgdHlwZSA9PT0gb3J0RmJzLlRlbnNvckRhdGFUeXBlLklOVDY0KSB7XG4gICAgaWYgKGkuZ3JlYXRlclRoYW5PckVxdWFsKDIxNDc0ODM2NDgpIHx8IGkubGVzc1RoYW4oLTIxNDc0ODM2NDgpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnQ2NCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKFxuICAgIHR5cGUgPT09IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyIHx8XG4gICAgdHlwZSA9PT0gb3J0RmJzLlRlbnNvckRhdGFUeXBlLlVJTlQzMiB8fFxuICAgIHR5cGUgPT09IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0IHx8XG4gICAgdHlwZSA9PT0gb3J0RmJzLlRlbnNvckRhdGFUeXBlLlVJTlQ2NFxuICApIHtcbiAgICBpZiAoaS5ncmVhdGVyVGhhbk9yRXF1YWwoNDI5NDk2NzI5NikgfHwgaS5sZXNzVGhhbigwKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndWludDY0IGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgbm90IGEgTE9ORyB0eXBlOiAke29ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVbdHlwZV19YCk7XG4gIH1cblxuICByZXR1cm4gaS50b051bWJlcigpO1xufVxuXG4vLyByZWFkIG9uZSB2YWx1ZSBmcm9tIFRlbnNvclByb3RvXG5mdW5jdGlvbiByZWFkUHJvdG8oXG4gIHZpZXc6IERhdGFWaWV3LFxuICB0eXBlOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHwgb3J0RmJzLlRlbnNvckRhdGFUeXBlLFxuICBieXRlT2Zmc2V0OiBudW1iZXIsXG4pOiBudW1iZXIge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgICByZXR1cm4gdmlldy5nZXRVaW50OChieXRlT2Zmc2V0KTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODpcbiAgICAgIHJldHVybiB2aWV3LmdldEludDgoYnl0ZU9mZnNldCk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICAgIHJldHVybiB2aWV3LmdldFVpbnQxNihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY6XG4gICAgICByZXR1cm4gdmlldy5nZXRJbnQxNihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgICByZXR1cm4gdmlldy5nZXRGbG9hdDMyKGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICAgIHJldHVybiB2aWV3LmdldEludDMyKGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICByZXR1cm4gdmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgICAgcmV0dXJuIGxvbmdUb051bWJlcihcbiAgICAgICAgTG9uZy5mcm9tQml0cyh2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0LCB0cnVlKSwgdmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCArIDQsIHRydWUpLCBmYWxzZSksXG4gICAgICAgIHR5cGUsXG4gICAgICApO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgICByZXR1cm4gdmlldy5nZXRGbG9hdDY0KGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICByZXR1cm4gbG9uZ1RvTnVtYmVyKFxuICAgICAgICBMb25nLmZyb21CaXRzKHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQsIHRydWUpLCB2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0ICsgNCwgdHJ1ZSksIHRydWUpLFxuICAgICAgICB0eXBlLFxuICAgICAgKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgcmVhZCBmcm9tIERhdGFWaWV3IGZvciB0eXBlICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlXX1gKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKipcbiAqIHJlcHJlc2VudCBhIHZlcnNpb24gaXJyZWxldmFudCBhYnN0cmFjdGlvbiBvZiBmb3IgR0xTTCBzb3VyY2UgY29kZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdsc2wge1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGF0dHJpYnV0ZTogc3RyaW5nO1xuICByZWFkb25seSB2YXJ5aW5nVmVydGV4OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhcnlpbmdGcmFnOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRleHR1cmUyRDogc3RyaW5nO1xuICByZWFkb25seSBvdXRwdXQ6IHN0cmluZztcbiAgcmVhZG9ubHkgb3V0cHV0RGVjbGFyYXRpb246IHN0cmluZztcbn1cblxuY29uc3QgR0xTTF9FU18yXzA6IEdsc2wgPSB7XG4gIHZlcnNpb246ICcnLFxuICBhdHRyaWJ1dGU6ICdhdHRyaWJ1dGUnLFxuICB2YXJ5aW5nVmVydGV4OiAndmFyeWluZycsXG4gIHZhcnlpbmdGcmFnOiAndmFyeWluZycsXG4gIHRleHR1cmUyRDogJ3RleHR1cmUyRCcsXG4gIG91dHB1dDogJ2dsX0ZyYWdDb2xvcicsXG4gIG91dHB1dERlY2xhcmF0aW9uOiAnJyxcbn07XG5jb25zdCBHTFNMX0VTXzNfMDogR2xzbCA9IHtcbiAgdmVyc2lvbjogJyN2ZXJzaW9uIDMwMCBlcycsXG4gIGF0dHJpYnV0ZTogJ2luJyxcbiAgdmFyeWluZ1ZlcnRleDogJ291dCcsXG4gIHZhcnlpbmdGcmFnOiAnaW4nLFxuICB0ZXh0dXJlMkQ6ICd0ZXh0dXJlJyxcbiAgb3V0cHV0OiAnb3V0cHV0Q29sb3InLFxuICBvdXRwdXREZWNsYXJhdGlvbjogJ291dCB2ZWM0IG91dHB1dENvbG9yOycsXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0R2xzbCh2ZXJzaW9uOiAxIHwgMikge1xuICByZXR1cm4gdmVyc2lvbiA9PT0gMSA/IEdMU0xfRVNfMl8wIDogR0xTTF9FU18zXzA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWZXJ0ZXhTaGFkZXJTb3VyY2UodmVyc2lvbjogMSB8IDIpOiBzdHJpbmcge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbCh2ZXJzaW9uKTtcbiAgcmV0dXJuIGAke2dsc2wudmVyc2lvbn1cbiAgICAgIHByZWNpc2lvbiBoaWdocCBmbG9hdDtcbiAgICAgICR7Z2xzbC5hdHRyaWJ1dGV9IHZlYzMgcG9zaXRpb247XG4gICAgICAke2dsc2wuYXR0cmlidXRlfSB2ZWMyIHRleHR1cmVDb29yZDtcblxuICAgICAgJHtnbHNsLnZhcnlpbmdWZXJ0ZXh9IHZlYzIgVGV4Q29vcmRzO1xuXG4gICAgICB2b2lkIG1haW4oKVxuICAgICAge1xuICAgICAgICAgIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbiwgMS4wKTtcbiAgICAgICAgICBUZXhDb29yZHMgPSB0ZXh0dXJlQ29vcmQ7XG4gICAgICB9YDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZyYWdTaGFkZXJQcmVhbWJsZSh2ZXJzaW9uOiAxIHwgMik6IHN0cmluZyB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHZlcnNpb24pO1xuICByZXR1cm4gYCR7Z2xzbC52ZXJzaW9ufVxuICAgIHByZWNpc2lvbiBoaWdocCBmbG9hdDtcbiAgICBwcmVjaXNpb24gaGlnaHAgaW50O1xuICAgIHByZWNpc2lvbiBoaWdocCBzYW1wbGVyMkQ7XG4gICAgJHtnbHNsLnZhcnlpbmdGcmFnfSB2ZWMyIFRleENvb3JkcztcbiAgICAke2dsc2wub3V0cHV0RGVjbGFyYXRpb259XG4gICAgY29uc3QgdmVjMiBoYWxmQ1IgPSB2ZWMyKDAuNSwgMC41KTtcblxuICAgIC8vIEN1c3RvbSB2ZWN0b3IgdHlwZXMgdG8gaGFuZGxlIGhpZ2hlciBkaW1lbmFsaXRpZXMuXG4gICAgc3RydWN0IGl2ZWM1XG4gICAge1xuICAgICAgaW50IHg7XG4gICAgICBpbnQgeTtcbiAgICAgIGludCB6O1xuICAgICAgaW50IHc7XG4gICAgICBpbnQgdTtcbiAgICB9O1xuXG4gICAgc3RydWN0IGl2ZWM2XG4gICAge1xuICAgICAgaW50IHg7XG4gICAgICBpbnQgeTtcbiAgICAgIGludCB6O1xuICAgICAgaW50IHc7XG4gICAgICBpbnQgdTtcbiAgICAgIGludCB2O1xuICAgIH07XG5cbiAgICBpbnQgaW1vZChpbnQgeCwgaW50IHkpIHtcbiAgICAgIHJldHVybiB4IC0geSAqICh4IC8geSk7XG4gICAgfVxuXG4gICAgYDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRGcmFnU2hhZGVyTWFpbih2ZXJzaW9uOiAxIHwgMiwgb3V0cHV0U2hhcGVMZW5ndGg6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHZlcnNpb24pO1xuICByZXR1cm4gYFxuICB2b2lkIG1haW4oKSB7XG4gICAgaW50IGluZGljZXNbJHtvdXRwdXRTaGFwZUxlbmd0aH1dO1xuICAgIHRvVmVjKFRleENvb3JkcywgaW5kaWNlcyk7XG4gICAgdmVjNCByZXN1bHQgPSB2ZWM0KHByb2Nlc3MoaW5kaWNlcykpO1xuICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICB9XG4gIGA7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uL3RlbnNvcic7XG5cbi8qKlxuICogTGF5b3V0IGluZm8gaXMgdXNlZCBmb3IgbWFwcGluZyBuLWRpbWVuc2lvbmFsIGFycmF5IHRvIDJEIHRleHR1cmVzXG4gKiBUaGUgbGF5b3V0IGlzIGNyZWF0ZWQgYnkgdGhlIFRleHR1cmVMYXlvdXRTdHJhdGVneSBiYXNlZCBvblxuICogdGhlIFRlbnNvcidzIGRpbWVuc2lvbnMgYW5kIHN0cmlkZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTGF5b3V0IHtcbiAgd2lkdGg6IG51bWJlcjtcbiAgaGVpZ2h0OiBudW1iZXI7XG4gIC8qKlxuICAgKiBzcGVjaWZ5IHRoZSBudW1iZXIgb2YgdmFsdWUgdGhhdCBlbmNvZGVkIGluIGEgc2luZ2xlIHBpeGVsXG4gICAqL1xuICBjaGFubmVsczogMSB8IDIgfCAzIHwgNDtcbiAgLyoqXG4gICAqIHdoZXRoZXIgaW4gcGFja2VkIG1vZGUgb3Igbm90XG4gICAqL1xuICBpc1BhY2tlZD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiB0aGUgbm9ybWFsaXplZCBzaGFwZVxuICAgKi9cbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogdGhlIHN0cmlkZSBvZiBlYWNoIGRpbWVuc2lvbnMsIGNhbGN1bGF0ZWQgYWNjb3JkaW5nIHRvIHNoYXBlXG4gICAqL1xuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbiAgLyoqXG4gICAqIHRoZSBvcmlnaW5hbCBzaGFwZShkaW1zKSBvZiB0aGUgY29ycmVzcG9uZGluZyB0ZW5zb3JcbiAgICovXG4gIHVucGFja2VkU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gIHJldmVyc2VkV0g/OiBib29sZWFuO1xufVxuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlRGF0YSBleHRlbmRzIFRleHR1cmVMYXlvdXQge1xuICB0ZW5zb3I6IFRlbnNvcjtcbiAgdGV4dHVyZTogV2ViR0xUZXh0dXJlO1xufVxuXG5leHBvcnQgZW51bSBUZXh0dXJlVHlwZSB7XG4gIHVucGFja2VkLCAvLyA8LS0gbm9ybWFsIHVucGFja2VkIHRleHR1cmVcbiAgdW5wYWNrZWRSZXZlcnNlZCwgLy8gPC0tIHVucGFja2VkIHRleHR1cmUgdXNlZCBpbiBvbGQgT05OWC5qcyBpbXBsZW1lbnRhdGlvbiAoZGVwcmVjYXRlZClcbiAgcGFja2VkLCAvLyA8LS0gbm9ybWFsIHBhY2tlZCB0ZXh0dXJlXG4gIGRvd25sb2FkVWludDhBc0Zsb2F0LCAvLyA8LS0gT05MWSB1c2VkIGluIHRleHR1cmUgZG93bmxvYWRpbmcgZm9yIGlPUyBkZXZpY2VzXG4gIHBhY2tlZExhc3REaW1lbnNpb24sIC8vIDwtLSBPTkxZIHVzZWQgaW4gb2xkIE9OTlguanMgQ29udiBpbXBsZW1lbnRhdGlvbiBmb3IgaW5wdXQgVyAoZGVwcmVjYXRlZClcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JJbmZvIHtcbiAgaWQ/OiBUZW5zb3IuSWQ7XG4gIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICB0eXBlOiBUZW5zb3IuRGF0YVR5cGU7XG4gIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtVmFyaWFibGUge1xuICB0eXBlOiAnZmxvYXQnIHwgJ2ludCc7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG4gIGRhdGE6IG51bWJlciB8IG51bWJlcltdO1xufVxuXG4vKipcbiAqIEEgc2V0IG9mIG1ldGFkYXRhIG9mIGEgc2hhZGVyIHByb2dyYW0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIHRoZSBuYW1lIG9mIHRoZSBwcm9ncmFtLiB1c2VkIGZvciBkZWJ1Z2dpbmcgYW5kIHByb2ZpbGluZ1xuICAgKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogdGV4dHVyZSB0eXBlcyBmb3IgZWFjaCBpbnB1dFxuICAgKi9cbiAgaW5wdXRUeXBlczogVGV4dHVyZVR5cGVbXTtcbiAgLyoqXG4gICAqIG5hbWVzIG9mIGVhY2ggaW5wdXRcbiAgICovXG4gIGlucHV0TmFtZXM6IHN0cmluZ1tdO1xuICAvKipcbiAgICogYW4gb3B0aW9uYWwgc3RyaW5nIGFzIGEgY2FjaGUgaGludCBpbiB0aGUgYXJ0aWZhY3QgY2FjaGVcbiAgICovXG4gIGNhY2hlSGludD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIFByb2dyYW1JbmZvTG9hZGVyIGFsbG93c1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1JbmZvTG9hZGVyIGV4dGVuZHMgUHJvZ3JhbU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIGEgZnVuY3Rpb24gdG8gZ2V0IHRoZSBwcm9ncmFtIGluZm9cbiAgICovXG4gIGdldCgpOiBQcm9ncmFtSW5mbztcbn1cblxuLyoqXG4gKiBBIHNldCBvZiBkYXRhIHRoYXQgcmVwcmVzZW50IGEgc2hhZGVyIHByb2dyYW1cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtSW5mbyBleHRlbmRzIFByb2dyYW1NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBpbmZvcm1hdGlvbiBvZiB1bmlmb3JtIHZhcmlhYmxlc1xuICAgKi9cbiAgdmFyaWFibGVzPzogUHJvZ3JhbVZhcmlhYmxlW107XG4gIC8qKlxuICAgKiB0ZW5zb3IgaW5mbyBmb3Igb3V0cHV0XG4gICAqL1xuICBvdXRwdXQ6IFRlbnNvckluZm87XG4gIC8qKlxuICAgKiB0aGUgc2hhZGVyJ3MgcHJvY2Vzc2luZyBzb3VyY2UgY29kZVxuICAgKi9cbiAgc2hhZGVyU291cmNlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiB3aGV0aGVyIHRoZSBzaGFkZXIgc291cmNlIGNvbnRhaW5zIGEgY3VzdG9taXplZCBtYWluIGZ1bmN0aW9uIGltcGxlbWVudGF0aW9uXG4gICAqL1xuICBoYXNNYWluPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWYXJpYWJsZUluZm8ge1xuICB0eXBlOiAnZmxvYXQnIHwgJ2ludCc7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbVZhcmlhYmxlIHtcbiAgdHlwZTogJ2Zsb2F0JyB8ICdpbnQnO1xuICBuYW1lOiBzdHJpbmc7XG4gIGFycmF5TGVuZ3RoPzogbnVtYmVyO1xuICBkYXRhOiBudW1iZXIgfCBudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBJbmZvcm1hdGlvbiBvZiB1bmlmb3JtcyB0aGF0IHNoYWRlciB1c2VzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVW5pZm9ybUluZm8ge1xuICB0eXBlOiAnc2FtcGxlcjJEJyB8IFZhcmlhYmxlSW5mb1sndHlwZSddO1xuICBuYW1lOiBzdHJpbmc7XG4gIGFycmF5TGVuZ3RoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZvcm1Mb2NhdGlvbiBleHRlbmRzIFVuaWZvcm1JbmZvIHtcbiAgbG9jYXRpb246IFdlYkdMVW5pZm9ybUxvY2F0aW9uO1xufVxuXG4vKipcbiAqIEFydGlmYWN0IGlzIHRoZSByZXN1bHQgb2YgY29tcGlsYXRpb25cbiAqIEl0IGRvZXMgbm90IGNvbnRhaW4gaW5wdXQgb2Ygb3V0cHV0IGRhdGFcbiAqIEhvd2V2ZXIgYW55dGhpbmcgdGhhdCBjb3VsZCBiZSBydW4gYXMgYSBcInByb2dyYW1cIlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFydGlmYWN0IHtcbiAgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvO1xuICBwcm9ncmFtOiBXZWJHTFByb2dyYW07XG4gIHVuaWZvcm1Mb2NhdGlvbnM6IFVuaWZvcm1Mb2NhdGlvbltdO1xuICBhdHRyaWJMb2NhdGlvbnM6IHsgcG9zaXRpb246IG51bWJlcjsgdGV4dHVyZUNvb3JkOiBudW1iZXIgfTtcbn1cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBBcnRpZmFjdCB7XG4gIHR5cGUgVW5pZm9ybUxvY2F0aW9ucyA9IEFydGlmYWN0Wyd1bmlmb3JtTG9jYXRpb25zJ107XG4gIHR5cGUgQXR0cmliTG9jYXRpb25zID0gQXJ0aWZhY3RbJ2F0dHJpYkxvY2F0aW9ucyddO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZvcm1EYXRhIHtcbiAgW25hbWU6IHN0cmluZ106IG51bWJlciB8IG51bWJlcltdO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi8uLi91dGlsJztcbi8qKlxuICogR2l2ZW4gYSBub24gUkdCQSBzaGFwZSBjYWxjdWxhdGUgdGhlIFIgdmVyc2lvblxuICogSXQgaXMgYXNzdW1lZCB0aGF0IHRoZSBkaW1lbnNpb25zIGFyZSBtdWx0aXBsZXMgb2YgZ2l2ZW4gY2hhbm5lbHNcbiAqIE5PVEU6IGl0IGlzIGFsd2F5cyB0aGUgbGFzdCBkaW0gdGhhdCBnZXRzIHBhY2tlZC5cbiAqIEBwYXJhbSB1bnBhY2tlZFNoYXBlIG9yaWdpbmFsIHNoYXBlIHRvIGNyZWF0ZSBhIHBhY2tlZCB2ZXJzaW9uIGZyb21cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBhY2tlZFNoYXBlKHVucGFja2VkU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICBjb25zdCBsZW4gPSB1bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgcmV0dXJuIHVucGFja2VkU2hhcGUuc2xpY2UoMCwgbGVuIC0gMSkuY29uY2F0KHVucGFja2VkU2hhcGVbbGVuIC0gMV0gLyA0KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcGVhdGVkVHJ5KFxuICBjaGVja0ZuOiAoKSA9PiBib29sZWFuLFxuICBkZWxheUZuID0gKF9jb3VudGVyOiBudW1iZXIpID0+IDAsXG4gIG1heENvdW50ZXI/OiBudW1iZXIsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBsZXQgdHJ5Q291bnQgPSAwO1xuXG4gICAgY29uc3QgdHJ5Rm4gPSAoKSA9PiB7XG4gICAgICBpZiAoY2hlY2tGbigpKSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0cnlDb3VudCsrO1xuXG4gICAgICBjb25zdCBuZXh0QmFja29mZiA9IGRlbGF5Rm4odHJ5Q291bnQpO1xuXG4gICAgICBpZiAobWF4Q291bnRlciAhPSBudWxsICYmIHRyeUNvdW50ID49IG1heENvdW50ZXIpIHtcbiAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNldFRpbWVvdXQodHJ5Rm4sIG5leHRCYWNrb2ZmKTtcbiAgICB9O1xuXG4gICAgdHJ5Rm4oKTtcbiAgfSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBmdW5jdGlvbiBuYW1lIGZyb20gYW4gaW5wdXQgc2FtcGxlciBuYW1lLlxuICogQHBhcmFtIHNhbXBsZXJOYW1lIE5hbWUgb2YgdGhlIHNhbXBsZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUoc2FtcGxlck5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydCh0eXBlb2Ygc2FtcGxlck5hbWUgIT09ICd1bmRlZmluZWQnICYmIHNhbXBsZXJOYW1lLmxlbmd0aCAhPT0gMCwgKCkgPT4gJ2VtcHR5IHN0cmluZyBmb3VuZCBmb3Igc2FtcGxlciBuYW1lJyk7XG4gIHJldHVybiAnZ2V0JyArIHNhbXBsZXJOYW1lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc2FtcGxlck5hbWUuc2xpY2UoMSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBmdW5jdGlvbiBuYW1lIGZyb20gYW4gaW5wdXQgc2FtcGxlciBuYW1lIGF0IG91dHB1dCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSBzYW1wbGVyTmFtZSBOYW1lIG9mIHRoZSBzYW1wbGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lQXRPdXRDb29yZHMoc2FtcGxlck5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGFzc2VydCh0eXBlb2Ygc2FtcGxlck5hbWUgIT09ICd1bmRlZmluZWQnICYmIHNhbXBsZXJOYW1lLmxlbmd0aCAhPT0gMCwgKCkgPT4gJ2VtcHR5IHN0cmluZyBmb3VuZCBmb3Igc2FtcGxlciBuYW1lJyk7XG4gIHJldHVybiAnZ2V0JyArIHNhbXBsZXJOYW1lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc2FtcGxlck5hbWUuc2xpY2UoMSkgKyAnQXRPdXRDb29yZHMnO1xufVxuXG4vKiogUmV0dXJucyBhIG5ldyBpbnB1dCBzaGFwZSAoYSBjb3B5KSB0aGF0IGhhcyBhIHNxdWVlemVkIGxvZ2ljYWwgc2hhcGUuICovXG5leHBvcnQgZnVuY3Rpb24gc3F1ZWV6ZUlucHV0U2hhcGUoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHNxdWVlemVkU2hhcGU6IG51bWJlcltdKTogbnVtYmVyW10ge1xuICAvLyBEZWVwIGNvcHkuXG4gIGxldCBuZXdJbnB1dFNoYXBlOiBudW1iZXJbXSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRTaGFwZSkpO1xuICBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZWRTaGFwZTtcbiAgcmV0dXJuIG5ld0lucHV0U2hhcGU7XG59XG5cbi8qKiBSZXR1cm5zIGEgbGlzdCBvZiBzcXVlZXplZCBwYXJhbWV0ZXJzIGZvciBzaGFkZXIgZnVuY3Rpb25zICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zOiBzdHJpbmdbXSwga2VwdERpbXM6IG51bWJlcltdKTogc3RyaW5nIHtcbiAgcmV0dXJuIGtlcHREaW1zLm1hcCgoZCkgPT4gcGFyYW1zW2RdKS5qb2luKCcsICcpO1xufVxuXG4vKiogUmV0dXJucyB0aGUgZGF0YSB0eXBlIGZvciBkaWZmZXJlbnQgcmFua3MuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29vcmRzRGF0YVR5cGUocmFuazogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPD0gMSkge1xuICAgIHJldHVybiAnaW50JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSAyKSB7XG4gICAgcmV0dXJuICdpdmVjMic7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gMykge1xuICAgIHJldHVybiAnaXZlYzMnO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDQpIHtcbiAgICByZXR1cm4gJ2l2ZWM0JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSA1KSB7XG4gICAgcmV0dXJuICdpdmVjNSc7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gNikge1xuICAgIHJldHVybiAnaXZlYzYnO1xuICB9IGVsc2Uge1xuICAgIHRocm93IEVycm9yKGBHUFUgZm9yIHJhbmsgJHtyYW5rfSBpcyBub3QgeWV0IHN1cHBvcnRlZGApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbENoYW5uZWxzKHJhbmsgPSA2KTogc3RyaW5nW10ge1xuICByZXR1cm4gWyd4JywgJ3knLCAneicsICd3JywgJ3UnLCAndiddLnNsaWNlKDAsIHJhbmspO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBnZXRHbENoYW5uZWxzIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVjQ2hhbm5lbHMobmFtZTogc3RyaW5nLCByYW5rOiBudW1iZXIpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBnZXRHbENoYW5uZWxzKHJhbmspLm1hcCgoZCkgPT4gYCR7bmFtZX0uJHtkfWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2hhbm5lbHMobmFtZTogc3RyaW5nLCByYW5rOiBudW1iZXIpOiBzdHJpbmdbXSB7XG4gIGlmIChyYW5rID09PSAxKSB7XG4gICAgcmV0dXJuIFtuYW1lXTtcbiAgfVxuICByZXR1cm4gZ2V0VmVjQ2hhbm5lbHMobmFtZSwgcmFuayk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bnBhY2tGcm9tQ2hhbm5lbCgpOiBzdHJpbmcge1xuICByZXR1cm4gYFxuICAgIGZsb2F0IGdldENoYW5uZWwodmVjNCBmcmFnLCBpbnQgZGltKSB7XG4gICAgICBpbnQgbW9kQ29vcmQgPSBpbW9kKGRpbSwgMik7XG4gICAgICByZXR1cm4gbW9kQ29vcmQgPT0gMCA/IGZyYWcuciA6IGZyYWcuZztcbiAgICB9XG5cbiAgICBmbG9hdCBnZXRDaGFubmVsKHZlYzQgZnJhZywgdmVjMiBpbm5lckRpbXMpIHtcbiAgICAgIHZlYzIgbW9kQ29vcmQgPSBtb2QoaW5uZXJEaW1zLCAyLik7XG4gICAgICByZXR1cm4gbW9kQ29vcmQueCA9PSAwLiA/XG4gICAgICAgIChtb2RDb29yZC55ID09IDAuID8gZnJhZy5yIDogZnJhZy5nKSA6XG4gICAgICAgIChtb2RDb29yZC55ID09IDAuID8gZnJhZy5iIDogZnJhZy5hKTtcbiAgICB9XG4gIGA7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyBnZXRDaGFubmVscyB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IHBhY2tQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdwYWNrJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZFJldmVyc2VkXSxcbn07XG5cbmNvbnN0IGNyZWF0ZVBhY2tQcm9ncmFtSW5mbyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0LmRpbXM7XG5cbiAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIC8vIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUgd29uJ3QgY2hhbmdlIG91dHB1dCByYW5rLiBOZWVkIHRvIHZlcmlmeSBieSBydW5uaW5nIHRlc3RzXG4gIGNvbnN0IG91dHB1dFJhbmsgPSBpbnB1dC5kaW1zLmxlbmd0aDtcblxuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dHB1dFJhbmspO1xuICBjb25zdCBjaGFubmVscyA9IGdldENoYW5uZWxzKCdyYycsIG91dHB1dFJhbmspO1xuICBjb25zdCBzZXR1cCA9IGdldFNldHVwKG91dHB1dFJhbmssIGNoYW5uZWxzLCBpbnB1dFNoYXBlW2lucHV0U2hhcGUubGVuZ3RoIC0gMl0sIGlucHV0U2hhcGVbaW5wdXRTaGFwZS5sZW5ndGggLSAxXSk7XG5cbiAgbGV0IHJldmVyc2VkSW5wdXRXSDtcbiAgaWYgKGlucHV0UmFuayA9PT0gMCkge1xuICAgIHJldmVyc2VkSW5wdXRXSCA9IFsxLCAxXTtcbiAgfSBlbHNlIGlmIChpbnB1dFJhbmsgPT09IDEpIHtcbiAgICByZXZlcnNlZElucHV0V0ggPSBbaW5wdXRTaGFwZVswXSwgMV07XG4gIH0gZWxzZSB7XG4gICAgcmV2ZXJzZWRJbnB1dFdIID0gW2lucHV0U2hhcGVbb3V0cHV0UmFuayAtIDFdLCBpbnB1dFNoYXBlW291dHB1dFJhbmsgLSAyXV07XG4gIH1cbiAgY29uc3Qgb3V0T2ZCb3VuZHNDb25kaXRpb24gPSBnZXRPdXRPZkJvdW5kc0NvbmRpdGlvbihvdXRwdXRSYW5rLCByZXZlcnNlZElucHV0V0gsIGNoYW5uZWxzKTtcbiAgY29uc3Qgb3V0cHV0ID0gZ2V0T3V0cHV0KGlucHV0U2hhcGUsIGNoYW5uZWxzKTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAke2Nvb3Jkc0RhdGFUeXBlfSByYyA9IGdldE91dHB1dENvb3JkcygpO1xuXG4gICAgICAgICAgaWYoJHtvdXRPZkJvdW5kc0NvbmRpdGlvbn0pIHtcbiAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCgwKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJHtzZXR1cH1cblxuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KCR7b3V0cHV0fSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLnBhY2tQcm9ncmFtTWV0YWRhdGEsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4gKHtcbiAgLi4ucGFja1Byb2dyYW1NZXRhZGF0YSxcbiAgZ2V0OiAoKSA9PiBjcmVhdGVQYWNrUHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXQpLFxufSk7XG5cbi8qKlxuICogY2hlY2sgb3V0cHV0IGNvb3JkaW5hdGUgbG9jYXRpb24gYW5kIHJldHVybiBmYWxzZSBpZiBpdCBpcyBvdXRzaWRlIGlucHV0J3Mgd2lkdGgvaGVpZ2h0IGJvdW5kYXJ5XG4gKi9cbmZ1bmN0aW9uIGdldE91dE9mQm91bmRzQ29uZGl0aW9uKHJhbms6IG51bWJlciwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBkaW1zOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGlmIChyYW5rID09PSAwKSB7XG4gICAgcmV0dXJuICdmYWxzZSc7XG4gIH1cbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gYHJjID4gJHtzaGFwZVswXX1gO1xuICB9XG5cbiAgbGV0IGNvbmQgPSAnJztcbiAgZm9yIChsZXQgaSA9IHJhbmsgLSAyOyBpIDwgcmFuazsgaSsrKSB7XG4gICAgY29uZCArPSBgJHtkaW1zW2ldfSA+PSAke3NoYXBlW2kgLSByYW5rICsgMl19YDtcbiAgICBpZiAoaSA8IHJhbmsgLSAxKSB7XG4gICAgICBjb25kICs9ICd8fCc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbmQ7XG59XG5cbi8qKlxuICogY29kZSBzbmlwcGV0IHRvIHNhbXBsZSBpbnB1dCB0ZXh0dXJlIHdpdGggb3V0cHV0IGNvb3JkaW5hdGVzXG4gKi9cbmZ1bmN0aW9uIGdldE91dHB1dChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGRpbXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICBpZiAocmFuayA9PT0gMCkge1xuICAgIHJldHVybiAnZ2V0QSgpLCAwLCAwLCAwJztcbiAgfVxuXG4gIGlmIChyYW5rID09PSAxKSB7XG4gICAgcmV0dXJuIGBnZXRBKHJjKSxcbiAgICAgICAgICAgIHJjICsgMSA+PSAke3NoYXBlWzBdfSA/IDAuIDogZ2V0QShyYyArIDEpLFxuICAgICAgICAgICAgMCwgMGA7XG4gIH1cblxuICBjb25zdCBjb29yZDAwID0gJ3IsIGMnO1xuICBjb25zdCBjb29yZDAxID0gJ3IsIGNwMSc7XG4gIGNvbnN0IGNvb3JkMTAgPSAncnAxLCBjJztcbiAgY29uc3QgY29vcmQxMSA9ICdycDEsIGNwMSc7XG4gIGxldCBEID0gJyc7XG4gIGlmIChyYW5rID4gMikge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7ICsraSkge1xuICAgICAgRCA9IEQgKyBgJHtkaW1zW2ldfSxgO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYGdldEEoJHtEfSR7Y29vcmQwMH0pLFxuICAgICAgICAgIHJFZGdlID8gMC4gOiBnZXRBKCR7RH0ke2Nvb3JkMTB9KSxcbiAgICAgICAgICBjRWRnZSA/IDAuIDogZ2V0QSgke0R9JHtjb29yZDAxfSksXG4gICAgICAgICAgckVkZ2UgfHwgY0VkZ2UgPyAwLiA6IGdldEEoJHtEfSR7Y29vcmQxMX0pYDtcbn1cblxuLyoqXG4gKiBjb2RlIHNuaXBwZXQgdG8gc2V0dXAgNCBjb29yZGluYXRlcyBhbmQgZWRnZSBjb25kaXRpb25zXG4gKi9cbmZ1bmN0aW9uIGdldFNldHVwKHJhbms6IG51bWJlciwgZGltczogc3RyaW5nW10sIHJvd3M6IG51bWJlciwgY29sczogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPT09IDAgfHwgcmFuayA9PT0gMSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuICAvLyByYW5rID49IDIgZm9yIHdpZHRoK2hlaWdodCBwYWNrLlxuICBlbHNlIHtcbiAgICBjb25zdCBzZXR1cCA9IGBcbiAgICBpbnQgciA9ICR7ZGltc1tyYW5rIC0gMl19O1xuICAgIGludCBjID0gJHtkaW1zW3JhbmsgLSAxXX07XG4gICAgaW50IHJwMSA9ICR7ZGltc1tyYW5rIC0gMl19ICsgMTtcbiAgICBpbnQgY3AxID0gJHtkaW1zW3JhbmsgLSAxXX0gKyAxO1xuICAgIGJvb2wgckVkZ2UgPSBycDEgPj0gJHtjb2xzfTtcbiAgICBib29sIGNFZGdlID0gY3AxID49ICR7cm93c307XG4gICAgYDtcbiAgICByZXR1cm4gc2V0dXA7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgdW5wYWNrRnJvbUNoYW5uZWwgfSBmcm9tICcuL3BhY2tpbmctdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtTWV0YWRhdGEgPSAob3V0cHV0U2hhcGUzRDogcmVhZG9ubHkgbnVtYmVyW10pID0+ICh7XG4gIG5hbWU6ICdSZXNoYXBlIChwYWNrZWQpJyxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF0sXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBjYWNoZUhpbnQ6IGAke291dHB1dFNoYXBlM0R9YCxcbn0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mbyA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDNEOiBUZW5zb3IsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIG91dHB1dFNoYXBlM0Q6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlM0QgPSBpbnB1dDNELmRpbXMgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICBjb25zdCBzcXVlZXplZE91dHB1dFNoYXBlID0gb3V0cHV0U2hhcGUzRCBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG5cbiAgbGV0IG1haW5Mb29wID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgbGV0IG91dHB1dENvb3JkcyA9ICcnO1xuICAgIHN3aXRjaCAoaSkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICBvdXRwdXRDb29yZHMgPSAnb3V0cHV0Q29vcmRzID0gcmM7JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSBpdmVjMyhyYy54LCByYy55KzEsIHJjLnopOyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBvdXRwdXRDb29yZHMgPSAnb3V0cHV0Q29vcmRzID0gaXZlYzMocmMueCwgcmMueSwgcmMueisxKTsnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgb3V0cHV0Q29vcmRzID0gJ291dHB1dENvb3JkcyA9IGl2ZWMzKHJjLngsIHJjLnkrMSwgcmMueisxKTsnO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgIH1cblxuICAgIG1haW5Mb29wICs9IGBcbiAgICAgICAgJHtvdXRwdXRDb29yZHN9XG4gICAgICAgICR7aSA+IDAgPyAnaWYob3V0cHV0Q29vcmRzLnkgPCByb3dzICYmIG91dHB1dENvb3Jkcy56IDwgY29scyl7JyA6ICcnfVxuICAgICAgICAgIGludCBmbGF0dGVuZWRJbmRleCA9IGdldEZsYXR0ZW5lZEluZGV4KG91dHB1dENvb3Jkcyk7XG5cbiAgICAgICAgICBpdmVjMyBpbnB1dFJDID0gaW5wdXRDb29yZHNGcm9tUmVzaGFwZWRPdXRDb29yZHMoZmxhdHRlbmVkSW5kZXgpO1xuICAgICAgICAgIHZlYzIgaW5uZXJEaW1zID0gdmVjMihmbG9hdChpbnB1dFJDLnkpLGZsb2F0KGlucHV0UkMueikpO1xuXG4gICAgICAgICAgcmVzdWx0WyR7aX1dID0gZ2V0Q2hhbm5lbChnZXRBKGlucHV0UkMueCwgaW5wdXRSQy55LCBpbnB1dFJDLnopLCBpbm5lckRpbXMpO1xuXG4gICAgICAgICR7aSA+IDAgPyAnfScgOiAnJ31cbiAgICAgIGA7XG4gIH1cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7Z2V0UmVzaGFwZWRJbnB1dENvb3JkcyhpbnB1dFNoYXBlM0QpfVxuICAgICAgJHtnZXRGbGF0dGVuZWRJbmRleEZyb20zRChzcXVlZXplZE91dHB1dFNoYXBlKX1cbiAgICAgICR7dW5wYWNrRnJvbUNoYW5uZWwoKX1cblxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICBpdmVjMyByYyA9IGdldE91dHB1dENvb3JkcygpO1xuXG4gICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLjApO1xuXG4gICAgICAgIGl2ZWMzIG91dHB1dENvb3JkcztcbiAgICAgICAgaW50IHJvd3MgPSAke3NxdWVlemVkT3V0cHV0U2hhcGVbMl19O1xuICAgICAgICBpbnQgY29scyA9ICR7c3F1ZWV6ZWRPdXRwdXRTaGFwZVsxXX07XG5cbiAgICAgICAgJHttYWluTG9vcH1cbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9XG4gICAgYDtcblxuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBzcXVlZXplZE91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dDNELnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDNEOiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlM0Q6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1NZXRhZGF0YShvdXRwdXRTaGFwZTNEKTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXQzRCwgbWV0YWRhdGEsIG91dHB1dFNoYXBlM0QpIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc0RpbXMzRChzaGFwZTogQXJyYXlMaWtlPG51bWJlcj4pOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIFsxLCAxLCAxXTtcbiAgfVxuICAvLyBUT0RPOiBzcXVlZXplIG90aGVyIHNoYXBlcyB0byAyRCBjYXNlXG4gIGxldCBiYXRjaCA9IDE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2hhcGUubGVuZ3RoIC0gMjsgKytpKSB7XG4gICAgYmF0Y2ggKj0gc2hhcGVbaV07XG4gIH1cbiAgcmV0dXJuIFtiYXRjaCwgc2hhcGUubGVuZ3RoID4gMSA/IHNoYXBlW3NoYXBlLmxlbmd0aCAtIDJdIDogMSwgc2hhcGVbc2hhcGUubGVuZ3RoIC0gMV1dO1xufVxuXG4vLyBGb3IgcGFja2VkIHJlc2hhcGUsIHdlIG5lZWQgdG8gcmUtYXJyYW5nZSB0ZXhlbCBkYXRhIGZvciBvdXRwdXQgc2hhcGUuXG4vLyBPdXIgcGFjayBpcyBkZXNpZ25lZCB0byBwYWNrIGEgMngyIHRpbGUgaW4gbGFzdCBoIGFuZCB3IGRpbWVuc2lvbiwgc29cbi8vIGZvciB0aGUgcmVzaGFwZWQgbmV3IHRlbnNvciwgd2UganVzdCBuZWVkIHRvIHJlLWFycmFuZ2UgdGhlIGxhc3QgaCBhbmRcbi8vIHcgZGltZW5zaW9uLiBGb3IgYW55IHNoYXBlIHRoYXQgaXMgbm90IGluIDNELCBpLmUuIFtiYXRjaCwgVywgSF0sIHdlXG4vLyBmaXJzdCBjb252ZXJ0IGl0IHRvIDNEIGJ5IGNvbGxhcHNpbmcgb3RoZXIgZGltZW5zaW9uIHRvIGJhdGNoIGRpbSwgdGhlblxuLy8gcHJvY2VzcyB3aXRoIHRoZSBsYXN0IHR3byBkaW1lbnNpb25zLlxuLy8gTm90ZTogd2Ugb25seSBuZWVkIHRoZSBzaGFwZSB0ZW5zb3IgdG8gY2FsY3VsYXRlIG91dHB1dCBzaGFwZSwgc28gdGhlXG4vLyBjb250ZW50IGluIHNoYXBlIHRlbnNvciBpcyBuZXZlciB1cGxvYWRlZCB0byBHUFUuIEl0IGlzIGFsd2F5cyBrZXB0IGluIENQVS5cbi8vIFRPRE86IG9wdGltaXplIHRoZSBhbGdvcml0aG0gLS0gaW4gc29tZSBjYXNlcywgaWYgdGhlIGxhc3QgdHdvIGRpbXMgYXJlXG4vLyB0aGUgc2FtZSBiZXR3ZWVuIGlucHV0IHNoYXBlIGFuZCBvdXRwdXQgc2hhcGUsIHRoZSBwYWNrZWQgcmVzaGFwZSBjYW4gYmVcbi8vIHRyZWF0ZWQgYXMgbm8tb3AuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXNoYXBlQ2hlYXAoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHJlc2hhcGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10pIHtcbiAgbGV0IGlzQ2hlYXBSZXNoYXBlID0gZmFsc2U7XG4gIGlmIChkaW1zLmxlbmd0aCA9PT0gMCB8fCByZXNoYXBlZERpbXMubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gc2NhbGFyXG4gICAgaXNDaGVhcFJlc2hhcGUgPSB0cnVlO1xuICB9IGVsc2UgaWYgKGRpbXMubGVuZ3RoIDwgMiB8fCByZXNoYXBlZERpbXMubGVuZ3RoIDwgMikge1xuICAgIC8vIDFEXG4gICAgaXNDaGVhcFJlc2hhcGUgPSBkaW1zW2RpbXMubGVuZ3RoIC0gMV0gPT09IHJlc2hhcGVkRGltc1tyZXNoYXBlZERpbXMubGVuZ3RoIC0gMV07XG4gIH0gZWxzZSB7XG4gICAgLy8gMkQgK1xuICAgIGlzQ2hlYXBSZXNoYXBlID1cbiAgICAgIGRpbXNbZGltcy5sZW5ndGggLSAxXSA9PT0gcmVzaGFwZWREaW1zW3Jlc2hhcGVkRGltcy5sZW5ndGggLSAxXSAmJlxuICAgICAgZGltc1tkaW1zLmxlbmd0aCAtIDJdID09PSByZXNoYXBlZERpbXNbcmVzaGFwZWREaW1zLmxlbmd0aCAtIDJdO1xuICB9XG5cbiAgcmV0dXJuIGlzQ2hlYXBSZXNoYXBlO1xufVxuXG5mdW5jdGlvbiBnZXRSZXNoYXBlZElucHV0Q29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiBzdHJpbmcge1xuICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHNoYXBlKTtcbiAgY29uc3QgY29vcmRzID0gWydiJywgJ3InLCAnYyddO1xuICBjb25zdCBpbmRleCA9ICdpbmRleCc7XG4gIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNbaV19ID0gJHtpbmRleH0gLyAke3N0cmlkZX1gO1xuICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICBpID09PSBzdHJpZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICA/IGBpbnQgJHtjb29yZHNbaSArIDFdfSA9ICR7aW5kZXh9IC0gJHtjb29yZHNbaV19ICogJHtzdHJpZGV9YFxuICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICByZXR1cm4gYCR7bGluZTF9OyAke2xpbmUyfTtgO1xuICAgIH0pXG4gICAgLmpvaW4oJycpO1xuXG4gIHJldHVybiBgXG4gICAgaXZlYzMgaW5wdXRDb29yZHNGcm9tUmVzaGFwZWRPdXRDb29yZHMoaW50IGluZGV4KSB7XG4gICAgICAke2Nvb3Jkc0Zyb21JbmRleFNuaXBwZXR9XG4gICAgICByZXR1cm4gaXZlYzMoYiwgciwgYyk7XG4gICAgfVxuICBgO1xufVxuXG5mdW5jdGlvbiBnZXRGbGF0dGVuZWRJbmRleEZyb20zRChzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhzaGFwZSk7XG5cbiAgcmV0dXJuIGBcbiAgaW50IGdldEZsYXR0ZW5lZEluZGV4KGl2ZWMzIGNvb3Jkcykge1xuICAgIC8vIHJldmVyc2UgeSwgeiBvcmRlclxuICAgIHJldHVybiBjb29yZHMueCAqICR7c3RyaWRlc1swXX0gKyBjb29yZHMueiAqICR7c3RyaWRlc1sxXX0gKyBjb29yZHMueTtcbiAgfVxuYDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFRleHR1cmVEYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGVuY29kZUFzVWludDggPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGV4dHVyZURhdGEpOiBUZXh0dXJlRGF0YSA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXQuc2hhcGU7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgLyoqXG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS90ZW5zb3JmbG93L3RmanMtY29yZS9ibG9iL21hc3Rlci9zcmMva2VybmVscy93ZWJnbC9lbmNvZGVfZmxvYXRfZ3B1LnRzXG4gICAqL1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgY29uc3QgZmxvYXQgRkxPQVRfTUFYID0gMS43MDE0MTE4NGUzODtcbiAgICBjb25zdCBmbG9hdCBGTE9BVF9NSU4gPSAxLjE3NTQ5NDM1ZS0zODtcblxuICAgIGJvb2wgaXNOYU4oZmxvYXQgdmFsKSB7XG4gICAgICByZXR1cm4gKHZhbCA8IDEuMCB8fCAwLjAgPCB2YWwgfHwgdmFsID09IDAuMCkgPyBmYWxzZSA6IHRydWU7XG4gICAgfVxuXG4gICAgaGlnaHAgdmVjNCBlbmNvZGVBc1VpbnQ4KGhpZ2hwIGZsb2F0IHYpIHtcbiAgICAgIGlmIChpc05hTih2KSkge1xuICAgICAgICByZXR1cm4gdmVjNCgyNTUsIDI1NSwgMjU1LCAyNTUpO1xuICAgICAgfVxuXG4gICAgICBoaWdocCBmbG9hdCBhdiA9IGFicyh2KTtcblxuICAgICAgaWYoYXYgPCBGTE9BVF9NSU4pIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoMC4wLCAwLjAsIDAuMCwgMC4wKTtcbiAgICAgIH0gZWxzZSBpZih2ID4gRkxPQVRfTUFYKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KDAuMCwgMC4wLCAxMjguMCwgMTI3LjApIC8gMjU1LjA7XG4gICAgICB9IGVsc2UgaWYodiA8IC1GTE9BVF9NQVgpIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoMC4wLCAwLjAsICAxMjguMCwgMjU1LjApIC8gMjU1LjA7XG4gICAgICB9XG5cbiAgICAgIGhpZ2hwIHZlYzQgYyA9IHZlYzQoMCwwLDAsMCk7XG5cbiAgICAgIGhpZ2hwIGZsb2F0IGUgPSBmbG9vcihsb2cyKGF2KSk7XG4gICAgICBoaWdocCBmbG9hdCBtID0gZXhwMihmcmFjdChsb2cyKGF2KSkpIC0gMS4wO1xuXG4gICAgICBjWzJdID0gZmxvb3IoMTI4LjAgKiBtKTtcbiAgICAgIG0gLT0gY1syXSAvIDEyOC4wO1xuICAgICAgY1sxXSA9IGZsb29yKDMyNzY4LjAgKiBtKTtcbiAgICAgIG0gLT0gY1sxXSAvIDMyNzY4LjA7XG4gICAgICBjWzBdID0gZmxvb3IoODM4ODYwOC4wICogbSk7XG5cbiAgICAgIGhpZ2hwIGZsb2F0IGViaWFzID0gZSArIDEyNy4wO1xuICAgICAgY1szXSA9IGZsb29yKGViaWFzIC8gMi4wKTtcbiAgICAgIGViaWFzIC09IGNbM10gKiAyLjA7XG4gICAgICBjWzJdICs9IGZsb29yKGViaWFzKSAqIDEyOC4wO1xuXG4gICAgICBjWzNdICs9IDEyOC4wICogc3RlcCgwLjAsIC12KTtcblxuICAgICAgcmV0dXJuIGMgLyAyNTUuMDtcbiAgICB9XG5cbiAgICB2b2lkIG1haW4oKSB7XG4gICAgICBmbG9hdCB2YWx1ZSA9ICR7Z2xzbC50ZXh0dXJlMkR9KFgsVGV4Q29vcmRzKS5yO1xuICAgICAgJHtnbHNsLm91dHB1dH0gPSBlbmNvZGVBc1VpbnQ4KHZhbHVlKTtcbiAgICB9YDtcbiAgY29uc3QgcHJvZ3JhbUluZm8gPSB7XG4gICAgbmFtZTogJ1VpbnQ4RW5jb2RlJyxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIGlucHV0TmFtZXM6IFsnWCddLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudGVuc29yLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5kb3dubG9hZFVpbnQ4QXNGbG9hdCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xuICByZXR1cm4gaW5mZXJlbmNlSGFuZGxlci5leGVjdXRlUHJvZ3JhbShwcm9ncmFtSW5mbywgW2lucHV0LnRlbnNvcl0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IGdldENoYW5uZWxzLCB1bnBhY2tGcm9tQ2hhbm5lbCB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IHVucGFja1Byb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ3VucGFjaycsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVVbnBhY2tQcm9ncmFtSW5mbyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHJhbmsgPSBpbnB1dC5kaW1zLmxlbmd0aDtcblxuICBjb25zdCBjaGFubmVscyA9IGdldENoYW5uZWxzKCdyYycsIHJhbmspO1xuICBjb25zdCBpbm5lckRpbXMgPSBjaGFubmVscy5zbGljZSgtMik7XG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUocmFuayk7XG4gIGNvbnN0IHVucGFja0NoYW5uZWwgPSB1bnBhY2tGcm9tQ2hhbm5lbCgpO1xuICBjb25zdCBpc1NjYWxhciA9IGlucHV0LmRpbXMubGVuZ3RoID09PSAwO1xuICBjb25zdCBzb3VyY2VDb29yZHMgPSBpc1NjYWxhciA/ICcnIDogZ2V0U291cmNlQ29vcmRzKHJhbmssIGNoYW5uZWxzKTtcbiAgY29uc3QgY29vcmRzID0gcmFuayA8PSAxID8gJ3JjJyA6IGB2ZWMyKCR7aW5uZXJEaW1zLmpvaW4oJywnKX0pYDtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgJHt1bnBhY2tDaGFubmVsfVxuICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICR7Y29vcmRzRGF0YVR5cGV9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAvLyBTYW1wbGUgdGhlIHRleHR1cmUgd2l0aCB0aGUgY29vcmRzIHRvIGdldCB0aGUgcmdiYSBjaGFubmVsIHZhbHVlLlxuICAgICAgIHZlYzQgcGFja2VkSW5wdXQgPSBnZXRBKCR7c291cmNlQ29vcmRzfSk7XG5cbiAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQoZ2V0Q2hhbm5lbChwYWNrZWRJbnB1dCwgJHtjb29yZHN9KSwgMCwgMCwgMCk7XG4gICAgIH1cbiAgIGA7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi51bnBhY2tQcm9ncmFtTWV0YWRhdGEsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvTG9hZGVyID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvTG9hZGVyID0+ICh7XG4gIC4uLnVucGFja1Byb2dyYW1NZXRhZGF0YSxcbiAgZ2V0OiAoKSA9PiBjcmVhdGVVbnBhY2tQcm9ncmFtSW5mbyhoYW5kbGVyLCBpbnB1dCksXG59KTtcblxuZnVuY3Rpb24gZ2V0U291cmNlQ29vcmRzKHJhbms6IG51bWJlciwgZGltczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBpZiAocmFuayA9PT0gMSkge1xuICAgIHJldHVybiAncmMnO1xuICB9XG5cbiAgbGV0IGNvb3JkcyA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7IGkrKykge1xuICAgIGNvb3JkcyArPSBkaW1zW2ldO1xuICAgIGlmIChpIDwgcmFuayAtIDEpIHtcbiAgICAgIGNvb3JkcyArPSAnLCc7XG4gICAgfVxuICB9XG4gIHJldHVybiBjb29yZHM7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgRW5jb2RlciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgRGF0YVR5cGVNYXAge1xuICAgIGZsb2F0OiBGbG9hdDMyQXJyYXk7XG4gICAgYnl0ZTogVWludDhBcnJheTtcbiAgICBpbnQ6IFVpbnQzMkFycmF5O1xuICB9XG4gIGV4cG9ydCB0eXBlIERhdGFUeXBlID0ga2V5b2YgRGF0YVR5cGVNYXA7XG4gIHR5cGUgRGF0YUFycmF5VHlwZSA9IERhdGFUeXBlTWFwW0RhdGFUeXBlXTtcbn1cblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXG5leHBvcnQgY29uc3QgZW51bSBFbmNvZGVyVXNhZ2Uge1xuICBEZWZhdWx0ID0gMCxcbiAgVXBsb2FkT25seSxcbiAgRG93bmxvYWQ0Qnl0ZXNBc0Zsb2F0MzIsXG59XG4vKiBlc2xpbnQtZW5hYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xuXG4vKipcbiAqIEFic3RyYWN0aW9uIGZvciBtYXBwaW5nIGRhdGEgdHlwZXMgdG8gdGV4dHVyZSB0ZXhsZXRzXG4gKiBFbmNvZGluZyBtZWFucyBob3cgYSBGbG9hdDMyIGlzIG1hcHBlZCB0byAxIG9yIDQgY2hhbm5lbHMgZm9yIGVhY2ggdGV4bGV0XG4gKiBEZWNvZGluZyBtZWFucyBob3cgYSB0ZXhsZXQncyBjaGFubmVscyBhcmUgbWFwcGVkIHRvIGEgcmVzdWx0aW5nIEZsb2F0MzJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRhRW5jb2RlciB7XG4gIGludGVybmFsRm9ybWF0OiBudW1iZXI7XG4gIGZvcm1hdDogbnVtYmVyO1xuICB0ZXh0dXJlVHlwZTogbnVtYmVyO1xuICBjaGFubmVsU2l6ZTogbnVtYmVyO1xuICBlbmNvZGUoc3JjOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIHRleHR1cmVTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGU7XG4gIGFsbG9jYXRlKHNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZTtcbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlO1xufVxuLyoqXG4gKiBXZWJHTDIgZGF0YSBlbmNvZGVyXG4gKiBVc2VzIFIzMkYgYXMgdGhlIGZvcm1hdCBmb3IgdGV4bGV0XG4gKi9cbmV4cG9ydCBjbGFzcyBSZWRGbG9hdDMyRGF0YUVuY29kZXIgaW1wbGVtZW50cyBEYXRhRW5jb2RlciB7XG4gIGludGVybmFsRm9ybWF0OiBudW1iZXI7XG4gIGZvcm1hdDogbnVtYmVyO1xuICB0ZXh0dXJlVHlwZTogbnVtYmVyO1xuICBjaGFubmVsU2l6ZTogbnVtYmVyO1xuICBjb25zdHJ1Y3RvcihnbDogV2ViR0wyUmVuZGVyaW5nQ29udGV4dCwgY2hhbm5lbHMgPSAxKSB7XG4gICAgaWYgKGNoYW5uZWxzID09PSAxKSB7XG4gICAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuUjMyRjtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZ2wuUkVEO1xuICAgICAgdGhpcy50ZXh0dXJlVHlwZSA9IGdsLkZMT0FUO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbHMgPT09IDQpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SR0JBMzJGO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy50ZXh0dXJlVHlwZSA9IGdsLkZMT0FUO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbnVtYmVyIG9mIGNoYW5uZWxzOiAke2NoYW5uZWxzfWApO1xuICAgIH1cbiAgfVxuICBlbmNvZGUoc3JjOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIHRleHR1cmVTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIGxldCByZXN1bHQ6IEZsb2F0MzJBcnJheTtcbiAgICBsZXQgc291cmNlOiBGbG9hdDMyQXJyYXk7XG4gICAgaWYgKHNyYy5jb25zdHJ1Y3RvciAhPT0gRmxvYXQzMkFycmF5KSB7XG4gICAgICBMb2dnZXIud2FybmluZygnRW5jb2RlcicsICdkYXRhIHdhcyBub3Qgb2YgdHlwZSBGbG9hdDMyOyBjcmVhdGluZyBuZXcgRmxvYXQzMkFycmF5Jyk7XG4gICAgICBzb3VyY2UgPSBuZXcgRmxvYXQzMkFycmF5KHNyYyk7XG4gICAgfVxuICAgIGlmICh0ZXh0dXJlU2l6ZSAqIHRoaXMuY2hhbm5lbFNpemUgPiBzcmMubGVuZ3RoKSB7XG4gICAgICBMb2dnZXIud2FybmluZygnRW5jb2RlcicsICdTb3VyY2UgZGF0YSB0b28gc21hbGwuIEFsbG9jYXRpbmcgbGFyZ2VyIGFycmF5Jyk7XG4gICAgICBzb3VyY2UgPSBzcmMgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgcmVzdWx0ID0gdGhpcy5hbGxvY2F0ZSh0ZXh0dXJlU2l6ZSAqIHRoaXMuY2hhbm5lbFNpemUpIGFzIEZsb2F0MzJBcnJheTtcbiAgICAgIHNvdXJjZS5mb3JFYWNoKCh2LCBpKSA9PiAocmVzdWx0W2ldID0gdikpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzb3VyY2UgPSBzcmMgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgcmVzdWx0ID0gc291cmNlO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGFsbG9jYXRlKHNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoc2l6ZSAqIDQpO1xuICB9XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IEZsb2F0MzJBcnJheSB7XG4gICAgaWYgKHRoaXMuY2hhbm5lbFNpemUgPT09IDEpIHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IChidWZmZXIgYXMgRmxvYXQzMkFycmF5KS5maWx0ZXIoKF92YWx1ZSwgaW5kZXgpID0+IGluZGV4ICUgNCA9PT0gMCkuc3ViYXJyYXkoMCwgZGF0YVNpemUpO1xuICAgICAgcmV0dXJuIGZpbHRlcmVkRGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1ZmZlci5zdWJhcnJheSgwLCBkYXRhU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICB9XG59XG4vKipcbiAqIERhdGEgZW5jb2RlciBmb3IgV2ViR0wgMSB3aXRoIHN1cHBvcnQgZm9yIGZsb2F0aW5nIHBvaW50IHRleHR1cmVcbiAqL1xuZXhwb3J0IGNsYXNzIFJHQkFGbG9hdERhdGFFbmNvZGVyIGltcGxlbWVudHMgRGF0YUVuY29kZXIge1xuICBpbnRlcm5hbEZvcm1hdDogbnVtYmVyO1xuICBmb3JtYXQ6IG51bWJlcjtcbiAgdGV4dHVyZVR5cGU6IG51bWJlcjtcbiAgY2hhbm5lbFNpemU6IG51bWJlcjtcbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgY2hhbm5lbHMgPSAxLCB0ZXh0dXJlVHlwZT86IG51bWJlcikge1xuICAgIGlmIChjaGFubmVscyAhPT0gMSAmJiBjaGFubmVscyAhPT0gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG51bWJlciBvZiBjaGFubmVsczogJHtjaGFubmVsc31gKTtcbiAgICB9XG4gICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLlJHQkE7XG4gICAgdGhpcy5mb3JtYXQgPSBnbC5SR0JBO1xuICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB0aGlzLnRleHR1cmVUeXBlID0gdGV4dHVyZVR5cGUgfHwgZ2wuRkxPQVQ7XG4gIH1cbiAgZW5jb2RlKHNyYzogRmxvYXQzMkFycmF5LCB0ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICBsZXQgZGVzdCA9IHNyYztcbiAgICBpZiAodGhpcy5jaGFubmVsU2l6ZSA9PT0gMSkge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ0VuY29kZXInLCAnRXhwbG9kaW5nIGludG8gYSBsYXJnZXIgYXJyYXknKTtcbiAgICAgIGRlc3QgPSB0aGlzLmFsbG9jYXRlKHRleHR1cmVTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICBzcmMuZm9yRWFjaCgodiwgaSkgPT4gKGRlc3RbaSAqIDRdID0gdikpO1xuICAgIH1cbiAgICByZXR1cm4gZGVzdDtcbiAgfVxuICBhbGxvY2F0ZShzaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KHNpemUgKiA0KTtcbiAgfVxuICBkZWNvZGUoYnVmZmVyOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIGRhdGFTaXplOiBudW1iZXIpOiBGbG9hdDMyQXJyYXkge1xuICAgIGlmICh0aGlzLmNoYW5uZWxTaXplID09PSAxKSB7XG4gICAgICBjb25zdCBmaWx0ZXJlZERhdGEgPSAoYnVmZmVyIGFzIEZsb2F0MzJBcnJheSkuZmlsdGVyKChfdmFsdWUsIGluZGV4KSA9PiBpbmRleCAlIDQgPT09IDApLnN1YmFycmF5KDAsIGRhdGFTaXplKTtcbiAgICAgIHJldHVybiBmaWx0ZXJlZERhdGE7XG4gICAgfVxuICAgIHJldHVybiBidWZmZXIuc3ViYXJyYXkoMCwgZGF0YVNpemUpIGFzIEZsb2F0MzJBcnJheTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgVWludDhEYXRhRW5jb2RlciBpbXBsZW1lbnRzIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplID0gNDtcbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgY2hhbm5lbHMgPSAxKSB7XG4gICAgaWYgKGNoYW5uZWxzID09PSAxKSB7XG4gICAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuQUxQSEE7XG4gICAgICB0aGlzLmZvcm1hdCA9IGdsLkFMUEhBOyAvLyBub3QgdGVzdGVkXG4gICAgICB0aGlzLnRleHR1cmVUeXBlID0gZ2wuVU5TSUdORURfQllURTtcbiAgICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB9IGVsc2UgaWYgKGNoYW5uZWxzID09PSA0KSB7XG4gICAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuUkdCQTtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZ2wuUkdCQTtcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5VTlNJR05FRF9CWVRFO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbnVtYmVyIG9mIGNoYW5uZWxzOiAke2NoYW5uZWxzfWApO1xuICAgIH1cbiAgfVxuICBlbmNvZGUoc3JjOiBVaW50OEFycmF5LCBfdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHNyYy5idWZmZXIsIHNyYy5ieXRlT2Zmc2V0LCBzcmMuYnl0ZUxlbmd0aCk7XG4gIH1cbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc2l6ZSAqIHRoaXMuY2hhbm5lbFNpemUpO1xuICB9XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IFVpbnQ4QXJyYXkge1xuICAgIGlmIChidWZmZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICByZXR1cm4gYnVmZmVyLnN1YmFycmF5KDAsIGRhdGFTaXplKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGFycmF5IHR5cGU6ICR7YnVmZmVyLmNvbnN0cnVjdG9yfWApO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5pbXBvcnQgeyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksIFdpZHRoSGVpZ2h0UHJlZnMgfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7IFRleHR1cmVMYXlvdXQsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlID0gKFxuICB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUsXG4pOiBUZXh0dXJlTGF5b3V0ID0+IHtcbiAgY29uc3QgY2hhbm5lbCA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS51bnBhY2tlZCB8fCB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUudW5wYWNrZWRSZXZlcnNlZCA/IDEgOiA0O1xuICBjb25zdCBpc1BhY2tlZCA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQ7XG4gIGNvbnN0IHJldmVyc2VXSCA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS51bnBhY2tlZFJldmVyc2VkIHx8IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQ7XG4gIGNvbnN0IGJyZWFrQXhpcyA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uID8gc2hhcGUubGVuZ3RoIC0gMSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgdW5wYWNrZWRTaGFwZSA9XG4gICAgdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb25cbiAgICAgID8gc2hhcGUubWFwKChkLCBpKSA9PiAoaSA9PT0gc2hhcGUubGVuZ3RoIC0gMSA/IGQgKiA0IDogZCkpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgcmV0dXJuIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUodGV4dHVyZUxheW91dFN0cmF0ZWd5LCBzaGFwZSwgY2hhbm5lbCwgdW5wYWNrZWRTaGFwZSwge1xuICAgIGlzUGFja2VkLFxuICAgIHJldmVyc2VXSCxcbiAgICBicmVha0F4aXMsXG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodCA9IChcbiAgdGV4dHVyZUxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLFxuKTogW251bWJlciwgbnVtYmVyXSA9PiB7XG4gIGNvbnN0IGxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUodGV4dHVyZUxheW91dFN0cmF0ZWd5LCBzaGFwZSwgdGV4dHVyZVR5cGUpO1xuICByZXR1cm4gW2xheW91dC53aWR0aCwgbGF5b3V0LmhlaWdodF07XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIFRleHR1cmVMYXlvdXQgb2JqZWN0IGZyb20gc2hhcGUuXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVNoYXBlID0gKFxuICB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBjaGFubmVsczogMSB8IDQgPSAxLFxuICB1bnBhY2tlZFNoYXBlPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyxcbik6IFRleHR1cmVMYXlvdXQgPT4ge1xuICBjb25zdCBpc1BhY2tlZCA9ICEhKHByZWZzICYmIHByZWZzLmlzUGFja2VkKTtcbiAgY29uc3QgW3dpZHRoLCBoZWlnaHRdID0gdGV4dHVyZUxheW91dFN0cmF0ZWd5LmNvbXB1dGVUZXh0dXJlV0goaXNQYWNrZWQgPyB1bnBhY2tlZFNoYXBlIHx8IHNoYXBlIDogc2hhcGUsIHByZWZzKTtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgbGV0IGluZmVycmVkRGltcyA9IHNoYXBlLnNsaWNlKDApO1xuICBpZiAocmFuayA9PT0gMCkge1xuICAgIGluZmVycmVkRGltcyA9IFsxXTtcbiAgfVxuICBpZiAoY2hhbm5lbHMgPT09IDEpIHtcbiAgICAvLyB1bnBhY2tlZFNoYXBlIHdpbGwgdGFrZSBgc2hhcGVgIGFuZCBub3QgYGluZmVycmVkRGltc2Agc28gYXMgdG8gY3JlYXRlIGEgc2NhbGFyIFRlbnNvciBpZiBuZWVkIGJlXG4gICAgdW5wYWNrZWRTaGFwZSA9IHNoYXBlO1xuICB9IGVsc2UgaWYgKGlzUGFja2VkKSB7XG4gICAgaWYgKGNoYW5uZWxzICE9PSA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2EgcGFja2VkIHRleHR1cmUgbXVzdCBiZSA0LWNoYW5uZWwnKTtcbiAgICB9XG4gICAgdW5wYWNrZWRTaGFwZSA9IHNoYXBlO1xuICAgIGlmIChyYW5rID4gMCkge1xuICAgICAgaW5mZXJyZWREaW1zW3JhbmsgLSAxXSA9IE1hdGguY2VpbChpbmZlcnJlZERpbXNbcmFuayAtIDFdIC8gMik7XG4gICAgfVxuICAgIGlmIChyYW5rID4gMSkge1xuICAgICAgaW5mZXJyZWREaW1zW3JhbmsgLSAyXSA9IE1hdGguY2VpbChpbmZlcnJlZERpbXNbcmFuayAtIDJdIC8gMik7XG4gICAgfVxuICB9IGVsc2UgaWYgKCF1bnBhY2tlZFNoYXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnBhY2tlZCBzaGFwZSBpcyBuZWVkZWQgd2hlbiB1c2luZyBjaGFubmVscyA+IDEnKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIHdpZHRoLFxuICAgIGhlaWdodCxcbiAgICBjaGFubmVscyxcbiAgICBpc1BhY2tlZCxcbiAgICBzaGFwZTogaW5mZXJyZWREaW1zLFxuICAgIHN0cmlkZXM6IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhpbmZlcnJlZERpbXMpLFxuICAgIHVucGFja2VkU2hhcGUsXG4gICAgcmV2ZXJzZWRXSDogcHJlZnMgJiYgcHJlZnMucmV2ZXJzZVdILFxuICB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uLy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmltcG9ydCB7IGNyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vb3BzL3BhY2snO1xuaW1wb3J0IHsgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm9Mb2FkZXIsIGlzUmVzaGFwZUNoZWFwLCBwcm9jZXNzRGltczNEIH0gZnJvbSAnLi9vcHMvcmVzaGFwZS1wYWNrZWQnO1xuaW1wb3J0IHsgZW5jb2RlQXNVaW50OCB9IGZyb20gJy4vb3BzL3VpbnQ4LWVuY29kZSc7XG5pbXBvcnQgeyBjcmVhdGVVbnBhY2tQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vb3BzL3VucGFjayc7XG5pbXBvcnQgeyBXZWJHTFNlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi9zZXNzaW9uLWhhbmRsZXInO1xuaW1wb3J0IHsgRW5jb2RlclVzYWdlIH0gZnJvbSAnLi90ZXh0dXJlLWRhdGEtZW5jb2Rlcic7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQsXG4gIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUsXG4gIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUsXG59IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQnO1xuaW1wb3J0IHsgQXJ0aWZhY3QsIFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZURhdGEsIFRleHR1cmVMYXlvdXQsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi90eXBlcyc7XG5cbmNvbnN0IGdldFByb2dyYW1JbmZvVW5pcXVlS2V5ID0gKFxuICBwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm8gfCBQcm9ncmFtSW5mb0xvYWRlcixcbiAgaW5wdXRUZXh0dXJlRGF0YXM6IFRleHR1cmVEYXRhW10sXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBpbnB1dFRleHR1cmVEYXRhc1xuICAgIC5tYXAoKHRleHR1cmUpID0+IGAke3RleHR1cmUudW5wYWNrZWRTaGFwZS5qb2luKCcsJyl9OyR7dGV4dHVyZS53aWR0aH14JHt0ZXh0dXJlLmhlaWdodH1gKVxuICAgIC5qb2luKCdfJyk7XG4gIGxldCBrZXkgPSBwcm9ncmFtSW5mby5uYW1lO1xuICBpZiAocHJvZ3JhbUluZm8uY2FjaGVIaW50KSB7XG4gICAga2V5ICs9ICdbJyArIHByb2dyYW1JbmZvLmNhY2hlSGludCArICddJztcbiAgfVxuICBrZXkgKz0gJzonICsgaW5wdXRzO1xuICByZXR1cm4ga2V5O1xufTtcblxuZXhwb3J0IGNsYXNzIFdlYkdMSW5mZXJlbmNlSGFuZGxlciBpbXBsZW1lbnRzIEluZmVyZW5jZUhhbmRsZXIge1xuICBwcml2YXRlIHBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgcHJpdmF0ZSB1bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgY29uc3RydWN0b3IocHVibGljIHNlc3Npb246IFdlYkdMU2Vzc2lvbkhhbmRsZXIpIHtcbiAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgW3dpZHRoLCBoZWlnaHRdXG4gICAqL1xuICBjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICByZXR1cm4gY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSwgc2hhcGUsIHRleHR1cmVUeXBlKTtcbiAgfVxuXG4gIGV4ZWN1dGVQcm9ncmFtKHByb2dyYW06IFByb2dyYW1JbmZvIHwgUHJvZ3JhbUluZm9Mb2FkZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10pOiBUZXh0dXJlRGF0YSB7XG4gICAgaWYgKGlucHV0cy5sZW5ndGggPCBwcm9ncmFtLmlucHV0TmFtZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYElucHV0IHNpemUgbXVzdG4ndCBiZSBsZXNzIHRoYW4gJHtwcm9ncmFtLmlucHV0TmFtZXMubGVuZ3RofS5gKTtcbiAgICB9XG4gICAgaWYgKHByb2dyYW0uaW5wdXROYW1lcy5sZW5ndGggIT09IHByb2dyYW0uaW5wdXRUeXBlcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgbmFtZXMgc2l6ZSBkb2VzIG5vdCBtYXRjaCBpbnB1dCB0eXBlcycpO1xuICAgIH1cblxuICAgIC8vIGNyZWF0ZSB0ZXh0dXJlIGluZm8gZm9yIGlucHV0XG4gICAgY29uc3QgaW5wdXRUZXh0dXJlRGF0YXM6IFRleHR1cmVEYXRhW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb2dyYW0uaW5wdXROYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgaW5wdXRUZXh0dXJlRGF0YXNbaV0gPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXRzW2ldLCBwcm9ncmFtLmlucHV0VHlwZXNbaV0pO1xuICAgIH1cblxuICAgIGNvbnN0IGtleSA9IGdldFByb2dyYW1JbmZvVW5pcXVlS2V5KHByb2dyYW0sIGlucHV0VGV4dHVyZURhdGFzKTtcbiAgICBsZXQgYXJ0aWZhY3QgPSB0aGlzLnNlc3Npb24ucHJvZ3JhbU1hbmFnZXIuZ2V0QXJ0aWZhY3Qoa2V5KTtcbiAgICBjb25zdCBwcm9ncmFtSW5mbyA9IGFydGlmYWN0XG4gICAgICA/IGFydGlmYWN0LnByb2dyYW1JbmZvXG4gICAgICA6IHR5cGVvZiAocHJvZ3JhbSBhcyBQcm9ncmFtSW5mb0xvYWRlcikuZ2V0ID09PSAnZnVuY3Rpb24nXG4gICAgICAgID8gKHByb2dyYW0gYXMgUHJvZ3JhbUluZm9Mb2FkZXIpLmdldCgpXG4gICAgICAgIDogKHByb2dyYW0gYXMgUHJvZ3JhbUluZm8pO1xuXG4gICAgLy8gY3JlYXRlIHRleHR1cmUgaW5mbyBmb3Igb3V0cHV0XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZUxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUoXG4gICAgICB0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksXG4gICAgICBwcm9ncmFtSW5mby5vdXRwdXQuZGltcyxcbiAgICAgIHByb2dyYW1JbmZvLm91dHB1dC50ZXh0dXJlVHlwZSxcbiAgICApO1xuICAgIGNvbnN0IG91dHB1dFRleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShvdXRwdXRUZXh0dXJlTGF5b3V0LCBwcm9ncmFtSW5mby5vdXRwdXQudHlwZSk7XG5cbiAgICBpZiAoIWFydGlmYWN0KSB7XG4gICAgICBhcnRpZmFjdCA9IHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5idWlsZChwcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlRGF0YXMsIG91dHB1dFRleHR1cmVEYXRhKTtcbiAgICAgIHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5zZXRBcnRpZmFjdChrZXksIGFydGlmYWN0KTtcbiAgICB9XG5cbiAgICB0aGlzLnJ1blByb2dyYW0oYXJ0aWZhY3QsIGlucHV0VGV4dHVyZURhdGFzLCBvdXRwdXRUZXh0dXJlRGF0YSk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhO1xuICB9XG5cbiAgcnVuKHByb2dyYW06IFByb2dyYW1JbmZvTG9hZGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdKTogVGVuc29yIHtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuZXhlY3V0ZVByb2dyYW0ocHJvZ3JhbSwgaW5wdXRzKTtcbiAgICByZXR1cm4gb3V0cHV0VGV4dHVyZURhdGEudGVuc29yO1xuICB9XG5cbiAgcHJpdmF0ZSBydW5Qcm9ncmFtKGFydGlmYWN0OiBBcnRpZmFjdCwgaW5wdXRzOiBUZXh0dXJlRGF0YVtdLCBvdXRwdXQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgLy8gaW5wdXQgc2hvdWxkIG1hdGNoXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmICghIWlucHV0c1tpXS5pc1BhY2tlZCAhPT0gKGFydGlmYWN0LnByb2dyYW1JbmZvLmlucHV0VHlwZXNbaV0gPT09IFRleHR1cmVUeXBlLnBhY2tlZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dFske2l9XSBwcm9wZXJ0eSBwYWNrZWQgaW5jb25zaXN0ZW50YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gb3V0cHV0IHNob3VsZCBtYXRjaFxuICAgIGlmICghIW91dHB1dC5pc1BhY2tlZCAhPT0gKGFydGlmYWN0LnByb2dyYW1JbmZvLm91dHB1dC50ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvdXRwdXQgcHJvcGVydHkgcGFja2VkIGluY29uc2lzdGVudCcpO1xuICAgIH1cblxuICAgIHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5ydW4oYXJ0aWZhY3QsIGlucHV0cywgb3V0cHV0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBUZXh0dXJlRGF0YSBvYmplY3QgZnJvbSBhIHRlbnNvci5cbiAgICogVXNhZ2UgPSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seS5cbiAgICogSWYgYSByZWxhdGVkIHRleHR1cmUgZGF0YSBpcyBmb3VuZCBpbiBjYWNoZSwgcmV0dXJucyBpdDtcbiAgICogT3RoZXJ3aXNlOlxuICAgKiAgIENyZWF0ZXMgYSBuZXcgdGV4dHVyZSBsYXlvdXQgaWYgbm90IHByb3ZpZGVkO1xuICAgKiAgIENyZWF0ZXMgV2ViR0xUZXh0dXJlIHdpdGggdGhlIGxheW91dDtcbiAgICogICBVcGxvYWQgdGVuc29yIGRhdGEgdG8gdGhlIHRleHR1cmU7XG4gICAqICAgQ3JlYXRlcyBhIHRleHR1cmUgZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiB0ZW5zb3IuXG4gICAqIEBwYXJhbSB0ZW5zb3IgdGhlIHRlbnNvciB3aXRoIGRhdGEgdG8gdXBsb2FkXG4gICAqL1xuICBwcml2YXRlIGdldE9yQ3JlYXRlVGV4dHVyZURhdGEodGVuc29yOiBUZW5zb3IsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZSkge1xuICAgIGxldCB0ZCA9IHRoaXMuZ2V0VGV4dHVyZURhdGEodGVuc29yLmRhdGFJZCwgdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZCk7XG5cbiAgICBpZiAoIXRkKSB7XG4gICAgICAvLyBjaGVjayBpZiB3ZSBoYXZlIHRleHR1cmUgZGF0YSBpbiBkaWZmZXJlbnQgdHlwZVxuICAgICAgdGQgPSB0aGlzLmdldFRleHR1cmVEYXRhKHRlbnNvci5kYXRhSWQsIHRleHR1cmVUeXBlICE9PSBUZXh0dXJlVHlwZS5wYWNrZWQpO1xuICAgICAgaWYgKHRkKSB7XG4gICAgICAgIGlmICh0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFjayh0ZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudW5wYWNrKHRkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGQpIHtcbiAgICAgIGNvbnN0IGxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCB0ZW5zb3IuZGltcywgdGV4dHVyZVR5cGUpO1xuXG4gICAgICBpZiAodGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24pIHtcbiAgICAgICAgY29uc3QgZ3JvdXAgPSAxO1xuICAgICAgICBjb25zdCBjaGFubmVscyA9IDQ7XG4gICAgICAgIGNvbnN0IHNoYXBlID0gdGVuc29yLmRpbXM7XG4gICAgICAgIGlmIChzaGFwZS5sZW5ndGggPT09IDQpIHtcbiAgICAgICAgICAvLyBwcmUtcHJvY2Vzc2luZyBmb3Iga2VybmVsIGRhdGEgb2YgQ29udi5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIFRPRE86IGN1cnJlbnRseSB0aGlzIGlzIGEgaGFja2luZyB0byBvdmVyd3JpdGUgQ29udidzIHdlaWdodC4gVGhlIGNvcnJlY3Qgd2F5IHRvIGRvIHRoaXMgc2hvdWxkIGJlOlxuICAgICAgICAgIC8vIDEuIGltcGxlbWVudCB0ZXh0dXJlIGJhc2VkIGNvbnN0LWZvbGRpbmdcbiAgICAgICAgICAvLyAyLiBjcmVhdGUgYSBXZWJHTCBwcm9ncmFtIFwicHJlcHJvY2Vzc0NvbnZXZWlnaHRcIiB0byBkbyB0aGUgc2FtZSB3b3JrIGFzIGJlbG93XG4gICAgICAgICAgLy8gMy4gcnVuIHRoZSBwcm9ncmFtIGJlZm9yZSBkb3RQcm9kdWN0LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgY29uc3QgYWRqdXN0ZWRLZXJuZWxTaGFwZSA9IFtzaGFwZVswXSwgTWF0aC5jZWlsKChzaGFwZVsxXSAqIHNoYXBlWzJdICogc2hhcGVbM10pIC8gY2hhbm5lbHMpXTtcbiAgICAgICAgICBjb25zdCBhZGp1c3RlZExheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUoXG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksXG4gICAgICAgICAgICBhZGp1c3RlZEtlcm5lbFNoYXBlLFxuICAgICAgICAgICAgdGV4dHVyZVR5cGUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBsZXQgYnVmZmVyID0gdGVuc29yLm51bWJlckRhdGE7XG4gICAgICAgICAgaWYgKChzaGFwZVsxXSAqIHNoYXBlWzJdICogc2hhcGVbM10pICUgY2hhbm5lbHMgIT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IG51bUZlYXR1cmVNYXBzID0gc2hhcGVbMF07XG4gICAgICAgICAgICBjb25zdCBvbGRSb3dTaXplID0gc2hhcGVbMV0gKiBzaGFwZVsyXSAqIHNoYXBlWzNdO1xuICAgICAgICAgICAgY29uc3QgbmV3Um93U2l6ZSA9IE1hdGguY2VpbCgob2xkUm93U2l6ZSAqIGdyb3VwKSAvIGNoYW5uZWxzKSAqIGNoYW5uZWxzO1xuICAgICAgICAgICAgY29uc3QgbmV3U2l6ZSA9IG51bUZlYXR1cmVNYXBzICogbmV3Um93U2l6ZTtcbiAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkobmV3U2l6ZSk7XG4gICAgICAgICAgICBmb3IgKGxldCBmID0gMDsgZiA8IG51bUZlYXR1cmVNYXBzOyArK2YpIHtcbiAgICAgICAgICAgICAgY29uc3Qgb2xkT2Zmc2V0ID0gZiAqIG9sZFJvd1NpemU7XG4gICAgICAgICAgICAgIGNvbnN0IG5ld09mZnNldCA9IGYgKiBuZXdSb3dTaXplICsgKGYgJSBncm91cCkgKiBvbGRSb3dTaXplO1xuICAgICAgICAgICAgICBidWZmZXIuc2V0KHRlbnNvci5udW1iZXJEYXRhLnN1YmFycmF5KG9sZE9mZnNldCwgb2xkT2Zmc2V0ICsgb2xkUm93U2l6ZSksIG5ld09mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKGFkanVzdGVkTGF5b3V0LCB0ZW5zb3IudHlwZSwgYnVmZmVyLCB0ZW5zb3IsIEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZCkge1xuICAgICAgICBjb25zdCB1bnBhY2tlZFRleHR1cmVMYXlvdXQgPSBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVNoYXBlKHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSwgdGVuc29yLmRpbXMsIDEsIFtdLCB7XG4gICAgICAgICAgcmV2ZXJzZVdIOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgdW5wYWNrZWRUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGEoXG4gICAgICAgICAgdW5wYWNrZWRUZXh0dXJlTGF5b3V0LFxuICAgICAgICAgIHRlbnNvci50eXBlLFxuICAgICAgICAgIHRlbnNvci5udW1iZXJEYXRhLFxuICAgICAgICAgIHRlbnNvcixcbiAgICAgICAgICBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSxcbiAgICAgICAgKTtcbiAgICAgICAgdGQgPSB0aGlzLnBhY2sodW5wYWNrZWRUZXh0dXJlRGF0YSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZCA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGEobGF5b3V0LCB0ZW5zb3IudHlwZSwgdGVuc29yLm51bWJlckRhdGEsIHRlbnNvciwgRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgVGV4dHVyZURhdGEgb2JqZWN0IHVzaW5nIHRoZSBnaXZlbiBkYXRhIGFuZCBiaW5kIHRvIHRoZSBnaXZlbiB0ZW5zb3IuXG4gICAqIFVzYWdlID0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkuXG4gICAqIE5PVEU6IHRoaXMgZnVuY3Rpb24gaXMgYSBoYWNrIGZvciBDb252IGltcGxlbWVudGF0aW9uLiBzaG91bGQgcmVtb3ZlIHRoaXMgZnVuY3Rpb24sIGFmdGVyIHJld3JpdGluZyBDb252XG4gICAqIGltcGxlbWVudGF0aW9uIGJ5IEdyYXBoLlRyYW5zZm9ybWVyXG4gICAqIEBwYXJhbSBkYXRhVHlwZSB0aGUgdGVuc29yIGRhdGEgdHlwZVxuICAgKiBAcGFyYW0gZGF0YSB0aGUgYWN0dWFsIGRhdGEgdG8gdXBsb2FkXG4gICAqIEBwYXJhbSB0ZW5zb3IgdGhlIHRlbnNvciB0byBiaW5kLiB0ZW5zb3IncyBkYXRhIGlzIGlnbm9yZWQuXG4gICAqL1xuICBjcmVhdGVUZXh0dXJlRGF0YUZyb21MYXlvdXRCaW5kVGVuc29yKFxuICAgIGxheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIGRhdGE6IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHRlbnNvcjogVGVuc29yLFxuICApOiBUZXh0dXJlRGF0YSB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dHVyZURhdGEobGF5b3V0LCBkYXRhVHlwZSwgZGF0YSwgdGVuc29yLCBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVRleHR1cmVEYXRhKFxuICAgIGxheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIGRhdGE/OiBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICB0ZW5zb3I/OiBUZW5zb3IsXG4gICAgdXNhZ2U/OiBFbmNvZGVyVXNhZ2UsXG4gICk6IFRleHR1cmVEYXRhIHtcbiAgICBMb2dnZXIudmVyYm9zZSgnSW5mZXJlbmNlSGFuZGxlcicsIGBDcmVhdGluZyBUZXh0dXJlRGF0YTogbGF5b3V0Olske0pTT04uc3RyaW5naWZ5KGxheW91dCl9XWApO1xuICAgIGNvbnN0IHRleHR1cmUgPSB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIuY3JlYXRlVGV4dHVyZUZyb21MYXlvdXQoZGF0YVR5cGUsIGxheW91dCwgZGF0YSwgdXNhZ2UpO1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUobGF5b3V0LCBkYXRhVHlwZSwgdGV4dHVyZSwgdGVuc29yKTtcbiAgfVxuXG4gIHJlc2hhcGVVbnBhY2tlZChpbnB1dDogVGVuc29yLCByZXNoYXBlZERpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yIHtcbiAgICBjb25zdCBpbnB1dFREID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0LCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gICAgY29uc3QgbmV3VGV4dHVyZUxheW91dDogVGV4dHVyZUxheW91dCA9IHtcbiAgICAgIGNoYW5uZWxzOiBpbnB1dFRELmNoYW5uZWxzLFxuICAgICAgaGVpZ2h0OiBpbnB1dFRELmhlaWdodCxcbiAgICAgIHdpZHRoOiBpbnB1dFRELndpZHRoLFxuICAgICAgLy8gaGFuZGxlIHJlc2hhcGluZyBpbnRvIHNjYWxhciBUZW5zb3JzXG4gICAgICBzaGFwZTogcmVzaGFwZWREaW1zLmxlbmd0aCAhPT0gMCA/IHJlc2hhcGVkRGltcyA6IFsxXSxcbiAgICAgIHN0cmlkZXM6IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhyZXNoYXBlZERpbXMpLFxuICAgICAgdW5wYWNrZWRTaGFwZTogcmVzaGFwZWREaW1zLFxuICAgIH07XG4gICAgY29uc3QgbmV3VGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUobmV3VGV4dHVyZUxheW91dCwgaW5wdXQudHlwZSwgaW5wdXRURC50ZXh0dXJlKTtcbiAgICByZXR1cm4gbmV3VGV4dHVyZURhdGEudGVuc29yO1xuICB9XG5cbiAgcmVzaGFwZVBhY2tlZChpbnB1dDogVGVuc29yLCByZXNoYXBlZERpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yIHtcbiAgICBjb25zdCBpbnB1dFREID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0LCBUZXh0dXJlVHlwZS5wYWNrZWQpO1xuXG4gICAgLy8gY2hlY2sgaWYgdGhlIHJlc2hhcGUgaXMgJ2NoZWFwJ1xuICAgIGlmIChpc1Jlc2hhcGVDaGVhcChpbnB1dC5kaW1zLCByZXNoYXBlZERpbXMpKSB7XG4gICAgICBjb25zdCBuZXdUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0ge1xuICAgICAgICBjaGFubmVsczogaW5wdXRURC5jaGFubmVscyxcbiAgICAgICAgaGVpZ2h0OiBpbnB1dFRELmhlaWdodCxcbiAgICAgICAgd2lkdGg6IGlucHV0VEQud2lkdGgsXG4gICAgICAgIC8vIGhhbmRsZSByZXNoYXBpbmcgaW50byBzY2FsYXIgVGVuc29yc1xuICAgICAgICBzaGFwZTogcmVzaGFwZWREaW1zLmxlbmd0aCAhPT0gMCA/IHJlc2hhcGVkRGltcyA6IFsxXSxcbiAgICAgICAgc3RyaWRlczogU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHJlc2hhcGVkRGltcyksXG4gICAgICAgIHVucGFja2VkU2hhcGU6IHJlc2hhcGVkRGltcyxcbiAgICAgICAgaXNQYWNrZWQ6IHRydWUsXG4gICAgICB9O1xuICAgICAgY29uc3QgbmV3VGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUobmV3VGV4dHVyZUxheW91dCwgaW5wdXQudHlwZSwgaW5wdXRURC50ZXh0dXJlKTtcbiAgICAgIHJldHVybiBuZXdUZXh0dXJlRGF0YS50ZW5zb3I7XG4gICAgfVxuXG4gICAgY29uc3Qgc3F1ZWV6ZWRJbnB1dFNoYXBlID0gcHJvY2Vzc0RpbXMzRChpbnB1dC5kaW1zKTtcbiAgICBjb25zdCBzcXVlZXplZE91dHB1dFNoYXBlID0gcHJvY2Vzc0RpbXMzRChyZXNoYXBlZERpbXMpO1xuXG4gICAgY29uc3Qgc3F1ZWV6ZWRJbnB1dFRlbnNvciA9IHRoaXMucmVzaGFwZVBhY2tlZChpbnB1dCwgc3F1ZWV6ZWRJbnB1dFNoYXBlKTtcbiAgICBjb25zdCBzcXVlZXplZE91dHB1dFRlbnNvciA9IHRoaXMucnVuKFxuICAgICAgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm9Mb2FkZXIodGhpcywgc3F1ZWV6ZWRJbnB1dFRlbnNvciwgc3F1ZWV6ZWRPdXRwdXRTaGFwZSksXG4gICAgICBbc3F1ZWV6ZWRJbnB1dFRlbnNvcl0sXG4gICAgKTtcbiAgICBjb25zdCBvdXRwdXRUZW5zb3IgPSB0aGlzLnJlc2hhcGVQYWNrZWQoc3F1ZWV6ZWRPdXRwdXRUZW5zb3IsIHJlc2hhcGVkRGltcyk7XG4gICAgcmV0dXJuIG91dHB1dFRlbnNvcjtcbiAgfVxuXG4gIGNhc3QoaW5wdXQ6IFRlbnNvciwgdHlwZTogVGVuc29yLkRhdGFUeXBlKTogVGVuc29yIHtcbiAgICBjb25zdCBpbnB1dFREID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0LCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gICAgY29uc3QgbmV3VGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUoaW5wdXRURCBhcyBUZXh0dXJlTGF5b3V0LCB0eXBlLCBpbnB1dFRELnRleHR1cmUpO1xuICAgIHJldHVybiBuZXdUZXh0dXJlRGF0YS50ZW5zb3I7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUoXG4gICAgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsXG4gICAgdGV4dHVyZTogV2ViR0xUZXh0dXJlLFxuICAgIHRlbnNvcj86IFRlbnNvcixcbiAgICB0ZW5zb3JJZD86IFRlbnNvci5JZCxcbiAgKSB7XG4gICAgY29uc3QgdGV4dHVyZURhdGE6IFRleHR1cmVEYXRhID0ge1xuICAgICAgLi4ubGF5b3V0LFxuICAgICAgdGVuc29yOlxuICAgICAgICB0ZW5zb3IgfHxcbiAgICAgICAgbmV3IFRlbnNvcihcbiAgICAgICAgICBsYXlvdXQudW5wYWNrZWRTaGFwZSxcbiAgICAgICAgICBkYXRhVHlwZSxcbiAgICAgICAgICAoX2lkOiBUZW5zb3IuSWQpID0+IHRoaXMucmVhZFRleHR1cmUodGV4dHVyZURhdGEpLFxuICAgICAgICAgIGFzeW5jIChfaWQ6IFRlbnNvci5JZCkgPT4gdGhpcy5yZWFkVGV4dHVyZUFzeW5jKHRleHR1cmVEYXRhKSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgdGVuc29ySWQsXG4gICAgICAgICksXG4gICAgICB0ZXh0dXJlLFxuICAgIH07XG4gICAgdGhpcy5zZXRUZXh0dXJlRGF0YSh0ZXh0dXJlRGF0YS50ZW5zb3IuZGF0YUlkLCB0ZXh0dXJlRGF0YSwgbGF5b3V0LmlzUGFja2VkKTtcbiAgICByZXR1cm4gdGV4dHVyZURhdGE7XG4gIH1cblxuICBwcml2YXRlIGdldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIGlzUGFja2VkID0gZmFsc2UpOiBUZXh0dXJlRGF0YSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi5pc0luaXRpYWxpemVyKHRlbnNvcklkKVxuICAgICAgPyB0aGlzLnNlc3Npb24uZ2V0VGV4dHVyZURhdGEodGVuc29ySWQsIGlzUGFja2VkKVxuICAgICAgOiBpc1BhY2tlZFxuICAgICAgICA/IHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5nZXQodGVuc29ySWQpXG4gICAgICAgIDogdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKTtcbiAgfVxuICBzZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCB0ZDogVGV4dHVyZURhdGEsIGlzUGFja2VkID0gZmFsc2UpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIodGVuc29ySWQpKSB7XG4gICAgICB0aGlzLnNlc3Npb24uc2V0VGV4dHVyZURhdGEodGVuc29ySWQsIHRkLCBpc1BhY2tlZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIChpc1BhY2tlZCA/IHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA6IHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlKS5zZXQodGVuc29ySWQsIHRkKTtcbiAgICB9XG4gIH1cbiAgaXNUZXh0dXJlTGF5b3V0Q2FjaGVkKHRlbnNvcjogVGVuc29yLCBpc1BhY2tlZCA9IGZhbHNlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5nZXRUZXh0dXJlRGF0YSh0ZW5zb3IuZGF0YUlkLCBpc1BhY2tlZCk7XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2goKHRkKSA9PiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVsZWFzZVRleHR1cmUodGQpKTtcbiAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZm9yRWFjaCgodGQpID0+IHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCkpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICB9XG5cbiAgcmVhZFRleHR1cmUodGV4dHVyZURhdGE6IFRleHR1cmVEYXRhKTogVGVuc29yLk51bWJlclR5cGUge1xuICAgIGlmICh0ZXh0dXJlRGF0YS5pc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVhZFRleHR1cmUodGhpcy51bnBhY2sodGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQuaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQoZW5jb2RlQXNVaW50OCh0aGlzLCB0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlKHRleHR1cmVEYXRhLCB0ZXh0dXJlRGF0YS50ZW5zb3IudHlwZSwgdGV4dHVyZURhdGEuY2hhbm5lbHMpO1xuICB9XG5cbiAgYXN5bmMgcmVhZFRleHR1cmVBc3luYyh0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEpOiBQcm9taXNlPFRlbnNvci5OdW1iZXJUeXBlPiB7XG4gICAgaWYgKHRleHR1cmVEYXRhLmlzUGFja2VkKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWFkVGV4dHVyZUFzeW5jKHRoaXMudW5wYWNrKHRleHR1cmVEYXRhKSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LmlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRVaW50OFRleHR1cmVBc0Zsb2F0KGVuY29kZUFzVWludDgodGhpcywgdGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWFkVGV4dHVyZUFzeW5jKHRleHR1cmVEYXRhLCB0ZXh0dXJlRGF0YS50ZW5zb3IudHlwZSwgdGV4dHVyZURhdGEuY2hhbm5lbHMpO1xuICB9XG5cbiAgcGFjayhpbnB1dDogVGV4dHVyZURhdGEpOiBUZXh0dXJlRGF0YSB7XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZURhdGEgPSB0aGlzLmV4ZWN1dGVQcm9ncmFtKGNyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlcih0aGlzLCBpbnB1dC50ZW5zb3IpLCBbaW5wdXQudGVuc29yXSk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhO1xuICB9XG5cbiAgdW5wYWNrKGlucHV0OiBUZXh0dXJlRGF0YSk6IFRleHR1cmVEYXRhIHtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuZXhlY3V0ZVByb2dyYW0oY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm9Mb2FkZXIodGhpcywgaW5wdXQudGVuc29yKSwgW2lucHV0LnRlbnNvcl0pO1xuICAgIHJldHVybiBvdXRwdXRUZXh0dXJlRGF0YTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5jbGFzcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXlJbXBsIHtcbiAgY29uc3RydWN0b3IoYXR0cmlidXRlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgYXR0cmlidXRlKTtcbiAgfVxuXG4gIHByaXZhdGUga2V5OiBzdHJpbmc7XG4gIHB1YmxpYyBnZXQgY2FjaGVLZXkoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMua2V5KSB7XG4gICAgICB0aGlzLmtleSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMpXG4gICAgICAgIC5zb3J0KClcbiAgICAgICAgLm1hcCgobmFtZSkgPT4gYCR7KHRoaXMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW25hbWVdfWApXG4gICAgICAgIC5qb2luKCc7Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmtleTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGNhY2hlS2V5OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgPSA8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+PihcbiAgYXR0cmlidXRlOiBULFxuKTogVCAmIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSA9PiBuZXcgQXR0cmlidXRlV2l0aENhY2hlS2V5SW1wbChhdHRyaWJ1dGUpIGFzIHVua25vd24gYXMgVCAmIEF0dHJpYnV0ZVdpdGhDYWNoZUtleTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBlcHNpbG9uOiBudW1iZXI7XG4gIG1vbWVudHVtOiBudW1iZXI7XG4gIHNwYXRpYWw6IG51bWJlcjtcbn1cblxuY29uc3QgYmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnQmF0Y2hOb3JtYWxpemF0aW9uJyxcbiAgaW5wdXROYW1lczogWydBJywgJ1NjYWxlJywgJ0InLCAnTWVhbicsICdWYXJpYW5jZSddLFxuICBpbnB1dFR5cGVzOiBbXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gIF0sXG59O1xuXG5leHBvcnQgY29uc3QgYmF0Y2hOb3JtYWxpemF0aW9uOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLmJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlQmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBlcHNpbG9uID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdlcHNpbG9uJywgMWUtNSk7XG4gIGNvbnN0IG1vbWVudHVtID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtb21lbnR1bScsIDAuOSk7XG4gIGNvbnN0IHNwYXRpYWwgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdzcGF0aWFsJywgMSk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBlcHNpbG9uLCBtb21lbnR1bSwgc3BhdGlhbCB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZUJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgcmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgY29uc3QgW3NjYWxlV2lkdGgsIHNjYWxlSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0c1sxXS5kaW1zLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICB2ZWMyIHBvc2l0aW9uID0gb2Zmc2V0VG9Db29yZHMoaW5kaWNlc1sxXSwgJHtzY2FsZVdpZHRofSwgJHtzY2FsZUhlaWdodH0pO1xuICAgIGZsb2F0IHNjYWxlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KFNjYWxlLCBwb3NpdGlvbikpO1xuICAgIGZsb2F0IG1lYW4gPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oTWVhbiwgcG9zaXRpb24pKTtcbiAgICBmbG9hdCB2YXJpYW5jZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShWYXJpYW5jZSwgcG9zaXRpb24pKTtcbiAgICBmbG9hdCBiID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEIsIHBvc2l0aW9uKSk7XG5cbiAgICByZXR1cm4gc2NhbGUgKiAoIChfQShpbmRpY2VzKSAtIG1lYW4pIC8gc3FydCh2YXJpYW5jZSArIGZsb2F0KCR7YXR0cmlidXRlcy5lcHNpbG9ufSkpICkgKyBiO1xuICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5iYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0c1swXS5kaW1zLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdCYXRjaE5vcm1hbGl6YXRpb24gcmVxdWlyZXMgNSBpbnB1dHMuJyk7XG4gIH1cblxuICBjb25zdCBYID0gaW5wdXRzWzBdO1xuICBjb25zdCBzY2FsZSA9IGlucHV0c1sxXTtcbiAgY29uc3QgQiA9IGlucHV0c1syXTtcbiAgY29uc3QgbWVhbiA9IGlucHV0c1szXTtcbiAgY29uc3QgdmFyXyA9IGlucHV0c1s0XTtcblxuICAvLyBpbnB1dCBzaG91bGQgYXRsZWFzdCBoYXZlIHRocmVlIGRpbWVuc2lvbnMgLSBOLEMsZGltMSwuLi4sZGltblxuICAvLyBvdGhlciBpbnB1dHMgY2FuIGhhdmUgb25seSBvbmUgZGltZW5zaW9uc1xuICBpZiAoXG4gICAgWC5kaW1zLmxlbmd0aCA8IDMgfHxcbiAgICBzY2FsZS5kaW1zLmxlbmd0aCAhPT0gMSB8fFxuICAgIEIuZGltcy5sZW5ndGggIT09IDEgfHxcbiAgICBtZWFuLmRpbXMubGVuZ3RoICE9PSAxIHx8XG4gICAgdmFyXy5kaW1zLmxlbmd0aCAhPT0gMVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKFxuICAgIHNjYWxlLmRpbXNbMF0gIT09IFguZGltc1sxXSB8fFxuICAgIEIuZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8XG4gICAgbWVhbi5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHxcbiAgICB2YXJfLmRpbXNbMF0gIT09IFguZGltc1sxXVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKFxuICAgIChYLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBYLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoc2NhbGUudHlwZSAhPT0gJ2Zsb2F0MzInICYmIHNjYWxlLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoQi50eXBlICE9PSAnZmxvYXQzMicgJiYgQi50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKG1lYW4udHlwZSAhPT0gJ2Zsb2F0MzInICYmIG1lYW4udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgICh2YXJfLnR5cGUgIT09ICdmbG9hdDMyJyAmJiB2YXJfLnR5cGUgIT09ICdmbG9hdDY0JylcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVMYXlvdXQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xuZXhwb3J0IGVudW0gRnVuY3Rpb25UeXBlIHtcbiAgVmFsdWVCYXNlZCxcbiAgUG9zaXRpb25hbCxcbn1cbmV4cG9ydCBpbnRlcmZhY2UgR2xzbEZ1bmN0aW9uPFQgZXh0ZW5kcyBGdW5jdGlvblR5cGU+IHtcbiAgYm9keTogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIHR5cGU6IFQ7XG59XG5leHBvcnQgdHlwZSBHbHNsVmFsdWVGdW5jdGlvbiA9IEdsc2xGdW5jdGlvbjxGdW5jdGlvblR5cGUuVmFsdWVCYXNlZD47XG5leHBvcnQgaW50ZXJmYWNlIEdsc2xQb3NpdGlvbmFsRnVuY3Rpb24gZXh0ZW5kcyBHbHNsRnVuY3Rpb248RnVuY3Rpb25UeXBlLlBvc2l0aW9uYWw+IHtcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNsYXNzIEdsc2xDb250ZXh0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGdsQ29udGV4dDogV2ViR0xDb250ZXh0LFxuICAgIHB1YmxpYyBwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm8sXG4gICAgcHVibGljIGlucHV0VGV4dHVyZUxheW91dHM6IFRleHR1cmVMYXlvdXRbXSxcbiAgICBwdWJsaWMgb3V0cHV0VGV4dHVyZUxheW91dDogVGV4dHVyZUxheW91dCxcbiAgKSB7fVxufVxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgY29udGV4dDogR2xzbENvbnRleHQpIHt9XG4gIGFic3RyYWN0IGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9O1xuICBhYnN0cmFjdCBnZXRDdXN0b21UeXBlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfTtcbn1cblxuLy8gYWJzdHJhY3Rpb24gdG8gcmVwcmVzZW50IGEgR0xTTCBsaWJyYXJ5IHJvdXRpbmUgYW5kIGl0J3MgZGVwZW5kZW5jaWVzXG5leHBvcnQgY2xhc3MgR2xzbExpYlJvdXRpbmUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcm91dGluZUJvZHk6IHN0cmluZyxcbiAgICBwdWJsaWMgZGVwZW5kZW5jaWVzPzogc3RyaW5nW10sXG4gICkge31cbn1cblxuLy8gYWJzdHJhY3Rpb24gdG8gcmVwcmVzZW50IGEgR0xTTCBsaWJyYXJ5IHJvdXRpbmUgYW5kIGl0J3MgZGVwZW5kZW5jaWVzIEFTIEdSQVBIIE5vZGVzXG4vLyB0aGlzIGxldmVsIG9mIGFic3RyYWN0aW9uIGlzIHVzZWQgdG8gdG9wb2xvZ2ljYWxseSBzb3J0IHJvdXRpbmVzIGJlZm9yZSBmcmFnbWVudCBzaGFkZSBpbmNsdXNpb25cbmV4cG9ydCBjbGFzcyBHbHNsTGliUm91dGluZU5vZGUge1xuICBkZXBlbmRlbmNpZXM6IEdsc2xMaWJSb3V0aW5lTm9kZVtdO1xuICByb3V0aW5lQm9keTogc3RyaW5nO1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nLFxuICAgIHJvdXRpbmVCb2R5Pzogc3RyaW5nLFxuICAgIGRlcGVuZGVuY2llcz86IEdsc2xMaWJSb3V0aW5lTm9kZVtdLFxuICApIHtcbiAgICBpZiAoZGVwZW5kZW5jaWVzKSB7XG4gICAgICB0aGlzLmRlcGVuZGVuY2llcyA9IGRlcGVuZGVuY2llcztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZXBlbmRlbmNpZXMgPSBbXTtcbiAgICB9XG5cbiAgICBpZiAocm91dGluZUJvZHkpIHtcbiAgICAgIHRoaXMucm91dGluZUJvZHkgPSByb3V0aW5lQm9keTtcbiAgICB9XG4gIH1cbiAgYWRkRGVwZW5kZW5jeShub2RlOiBHbHNsTGliUm91dGluZU5vZGUpIHtcbiAgICBpZiAobm9kZSkge1xuICAgICAgdGhpcy5kZXBlbmRlbmNpZXMucHVzaChub2RlKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gdG9wb2xvZ2ljYWxseSBzb3J0IEdMU0wgbGlicmFyeSByb3V0aW5lcyAoZ3JhcGggbm9kZXMgYWJzdHJhY3Rpb24pIGJlZm9yZSBzaGFkZXIgc2NyaXB0IGluY2x1c2lvblxuZXhwb3J0IGNsYXNzIFRvcG9sb2dpY2FsU29ydEdsc2xSb3V0aW5lcyB7XG4gIHN0YXRpYyByZXR1cm5PcmRlcmVkTm9kZXMobm9kZXM6IEdsc2xMaWJSb3V0aW5lTm9kZVtdKTogR2xzbExpYlJvdXRpbmVOb2RlW10ge1xuICAgIGlmICghbm9kZXMgfHwgbm9kZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgaWYgKG5vZGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIG5vZGVzO1xuICAgIH1cblxuICAgIGNvbnN0IGN5Y2xlQ2hlY2sgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCBhbHJlYWR5VHJhdmVyc2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IEFycmF5PEdsc2xMaWJSb3V0aW5lTm9kZT4oKTtcblxuICAgIHRoaXMuY3JlYXRlT3JkZXJlZE5vZGVzKG5vZGVzLCBjeWNsZUNoZWNrLCBhbHJlYWR5VHJhdmVyc2VkLCByZXN1bHQpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjcmVhdGVPcmRlcmVkTm9kZXMoXG4gICAgZ3JhcGhOb2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10sXG4gICAgY3ljbGVDaGVjazogU2V0PHN0cmluZz4sXG4gICAgYWxyZWFkeVRyYXZlcnNlZDogU2V0PHN0cmluZz4sXG4gICAgcmVzdWx0OiBHbHNsTGliUm91dGluZU5vZGVbXSxcbiAgKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaE5vZGVzLmxlbmd0aDsgKytpKSB7XG4gICAgICB0aGlzLmRmc1RyYXZlcnNlKGdyYXBoTm9kZXNbaV0sIGN5Y2xlQ2hlY2ssIGFscmVhZHlUcmF2ZXJzZWQsIHJlc3VsdCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZGZzVHJhdmVyc2UoXG4gICAgcm9vdDogR2xzbExpYlJvdXRpbmVOb2RlLFxuICAgIGN5Y2xlQ2hlY2s6IFNldDxzdHJpbmc+LFxuICAgIGFscmVhZHlUcmF2ZXJzZWQ6IFNldDxzdHJpbmc+LFxuICAgIHJlc3VsdDogR2xzbExpYlJvdXRpbmVOb2RlW10sXG4gICkge1xuICAgIC8vIGlmIHRoaXMgcm9vdCBoYXMgYWxyZWFkeSBiZWVuIHRyYXZlcnNlZCByZXR1cm5cbiAgICBpZiAoIXJvb3QgfHwgYWxyZWFkeVRyYXZlcnNlZC5oYXMocm9vdC5uYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGN5Y2xpYyBkZXBlbmRlbmN5IGhhcyBiZWVuIGRldGVjdGVkXG4gICAgaWYgKGN5Y2xlQ2hlY2suaGFzKHJvb3QubmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkN5Y2xpYyBkZXBlbmRlbmN5IGRldGVjdGVkLiBDYW4ndCB0b3BvbG9naWNhbGx5IHNvcnQgcm91dGluZXMgbmVlZGVkIGZvciBzaGFkZXIuXCIpO1xuICAgIH1cblxuICAgIC8vIGhvbGQgdGhpcyBub2RlIHRvIGRldGVjdCBjeWNsZXMgaWYgYW55XG4gICAgY3ljbGVDaGVjay5hZGQocm9vdC5uYW1lKTtcblxuICAgIC8vIHRyYXZlcnNlIGNoaWxkcmVuIGluIGEgZGZzIGZhc2hpb25cbiAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSByb290LmRlcGVuZGVuY2llcztcbiAgICBpZiAoZGVwZW5kZW5jaWVzICYmIGRlcGVuZGVuY2llcy5sZW5ndGggPiAwKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlcGVuZGVuY2llcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB0aGlzLmRmc1RyYXZlcnNlKGRlcGVuZGVuY2llc1tpXSwgY3ljbGVDaGVjaywgYWxyZWFkeVRyYXZlcnNlZCwgcmVzdWx0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGQgdG8gcmVzdWx0IGhvbGRlclxuICAgIHJlc3VsdC5wdXNoKHJvb3QpO1xuXG4gICAgLy8gbWFyayB0aGlzIG5vZGUgYXMgdHJhdmVyc2VkIHNvIHRoYXQgd2UgZG9uJ3QgdHJhdmVyc2UgZnJvbSB0aGlzIGFnYWluXG4gICAgYWxyZWFkeVRyYXZlcnNlZC5hZGQocm9vdC5uYW1lKTtcblxuICAgIC8vIHJlbGVhc2UgdGhlIGhvbGRcbiAgICBjeWNsZUNoZWNrLmRlbGV0ZShyb290Lm5hbWUpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IEZ1bmN0aW9uVHlwZSwgR2xzbFZhbHVlRnVuY3Rpb24gfSBmcm9tICcuLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2xzbEFkZCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnYWRkXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhICsgYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSArIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbERpdigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnZGl2Xyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhIC8gYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSAvIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbE11bCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbXVsXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhICogYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSAqIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFN1YigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnc3ViXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhIC0gYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSAtIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEVxdWFsKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdlcXVhbF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoYSA9PSBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KGVxdWFsKHYxLCB2MikpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEdyZWF0ZXIoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2dyZWF0ZXJfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KGEgPiBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KCB2MS5yID4gdjIuciAsXG4gICAgICB2MS5nID4gdjIuZyxcbiAgICAgIHYxLmIgPiB2Mi5iLFxuICAgICAgdjEuYSA+IHYyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xMZXNzKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdsZXNzXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdChhIDwgYik7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdmVjNCggdjEuciA8IHYyLnIgLFxuICAgICAgICAgICAgICAgIHYxLmcgPCB2Mi5nLFxuICAgICAgICAgICAgICAgIHYxLmIgPCB2Mi5iLFxuICAgICAgICAgICAgICAgIHYxLmEgPCB2Mi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQW5kKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdhbmRfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KCBib29sKGEpICYmIGJvb2woYikgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIGJ2ZWM0IGIxID0gYnZlYzQodjEpO1xuICAgIGJ2ZWM0IGIyID0gYnZlYzQodjIpO1xuICAgIHJldHVybiB2ZWM0KCBiMS5yICYmIGIyLnIgLFxuICAgICAgICAgICAgICAgIGIxLmcgJiYgYjIuZyxcbiAgICAgICAgICAgICAgICBiMS5iICYmIGIyLmIsXG4gICAgICAgICAgICAgICAgYjEuYSAmJiBiMi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsT3IoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ29yXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdCggYm9vbChhKSB8fCBib29sKGIpICk7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICBidmVjNCBiMSA9IGJ2ZWM0KHYxKTtcbiAgICBidmVjNCBiMiA9IGJ2ZWM0KHYyKTtcbiAgICByZXR1cm4gdmVjNCggYjEuciB8fCBiMi5yICxcbiAgICAgICAgICAgICAgICBiMS5nIHx8IGIyLmcsXG4gICAgICAgICAgICAgICAgYjEuYiB8fCBiMi5iLFxuICAgICAgICAgICAgICAgIGIxLmEgfHwgYjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFhvcigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAneG9yXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdCggYm9vbChhKSBeXiBib29sKGIpICk7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICBidmVjNCBiMSA9IGJ2ZWM0KHYxKTtcbiAgICBidmVjNCBiMiA9IGJ2ZWM0KHYyKTtcbiAgICByZXR1cm4gdmVjNCggYjEuciBeXiBiMi5yICxcbiAgICAgICAgICAgICAgICBiMS5nIF5eIGIyLmcsXG4gICAgICAgICAgICAgICAgYjEuYiBeXiBiMi5iLFxuICAgICAgICAgICAgICAgIGIxLmEgXl4gYjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFBvdygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpbkJpbmFyeSgncG93Jyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFBSZWx1KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdwcmVsdV8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSA8IDAuMCA/IGEgKiBiOiBhO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoXG4gICAgICB2MS5yIDwgMC4wID8gdjEuciAqIHYyLnI6IHYxLnIsXG4gICAgICB2MS5nIDwgMC4wID8gdjEuZyAqIHYyLmc6IHYxLmcsXG4gICAgICB2MS5iIDwgMC4wID8gdjEuYiAqIHYyLmI6IHYxLmIsXG4gICAgICB2MS5hIDwgMC4wID8gdjEuYSAqIHYyLmE6IHYxLmFcbiAgICAgICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cblxuZnVuY3Rpb24gZ2xzbEJ1aWx0aW5CaW5hcnkoZm5hbWU6IHN0cmluZyk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9IGAke2ZuYW1lfV9gO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gJHtmbmFtZX0oYSwgYik7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gJHtmbmFtZX0odjEsIHYyKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuXG5jb25zdCBjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4gIG91dHB1dFRlbnNvclR5cGU6IFRlbnNvci5EYXRhVHlwZSA9IGlucHV0c1swXS50eXBlLFxuICBjYWNoZUtleT86IHN0cmluZyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICByZXR1cm4ge1xuICAgIG5hbWU6IGdsc2xGdW5jLm5hbWUsXG4gICAgaW5wdXROYW1lczogWydBJywgJ0InXSxcbiAgICBpbnB1dFR5cGVzOiBbdGV4dHVyZVR5cGUsIHRleHR1cmVUeXBlXSxcbiAgICBjYWNoZUhpbnQ6IGNhY2hlS2V5LFxuICAgIGdldDogKCkgPT4gY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXRzLCBnbHNsRnVuYywgb3V0cHV0VGVuc29yVHlwZSksXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVCaW5hcnlQcm9ncmFtSW5mbyA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4gIG91dHB1dFRlbnNvclR5cGU6IFRlbnNvci5EYXRhVHlwZSA9IGlucHV0c1swXS50eXBlLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB0ZXh0dXJlVHlwZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrID8gVGV4dHVyZVR5cGUucGFja2VkIDogVGV4dHVyZVR5cGUudW5wYWNrZWQ7XG4gIGNvbnN0IGlzQnJvYWRjYXN0ID0gIVNoYXBlVXRpbC5hcmVFcXVhbChpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMpO1xuICBsZXQgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcblxuICBjb25zdCB1c2VQYWNrZWRUZXh0dXJlID0gaGFuZGxlci5zZXNzaW9uLnBhY2s7XG5cbiAgaWYgKGlzQnJvYWRjYXN0KSB7XG4gICAgY29uc3QgY2FsY3VsYXRlZFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5kaW1zLCBmYWxzZSk7XG4gICAgaWYgKCFjYWxjdWxhdGVkU2hhcGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHBlcmZvcm0gYmluYXJ5IG9wIG9uIHRoZSBnaXZlbiB0ZW5zb3JzXCIpO1xuICAgIH1cbiAgICBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZWRTaGFwZTtcbiAgICBjb25zdCBvdXRwdXRSYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGFSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSAwID8gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIDogMTtcbiAgICBjb25zdCBiUmFuayA9IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMCA/IGlucHV0c1sxXS5kaW1zLmxlbmd0aCA6IDE7XG4gICAgY29uc3QgYUJjYXN0ID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSAwID8gJ2JjYXN0SW5kaWNlc19BKGluZGljZXMsIGFpbmRpY2VzKTsnIDogJ2FpbmRpY2VzWzBdID0gMDsnO1xuICAgIGNvbnN0IGJCY2FzdCA9IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMCA/ICdiY2FzdEluZGljZXNfQihpbmRpY2VzLCBiaW5kaWNlcyk7JyA6ICdiaW5kaWNlc1swXSA9IDA7JztcblxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSB1c2VQYWNrZWRUZXh0dXJlXG4gICAgICA/IGBcbiAgICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgdmVjNCBhID0gZ2V0QUF0T3V0Q29vcmRzKCk7XG4gICAgICAgIHZlYzQgYiA9IGdldEJBdE91dENvb3JkcygpO1xuICAgICAgICB2ZWM0IHJlc3VsdCA9ICR7Z2xzbEZ1bmMubmFtZX0oYSwgYik7XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfWBcbiAgICAgIDogYFxuICAgICAgJHtnbHNsRnVuYy5ib2R5fVxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske291dHB1dFJhbmt9XSkge1xuICAgICAgICBpbnQgYWluZGljZXNbJHthUmFua31dO1xuICAgICAgICBpbnQgYmluZGljZXNbJHtiUmFua31dO1xuICAgICAgICAke2FCY2FzdH1cbiAgICAgICAgJHtiQmNhc3R9XG4gICAgICAgIHJldHVybiAke2dsc2xGdW5jLm5hbWV9KF9BKGFpbmRpY2VzKSwgX0IoYmluZGljZXMpKTtcbiAgICAgIH1gO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IGdsc2xGdW5jLm5hbWUsXG4gICAgICBpbnB1dE5hbWVzOiBbJ0EnLCAnQiddLFxuICAgICAgaW5wdXRUeXBlczogW3RleHR1cmVUeXBlLCB0ZXh0dXJlVHlwZV0sXG4gICAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IG91dHB1dFRlbnNvclR5cGUsIHRleHR1cmVUeXBlIH0sXG4gICAgICBzaGFkZXJTb3VyY2UsXG4gICAgICBoYXNNYWluOiB1c2VQYWNrZWRUZXh0dXJlLFxuICAgIH07XG4gIH1cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgJHtnbHNsRnVuYy5ib2R5fVxuICAgIHZvaWQgbWFpbigpIHtcbiAgICAgIHZlYzQgdjEgPSAke2dsc2wudGV4dHVyZTJEfShBLCBUZXhDb29yZHMpO1xuICAgICAgdmVjNCB2MiA9ICR7Z2xzbC50ZXh0dXJlMkR9KEIsIFRleENvb3Jkcyk7XG4gICAgICB2ZWM0IHJlc3VsdCA9ICR7Z2xzbEZ1bmMubmFtZX0odjEsIHYyKTtcbiAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgIH1cbiAgICBgO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogZ2xzbEZ1bmMubmFtZSxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnLCAnQiddLFxuICAgIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZSwgdGV4dHVyZVR5cGVdLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dHNbMF0uZGltcywgdHlwZTogb3V0cHV0VGVuc29yVHlwZSwgdGV4dHVyZVR5cGUgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBhZGQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xBZGQoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgYW5kID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsQW5kKCksICdib29sJyksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgZGl2ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsRGl2KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGVxdWFsID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsRXF1YWwoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBncmVhdGVyID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsR3JlYXRlcigpLCAnYm9vbCcpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGxlc3MgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xMZXNzKCksICdib29sJyksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgbXVsID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsTXVsKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IG9yID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsT3IoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBwb3cgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xQb3coKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgcFJlbHUgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xQUmVsdSgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBzdWIgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xTdWIoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgeG9yID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsWG9yKCksICdib29sJyksIGlucHV0cyksXG5dO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFByb3RvVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgY2FzdDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxUZW5zb3IuRGF0YVR5cGU+ID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIHRvOiBUZW5zb3IuRGF0YVR5cGUsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIHJldHVybiBbaGFuZGxlci5jYXN0KGlucHV0c1swXSwgdG8pXTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNhc3RBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFRlbnNvci5EYXRhVHlwZT4gPSAobm9kZTogR3JhcGguTm9kZSk6IFRlbnNvci5EYXRhVHlwZSA9PlxuICBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8obm9kZS5hdHRyaWJ1dGVzLmdldEludCgndG8nKSk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FzdCByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyBDb25jYXRBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb25jYXQnO1xuaW1wb3J0IHsgZ2V0Q2hhbm5lbHMsIHVucGFja0Zyb21DaGFubmVsIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbU1ldGFkYXRhID0gKGlucHV0Q291bnQ6IG51bWJlciwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdDb25jYXQgKHBhY2tlZCknLFxuICBpbnB1dE5hbWVzOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBpbnB1dENvdW50IH0sIChfdiwgaSkgPT4gYFgke2l9YCksXG4gIGlucHV0VHlwZXM6IEFycmF5KGlucHV0Q291bnQpLmZpbGwoVGV4dHVyZVR5cGUucGFja2VkKSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGlmIChheGlzID49IGlucHV0U2hhcGUubGVuZ3RoIHx8IGF4aXMgPCAtMSAqIGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYXhpcyBzcGVjaWZpZWQgZm9yIGNvbmNhdCBkb2Vzbid0IG1hdGNoIGlucHV0IGRpbWVuc2lvbmFsaXR5XCIpO1xuICB9XG4gIGlmIChheGlzIDwgMCkge1xuICAgIGF4aXMgPSBpbnB1dFNoYXBlLmxlbmd0aCArIGF4aXM7XG4gIH1cbiAgLy8gZW5zdXJlIGFsbCBvZiB0aGUgbm9uLWNvbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgLy8gY2FsY3VsYXRlIHRoZSBzaGFwZSBvZiB0aGUgb3V0cHV0IHRlbnNvciB3aGlsZSB3ZSBkbyB0aGF0XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgwKTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBkYXRhTlNoYXBlID0gaW5wdXRzW2ldLmRpbXMuc2xpY2UoKTtcbiAgICBmb3IgKGxldCBheGlzSW5kZXggPSAwOyBheGlzSW5kZXggPCBpbnB1dFNoYXBlLmxlbmd0aDsgYXhpc0luZGV4KyspIHtcbiAgICAgIC8vIGFkZCB0byB0aGUgcGxhY2Vob2xkZXIgZm9yIGNvbXB1dGluZyBvdXRwdXQgc2hhcGVcbiAgICAgIGlmIChheGlzSW5kZXggPT09IGF4aXMpIHtcbiAgICAgICAgb3V0cHV0U2hhcGVbYXhpc10gKz0gZGF0YU5TaGFwZVtheGlzSW5kZXhdO1xuICAgICAgfVxuICAgICAgLy8gZW5zdXJlIGFsbCBub24tY2FuY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAgICAgZWxzZSBpZiAoaW5wdXRTaGFwZVtheGlzSW5kZXhdICE9PSBkYXRhTlNoYXBlW2F4aXNJbmRleF0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub24gY29uY2F0IGRpbWVuc2lvbnMgbXVzdCBtYXRjaCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGNvb3JkcyA9IGdldENoYW5uZWxzKCdjb29yZHMnLCByYW5rKTtcbiAgY29uc3QgZHR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShyYW5rKTtcbiAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG5cbiAgY29uc3Qgc2hhcGVzID0gaW5wdXRzLm1hcCgoaSkgPT4gaS5kaW1zKTtcbiAgY29uc3QgY2hhbm5lbHMgPSBnZXRHbENoYW5uZWxzKHJhbmspO1xuICBjb25zdCBvZmZzZXRzOiBudW1iZXJbXSA9IG5ldyBBcnJheShzaGFwZXMubGVuZ3RoIC0gMSk7XG5cbiAgb2Zmc2V0c1swXSA9IHNoYXBlc1swXVtheGlzXTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBvZmZzZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgb2Zmc2V0c1tpXSA9IG9mZnNldHNbaSAtIDFdICsgc2hhcGVzW2ldW2F4aXNdO1xuICB9XG5cbiAgY29uc3QgY2hhbm5lbCA9IGNoYW5uZWxzW2F4aXNdO1xuICBjb25zdCBsYXN0Q2hhbm5lbHMgPSBjaGFubmVscy5zbGljZSgtMik7XG4gIGNvbnN0IGFsbENoYW5uZWxzID0gY2hhbm5lbHMuam9pbigpO1xuXG4gIGxldCBnZXRWYWx1ZVNuaXBwZXQgPSBgaWYgKCR7Y2hhbm5lbH0gPCAke29mZnNldHNbMF19KSB7XG4gICAgICAgIHJldHVybiBnZXRDaGFubmVsKFxuICAgICAgICAgICAgZ2V0WDAoJHthbGxDaGFubmVsc30pLCB2ZWMyKCR7bGFzdENoYW5uZWxzLmpvaW4oKX0pKTtcbiAgICAgICAgfWA7XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgb2Zmc2V0cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHNoaWZ0ID0gb2Zmc2V0c1tpIC0gMV07XG4gICAgZ2V0VmFsdWVTbmlwcGV0ICs9IGBcbiAgICAgICAgICAgIGlmICgke2NoYW5uZWx9IDwgJHtvZmZzZXRzW2ldfSAgJiYgJHtjaGFubmVsfSA+PSAke29mZnNldHNbaSAtIDFdfSkge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgICAgICBnZXRYJHtpfSgke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQoY2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pLFxuICAgICAgICAgICAgICAgIHZlYzIoJHtnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0KGxhc3RDaGFubmVscywgY2hhbm5lbCwgc2hpZnQpfSkpO1xuICAgICAgICAgICAgfWA7XG4gIH1cbiAgY29uc3QgbGFzdEluZGV4ID0gb2Zmc2V0cy5sZW5ndGg7XG4gIGNvbnN0IHNoaWZ0ID0gb2Zmc2V0c1tvZmZzZXRzLmxlbmd0aCAtIDFdO1xuICBnZXRWYWx1ZVNuaXBwZXQgKz0gYFxuICAgICAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoXG4gICAgICAgICAgICAgIGdldFgke2xhc3RJbmRleH0oJHtnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0KGNoYW5uZWxzLCBjaGFubmVsLCBzaGlmdCl9KSxcbiAgICAgICAgICAgICAgdmVjMigke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQobGFzdENoYW5uZWxzLCBjaGFubmVsLCBzaGlmdCl9KSk7YDtcblxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAgICR7dW5wYWNrQ2hhbm5lbH1cbiAgICAgICAgICBmbG9hdCBnZXRWYWx1ZSgke2NoYW5uZWxzLm1hcCgoeCkgPT4gJ2ludCAnICsgeCl9KSB7XG4gICAgICAgICAgICAke2dldFZhbHVlU25pcHBldH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAke2R0eXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgICAgIGludCBsYXN0RGltID0gY29vcmRzLiR7Y2hhbm5lbHNbcmFuayAtIDFdfTtcbiAgICAgICAgICAgIGNvb3Jkcy4ke2NoYW5uZWxzW3JhbmsgLSAxXX0gPSBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMl19O1xuICAgICAgICAgICAgY29vcmRzLiR7Y2hhbm5lbHNbcmFuayAtIDJdfSA9IGxhc3REaW07XG5cbiAgICAgICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNChnZXRWYWx1ZSgke2Nvb3Jkc30pLCAwLiwgMC4sIDAuKTtcblxuICAgICAgICAgICAgJHtjb29yZHNbcmFuayAtIDFdfSA9ICR7Y29vcmRzW3JhbmsgLSAxXX0gKyAxO1xuICAgICAgICAgICAgaWYgKCR7Y29vcmRzW3JhbmsgLSAxXX0gPCAke291dHB1dFNoYXBlW3JhbmsgLSAxXX0pIHtcbiAgICAgICAgICAgICAgcmVzdWx0LmcgPSBnZXRWYWx1ZSgke2Nvb3Jkc30pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMl19ID0gJHtjb29yZHNbcmFuayAtIDJdfSArIDE7XG4gICAgICAgICAgICBpZiAoJHtjb29yZHNbcmFuayAtIDJdfSA8ICR7b3V0cHV0U2hhcGVbcmFuayAtIDJdfSkge1xuICAgICAgICAgICAgICByZXN1bHQuYSA9IGdldFZhbHVlKCR7Y29vcmRzfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICR7Y29vcmRzW3JhbmsgLSAxXX0gPSAke2Nvb3Jkc1tyYW5rIC0gMV19IC0gMTtcbiAgICAgICAgICAgIGlmICgke2Nvb3Jkc1tyYW5rIC0gMl19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMl19ICYmXG4gICAgICAgICAgICAgICAgJHtjb29yZHNbcmFuayAtIDFdfSA8ICR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkge1xuICAgICAgICAgICAgICByZXN1bHQuYiA9IGdldFZhbHVlKCR7Y29vcmRzfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29uY2F0QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCwgYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMuYXhpcykgfTtcbn07XG5cbmNvbnN0IGdldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQgPSAoY2hhbm5lbHM6IHN0cmluZ1tdLCBjaGFubmVsOiBzdHJpbmcsIHNoaWZ0OiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjaGFubmVsSWR4ID0gY2hhbm5lbHMuaW5kZXhPZihjaGFubmVsKTtcbiAgY29uc3QgcmVzID0gY2hhbm5lbHMubWFwKChjLCBpZHgpID0+IHtcbiAgICBpZiAoaWR4ID09PSBjaGFubmVsSWR4KSB7XG4gICAgICByZXR1cm4gYCR7Y30gLSAke3NoaWZ0fWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXMuam9pbigpO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9jb25jYXQtcGFja2VkJztcblxuZXhwb3J0IGludGVyZmFjZSBDb25jYXRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgY29uY2F0OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbmNhdEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbmNhdEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGlmIChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24ucGFjayAmJiBpbnB1dHNbMF0uZGltcy5sZW5ndGggPiAxKSB7XG4gICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgICAgaW5wdXRzLFxuICAgICk7XG4gICAgcmV0dXJuIFtvdXRwdXRdO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgICAgaW5wdXRzLFxuICAgICk7XG4gICAgcmV0dXJuIFtvdXRwdXRdO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YSA9IChpbnB1dENvdW50OiBudW1iZXIsIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnQ29uY2F0JyxcbiAgaW5wdXROYW1lczogQXJyYXkuZnJvbSh7IGxlbmd0aDogaW5wdXRDb3VudCB9LCAoX3YsIGkpID0+IGBYJHtpfWApLFxuICBpbnB1dFR5cGVzOiBBcnJheShpbnB1dENvdW50KS5maWxsKFRleHR1cmVUeXBlLnVucGFja2VkKSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbUluZm8gPSAoXG4gIF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGlmIChheGlzID49IGlucHV0U2hhcGUubGVuZ3RoIHx8IGF4aXMgPCAtMSAqIGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYXhpcyBzcGVjaWZpZWQgZm9yIGNvbmNhdCBkb2Vzbid0IG1hdGNoIGlucHV0IGRpbWVuc2lvbmFsaXR5XCIpO1xuICB9XG4gIGlmIChheGlzIDwgMCkge1xuICAgIGF4aXMgPSBpbnB1dFNoYXBlLmxlbmd0aCArIGF4aXM7XG4gIH1cbiAgLy8gZW5zdXJlIGFsbCBvZiB0aGUgbm9uLWNvbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgLy8gY2FsY3VsYXRlIHRoZSBzaGFwZSBvZiB0aGUgb3V0cHV0IHRlbnNvciB3aGlsZSB3ZSBkbyB0aGF0XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgwKTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBkYXRhTlNoYXBlID0gaW5wdXRzW2ldLmRpbXMuc2xpY2UoKTtcbiAgICBmb3IgKGxldCBheGlzSW5kZXggPSAwOyBheGlzSW5kZXggPCBpbnB1dFNoYXBlLmxlbmd0aDsgYXhpc0luZGV4KyspIHtcbiAgICAgIC8vIGFkZCB0byB0aGUgcGxhY2Vob2xkZXIgZm9yIGNvbXB1dGluZyBvdXRwdXQgc2hhcGVcbiAgICAgIGlmIChheGlzSW5kZXggPT09IGF4aXMpIHtcbiAgICAgICAgb3V0cHV0U2hhcGVbYXhpc10gKz0gZGF0YU5TaGFwZVtheGlzSW5kZXhdO1xuICAgICAgfVxuICAgICAgLy8gZW5zdXJlIGFsbCBub24tY2FuY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAgICAgZWxzZSBpZiAoaW5wdXRTaGFwZVtheGlzSW5kZXhdICE9PSBkYXRhTlNoYXBlW2F4aXNJbmRleF0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub24gY29uY2F0IGRpbWVuc2lvbnMgbXVzdCBtYXRjaCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3Qgc2l6ZUluQ29uY2F0QXhpcyA9IG5ldyBBcnJheTxudW1iZXI+KGlucHV0cy5sZW5ndGgpO1xuICBsZXQgcHJldmlvdXNTdW0gPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemVJbkNvbmNhdEF4aXMubGVuZ3RoOyArK2kpIHtcbiAgICBwcmV2aW91c1N1bSArPSBpbnB1dHNbaV0uZGltc1theGlzXTtcbiAgICBzaXplSW5Db25jYXRBeGlzW2ldID0gcHJldmlvdXNTdW07XG4gIH1cblxuICBsZXQgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZCA9ICcnO1xuICAvLyBpbiBtb3N0IGNhc2VzIGxpbmVhciBzZWFyY2ggaXMgc3VmZmljaWVudCwgYXMgaW4gbW9zdCBzY2VuYXJpb3MsIG9ubHkgMiB0ZW5zb3JzIGFyZSBjb25jYXRlbmF0ZWRcbiAgaWYgKGlucHV0cy5sZW5ndGggPCA1KSB7XG4gICAgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZCA9IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNMaW5lYXJTZWFyY2goc2l6ZUluQ29uY2F0QXhpcyk7XG4gIH0gZWxzZSB7XG4gICAgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZCA9IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNCaW5hcnlTZWFyY2goc2l6ZUluQ29uY2F0QXhpcyk7XG4gIH1cblxuICBjb25zdCBmZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmVNZXRob2QgPSBnZXRGZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmVNZXRob2QoaW5wdXRzLmxlbmd0aCwgcmFuayk7XG4gIGNvbnN0IGdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZCA9IGdldEdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZChzaXplSW5Db25jYXRBeGlzKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAke2ZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZH1cbiAgICAgICAgJHtnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXhNZXRob2R9XG4gICAgICAgICR7Z2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZH1cbiAgICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCB0ZXh0dXJlSW5kZXggPSBnZXRUZXh0dXJlV2hlcmVEYXRhUmVzaWRlcyAoaW5kaWNlc1ske2F4aXN9XSk7XG5cbiAgICAgICAgICBpZih0ZXh0dXJlSW5kZXggIT0gMCkge1xuICAgICAgICAgICAgaW5kaWNlc1ske2F4aXN9XSA9IGluZGljZXNbJHtheGlzfV0gLSBpbnQoZ2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4KHRleHR1cmVJbmRleC1pbnQoMSkpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlKHRleHR1cmVJbmRleCwgaW5kaWNlcyk7XG4gICAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29uY2F0QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzLmF4aXMpIH07XG59O1xuXG5jb25zdCBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTGluZWFyU2VhcmNoID0gKHNpemVJbkNvbmNhdEF4aXM6IG51bWJlcltdKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc2VhcmNoQXhpcyA9IHNpemVJbkNvbmNhdEF4aXMubWFwKFxuICAgIChzaXplLCBpKSA9PiBgaWYoaW5kZXg8JHtzaXplfSkge3JldHVybiAke2l9O31cbmAsXG4gICk7XG4gIHJldHVybiBgaW50IGdldFRleHR1cmVXaGVyZURhdGFSZXNpZGVzKGludCBpbmRleCkge1xuICAgICAgJHtzZWFyY2hBeGlzLmpvaW4oJycpfVxuICAgIH1gO1xufTtcblxuLy8gVE9ETzogSW1wbGVtZW50IEJpbmFyeVNlYXJjaCBpbiBHTFNMXG5jb25zdCBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzQmluYXJ5U2VhcmNoID0gKHNpemVJbkNvbmNhdEF4aXM6IG51bWJlcltdKTogc3RyaW5nID0+XG4gIGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNMaW5lYXJTZWFyY2goc2l6ZUluQ29uY2F0QXhpcyk7XG5cbmNvbnN0IGdldEZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZCA9IChudW1iZXJPZlRlbnNvcnM6IG51bWJlciwgdGVuc29yUmFuazogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IGNvZGVMaW5lczogc3RyaW5nW10gPSBbYGZsb2F0IGZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZShpbnQgdGV4dHVyZUluZGV4LCBpbnQgaW5kaWNlc1ske3RlbnNvclJhbmt9XSkge2BdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mVGVuc29yczsgKytpKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGlmICh0ZXh0dXJlSW5kZXggPT0gJHtpfSkgeyByZXR1cm4gX1gke2l9KGluZGljZXMpOyB9YCk7XG4gICAgfSBlbHNlIGlmIChpID09PSBudW1iZXJPZlRlbnNvcnMgLSAxKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIHsgcmV0dXJuIF9YJHtpfShpbmRpY2VzKTsgfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIGlmICh0ZXh0dXJlSW5kZXggPT0gJHtpfSkgeyByZXR1cm4gX1gke2l9KGluZGljZXMpOyB9YCk7XG4gICAgfVxuICB9XG4gIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgJ30nKTtcbiAgcmV0dXJuIGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IGdldEdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZCA9IChzaXplSW5Db25jYXRBeGlzOiBudW1iZXJbXSk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNvZGVMaW5lczogc3RyaW5nW10gPSBbJ2ludCBnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXgoaW50IGluZGV4KSB7J107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZUluQ29uY2F0QXhpcy5sZW5ndGg7ICsraSkge1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBpZiAoaW5kZXggPT0gJHtpfSkgeyByZXR1cm4gJHtzaXplSW5Db25jYXRBeGlzW2ldfTsgfWApO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gc2l6ZUluQ29uY2F0QXhpcy5sZW5ndGggLSAxKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIHsgcmV0dXJuICR7c2l6ZUluQ29uY2F0QXhpc1tpXX07IH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgZWxzZSBpZiAoaW5kZXggPT0gJHtpfSkgeyByZXR1cm4gJHtzaXplSW5Db25jYXRBeGlzW2ldfTsgfWApO1xuICAgIH1cbiAgfVxuICBjb2RlTGluZXMucHVzaCgnXFx0JyArICd9Jyk7XG5cbiAgcmV0dXJuIGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248Q29uY2F0QXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IENvbmNhdEF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycpIH0pO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0b28gZmV3IGlucHV0cycpO1xuICB9XG5cbiAgY29uc3QgaW5wdXRUeXBlID0gaW5wdXRzWzBdLnR5cGU7XG4gIGNvbnN0IGlucHV0RGltZW5zaW9uYWxpdHkgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG5cbiAgLy8gVE9ETzogU3VwcG9ydCBzdHJpbmcgY29uY2F0XG4gIGlmIChpbnB1dFR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpbmcgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGlucHV0IG9mIGlucHV0cykge1xuICAgIC8vIG1ha2Ugc3VyZSB0eXBlcyBvZiBhbGwgaW5wdXRzIG1hdGNoXG4gICAgaWYgKGlucHV0LnR5cGUgIT09IGlucHV0VHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCB0ZW5zb3JzIHNob3VsZCBiZSBvbmUgdHlwZScpO1xuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGUgZGltZW5zaW9uYWxpdHkgb2YgYWxsIGlucHV0cyBhcmUgdGhlIHNhbWVcbiAgICBpZiAoaW5wdXQuZGltcy5sZW5ndGggIT09IGlucHV0RGltZW5zaW9uYWxpdHkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgdGVuc29ycyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBzaGFwZScpO1xuICAgIH1cbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgTUFYX0NMSVAsIE1JTl9DTElQIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBGdW5jdGlvblR5cGUsIEdsc2xWYWx1ZUZ1bmN0aW9uIH0gZnJvbSAnLi4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2xzbEFicygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdhYnMnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQWNvcygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdhY29zJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEFzaW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnYXNpbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBdGFuKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2F0YW4nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQ2VpbCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdjZWlsJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbENvcygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdjb3MnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRWx1KGFscGhhOiBudW1iZXIpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnZWx1JztcbiAgY29uc3QgYm9keSA9IGBcbiAgY29uc3QgZmxvYXQgYWxwaGEgPSBmbG9hdCgke2FscGhhfSk7XG5cbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBhID49IDAuMCA/IGE6IChleHAoYSkgLSAxLjApICogYWxwaGE7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gdmVjNCgke25hbWV9Xyh2LngpLCAke25hbWV9Xyh2LnkpLCAke25hbWV9Xyh2LnopLCAke25hbWV9Xyh2LncpKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xFeHAoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnZXhwJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEZsb29yKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2Zsb29yJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbENsaXAobWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2NsaXAnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBtaW4gPSBmbG9hdCgke21pbn0pO1xuICBjb25zdCBmbG9hdCBtYXggPSBmbG9hdCgke21heH0pO1xuXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gY2xhbXAoYSwgbWluLCBtYXgpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIGNsYW1wKHYsIG1pbiwgbWF4KTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xJZGVudGl0eSgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnaW5kZW50aXR5JztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHY7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTGVha3lSZWx1KGFscGhhOiBudW1iZXIpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbGVha3lSZWx1JztcbiAgY29uc3QgYm9keSA9IGBcbiAgY29uc3QgZmxvYXQgYWxwaGEgPSBmbG9hdCgke2FscGhhfSk7XG5cbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBhIDwgMC4wID8gYSAqIGFscGhhIDogYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2ZWM0KCR7bmFtZX1fKHYueCksICR7bmFtZX1fKHYueSksICR7bmFtZX1fKHYueiksICR7bmFtZX1fKHYudykpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbExvZygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdsb2cnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTmVnKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICduZWcnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIC1hO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIC12O1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbE5vdCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbm90JztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBmbG9hdCggISBib29sKGEpICk7XG4gIH1cbiAgYm9vbCAke25hbWV9Xyhib29sIGEpIHtcbiAgICByZXR1cm4gIWE7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gdmVjNCghYm9vbCh2LngpLCAhYm9vbCh2LnkpLCAhYm9vbCh2LnopLCAhYm9vbCh2LncpKTtcbiAgfVxuICBidmVjNCAke25hbWV9XyhidmVjNCB2KSB7XG4gICAgcmV0dXJuIGJ2ZWM0KCF2LngsICF2LnksICF2LnosICF2LncpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFNpbigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdzaW4nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsUmVsdSgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAncmVsdSc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gbWF4KCBhLCAwLjAgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiBtYXgoIHYsIDAuMCApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFNpZ21vaWQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3NpZ21vaWQnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIDEuMCAvICgxLjAgKyBleHAoLWEpKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiAxLjAgLyAoMS4wICsgZXhwKC12KSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU3FydCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdzcXJ0Jyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFRhbigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCd0YW4nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsVGFuaCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAndGFuaCc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICBhID0gY2xhbXAoYSwgLTEwLiwgMTAuKTtcbiAgICBhID0gZXhwKDIuKmEpO1xuICAgIHJldHVybiAoYSAtIDEuKSAvIChhICsgMS4pO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgdiA9IGNsYW1wKHYsIC0xMC4sIDEwLik7XG4gICAgdiA9IGV4cCgyLip2KTtcbiAgICByZXR1cm4gKHYgLSAxLikgLyAodiArIDEuKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZnVuY3Rpb24gZ2xzbEJ1aWx0aW5VbmFyeShuYW1lOiBzdHJpbmcpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gJHtuYW1lfShhKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiAke25hbWV9KHYpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5cbi8vLy8vXG4vLy8vL1xuLy8vLy9cblxuY29uc3QgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dDogVGVuc29yLFxuICBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZSB9LFxuICAgIHNoYWRlclNvdXJjZTogYFxuICAgICAke2dsc2xGdW5jLmJvZHl9XG4gICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICB2ZWM0IHYgPSAke2dsc2wudGV4dHVyZTJEfShBLCBUZXhDb29yZHMpO1xuICAgICAgIHYgPSAke2dsc2xGdW5jLm5hbWV9Xyh2KTtcbiAgICAgICAke2dsc2wub3V0cHV0fSA9IHY7XG4gICAgIH1cbiAgICAgYCxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4gIGNhY2hlS2V5Pzogc3RyaW5nLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCB0ZXh0dXJlVHlwZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrID8gVGV4dHVyZVR5cGUucGFja2VkIDogVGV4dHVyZVR5cGUudW5wYWNrZWQ7XG4gIGNvbnN0IG1ldGFkYXRhID0geyBuYW1lOiBnbHNsRnVuYy5uYW1lLCBpbnB1dFR5cGVzOiBbdGV4dHVyZVR5cGVdLCBpbnB1dE5hbWVzOiBbJ0EnXSwgY2FjaGVIaW50OiBjYWNoZUtleSB9O1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dCwgZ2xzbEZ1bmMpIH07XG59O1xuXG5leHBvcnQgY29uc3QgYWJzID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBYnMoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgYWNvcyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQWNvcygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBhc2luID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBc2luKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGF0YW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEF0YW4oKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgaW50ZXJmYWNlIENsaXBBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgbWluOiBudW1iZXI7XG4gIHJlYWRvbmx5IG1heDogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgY2xpcCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENsaXBBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKFxuICAgICAgaGFuZGxlcixcbiAgICAgIGlucHV0c1swXSxcbiAgICAgIGdsc2xDbGlwKGF0dHJpYnV0ZXMubWluLCBhdHRyaWJ1dGVzLm1heCksXG4gICAgICBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICksXG4gICAgaW5wdXRzLFxuICApLFxuXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ2xpcEF0dHJpYnV0ZXMgPSAobm9kZTogR3JhcGguTm9kZSk6IENsaXBBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgbWluOiBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21pbicsIE1JTl9DTElQKSxcbiAgICBtYXg6IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnbWF4JywgTUFYX0NMSVApLFxuICB9KTtcblxuZXhwb3J0IGNvbnN0IGNsaXBWMTEgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBhdHRyaWJ1dGVzID0gZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMoaGFuZGxlciwgaW5wdXRzKTtcbiAgcmV0dXJuIGNsaXAoaGFuZGxlciwgW2lucHV0c1swXV0sIGF0dHJpYnV0ZXMpO1xufTtcblxuY29uc3QgZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogQ2xpcEF0dHJpYnV0ZXMgPT4ge1xuICBpZiAoXG4gICAgaW5wdXRzLmxlbmd0aCA+PSAzICYmXG4gICAgKCFoYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMV0uZGF0YUlkKSB8fCAhaGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzJdLmRhdGFJZCkpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignZHluYW1pYyBjbGlwIGF0dHJpYnV0ZXMgYXJlIG5vdCBhbGxvd2VkJyk7XG4gIH1cblxuICBjb25zdCBtaW4gPSBpbnB1dHMubGVuZ3RoID49IDMgPyBpbnB1dHNbMV0ubnVtYmVyRGF0YVswXSA6IE1JTl9DTElQO1xuICBjb25zdCBtYXggPSBpbnB1dHMubGVuZ3RoID49IDMgPyBpbnB1dHNbMl0ubnVtYmVyRGF0YVswXSA6IE1BWF9DTElQO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgbWluLCBtYXggfSk7XG59O1xuXG5leHBvcnQgY29uc3QgY2VpbCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQ2VpbCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBjb3MgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbENvcygpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgRWx1QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGFscGhhOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBlbHUgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBFbHVBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEVsdShhdHRyaWJ1dGVzLmFscGhhKSwgYXR0cmlidXRlcy5jYWNoZUtleSksXG4gICAgaW5wdXRzLFxuICApLFxuXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRWx1QXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogRWx1QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBhbHBoYTogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdhbHBoYScsIDEuMCkgfSk7XG5cbmV4cG9ydCBjb25zdCBleHAgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEV4cCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBmbG9vciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsRmxvb3IoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgaWRlbnRpdHkgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbElkZW50aXR5KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBMZWFreVJlbHVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYWxwaGE6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGxlYWt5UmVsdSA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBMZWFreVJlbHVBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbExlYWt5UmVsdShhdHRyaWJ1dGVzLmFscGhhKSwgYXR0cmlidXRlcy5jYWNoZUtleSksXG4gICAgaW5wdXRzLFxuICApLFxuXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTGVha3lSZWx1QXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogTGVha3lSZWx1QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBhbHBoYTogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdhbHBoYScsIDAuMDEpIH0pO1xuXG5leHBvcnQgY29uc3QgbG9nID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xMb2coKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgbmVnID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xOZWcoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgbm90ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xOb3QoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgcmVsdSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsUmVsdSgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBzaWdtb2lkID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xTaWdtb2lkKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHNpbiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsU2luKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHNxcnQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFNxcnQoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgdGFuID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xUYW4oKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgdGFuaCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsVGFuaCgpKSwgaW5wdXRzKSxcbl07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZSc7XG5pbXBvcnQgeyBNQVhfQ0xJUCwgTUlOX0NMSVAgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IEdsc2xWYWx1ZUZ1bmN0aW9uIH0gZnJvbSAnLi4vZ2xzbC1kZWZpbml0aW9ucyc7XG5cbmltcG9ydCB7IGdsc2xDbGlwLCBnbHNsUmVsdSwgZ2xzbFNpZ21vaWQgfSBmcm9tICcuL3VuYXJ5LW9wJztcblxuZXhwb3J0IGludGVyZmFjZSBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgYWN0aXZhdGlvbjogc3RyaW5nO1xuICByZWFkb25seSBjbGlwTWluPzogbnVtYmVyO1xuICByZWFkb25seSBjbGlwTWF4PzogbnVtYmVyO1xuICByZWFkb25seSBhY3RpdmF0aW9uQ2FjaGVLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMpIHtcbiAgbGV0IGZ1bmM6IEdsc2xWYWx1ZUZ1bmN0aW9uO1xuICBzd2l0Y2ggKGF0dHJpYnV0ZXMuYWN0aXZhdGlvbikge1xuICAgIGNhc2UgJ1JlbHUnOlxuICAgICAgZnVuYyA9IGdsc2xSZWx1KCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdTaWdtb2lkJzpcbiAgICAgIGZ1bmMgPSBnbHNsU2lnbW9pZCgpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnQ2xpcCc6XG4gICAgICBmdW5jID0gZ2xzbENsaXAoYXR0cmlidXRlcy5jbGlwTWluISwgYXR0cmlidXRlcy5jbGlwTWF4ISk7XG4gICAgICBicmVhaztcbiAgICAvLyBUT0RPOiBhZGRpbmcgb3RoZXIgYWN0aXZhdGlvbnMgdGhhdCBjYW4gYmUgZnVzZWQuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7IGFjdGl2YXRpb25GdW5jdGlvbjogJycsIGFwcGx5QWN0aXZhdGlvbjogJycgfTtcbiAgfVxuXG4gIGNvbnN0IGFjdGl2YXRpb25OYW1lID0gZnVuYy5uYW1lO1xuICBjb25zdCBhY3RpdmF0aW9uRnVuY3Rpb24gPSBmdW5jLmJvZHk7XG4gIGNvbnN0IGFwcGx5QWN0aXZhdGlvbiA9IGB2YWx1ZSA9ICR7YWN0aXZhdGlvbk5hbWV9Xyh2YWx1ZSk7YDtcbiAgcmV0dXJuIHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfTtcbn1cblxuZXhwb3J0IGNvbnN0IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBBdHRyaWJ1dGUpOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYWN0aXZhdGlvbiA9IGF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhY3RpdmF0aW9uJywgJycpO1xuXG4gIGlmIChhY3RpdmF0aW9uID09PSAnQ2xpcCcpIHtcbiAgICBjb25zdCBbY2xpcE1pbiwgY2xpcE1heF0gPSBhdHRyaWJ1dGVzLmdldEZsb2F0cygnYWN0aXZhdGlvbl9wYXJhbXMnLCBbTUlOX0NMSVAsIE1BWF9DTElQXSk7XG4gICAgcmV0dXJuIHsgYWN0aXZhdGlvbiwgY2xpcE1heCwgY2xpcE1pbiwgYWN0aXZhdGlvbkNhY2hlS2V5OiBgJHthY3RpdmF0aW9ufToke2NsaXBNaW59LCR7Y2xpcE1heH1gIH07XG4gIH1cbiAgcmV0dXJuIHsgYWN0aXZhdGlvbiwgYWN0aXZhdGlvbkNhY2hlS2V5OiBhY3RpdmF0aW9uIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjYWxjdWxhdGVPdXRwdXRTaGFwZSwgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgZ2V0QWN0aXZhdGlvblNuaXBwZXQgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKTogUHJvZ3JhbU1ldGFkYXRhID0+ICh7XG4gIG5hbWU6ICdHcm91cGVkQ29udicsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ1gnLCAnVycsICdCaWFzJ10gOiBbJ1gnLCAnVyddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzXG4gICAgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IHByb2Nlc3NCaWFzID0gaGFzQmlhcyA/ICd2YWx1ZSArPSBnZXRCaWFzKG91dHB1dF9jaGFubmVsKTsnIDogJyc7XG4gIGNvbnN0IHhTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IHdTaGFwZSA9IGlucHV0c1sxXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IG91dHB1dENoYW5uZWxzUGVyR3JvdXAgPSB3U2hhcGVbMF0gLyBhdHRyaWJ1dGVzLmdyb3VwO1xuICBMb2dnZXIudmVyYm9zZShcbiAgICAnR3JvdXBlZENvbnYnLFxuICAgIGBhdXRwUGFkOiR7YXR0cmlidXRlcy5hdXRvUGFkfSwgZGlsYXRpb25zOiR7YXR0cmlidXRlcy5kaWxhdGlvbnN9LCBncm91cDoke2F0dHJpYnV0ZXMuZ3JvdXB9LCBrZXJuZWxTaGFwZToke1xuICAgICAgYXR0cmlidXRlcy5rZXJuZWxTaGFwZVxuICAgIH0sIHBhZHM6JHthdHRyaWJ1dGVzLnBhZHN9LCBzdHJpZGVzOiR7YXR0cmlidXRlcy5zdHJpZGVzfWAsXG4gICk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoeFNoYXBlLCB3U2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgeyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcyk7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICBjb25zdCBpdmVjMiBzdHJpZGVzID0gaXZlYzIoJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19LCAke2F0dHJpYnV0ZXMuc3RyaWRlc1sxXX0pO1xuICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHthdHRyaWJ1dGVzLnBhZHNbMF19LCAke2F0dHJpYnV0ZXMucGFkc1sxXX0pO1xuICAke2FjdGl2YXRpb25GdW5jdGlvbn1cbiAgdm9pZCBtYWluKCkge1xuICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgIGludCBiYXRjaCA9IGNvb3Jkcy54O1xuICAgIGludCBvdXRwdXRfY2hhbm5lbCA9IGNvb3Jkcy55O1xuICAgIGl2ZWMyIHhSQ0Nvcm5lciA9IGNvb3Jkcy56dyAqIHN0cmlkZXMgLSBwYWRzO1xuICAgIGludCBncm91cF9pZCA9IG91dHB1dF9jaGFubmVsIC8gJHtvdXRwdXRDaGFubmVsc1Blckdyb3VwfTtcblxuICAgIGZsb2F0IHZhbHVlID0gMC4wO1xuICAgIGZvciAoaW50IHdJbkNoYW5uZWwgPSAwOyB3SW5DaGFubmVsIDwgJHt3U2hhcGVbMV19OyB3SW5DaGFubmVsKyspIHtcbiAgICAgIGludCBpbnB1dF9jaGFubmVsID0gZ3JvdXBfaWQgKiAke3dTaGFwZVsxXX0gKyB3SW5DaGFubmVsO1xuICAgICAgZm9yIChpbnQgd0hlaWdodCA9IDA7IHdIZWlnaHQgPCAke3dTaGFwZVsyXX07IHdIZWlnaHQrKykge1xuICAgICAgICBpbnQgeEhlaWdodCA9IHhSQ0Nvcm5lci54ICsgd0hlaWdodCAqICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19O1xuXG4gICAgICAgIGlmICh4SGVpZ2h0IDwgMCB8fCB4SGVpZ2h0ID49ICR7eFNoYXBlWzJdfSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChpbnQgd1dpZHRoID0gMDsgd1dpZHRoIDwgJHt3U2hhcGVbM119OyB3V2lkdGgrKykge1xuICAgICAgICAgIGludCB4V2lkdGggPSB4UkNDb3JuZXIueSArIHdXaWR0aCAqICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMV19O1xuICAgICAgICAgIGlmICh4V2lkdGggPCAwIHx8IHhXaWR0aCA+PSAke3hTaGFwZVszXX0pIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZsb2F0IHhWYWwgPSBnZXRYKGJhdGNoLCBpbnB1dF9jaGFubmVsLCB4V2lkdGgsIHhIZWlnaHQpO1xuICAgICAgICAgIGZsb2F0IHdWYWwgPSBnZXRXKG91dHB1dF9jaGFubmVsLCB3SW5DaGFubmVsLCB3V2lkdGgsIHdIZWlnaHQpO1xuICAgICAgICAgIHZhbHVlICs9IHhWYWwqd1ZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAke3Byb2Nlc3NCaWFzfVxuICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCh2YWx1ZSwgLjAsIC4wLCAuMCk7XG4gIH1cbmA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgbWV0YWRhdGEsIGF0dHJpYnV0ZXMpLFxuICB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb252JztcbmltcG9ydCB7IHVucGFja0Zyb21DaGFubmVsIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbU1ldGFkYXRhID0gKGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnSW0yQ29sIChwYWNrZWQpJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgeDogVGVuc29yLFxuICB3OiBUZW5zb3IsXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IHguZGltcztcbiAgY29uc3Qgd3NoYXBlID0gdy5kaW1zO1xuICBjb25zdCByb3dEaW0gPSAyO1xuICBjb25zdCBjb2xEaW0gPSAzO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBpbTJjb2xTaGFwZSA9IFt3c2hhcGVbMV0gKiB3c2hhcGVbMl0gKiB3c2hhcGVbM10sIG91dHB1dFNoYXBlWzJdICogb3V0cHV0U2hhcGVbM11dO1xuICBjb25zdCBrZXJuZWxTaXplID0gd3NoYXBlWzJdICogd3NoYXBlWzNdO1xuICBjb25zdCB1bnBhY2tDaGFubmVsID0gdW5wYWNrRnJvbUNoYW5uZWwoKTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBsZXQgdW5yb2xsZWQgPSAnJztcblxuICBmb3IgKGxldCByb3cgPSAwOyByb3cgPD0gMTsgcm93KyspIHtcbiAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPD0gMTsgY29sKyspIHtcbiAgICAgIHVucm9sbGVkICs9IGBcbiAgICAgICAgICAgIGJsb2NrSW5kZXggPSByYy54ICsgJHtjb2x9O1xuICAgICAgICAgICAgcG9zID0gcmMueSArICR7cm93fTtcblxuICAgICAgICAgICAgaWYoYmxvY2tJbmRleCA8ICR7aW0yY29sU2hhcGVbMV19ICYmIHBvcyA8ICR7aW0yY29sU2hhcGVbMF19KSB7XG4gICAgICAgICAgICAgIG9mZnNldFkgPSBpbnQoYmxvY2tJbmRleCAvICgke291dHB1dFNoYXBlW3JhbmsgLSAxXX0pKSAqICR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfSAtXG4gICAgICAgICAgICAgICAgJHthdHRyaWJ1dGVzLnBhZHNbMF19O1xuICAgICAgICAgICAgICBkMCA9IG9mZnNldFkgKyAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzBdfSAqIChpbW9kKHBvcywgJHtrZXJuZWxTaXplfSkgLyAke3dzaGFwZVsyXX0pO1xuXG4gICAgICAgICAgICAgIGlmKGQwIDwgJHt4c2hhcGVbcm93RGltXX0gJiYgZDAgPj0gMCkge1xuICAgICAgICAgICAgICAgIG9mZnNldFggPSBpbW9kKGJsb2NrSW5kZXgsICR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkgKiAke2F0dHJpYnV0ZXMuc3RyaWRlc1sxXX0gLVxuICAgICAgICAgICAgICAgICAgJHthdHRyaWJ1dGVzLnBhZHNbMV19O1xuICAgICAgICAgICAgICAgIGQxID0gb2Zmc2V0WCArICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMV19ICogaW1vZChpbW9kKHBvcywgJHtrZXJuZWxTaXplfSksICR7d3NoYXBlWzJdfSk7XG5cbiAgICAgICAgICAgICAgICBpZihkMSA8ICR7eHNoYXBlW2NvbERpbV19ICYmIGQxID49IDApIHtcblxuICAgICAgICAgICAgICAgICAgY2ggPSBpbnQoZmxvYXQocG9zKS8gJHtrZXJuZWxTaXplfS4pO1xuICAgICAgICAgICAgICAgICAgICBpbm5lckRpbXMgPSB2ZWMyKGQwLCBkMSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFske3JvdyAqIDIgKyBjb2x9XSA9IGdldENoYW5uZWwoXG4gICAgICAgICAgICAgICAgICAgICAgZ2V0QSgwLCBjaCwgaW50KGlubmVyRGltcy54KSxcbiAgICAgICAgICAgICAgICAgICAgICBpbnQoaW5uZXJEaW1zLnkpKSwgaW5uZXJEaW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIGA7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHt1bnBhY2tDaGFubmVsfVxuXG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIGl2ZWMyIHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuMCk7XG4gICAgICAgICAgaW50IGJsb2NrSW5kZXgsIHBvcywgb2Zmc2V0WSwgZDAsIG9mZnNldFgsIGQxLCBjaDtcbiAgICAgICAgICB2ZWMyIGlubmVyRGltcztcbiAgICAgICAgICAke3Vucm9sbGVkfVxuICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfVxuICAgICAgICAgICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW0yY29sU2hhcGUsIHR5cGU6IHgudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIHg6IFRlbnNvcixcbiAgdzogVGVuc29yLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1NZXRhZGF0YShhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCB4LCB3LCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IEJyb2FkY2FzdFV0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0Q29vcmRzRGF0YVR5cGUsIGdldEdsQ2hhbm5lbHMgfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IGdldEFjdGl2YXRpb25TbmlwcGV0LCBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL21hdG11bC1wYWNrJztcblxuZXhwb3J0IGNvbnN0IG1hdE11bDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGlmIChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24ucGFjaykge1xuICAgIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpXTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTWF0TXVsQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgPT4gcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKG5vZGUuYXR0cmlidXRlcyk7XG5cbmNvbnN0IGNyZWF0ZU1hdG11bFByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ01hdE11bCcsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ0EnLCAnQicsICdCaWFzJ10gOiBbJ0EnLCAnQiddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzXG4gICAgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuZnVuY3Rpb24gY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8oXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8ge1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoYVNoYXBlLCBiU2hhcGUsIHRydWUpO1xuICBpZiAoIW91dHB1dFNoYXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgdXNlIG1hdG11bCBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgfVxuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IGFsbEdsQ2hhbm5lbHMgPSBnZXRHbENoYW5uZWxzKCk7XG4gIGNvbnN0IHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGFjdGl2YXRpb25BdHRyaWJ1dGVzKTtcblxuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IHByb2Nlc3NCaWFzID0gaGFzQmlhcyA/ICd2YWx1ZSArPSBnZXRCaWFzRm9yTWF0bXVsKCk7JyA6ICcnO1xuICBjb25zdCBnZXRCaWFzRm9yTWF0bXVsU25pcHBldCA9IGhhc0JpYXNcbiAgICA/IGAke2dldEJpYXNGb3JNYXRtdWwoY29vcmRzRGF0YVR5cGUsIGFsbEdsQ2hhbm5lbHMsIGlucHV0c1syXS5kaW1zLCBvdXRwdXRTaGFwZSwgZmFsc2UpfWBcbiAgICA6ICcnO1xuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGFyYW5rID0gYVNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYnJhbmsgPSBiU2hhcGUubGVuZ3RoO1xuICBjb25zdCBzaGFyZWREaW0gPSBhU2hhcGVbYVNoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gICAgJHtnZXRCaWFzRm9yTWF0bXVsU25pcHBldH1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGludCBhWyR7YXJhbmt9XTtcbiAgICAgICAgaW50IGJbJHticmFua31dO1xuICAgICAgICBiY2FzdE1hdG11bEluZGljZXNfQShpbmRpY2VzLCBhKTtcbiAgICAgICAgYmNhc3RNYXRtdWxJbmRpY2VzX0IoaW5kaWNlcywgYik7XG5cbiAgICAgICAgZmxvYXQgdmFsdWU7XG4gICAgICAgIGZvciAoaW50IGs9MDsgazwke3NoYXJlZERpbX07ICsraykge1xuICAgICAgICAgICAgYVske2FyYW5rIC0gMX1dID0gaztcbiAgICAgICAgICAgIGJbJHticmFuayAtIDJ9XSA9IGs7XG4gICAgICAgICAgICB2YWx1ZSArPSBfQShhKSAqIF9CKGIpO1xuICAgICAgICB9XG4gICAgICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoXG4gIGlucHV0czogVGVuc29yW10sXG4gIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZU1hdG11bFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYWN0aXZhdGlvbkF0dHJpYnV0ZXMuYWN0aXZhdGlvbkNhY2hlS2V5KTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8obWV0YWRhdGEsIGlucHV0cywgYWN0aXZhdGlvbkF0dHJpYnV0ZXMpIH07XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignTWF0TXVsIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS5kaW1zW2lucHV0c1swXS5kaW1zLmxlbmd0aCAtIDFdICE9PSBpbnB1dHNbMV0uZGltc1tpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyXSkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2hhcmVkIGRpbWVuc2lvbiBkb2VzIG5vdCBtYXRjaC4nKTtcbiAgfVxuXG4gIGlmIChcbiAgICAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQ2NCcpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXRzIHNob3VsZCBiZSBmbG9hdCB0eXBlJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1sxXS50eXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dHMgdHlwZXMgc2hvdWxkIG1hdGNoJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCaWFzRm9yTWF0bXVsKFxuICBjb29yZHNEYXRhVHlwZTogc3RyaW5nLFxuICBhbGxHbENoYW5uZWxzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgaW5TaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG91dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgaXNQYWNrZWQ6IGJvb2xlYW4sXG4pOiBzdHJpbmcge1xuICBsZXQgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJyc7XG4gIGNvbnN0IGluUmFuayA9IGluU2hhcGUubGVuZ3RoO1xuICBjb25zdCBvdXRSYW5rID0gb3V0U2hhcGUubGVuZ3RoO1xuICBjb25zdCByYW5rRGlmZiA9IG91dFJhbmsgLSBpblJhbms7XG4gIGlmIChvdXRSYW5rIDwgMiAmJiBpblJhbmsgPiAwKSB7XG4gICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJ2Nvb3Jkcyc7XG4gIH0gZWxzZSB7XG4gICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gaW5TaGFwZS5tYXAoKF9zLCBpKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tpICsgcmFua0RpZmZdfWApLmpvaW4oJywgJyk7XG4gIH1cbiAgY29uc3QgYnJvYWRjYXN0RGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpblNoYXBlLCBvdXRTaGFwZSk7XG4gIGNvbnN0IGNvb3Jkc1NuaXBwZXQgPSBicm9hZGNhc3REaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbZCArIHJhbmtEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICBjb25zdCBpblNpemUgPSBTaGFwZVV0aWwuc2l6ZShpblNoYXBlKTtcbiAgY29uc3QgaXNJbnB1dFNjYWxhciA9IGluU2l6ZSA9PT0gMTtcbiAgbGV0IG91dHB1dCA9ICd2ZWM0KG91dHB1dFZhbHVlLnh4LCBvdXRwdXRWYWx1ZS55eSknO1xuICBpZiAoaXNJbnB1dFNjYWxhcikge1xuICAgIG91dHB1dCA9ICd2ZWM0KG91dHB1dFZhbHVlLngpJztcbiAgfVxuICBjb25zdCBnZXRCaWFzRm9yTWF0bXVsU291cmNlID0gaXNQYWNrZWRcbiAgICA/IGBcbnZlYzQgZ2V0Qmlhc0Zvck1hdG11bCgpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7Y29vcmRzU25pcHBldH1cbiAgdmVjNCBvdXRwdXRWYWx1ZSA9IGdldEJpYXMoJHt1bnBhY2tlZENvb3Jkc1NuaXBwZXR9KTtcbiAgcmV0dXJuICR7b3V0cHV0fTtcbn1gXG4gICAgOiBgXG5mbG9hdCBnZXRCaWFzRm9yTWF0bXVsKCkge1xuICAke2Nvb3Jkc0RhdGFUeXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgJHtjb29yZHNTbmlwcGV0fVxuICByZXR1cm4gZ2V0Qmlhcyhjb29yZHMueCk7XG59YDtcblxuICByZXR1cm4gZ2V0Qmlhc0Zvck1hdG11bFNvdXJjZTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IEJyb2FkY2FzdFV0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyBnZXRBY3RpdmF0aW9uU25pcHBldCwgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQgeyBnZXRCaWFzRm9yTWF0bXVsIH0gZnJvbSAnLi9tYXRtdWwnO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdNYXRNdWwgKHBhY2tlZCknLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydBJywgJ0InLCAnQmlhcyddIDogWydBJywgJ0InXSxcbiAgaW5wdXRUeXBlczogaGFzQmlhc1xuICAgID8gW1RleHR1cmVUeXBlLnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRdXG4gICAgOiBbVGV4dHVyZVR5cGUucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGdldEJpYXNGb3JNYXRtdWwoKTsnIDogJyc7XG4gIGNvbnN0IGFTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBiU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShhU2hhcGUsIGJTaGFwZSwgdHJ1ZSk7XG4gIGNvbnN0IGlzQnJvYWRjYXN0ID0gIVNoYXBlVXRpbC5hcmVFcXVhbChpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMpO1xuXG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgbWF0bXVsIG9uIHRoZSBnaXZlbiB0ZW5zb3JzXCIpO1xuICB9XG4gIGNvbnN0IHNoYXJlZERpbSA9IGFTaGFwZVthU2hhcGUubGVuZ3RoIC0gMV07XG4gIGNvbnN0IHNoYXJlZERpbUluZGV4ID0gTWF0aC5jZWlsKHNoYXJlZERpbSAvIDIpO1xuICBjb25zdCBhUmFuayA9IGFTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGJSYW5rID0gYlNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3Qgb3V0UmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYWxsR2xDaGFubmVscyA9IGdldEdsQ2hhbm5lbHMoKTtcbiAgY29uc3QgeyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYWN0aXZhdGlvbkF0dHJpYnV0ZXMpO1xuXG4gIGNvbnN0IGdldEJpYXNGb3JNYXRtdWxTbmlwcGV0ID0gaGFzQmlhc1xuICAgID8gYCR7Z2V0Qmlhc0Zvck1hdG11bChjb29yZHNEYXRhVHlwZSwgYWxsR2xDaGFubmVscywgaW5wdXRzWzJdLmRpbXMsIG91dHB1dFNoYXBlLCB0cnVlKX1gXG4gICAgOiAnJztcblxuICBjb25zdCBnZXRCY2FzdGVkU2FtcGxlckZvck1hdG11bFNuaXBwZXQgPSBpc0Jyb2FkY2FzdFxuICAgID8gYCR7Z2V0QmNhc3RTYW1wbGVyRm9yTWF0bXVsKGNvb3Jkc0RhdGFUeXBlLCBhbGxHbENoYW5uZWxzLCBpbnB1dHMsIG91dHB1dFNoYXBlKX1gXG4gICAgOiAnJztcblxuICBjb25zdCBnZXRTYW1wbGVyQUluTG9vcFNuaXBwZXQgPSBpc0Jyb2FkY2FzdCA/ICdnZXRBQXRPdXRDb29yZHNNYXRtdWwoaSknIDogYGdldEEoJHtnZXRBKGFsbEdsQ2hhbm5lbHMsIGFSYW5rKX0pYDtcbiAgY29uc3QgZ2V0U2FtcGxlckJJbkxvb3BTbmlwcGV0ID0gaXNCcm9hZGNhc3QgPyAnZ2V0QkF0T3V0Q29vcmRzTWF0bXVsKGkpJyA6IGBnZXRCKCR7Z2V0QihhbGxHbENoYW5uZWxzLCBiUmFuayl9KWA7XG4gIGNvbnN0IGdldE91dHB1dENvb3Jkc1NuaXBwZXQgPSBpc0Jyb2FkY2FzdFxuICAgID8gJydcbiAgICA6IGAke2Nvb3Jkc0RhdGFUeXBlfSByYyA9XG4gICAgICAgICAgZ2V0T3V0cHV0Q29vcmRzKCk7IGludCBsYXN0RGltID0gcmMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX07IHJjLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMV19ID1cbiAgICAgICAgICByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfTsgcmMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAyXX0gPSBsYXN0RGltO1xuICAgICAgYDtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAgICAgJHtnZXRCY2FzdGVkU2FtcGxlckZvck1hdG11bFNuaXBwZXR9XG4gICAgICAgICAgICAke2dldEJpYXNGb3JNYXRtdWxTbmlwcGV0fVxuICAgICAgICAgICAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gICAgICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAgICR7Z2V0T3V0cHV0Q29vcmRzU25pcHBldH1cblxuICAgICAgICAgICAgICB2ZWM0IHZhbHVlID0gdmVjNCgwKTtcbiAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3NoYXJlZERpbUluZGV4fTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmVjNCBhID0gJHtnZXRTYW1wbGVyQUluTG9vcFNuaXBwZXR9O1xuICAgICAgICAgICAgICAgIHZlYzQgYiA9ICR7Z2V0U2FtcGxlckJJbkxvb3BTbmlwcGV0fTtcblxuICAgICAgICAgICAgICAgIHZhbHVlICs9IChhLnJyYmIgKiBiLnJncmcpO1xuICAgICAgICAgICAgICAgIHZhbHVlICs9IChhLmdnYWEgKiBiLmJhYmEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgICAgICAgICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZhbHVlO1xuICAgICAgICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYWN0aXZhdGlvbkF0dHJpYnV0ZXMuYWN0aXZhdGlvbkNhY2hlS2V5KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGFjdGl2YXRpb25BdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIGdldEJjYXN0U2FtcGxlckZvck1hdG11bChcbiAgY29vcmRzRGF0YVR5cGU6IHN0cmluZyxcbiAgYWxsR2xDaGFubmVsczogcmVhZG9ubHkgc3RyaW5nW10sXG4gIGlucHV0czogVGVuc29yW10sXG4gIG91dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbik6IHN0cmluZyB7XG4gIGxldCB1bnBhY2tlZEFDb29yZHNTbmlwcGV0ID0gW107XG4gIGxldCB1bnBhY2tlZEJDb29yZHNTbmlwcGV0ID0gW107XG5cbiAgY29uc3QgaW5BU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgaW5CU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcblxuICBjb25zdCBpbkFSYW5rID0gaW5BU2hhcGUubGVuZ3RoO1xuICBjb25zdCBpbkJSYW5rID0gaW5CU2hhcGUubGVuZ3RoO1xuXG4gIGNvbnN0IG91dFJhbmsgPSBvdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHJhbmtBRGlmZiA9IG91dFJhbmsgLSBpbkFSYW5rO1xuICBjb25zdCByYW5rQkRpZmYgPSBvdXRSYW5rIC0gaW5CUmFuaztcblxuICB1bnBhY2tlZEFDb29yZHNTbmlwcGV0ID0gaW5BU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbaSArIHJhbmtBRGlmZl19YCk7XG4gIHVucGFja2VkQUNvb3Jkc1NuaXBwZXRbaW5BUmFuayAtIDFdID0gJ2kqMic7XG4gIHVucGFja2VkQUNvb3Jkc1NuaXBwZXQuam9pbignLCAnKTtcbiAgdW5wYWNrZWRCQ29vcmRzU25pcHBldCA9IGluQlNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2kgKyByYW5rQkRpZmZdfWApO1xuICB1bnBhY2tlZEJDb29yZHNTbmlwcGV0W2luQlJhbmsgLSAyXSA9ICdpKjInO1xuICB1bnBhY2tlZEJDb29yZHNTbmlwcGV0LmpvaW4oJywgJyk7XG5cbiAgY29uc3QgYnJvYWRjYXN0QURpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5BU2hhcGUsIG91dFNoYXBlKTtcbiAgY29uc3QgYnJvYWRjYXN0QkRpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5CU2hhcGUsIG91dFNoYXBlKTtcblxuICBjb25zdCBjb29yZHNBU25pcHBldCA9IGJyb2FkY2FzdEFEaW1zLm1hcCgoZCkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbZCArIHJhbmtBRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgY29uc3QgY29vcmRzQlNuaXBwZXQgPSBicm9hZGNhc3RCRGltcy5tYXAoKGQpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2QgKyByYW5rQkRpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gIGNvbnN0IHN3YXBEaW1TbmlwcGV0ID0gYGludCBsYXN0RGltID0gY29vcmRzLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMV19O1xuICBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX0gPSBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAyXX07XG4gIGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfSA9IGxhc3REaW07YDtcblxuICBjb25zdCBnZXRCY2FzdFNhbXBsZXJNYXRtdWxTb3VyY2UgPSBgXG52ZWM0IGdldEFBdE91dENvb3Jkc01hdG11bChpbnQgaSkge1xuICAke2Nvb3Jkc0RhdGFUeXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgJHtzd2FwRGltU25pcHBldH1cbiAgJHtjb29yZHNBU25pcHBldH1cbiAgdmVjNCBvdXRwdXRWYWx1ZSA9IGdldEEoJHt1bnBhY2tlZEFDb29yZHNTbmlwcGV0fSk7XG4gIHJldHVybiBvdXRwdXRWYWx1ZTtcbn1cblxudmVjNCBnZXRCQXRPdXRDb29yZHNNYXRtdWwoaW50IGkpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7c3dhcERpbVNuaXBwZXR9XG4gICR7Y29vcmRzQlNuaXBwZXR9XG4gIHZlYzQgb3V0cHV0VmFsdWUgPSBnZXRCKCR7dW5wYWNrZWRCQ29vcmRzU25pcHBldH0pO1xuICByZXR1cm4gb3V0cHV0VmFsdWU7XG59YDtcblxuICByZXR1cm4gZ2V0QmNhc3RTYW1wbGVyTWF0bXVsU291cmNlO1xufVxuXG5mdW5jdGlvbiBnZXRBKGFsbEdsQ2hhbm5lbHM6IHN0cmluZ1tdLCByYW5rOiBudW1iZXIpOiBzdHJpbmcge1xuICBsZXQgcmVzID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7IGkrKykge1xuICAgIHJlcyArPSBgcmMuJHthbGxHbENoYW5uZWxzW2ldfSwgYDtcbiAgfVxuICByZXMgKz0gYHJjLiR7YWxsR2xDaGFubmVsc1tyYW5rIC0gMl19LCBgICsgJ2kqMic7XG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIGdldEIoYWxsR2xDaGFubmVsczogc3RyaW5nW10sIHJhbms6IG51bWJlcik6IHN0cmluZyB7XG4gIGxldCByZXMgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMjsgaSsrKSB7XG4gICAgcmVzICs9IGByYy4ke2FsbEdsQ2hhbm5lbHNbaV19LCBgO1xuICB9XG4gIHJlcyArPSAnaSoyLCAnICsgYHJjLiR7YWxsR2xDaGFubmVsc1tyYW5rIC0gMV19YDtcbiAgcmV0dXJuIHJlcztcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuaW1wb3J0IHsgY2FsY3VsYXRlT3V0cHV0U2hhcGUsIENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb252JztcbmltcG9ydCB7IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9pbTJjb2wtcGFjayc7XG5pbXBvcnQgeyBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vbWF0bXVsLXBhY2snO1xuXG5leHBvcnQgY29uc3QgY29udjJEUGFja2VkUG9pbnR3aXNlID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhzaGFwZSwga3NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuICBjb25zdCByZXNoYXBlZFggPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzBdLCBbeHNoYXBlWzFdLCB4c2hhcGVbMl0gKiB4c2hhcGVbM11dKTtcbiAgY29uc3QgcmVzaGFwZWRLID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1sxXSwgW2tzaGFwZVswXSwga3NoYXBlWzFdXSk7XG5cbiAgY29uc3QgbWF0bXVsSW5wdXRzID0gaW5wdXRzLmxlbmd0aCA+IDIgPyBbcmVzaGFwZWRLLCByZXNoYXBlZFgsIGlucHV0c1syXV0gOiBbcmVzaGFwZWRLLCByZXNoYXBlZFhdO1xuICBjb25zdCBtYXRtdWxPdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBtYXRtdWxJbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgIG1hdG11bElucHV0cyxcbiAgKTtcbiAgcmV0dXJuIGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChtYXRtdWxPdXRwdXQsIG91dHB1dFNoYXBlKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb252MkRQYWNrZWQgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG5cbiAgLy8gcnVuIGltMmNvbFxuICBjb25zdCBpbTJjb2xPdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGlucHV0c1sxXSwgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICAgIFtpbnB1dHNbMF1dLFxuICApO1xuXG4gIC8vIHJlc2hhcGUga2VybmVsXG4gIGNvbnN0IGtlcm5lbFJlc2hhcGVkID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1sxXSwgW2tzaGFwZVswXSwga3NoYXBlWzFdICoga3NoYXBlWzJdICoga3NoYXBlWzNdXSk7XG5cbiAgLy8gcnVuIG1hdG11bFxuICBjb25zdCBtYXRtdWxJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gW2tlcm5lbFJlc2hhcGVkLCBpbTJjb2xPdXRwdXQsIGlucHV0c1syXV0gOiBba2VybmVsUmVzaGFwZWQsIGltMmNvbE91dHB1dF07XG4gIGNvbnN0IG1hdG11bE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIG1hdG11bElucHV0cywgYXR0cmlidXRlcyksXG4gICAgbWF0bXVsSW5wdXRzLFxuICApO1xuXG4gIC8vIHJlc2hhcGUgb3V0cHV0XG4gIGNvbnN0IG91dHB1dFJlc2hhcGVkID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKG1hdG11bE91dHB1dCwgb3V0cHV0U2hhcGUpO1xuICByZXR1cm4gb3V0cHV0UmVzaGFwZWQ7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBDb252QXR0cmlidXRlcyB9IGZyb20gJy4vY29udic7XG5cbmNvbnN0IGNyZWF0ZUltMkNvbFByb2dyYW1NZXRhZGF0YSA9IChjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ0ltMkNvbCcsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm8gPSAoXG4gIF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIHg6IFRlbnNvcixcbiAgdzogVGVuc29yLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB4c2hhcGUgPSB4LmRpbXM7XG4gIGNvbnN0IHdzaGFwZSA9IHcuZGltcztcblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBpbTJjb2xEaW1zID0gY2FsY3VsYXRlSW0yQ29sRGltcyh4c2hhcGUsIHdzaGFwZSwgb3V0cHV0U2hhcGUsIDQpO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgY29uc3QgaW50IFhDID0gJHt4c2hhcGVbMV19O1xuICAgICAgICBjb25zdCBpbnQgWEggPSAke3hzaGFwZVsyXX07XG4gICAgICAgIGNvbnN0IGludCBYVyA9ICR7eHNoYXBlWzNdfTtcbiAgICAgICAgY29uc3QgaW50IEtIID0gJHthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzBdfTtcbiAgICAgICAgY29uc3QgaW50IEtXID0gJHthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzFdfTtcbiAgICAgICAgY29uc3QgaW50IGRpbGF0aW9uSCA9ICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19O1xuICAgICAgICBjb25zdCBpbnQgZGlsYXRpb25XID0gJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX07XG4gICAgICAgIGNvbnN0IGludCBzdHJpZGVIID0gJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19O1xuICAgICAgICBjb25zdCBpbnQgc3RyaWRlVyA9ICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfTtcbiAgICAgICAgY29uc3QgaW50IHBhZEggPSAke2F0dHJpYnV0ZXMucGFkc1swXX07XG4gICAgICAgIGNvbnN0IGludCBwYWRXID0gJHthdHRyaWJ1dGVzLnBhZHNbMV19O1xuICAgICAgICBjb25zdCBpbnQgS0hLVyA9IEtIKktXO1xuICAgICAgICBjb25zdCBpbnQgWENLSEtXID0gWEMgKiBLSEtXO1xuICAgICAgICBjb25zdCBpbnQgb3V0cHV0Q2hhbm5lbHMgPSA0O1xuICAgICAgICB2ZWM0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgYiAgPSBpbmRpY2VzWzBdOyAvLyBiYXRjaCBzaXplXG4gICAgICAgICAgaW50IG9oID0gaW5kaWNlc1sxXSAqIHN0cmlkZUggLSBwYWRIOyAvL291dHB1dCBoZWlnaHRcbiAgICAgICAgICBpbnQgb3cgPSBpbmRpY2VzWzJdICogc3RyaWRlVyAtIHBhZFc7IC8vb3V0cHV0IHdpZHRoXG4gICAgICAgICAgaW50IHAgPSBpbmRpY2VzWzNdICogb3V0cHV0Q2hhbm5lbHM7IC8vcGF0Y2hcbiAgICAgICAgICB2ZWM0IHZhbHVlID0gdmVjNCgwLjApO1xuICAgICAgICAgIGZvcihpbnQgaT0wOyBpIDwgb3V0cHV0Q2hhbm5lbHM7ICsraSkge1xuICAgICAgICAgICAgaWYocCA8IFhDS0hLVykge1xuICAgICAgICAgICAgICBpbnQgcGF0Y2hDID0gcCAvIEtIS1c7XG4gICAgICAgICAgICAgIGludCBwYXRjaEggPSAocCAtIHBhdGNoQypLSEtXKSAvIEtXO1xuICAgICAgICAgICAgICBpbnQgcGF0Y2hXID0gKHAgLSBwYXRjaEMqS0hLVykgLSBwYXRjaEggKiBLVztcbiAgICAgICAgICAgICAgaW50IHhoMiA9IG9oICsgcGF0Y2hIICogZGlsYXRpb25IO1xuICAgICAgICAgICAgICBpbnQgeHcyID0gb3cgKyBwYXRjaFcgKiBkaWxhdGlvblc7XG4gICAgICAgICAgICAgIGludCB4WyR7eHNoYXBlLmxlbmd0aH1dO1xuICAgICAgICAgICAgICB4WzBdID0gYjtcbiAgICAgICAgICAgICAgeFsxXSA9IHBhdGNoQztcbiAgICAgICAgICAgICAgeFsyXSA9IHhoMjtcbiAgICAgICAgICAgICAgeFszXSA9IHh3MjtcbiAgICAgICAgICAgICAgaWYoeGgyID49IDAgJiZcbiAgICAgICAgICAgICAgICAgIHhoMiA8IFhIICYmXG4gICAgICAgICAgICAgICAgICB4dzIgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgeHcyIDwgWFcpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZVtpXSA9IF9YKHgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK3A7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbTJjb2xEaW1zLCB0eXBlOiB4LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUltMkNvbFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIHg6IFRlbnNvcixcbiAgdzogVGVuc29yLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZUltMkNvbFByb2dyYW1NZXRhZGF0YShhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZUltMkNvbFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCB4LCB3LCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlSW0yQ29sRGltcyA9IChcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBjaGFubmVscyA9IDQsXG4pOiBudW1iZXJbXSA9PiBbXG4gIG91dHB1dFNoYXBlWzBdLFxuICBvdXRwdXRTaGFwZVsyXSxcbiAgb3V0cHV0U2hhcGVbM10sXG4gIE1hdGguY2VpbCgoaW5wdXRTaGFwZVsxXSAqIGtlcm5lbFNoYXBlWzJdICoga2VybmVsU2hhcGVbM10pIC8gY2hhbm5lbHMpLFxuXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgZ2V0QWN0aXZhdGlvblNuaXBwZXQsIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgY2FsY3VsYXRlSW0yQ29sRGltcyB9IGZyb20gJy4vaW0yY29sJztcblxuY29uc3QgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKSA9PiAoe1xuICBuYW1lOiAnQ29udkRvdFByb2R1Y3QnLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydJbTJDb2wnLCAnSycsICdCJ10gOiBbJ0ltMkNvbCcsICdLJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXNcbiAgICA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbiwgVGV4dHVyZVR5cGUudW5wYWNrZWRdXG4gICAgOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb25dLFxuICBjYWNoZUtleTogYXR0cmlidXRlcy5hY3RpdmF0aW9uQ2FjaGVLZXksXG59KTtcblxuY29uc3QgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbiAgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBhZGp1c3RlZEtlcm5lbFNoYXBlID0gW2tzaGFwZVswXSwgTWF0aC5jZWlsKCh4c2hhcGVbMV0gKiBrc2hhcGVbMl0gKiBrc2hhcGVbM10pIC8gNCldO1xuICBjb25zdCBpbTJjb2xTaGFwZSA9IGNhbGN1bGF0ZUltMkNvbERpbXMoeHNoYXBlLCBrc2hhcGUsIG91dHB1dFNoYXBlKTtcbiAgY29uc3QgW2tXaWR0aCwga0hlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBhZGp1c3RlZEtlcm5lbFNoYXBlLFxuICAgIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sXG4gICk7XG5cbiAgY29uc3QgaW0yY29sU3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhpbTJjb2xTaGFwZSk7XG4gIGNvbnN0IFtpbTJjb2xXaWR0aCwgaW0yY29sSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGltMmNvbFNoYXBlLFxuICAgIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sXG4gICk7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3QgaW5pdFZhbHVlID0gaW5wdXRzLmxlbmd0aCA8IDMgPyAnMC4wJyA6ICdfQihiKSc7XG4gIGNvbnN0IHNoYXJlZERpbSA9IE1hdGguY2VpbCgoeHNoYXBlWzFdICoga3NoYXBlWzJdICoga3NoYXBlWzNdKSAvIDQpO1xuICBjb25zdCB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhdHRyaWJ1dGVzKTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4ke2FjdGl2YXRpb25GdW5jdGlvbn1cbmZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgaW50IGJbMV07XG4gIGJbMF0gPSBpbmRpY2VzWzFdO1xuICBpbnQgaW0yY29sWzRdO1xuICBpbTJjb2xbMF0gPSBpbmRpY2VzWzBdO1xuICBpbTJjb2xbMV0gPSBpbmRpY2VzWzJdO1xuICBpbTJjb2xbMl0gPSBpbmRpY2VzWzNdO1xuICBpbnQgaW0yY29sT2Zmc2V0ID0gaW0yY29sWzBdICogJHtpbTJjb2xTdHJpZGVzWzBdfSArIGltMmNvbFsxXSAqICR7aW0yY29sU3RyaWRlc1sxXX0gKyBpbTJjb2xbMl0gKiAke1xuICAgIGltMmNvbFN0cmlkZXNbMl1cbiAgfTtcbiAgaW50IGtlcm5lbE9mZnNldCA9IGluZGljZXNbMV0gKiAke2FkanVzdGVkS2VybmVsU2hhcGVbMV19O1xuICBmbG9hdCB2YWx1ZSA9ICR7aW5pdFZhbHVlfTtcbiAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3NoYXJlZERpbX07ICsraSkge1xuICAgIHZlYzIgaW0yY29sQ29vcmRzID0gb2Zmc2V0VG9Db29yZHMoaW0yY29sT2Zmc2V0LCAke2ltMmNvbFdpZHRofSwgJHtpbTJjb2xIZWlnaHR9KTtcbiAgICB2ZWMyIGtlcm5lbENvb3JkcyA9IG9mZnNldFRvQ29vcmRzKGtlcm5lbE9mZnNldCwgJHtrV2lkdGh9LCAke2tIZWlnaHR9KTtcbiAgICB2YWx1ZSArPSBkb3QoJHtnbHNsLnRleHR1cmUyRH0oSW0yQ29sLCBpbTJjb2xDb29yZHMpLCAke2dsc2wudGV4dHVyZTJEfShLLCBrZXJuZWxDb29yZHMpKTtcbiAgICArK2ltMmNvbE9mZnNldDtcbiAgICArK2tlcm5lbE9mZnNldDtcbiAgfVxuICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgcmV0dXJuIHZhbHVlO1xufWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBvdXRwdXRTaGFwZTogbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlRG90UHJvZHVjdFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYXR0cmlidXRlcyk7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uLy4uLy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBQb29sQ29udlV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuaW1wb3J0IHsgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9jb252LWdyb3VwZWQnO1xuaW1wb3J0IHsgY29udjJEUGFja2VkIH0gZnJvbSAnLi9jb252LXBhY2snO1xuaW1wb3J0IHsgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9kb3QtcHJvZHVjdCc7XG5pbXBvcnQgeyBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL2ltMmNvbCc7XG5pbXBvcnQgeyBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vbWF0bXVsJztcblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZU91dHB1dFNoYXBlID0gKFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhZGp1c3RQYWRzOiByZWFkb25seSBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IGJhdGNoU2l6ZSA9IGlucHV0U2hhcGVbMF07XG4gIGNvbnN0IGlucHV0U3BhdGlhbFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgyKTtcbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dFNwYXRpYWxTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IG91dENoYW5uZWxzID0ga2VybmVsU2hhcGVbMF07XG4gIGNvbnN0IGtlcm5lbFNwYXRpYWxTaGFwZSA9IGtlcm5lbFNoYXBlLnNsaWNlKDIpO1xuICBjb25zdCBkaWxhdGVkS2VybmVsU2hhcGUgPSBrZXJuZWxTcGF0aWFsU2hhcGUubWFwKCh2LCBpKSA9PiB2ICsgKHYgLSAxKSAqIChkaWxhdGlvbnNbaV0gLSAxKSk7XG4gIGNvbnN0IGlucHV0U3BhdGlhbFNoYXBlV2l0aFBhZCA9IGlucHV0U3BhdGlhbFNoYXBlLm1hcCgodiwgaSkgPT4gdiArIGFkanVzdFBhZHNbaV0gKyBhZGp1c3RQYWRzW2kgKyBzcGF0aWFsUmFua10pO1xuICBjb25zdCBvdXRwdXRTcGF0aWFsU2hhcGUgPSBpbnB1dFNwYXRpYWxTaGFwZVdpdGhQYWQubWFwKCh2LCBpKSA9PlxuICAgIE1hdGguZmxvb3IoKHYgLSBkaWxhdGVkS2VybmVsU2hhcGVbaV0gKyBzdHJpZGVzW2ldKSAvIHN0cmlkZXNbaV0pLFxuICApO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFtiYXRjaFNpemUsIG91dENoYW5uZWxzXS5jb25jYXQoLi4ub3V0cHV0U3BhdGlhbFNoYXBlKTtcbiAgcmV0dXJuIG91dHB1dFNoYXBlO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBDb252QXR0cmlidXRlcyBleHRlbmRzIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF1dG9QYWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZ3JvdXA6IG51bWJlcjtcbiAgcmVhZG9ubHkga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBwYWRzOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBjb252OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbnZBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7IC8vIGN1cnJlbnRseSB3aWxsIGZhaWwgaWYgbm90IGNvbnYyRFxuICByZXR1cm4gY29udjJkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyk7XG59O1xuXG5jb25zdCBjb252MmQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udkF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBhZGp1c3RlZEF0dHJpYnV0ZXMgPSBnZXRBZGp1c3RlZENvbnZBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIGlucHV0cyk7XG4gIGNvbnN0IHBhY2tNb2RlID0gaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLnBhY2s7XG4gIGNvbnN0IGlzUG9pbnR3aXNlID0gYWRqdXN0ZWRBdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzBdID09PSAxICYmIGFkanVzdGVkQXR0cmlidXRlcy5rZXJuZWxTaGFwZVsxXSA9PT0gMTtcbiAgaWYgKGFkanVzdGVkQXR0cmlidXRlcy5ncm91cCA+IDEpIHtcbiAgICBjb25zdCByZXN1bHQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgIGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyksXG4gICAgICBpbnB1dHMsXG4gICAgKTtcbiAgICByZXR1cm4gW3Jlc3VsdF07XG4gIH0gZWxzZSBpZiAoaXNQb2ludHdpc2UgJiYgcGFja01vZGUpIHtcbiAgICByZXR1cm4gW2NvbnYyRFVucGFja2VkUG9pbnR3aXNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG4gIH0gZWxzZSBpZiAocGFja01vZGUgJiYgaW5wdXRzWzBdLmRpbXMubGVuZ3RoID09PSA0ICYmIGlucHV0c1swXS5kaW1zWzBdID09PSAxICYmICFpc1BvaW50d2lzZSkge1xuICAgIHJldHVybiBbY29udjJEUGFja2VkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtjb252MkRVbnBhY2tlZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyldO1xuICB9XG59O1xuXG5jb25zdCBjb252MkRVbnBhY2tlZFBvaW50d2lzZSA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBrc2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4c2hhcGUsIGtzaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcbiAgY29uc3QgcmVzaGFwZWRYID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBbeHNoYXBlWzFdLCB4c2hhcGVbMl0gKiB4c2hhcGVbM11dKTtcbiAgY29uc3QgcmVzaGFwZWRLID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzFdLCBba3NoYXBlWzBdLCBrc2hhcGVbMV1dKTtcblxuICBjb25zdCBtYXRtdWxJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID4gMiA/IFtyZXNoYXBlZEssIHJlc2hhcGVkWCwgaW5wdXRzWzJdXSA6IFtyZXNoYXBlZEssIHJlc2hhcGVkWF07XG4gIGNvbnN0IG1hdG11bE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyKG1hdG11bElucHV0cywgYXR0cmlidXRlcyksIG1hdG11bElucHV0cyk7XG4gIHJldHVybiBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChtYXRtdWxPdXRwdXQsIG91dHB1dFNoYXBlKTtcbn07XG5cbmNvbnN0IGNvbnYyRFVucGFja2VkID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhzaGFwZSwga3NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuICBjb25zdCB4SW0yQ29sID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBpbnB1dHNbMV0sIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSxcbiAgICBbaW5wdXRzWzBdXSxcbiAgKTtcblxuICBjb25zdCBkb3RQcm9kdWN0SW5wdXRzID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/IFt4SW0yQ29sLCBpbnB1dHNbMV0sIGlucHV0c1syXV0gOiBbeEltMkNvbCwgaW5wdXRzWzFdXTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICAgIGRvdFByb2R1Y3RJbnB1dHMsXG4gICk7XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5jb25zdCBnZXRBZGp1c3RlZENvbnZBdHRyaWJ1dGVzID0gPFQgZXh0ZW5kcyBDb252QXR0cmlidXRlcz4oYXR0cmlidXRlczogVCwgaW5wdXRzOiBUZW5zb3JbXSk6IFQgPT4ge1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGUuc2xpY2UoKTtcbiAgLy8gaWYga2VybmVsU2hhcGUgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIG9wLCBpbmZlciBpdCBmcm9tIHRoZSB3ZWlnaHQgdGVuc29yIGRpbXNcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChsZXQgaSA9IDI7IGkgPCBpbnB1dHNbMV0uZGltcy5sZW5ndGg7ICsraSkge1xuICAgICAga2VybmVsU2hhcGUucHVzaChpbnB1dHNbMV0uZGltc1tpXSk7XG4gICAgfVxuICB9XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMuc2xpY2UoKTtcbiAgUG9vbENvbnZVdGlsLmFkanVzdFBhZHNCYXNlZE9uQXV0b1BhZChcbiAgICBpbnB1dHNbMF0uZGltcyxcbiAgICBhdHRyaWJ1dGVzLnN0cmlkZXMsXG4gICAgYXR0cmlidXRlcy5kaWxhdGlvbnMsXG4gICAga2VybmVsU2hhcGUsXG4gICAgcGFkcyxcbiAgICBhdHRyaWJ1dGVzLmF1dG9QYWQsXG4gICk7XG5cbiAgLy8gYWx3YXlzIHJldHVybiBhIG5ldyBvYmplY3Qgc28gZG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBhdHRyaWJ1dGVzXG4gIGNvbnN0IG5ld0F0dHJpYnV0ZXM6IFQgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKTtcbiAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBwYWRzLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleSB9KTtcbiAgcmV0dXJuIG5ld0F0dHJpYnV0ZXM7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDb252QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxDb252QXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IENvbnZBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXR0cmlidXRlcyA9IG5vZGUuYXR0cmlidXRlcztcbiAgY29uc3QgYWN0aXZhdGlvbkF0dHJpYnV0ZXMgPSBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMoYXR0cmlidXRlcyk7XG4gIC8vIFRPRE8gOiBNYWtlIHRoaXMgZ2VuZXJpYyBlbm91Z2ggdG8gY29tcHV0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgY29uc3QgYXV0b1BhZCA9IGF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhdXRvX3BhZCcsICdOT1RTRVQnKTtcbiAgY29uc3QgZGlsYXRpb25zID0gYXR0cmlidXRlcy5nZXRJbnRzKCdkaWxhdGlvbnMnLCBbMSwgMV0pO1xuICBjb25zdCBncm91cCA9IGF0dHJpYnV0ZXMuZ2V0SW50KCdncm91cCcsIDEpO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMuZ2V0SW50cygna2VybmVsX3NoYXBlJywgW10pO1xuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgWzAsIDAsIDAsIDBdKTtcbiAgY29uc3Qgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnc3RyaWRlcycsIFsxLCAxXSk7XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYXV0b1BhZCxcbiAgICBkaWxhdGlvbnMsXG4gICAgZ3JvdXAsXG4gICAga2VybmVsU2hhcGUsXG4gICAgcGFkcyxcbiAgICBzdHJpZGVzLFxuICAgIC4uLmFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuICB9KTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIC8vIFJlZmVyIHRvIHRoZSBiZWxvdyBsaW5rIGZvciBhbGwgaW5wdXQgY2hlY2tzXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvT3BlcmF0b3JzLm1kI0NvbnZcbiAgaWYgKCFpbnB1dHMgfHwgKGlucHV0cy5sZW5ndGggIT09IDIgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgcmVxdWlyZXMgMiBvciAzIGlucHV0cycpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCB8fCBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBvbmx5IHN1cHBvcnQgMi1kaW1lbnNpb25hbCBjb252Jyk7XG4gIH1cblxuICAvLyBGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMXG4gIGNvbnN0IGRhdGFDaGFubmVsID0gaW5wdXRzWzBdLmRpbXNbMV07XG4gIGNvbnN0IGZpbHRlckluQ2hhbm5lbCA9IGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cDtcbiAgaWYgKGRhdGFDaGFubmVsICE9PSBmaWx0ZXJJbkNoYW5uZWwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUwnKTtcbiAgfVxuXG4gIC8vIGlmIGJpYXMgaXMgcHJvdmlkZWQgaXQgc2hvdWxkIGJlIDFEIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGZlYXR1cmUgbWFwc1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiAoaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxIHx8IGlucHV0c1sxXS5kaW1zWzBdICE9PSBpbnB1dHNbMl0uZGltc1swXSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYmlhcycpO1xuICB9XG5cbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyO1xuICAvLyB3cm9uZyBkaWxhdGlvbnMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLmRpbGF0aW9ucy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBkaWxhdGlvbnMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3Jvbmcgc3RyaWRlcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBzdHJpZGVzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHBhZHMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoICE9PSBzcGF0aWFsUmFuayAqIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBhZHMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmsgKiAyfURgKTtcbiAgfVxuXG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIHNwZWNpZmllZCwgaXQncyBkYXRhIGxlbmd0aCBtdXN0IGJlIDIgbGVzcyB0aGFuIGRpbXMgbGVuZ3RoIG9mIHRoZSB3ZWlnaHRzIHRlbnNvclxuICAvLyAodGhlIGZpcnN0IDIgZGltcyBhcmUgYmF0Y2hfc2l6ZSBhbmQgY2hhbm5lbHMpXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBrZXJuZWwgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBmbG9hdDY0XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInIHx8IGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgaW5wdXQoWCxXKSBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0udHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IGlucHV0KGJpYXMpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi8uLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgZ2V0QWN0aXZhdGlvblNuaXBwZXQsIHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5cbmNvbnN0IGNvbXB1dGVUb3RhbFBhZCA9IChcbiAgaW5EaW06IG51bWJlcixcbiAgc3RyaWRlOiBudW1iZXIsXG4gIGFkajogbnVtYmVyLFxuICBrZXJuZWw6IG51bWJlcixcbiAgZGlsYXRpb246IG51bWJlcixcbiAgb3V0U2l6ZTogbnVtYmVyLFxuKSA9PiAoaW5EaW0gLSAxKSAqIHN0cmlkZSArIGFkaiArIChrZXJuZWwgLSAxKSAqIGRpbGF0aW9uICsgMSAtIG91dFNpemU7XG5cbmNvbnN0IGRpc3RyaWJ1dGVQYWRkaW5nID0gKHRvdGFsUGFkOiBudW1iZXIsIGF1dG9QYWQ6IHN0cmluZywgcGFkczogbnVtYmVyW10sIGhlYWQ6IG51bWJlciwgdGFpbDogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IHNtYWxsUGFkID0gTWF0aC5mbG9vcih0b3RhbFBhZCAvIDIpO1xuICBpZiAoYXV0b1BhZCA9PT0gJ1NBTUVfVVBQRVInKSB7XG4gICAgcGFkc1toZWFkXSA9IHNtYWxsUGFkO1xuICAgIHBhZHNbdGFpbF0gPSB0b3RhbFBhZCAtIHNtYWxsUGFkO1xuICB9IGVsc2UgaWYgKGF1dG9QYWQgPT09ICdTQU1FX0xPV0VSJykge1xuICAgIHBhZHNbaGVhZF0gPSB0b3RhbFBhZCAtIHNtYWxsUGFkO1xuICAgIHBhZHNbdGFpbF0gPSBzbWFsbFBhZDtcbiAgfVxufTtcblxuY29uc3QgY2FsY3VsYXRlT3V0cHV0U2hhcGVBbmRQYWRzID0gKFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdXRvUGFkOiBzdHJpbmcsXG4gIHBhZHM6IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgb3V0cHV0UGFkZGluZzogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbikgPT4ge1xuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0U2hhcGUubGVuZ3RoIC0gMjtcbiAgY29uc3QgdXBkYXRlU2hhcGUgPSBvdXRwdXRTaGFwZS5sZW5ndGggPT09IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3BhdGlhbFJhbms7ICsraSkge1xuICAgIGNvbnN0IG91dFNpemUgPSB1cGRhdGVTaGFwZSA/IGlucHV0U2hhcGVbaSArIDJdICogc3RyaWRlc1tpXSA6IG91dHB1dFNoYXBlW2ldO1xuICAgIGNvbnN0IHRvdGFsUGFkID0gY29tcHV0ZVRvdGFsUGFkKGlucHV0U2hhcGVbaSArIDJdLCBzdHJpZGVzW2ldLCBwYWRzW2ldLCBrZXJuZWxTaGFwZVtpXSwgZGlsYXRpb25zW2ldLCBvdXRTaXplKTtcbiAgICBkaXN0cmlidXRlUGFkZGluZyh0b3RhbFBhZCwgYXV0b1BhZCwgcGFkcywgaSwgaSArIHNwYXRpYWxSYW5rKTtcbiAgICBpZiAodXBkYXRlU2hhcGUpIHtcbiAgICAgIG91dHB1dFNoYXBlLnB1c2goXG4gICAgICAgIHN0cmlkZXNbaV0gKiAoaW5wdXRTaGFwZVtpICsgMl0gLSAxKSArXG4gICAgICAgICAgb3V0cHV0UGFkZGluZ1tpXSArXG4gICAgICAgICAgKGtlcm5lbFNoYXBlW2ldIC0gMSkgKiBkaWxhdGlvbnNbaV0gK1xuICAgICAgICAgIDEgLVxuICAgICAgICAgIHBhZHNbaV0gLVxuICAgICAgICAgIHBhZHNbaSArIHNwYXRpYWxSYW5rXSxcbiAgICAgICk7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzIGV4dGVuZHMgQ29udkF0dHJpYnV0ZXMge1xuICByZWFkb25seSBvdXRwdXRQYWRkaW5nOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgY29udlRyYW5zcG9zZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb252VHJhbnNwb3NlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpOyAvLyBjdXJyZW50bHkgd2lsbCBmYWlsIGlmIG5vdCBjb252VHJhbnNwb3NlMkRcbiAgcmV0dXJuIGNvbnZUcmFuc3Bvc2UyZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpO1xufTtcblxuY29uc3QgY29udlRyYW5zcG9zZTJkOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgYWRqdXN0ZWRBdHRyaWJ1dGVzID0gZ2V0QWRqdXN0ZWRDb252VHJhbnNwb3NlQXR0cmlidXRlcyhhdHRyaWJ1dGVzLCBpbnB1dHMpO1xuICByZXR1cm4gW2NvbnZUcmFuc3Bvc2UyRFVucGFja2VkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG59O1xuXG5jb25zdCBjcmVhdGVDb252VHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnQ29udlRyYW5zcG9zZScsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ1gnLCAnVycsICdCJ10gOiBbJ1gnLCAnVyddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzXG4gICAgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbiAgICA6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb252VHJhbnNwb3NlUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3QgdmFsdWVJbml0ID0gaGFzQmlhcyA/ICdnZXRCKG91dHB1dF9jaGFubmVsKScgOiAnMC4wJztcbiAgY29uc3QgeFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IHdTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRDaGFubmVsc1Blckdyb3VwID0gd1NoYXBlWzFdO1xuICBjb25zdCBpbnB1dENoYW5uZWxzUGVyR3JvdXAgPSB3U2hhcGVbMF0gLyBhdHRyaWJ1dGVzLmdyb3VwO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFtpbnB1dHNbMF0uZGltc1swXSwgaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwLCAuLi5hdHRyaWJ1dGVzLm91dHB1dFNoYXBlXTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhdHRyaWJ1dGVzKTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gIGNvbnN0IGl2ZWMyIHN0cmlkZXMgPSBpdmVjMigke2F0dHJpYnV0ZXMuc3RyaWRlc1swXX0sICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfSk7XG4gIGNvbnN0IGl2ZWMyIHBhZHMgPSBpdmVjMigke2F0dHJpYnV0ZXMucGFkc1swXX0sICR7YXR0cmlidXRlcy5wYWRzWzFdfSk7XG4gICR7YWN0aXZhdGlvbkZ1bmN0aW9ufVxuICB2b2lkIG1haW4oKSB7XG4gICAgaXZlYzQgY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgaW50IGJhdGNoID0gY29vcmRzLng7XG4gICAgaW50IG91dHB1dF9jaGFubmVsID0gY29vcmRzLnk7XG5cbiAgICBpdmVjMiBsb2MgPSBjb29yZHMuencgKyBwYWRzO1xuXG4gICAgaW50IGdyb3VwX2lkID0gb3V0cHV0X2NoYW5uZWwgLyAke291dHB1dENoYW5uZWxzUGVyR3JvdXB9O1xuICAgIGludCB3T3V0Q2hhbm5lbCA9IG91dHB1dF9jaGFubmVsIC0gZ3JvdXBfaWQgKiAke291dHB1dENoYW5uZWxzUGVyR3JvdXB9O1xuXG4gICAgZmxvYXQgdmFsdWUgPSAke3ZhbHVlSW5pdH07XG4gICAgZm9yIChpbnQgaW5DaGFubmVsT2Zmc2V0ID0gMDsgaW5DaGFubmVsT2Zmc2V0IDwgJHtpbnB1dENoYW5uZWxzUGVyR3JvdXB9OyBpbkNoYW5uZWxPZmZzZXQrKykge1xuICAgICAgaW50IGlucHV0X2NoYW5uZWwgPSBncm91cF9pZCAqICR7aW5wdXRDaGFubmVsc1Blckdyb3VwfSArIGluQ2hhbm5lbE9mZnNldDtcbiAgICAgIGZvciAoaW50IHdXT2ZmID0gMDsgd1dPZmYgPCAke3dTaGFwZVsyXX07IHdXT2ZmKyspIHtcbiAgICAgICAgZm9yIChpbnQgd0hPZmYgPSAwOyB3SE9mZiA8ICR7d1NoYXBlWzNdfTsgd0hPZmYrKykge1xuICAgICAgICAgIGl2ZWMyIHdPZmYgPSBpdmVjMih3V09mZiAqICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19LCB3SE9mZiAqICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMV19KTtcbiAgICAgICAgICBpdmVjMiB3TG9jID0gbG9jIC0gd09mZjtcbiAgICAgICAgICBpdmVjMiB3TG9jSW4gPSB3TG9jIC8gc3RyaWRlcztcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB3TG9jSW4gKiBzdHJpZGVzID09IHdMb2MgJiZcbiAgICAgICAgICAgIHdMb2NJbi54ID49IDAgJiYgd0xvY0luLnggPCAke3hTaGFwZVsyXX0gJiZcbiAgICAgICAgICAgIHdMb2NJbi55ID49IDAgJiYgd0xvY0luLnkgPCAke3hTaGFwZVszXX1cbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGZsb2F0IHhWYWwgPSBnZXRYKGJhdGNoLCBpbnB1dF9jaGFubmVsLCB3TG9jSW4ueSwgd0xvY0luLngpO1xuICAgICAgICAgICAgZmxvYXQgd1ZhbCA9IGdldFcoaW5wdXRfY2hhbm5lbCwgd091dENoYW5uZWwsIHdIT2ZmLCB3V09mZik7XG4gICAgICAgICAgICB2YWx1ZSArPSB4VmFsICogd1ZhbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KHZhbHVlLCAuMCwgLjAsIC4wKTtcbiAgfVxuYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZUNvbnZUcmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRDb252VHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBtZXRhZGF0YSwgYXR0cmlidXRlcyksXG4gIH07XG59O1xuXG5jb25zdCBjb252VHJhbnNwb3NlMkRVbnBhY2tlZCA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHJlc3VsdCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRDb252VHJhbnNwb3NlQXR0cmlidXRlcyA9IDxUIGV4dGVuZHMgQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXM+KGF0dHJpYnV0ZXM6IFQsIGlucHV0czogVGVuc29yW10pOiBUID0+IHtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBvcCwgaW5mZXIgaXQgZnJvbSB0aGUgd2VpZ2h0IHRlbnNvciBkaW1zXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAobGV0IGkgPSAyOyBpIDwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGtlcm5lbFNoYXBlLnB1c2goaW5wdXRzWzFdLmRpbXNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLnNsaWNlKCk7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgLy8gSWYgb3V0cHV0U2hhcGUgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIG9wLCBpbmZlciBpdCBmcm9tIHRoZSBwYXJhbWV0ZXJzXG4gIC8vIFNpbWlsYXJseSwgYXV0b21hdGljYWxseSBpbmZlciBwYWRzIGlmIG5vdCBzcGVjaWZpZWRcbiAgY2FsY3VsYXRlT3V0cHV0U2hhcGVBbmRQYWRzKFxuICAgIGlucHV0U2hhcGUsXG4gICAga2VybmVsU2hhcGUsXG4gICAgYXR0cmlidXRlcy5kaWxhdGlvbnMsXG4gICAgYXR0cmlidXRlcy5hdXRvUGFkLFxuICAgIHBhZHMsXG4gICAgYXR0cmlidXRlcy5zdHJpZGVzLFxuICAgIGF0dHJpYnV0ZXMub3V0cHV0UGFkZGluZyxcbiAgICBvdXRwdXRTaGFwZSxcbiAgKTtcblxuICAvLyBhbHdheXMgcmV0dXJuIGEgbmV3IG9iamVjdCBzbyBkb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsIGF0dHJpYnV0ZXNcbiAgY29uc3QgbmV3QXR0cmlidXRlczogVCA9IE9iamVjdC5hc3NpZ24oe30sIGF0dHJpYnV0ZXMpO1xuICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHsga2VybmVsU2hhcGUsIHBhZHMsIG91dHB1dFNoYXBlLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleSB9KTtcbiAgcmV0dXJuIG5ld0F0dHJpYnV0ZXM7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxDb252VHJhbnNwb3NlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBub2RlLmF0dHJpYnV0ZXM7XG4gIGNvbnN0IGFjdGl2YXRpb25BdHRyaWJ1dGVzID0gcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpO1xuICAvLyBUT0RPIDogTWFrZSB0aGlzIGdlbmVyaWMgZW5vdWdoIHRvIGNvbXB1dGUgZGVmYXVsdCBhdHRyaWJ1dGVzIGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGNvbnN0IGF1dG9QYWQgPSBhdHRyaWJ1dGVzLmdldFN0cmluZygnYXV0b19wYWQnLCAnTk9UU0VUJyk7XG4gIGNvbnN0IGRpbGF0aW9ucyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnZGlsYXRpb25zJywgWzEsIDFdKTtcbiAgY29uc3QgZ3JvdXAgPSBhdHRyaWJ1dGVzLmdldEludCgnZ3JvdXAnLCAxKTtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScsIFtdKTtcbiAgY29uc3Qgb3V0cHV0UGFkZGluZyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnb3V0cHV0X3BhZGRpbmcnLCBbMCwgMF0pO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnb3V0cHV0X3NoYXBlJywgW10pO1xuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgWzAsIDAsIDAsIDBdKTtcbiAgY29uc3Qgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnc3RyaWRlcycsIFsxLCAxXSk7XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYXV0b1BhZCxcbiAgICBkaWxhdGlvbnMsXG4gICAgZ3JvdXAsXG4gICAga2VybmVsU2hhcGUsXG4gICAgb3V0cHV0UGFkZGluZyxcbiAgICBvdXRwdXRTaGFwZSxcbiAgICBwYWRzLFxuICAgIHN0cmlkZXMsXG4gICAgLi4uYWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4gIH0pO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gUmVmZXIgdG8gdGhlIGJlbG93IGxpbmsgZm9yIGFsbCBpbnB1dCBjaGVja3NcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjQ29udlxuICBpZiAoIWlucHV0cyB8fCAoaW5wdXRzLmxlbmd0aCAhPT0gMiAmJiBpbnB1dHMubGVuZ3RoICE9PSAzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiByZXF1aXJlcyAyIG9yIDMgaW5wdXRzJyk7XG4gIH1cblxuICAvLyBUT0RPIDogTmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0IHx8IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG9ubHkgc3VwcG9ydCAyLWRpbWVuc2lvbmFsIGNvbnYnKTtcbiAgfVxuXG4gIC8vIEZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUxcbiAgY29uc3QgZGF0YUNoYW5uZWwgPSBpbnB1dHNbMF0uZGltc1sxXTtcbiAgY29uc3QgZmlsdGVySW5DaGFubmVsID0gaW5wdXRzWzFdLmRpbXNbMF07XG4gIGlmIChkYXRhQ2hhbm5lbCAhPT0gZmlsdGVySW5DaGFubmVsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMJyk7XG4gIH1cblxuICBjb25zdCBmZWF0dXJlTWFwcyA9IGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cDtcblxuICAvLyBpZiBiaWFzIGlzIHByb3ZpZGVkIGl0IHNob3VsZCBiZSAxRCBhbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBzaG91bGQgYmUgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBmZWF0dXJlIG1hcHNcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgKGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMSB8fCBpbnB1dHNbMl0uZGltc1swXSAhPT0gZmVhdHVyZU1hcHMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJpYXMnKTtcbiAgfVxuXG4gIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMjtcbiAgLy8gd3JvbmcgZGlsYXRpb25zIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5kaWxhdGlvbnMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgZGlsYXRpb25zIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHN0cmlkZXMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgc3RyaWRlcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBwYWRzIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmsgKiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBwYWRzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rICogMn1EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBvdXRwdXQgcGFkZGluZyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMub3V0cHV0UGFkZGluZy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXRfcGFkZGluZyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBzcGVjaWZpZWQsIGl0J3MgZGF0YSBsZW5ndGggbXVzdCBiZSAyIGxlc3MgdGhhbiBkaW1zIGxlbmd0aCBvZiB0aGUgd2VpZ2h0cyB0ZW5zb3JcbiAgLy8gKHRoZSBmaXJzdCAyIGRpbXMgYXJlIGJhdGNoX3NpemUgYW5kIGNoYW5uZWxzKVxuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggIT09IDAgJiYgYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggIT09IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAtIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQga2VybmVsIHNoYXBlJyk7XG4gIH1cblxuICAvLyBhcyB3aXRoIGtlcm5lbFNoYXBlLCBtdXN0IGhhdmUgc2FtZSBudW1iZXIgb2Ygc3BhdGlhbCBkaW1zIGFzIGlucHV0XG4gIGlmIChhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBvdXRwdXQgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBmbG9hdDY0XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInIHx8IGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnZUcmFuc3Bvc2UgaW5wdXQoWCxXKSBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0udHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252VHJhbnNwb3NlIGlucHV0KGJpYXMpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc3Bvc2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgcGVybTogbnVtYmVyW107XG59XG5cbmNvbnN0IHRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1RyYW5zcG9zZScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHRyYW5zcG9zZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi50cmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcy5wZXJtKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVHJhbnNwb3NlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFRyYW5zcG9zZUF0dHJpYnV0ZXMgPT4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgcGVybTogbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3Blcm0nLCBbXSkgfSk7XG5cbmNvbnN0IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvID0gKFxuICBfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBwZXJtOiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0LmRpbXM7XG4gIHBlcm0gPSBnZXRBZGp1c3RlZFBlcm0oaW5wdXRTaGFwZSwgcGVybSk7XG4gIGNvbnN0IHVucGFja2VkT3V0cHV0U2hhcGUgPSBnZXRPdXRwdXRTaGFwZShpbnB1dFNoYXBlLCBwZXJtKTtcbiAgY29uc3QgcmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICAvLyBBIGRpbXM9WyR7aW5wdXRzWzBdLmRpbXMudG9TdHJpbmcoKX1dXG4gIC8vIG91dCBEaW1zPVske3VucGFja2VkT3V0cHV0U2hhcGUudG9TdHJpbmcoKX1dXG4gIC8vIGJhc2VkIG9uIHBlcm09WyR7cGVybS50b1N0cmluZygpfV1cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtnZXRQZXJtRnVuY3Rpb25Cb2R5KCdwZXJtJywgcGVybSwgcmFuayl9XG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGludCBhWyR7cmFua31dO1xuICAgICAgICBwZXJtKGEsIGluZGljZXMpO1xuICAgICAgICByZXR1cm4gX0EoYSk7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi50cmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IHVucGFja2VkT3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGdldEFkanVzdGVkUGVybSA9IChpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcGVybTogbnVtYmVyW10pOiBudW1iZXJbXSA9PiB7XG4gIGlmIChwZXJtICYmIHBlcm0ubGVuZ3RoICE9PSBpbnB1dFNoYXBlLmxlbmd0aCkge1xuICAgIHBlcm0gPSBbLi4uaW5wdXRTaGFwZS5rZXlzKCldLnJldmVyc2UoKTtcbiAgfVxuICByZXR1cm4gcGVybTtcbn07XG5cbmNvbnN0IGdldE91dHB1dFNoYXBlID0gKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwZXJtOiBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdID0+IHtcbiAgcGVybSA9IGdldEFkanVzdGVkUGVybShpbnB1dFNoYXBlLCBwZXJtKTtcbiAgcmV0dXJuIFNoYXBlVXRpbC5zb3J0QmFzZWRPblBlcm0oaW5wdXRTaGFwZSwgcGVybSk7XG59O1xuXG5jb25zdCBnZXRQZXJtRnVuY3Rpb25Cb2R5ID0gKG5hbWU6IHN0cmluZywgcGVybTogbnVtYmVyW10sIHJhbms6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJldmVyc2VGdW5jID0gW107XG4gIHJldmVyc2VGdW5jLnB1c2goYHZvaWQgJHtuYW1lfShvdXQgaW50IGFbJHtyYW5rfV0sIGludCBzcmNbJHtyYW5rfV0pIHtgKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICByZXZlcnNlRnVuYy5wdXNoKGBcXHRhWyR7cGVybVtpXX1dPXNyY1ske2l9XTtgKTtcbiAgfVxuICByZXZlcnNlRnVuYy5wdXNoKCdcXHR9Jyk7XG4gIHJldHVybiByZXZlcnNlRnVuYy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVHJhbnNwb3NlIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5pbXBvcnQgeyB0cmFuc3Bvc2UsIFRyYW5zcG9zZUF0dHJpYnV0ZXMgfSBmcm9tICcuL3RyYW5zcG9zZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwdGhUb1NwYWNlQXR0cmlidXRlcyB7XG4gIG1vZGU6ICdEQ1InIHwgJ0NSRCc7XG4gIGJsb2Nrc2l6ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgZGVwdGhUb1NwYWNlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPERlcHRoVG9TcGFjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IERlcHRoVG9TcGFjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IGJsb2Nrc2l6ZSA9IGF0dHJpYnV0ZXMuYmxvY2tzaXplO1xuICBjb25zdCBibG9ja3NpemVTcXIgPSBibG9ja3NpemUgKiBibG9ja3NpemU7XG4gIGNvbnN0IHRyYW5zcG9zZVBlcm0gPSBhdHRyaWJ1dGVzLm1vZGUgPT09ICdEQ1InID8gWzAsIDMsIDQsIDEsIDUsIDJdIDogWzAsIDEsIDQsIDIsIDUsIDNdO1xuICBjb25zdCBmaXJzdFJlc2hhcGVTaGFwZSA9XG4gICAgYXR0cmlidXRlcy5tb2RlID09PSAnRENSJ1xuICAgICAgPyBbXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMF0sXG4gICAgICAgICAgYmxvY2tzaXplLFxuICAgICAgICAgIGJsb2Nrc2l6ZSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1sxXSAvIGJsb2Nrc2l6ZVNxcixcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1syXSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1szXSxcbiAgICAgICAgXVxuICAgICAgOiBbXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMF0sXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMV0gLyBibG9ja3NpemVTcXIsXG4gICAgICAgICAgYmxvY2tzaXplLFxuICAgICAgICAgIGJsb2Nrc2l6ZSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1syXSxcbiAgICAgICAgICBpbnB1dHNbMF0uZGltc1szXSxcbiAgICAgICAgXTtcblxuICAvLyBjb25zdCB0cmFuc3Bvc2UgPSBuZXcgV2ViR0xUcmFuc3Bvc2UoKTtcbiAgLy8gY29uc3QgYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGUodW5kZWZpbmVkKTtcbiAgLy8gYXR0cmlidXRlcy5zZXQoJ3Blcm0nLCAnaW50cycsIHRyYW5zcG9zZVBlcm0pO1xuICAvLyB0cmFuc3Bvc2UuaW5pdGlhbGl6ZShhdHRyaWJ1dGVzKTtcblxuICAvLyBGaXJzdCByZXNoYXBlXG4gIGNvbnN0IGZpcnN0UmVzaGFwZWRUZW5zb3IgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIGZpcnN0UmVzaGFwZVNoYXBlKTtcblxuICAvLyB0cmFuc3Bvc2VcbiAgY29uc3QgdHJhbnNwb3NlQXR0cmlidXRlczogVHJhbnNwb3NlQXR0cmlidXRlcyA9IHsgcGVybTogdHJhbnNwb3NlUGVybSwgY2FjaGVLZXk6IGAke3RyYW5zcG9zZVBlcm19YCB9O1xuICBjb25zdCBbdHJhbnNwb3NlT3V0cHV0XSA9IHRyYW5zcG9zZShpbmZlcmVuY2VIYW5kbGVyLCBbZmlyc3RSZXNoYXBlZFRlbnNvcl0sIHRyYW5zcG9zZUF0dHJpYnV0ZXMpO1xuXG4gIC8vIFNlY29uZCByZXNoYXBlXG4gIGNvbnN0IHNlY29uZFJlc2hhcGVTaGFwZSA9IFtcbiAgICBpbnB1dHNbMF0uZGltc1swXSxcbiAgICBpbnB1dHNbMF0uZGltc1sxXSAvIGJsb2Nrc2l6ZVNxcixcbiAgICBpbnB1dHNbMF0uZGltc1syXSAqIGJsb2Nrc2l6ZSxcbiAgICBpbnB1dHNbMF0uZGltc1szXSAqIGJsb2Nrc2l6ZSxcbiAgXTtcbiAgY29uc3QgcmVzdWx0ID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQodHJhbnNwb3NlT3V0cHV0LCBzZWNvbmRSZXNoYXBlU2hhcGUpO1xuICByZXR1cm4gW3Jlc3VsdF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPERlcHRoVG9TcGFjZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogRGVwdGhUb1NwYWNlQXR0cmlidXRlcyA9PiB7XG4gIC8vIHByb2Nlc3Npbmcgbm9kZSBhdHRyaWJ1dGVzXG4gIGNvbnN0IGJsb2Nrc2l6ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2Jsb2Nrc2l6ZScpO1xuICBpZiAoYmxvY2tzaXplIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgYmxvY2tzaXplIG11c3QgYmUgPj0gMSwgYnV0IGdvdCA6ICR7YmxvY2tzaXplfSBmb3IgRGVwdGhUb1NwYWNlYCk7XG4gIH1cbiAgY29uc3QgbW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnRENSJyk7XG4gIGlmIChtb2RlICE9PSAnRENSJyAmJiBtb2RlICE9PSAnQ1JEJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgdW5yZWNvZ25pemVkIG1vZGU6ICR7bW9kZX0gZm9yIERlcHRoVG9TcGFjZWApO1xuICB9XG4gIHJldHVybiB7IG1vZGUsIGJsb2Nrc2l6ZSB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRGVwdGhUb1NwYWNlIGV4cGVjdCAxIGlucHV0cywgYnV0IGdvdCAke2lucHV0cy5sZW5ndGh9YCk7XG4gIH1cblxuICAvLyBJbnB1dCBoYXMgdG8gYmUgYSA0LUQgdGVuc29yXG4gIC8vIFRPRE86IFN1cHBvcnQgc3RyaW5nIGRlcHRoLXRvLXNwYWNlLlxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnIHx8IGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0RlcHRoVG9TcGFjZSBpbnB1dCBzaG91bGQgYmUgYSA0LUQgbnVtZXJpYyB0ZW5zb3InKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IGZsYXR0ZW46IE9wZXJhdG9ySW1wbGVtZW50YXRpb248bnVtYmVyPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGlzOiBudW1iZXIsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXhpcyk7XG5cbiAgY29uc3Qgb3V0cHV0RGltcyA9IFNoYXBlVXRpbC5mbGF0dGVuU2hhcGUoaW5wdXRzWzBdLmRpbXMsIGF4aXMpO1xuICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgb3V0cHV0RGltcyldO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAxKTsgLy8gZGVmYXVsdCBheGlzIGlzIDFcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXR0ZW4gcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGNvbnN0IHIgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGlmIChyID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzY2FsYXIgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gIH1cblxuICBpZiAoYXhpcyA8IC1yIHx8IGF4aXMgPiByKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGF4aXMnKTtcbiAgfVxuXG4gIC8vIFRPRE86IFN1cHBvcnQgc3RyaW5nIHR5cGVcbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignc3RyaW5nIHRlbnNvciBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5cbmV4cG9ydCB0eXBlIE9wZXJhdG9ySW1wbGVtZW50YXRpb248VD4gPSAoaW5mZXJlbmNlSGFuZGxlcjogSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgY29udGV4dDogVCkgPT4gVGVuc29yW107XG5leHBvcnQgdHlwZSBPcGVyYXRvckluaXRpYWxpemF0aW9uPFQ+ID0gKG5vZGU6IEdyYXBoLk5vZGUsIGdyYXBoOiBHcmFwaCkgPT4gVDtcblxuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRvciB7XG4gIHJlYWRvbmx5IGltcGw6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248dW5rbm93bj47XG4gIHJlYWRvbmx5IGNvbnRleHQ6IEdyYXBoLk5vZGUgfCB1bmtub3duO1xufVxuXG5leHBvcnQgY29uc3QgTlVNQkVSX1RZUEVTOiByZWFkb25seSBUZW5zb3IuRGF0YVR5cGVbXSA9IFtcbiAgJ2Zsb2F0MzInLFxuICAnZmxvYXQ2NCcsXG4gICdpbnQzMicsXG4gICdpbnQxNicsXG4gICdpbnQ4JyxcbiAgJ3VpbnQxNicsXG4gICd1aW50MzInLFxuICAndWludDgnLFxuXTtcbmV4cG9ydCBjb25zdCBJTlRfVFlQRVM6IHJlYWRvbmx5IFRlbnNvci5EYXRhVHlwZVtdID0gWydpbnQzMicsICdpbnQxNicsICdpbnQ4JywgJ3VpbnQxNicsICd1aW50MzInLCAndWludDgnXTtcbmV4cG9ydCBjb25zdCBGTE9BVF9UWVBFUzogcmVhZG9ubHkgVGVuc29yLkRhdGFUeXBlW10gPSBbJ2Zsb2F0MzInLCAnZmxvYXQ2NCddO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE5VTUJFUl9UWVBFUywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmludGVyZmFjZSBHYXRoZXJBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgZ2F0aGVyOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEdhdGhlckF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEdhdGhlckF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcy5heGlzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2F0aGVyQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxHYXRoZXJBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogR2F0aGVyQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJywgMCkgfSk7XG5cbmNvbnN0IGdhdGhlclByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0dhdGhlcicsXG4gIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm8gPSAoXG4gIF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGluZGV4RGF0YVNoYXBlID0gaW5wdXRzWzFdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBuZXcgQXJyYXkoaW5wdXRTaGFwZS5sZW5ndGggKyBpbmRleERhdGFTaGFwZS5sZW5ndGggLSAxKTtcblxuICBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBpbmRleENvcHlPcHM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0U2hhcGUubGVuZ3RoOyBpKyspIHtcbiAgICAvLyBvdXRwdXRTaGFwZSBpcyBkaXZpZGVkIGludG8gdGhyZWUgcGFydHM6IEEsIEIsIENcbiAgICAvLyB8MCAgICAgICAgYXhpc3wgIGF4aXMgKyBpbmRleERhdGFTaGFwZS5sZW5ndGggfCAgICAgICAgICBlbmR8XG4gICAgLy8gfCAgICAgQSAgICAgICB8ICAgICAgICAgICAgIEIgICAgICAgICAgICAgICAgIHwgICAgICBDICAgICAgfFxuICAgIC8vXG4gICAgLy8gaW5wdXRJZHg6IFtBLCBpbnB1dHNbMV1bQl0sIENdXG4gICAgaWYgKGkgPCBheGlzKSB7XG4gICAgICAvLyBBXG4gICAgICBvdXRwdXRTaGFwZVtpXSA9IGlucHV0U2hhcGVbaV07XG4gICAgICBpbmRleENvcHlPcHMucHVzaChgaW5wdXRJZHhbJHtpfV0gPSBvdXRwdXRJZHhbJHtpfV07YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpIDwgYXhpcyArIGluZGV4RGF0YVNoYXBlLmxlbmd0aCkge1xuICAgICAgICAvLyBCXG4gICAgICAgIG91dHB1dFNoYXBlW2ldID0gaW5kZXhEYXRhU2hhcGVbaSAtIGF4aXNdO1xuICAgICAgICBpbmRleENvcHlPcHMucHVzaChgaW5kZXhEYXRhSWR4WyR7aSAtIGF4aXN9XSA9IG91dHB1dElkeFske2l9XTtgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIENcbiAgICAgICAgb3V0cHV0U2hhcGVbaV0gPSBpbnB1dFNoYXBlW2kgLSBpbmRleERhdGFTaGFwZS5sZW5ndGggKyAxXTsgLy8gc2tpcCAxIGZvciBheGlzXG4gICAgICAgIGluZGV4Q29weU9wcy5wdXNoKGBpbnB1dElkeFske2kgLSBpbmRleERhdGFTaGFwZS5sZW5ndGggKyAxfV0gPSBvdXRwdXRJZHhbJHtpfV07YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb3JhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGggfHwgMTtcbiAgY29uc3QgaXJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgaURyYW5rID0gaW5kZXhEYXRhU2hhcGUubGVuZ3RoIHx8IDE7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske29yYW5rfV0pIHtcbiAgICAgICAgaW50IGlucHV0SWR4WyR7aXJhbmt9XTtcbiAgICAgICAgaW50IGluZGV4RGF0YUlkeFske2lEcmFua31dO1xuICAgICAgICBpbmRleERhdGFJZHhbMF0gPSAwO1xuICAgICAgICAke2luZGV4Q29weU9wcy5qb2luKCdcXG4gICAgICAgICcpfVxuICAgICAgICBpbnQgaWR4ID0gaW50KF9CKGluZGV4RGF0YUlkeCkpO1xuICAgICAgICBpbnB1dElkeFske2F4aXN9XSA9IGlkeCA8IDAgPyBpZHggKyAke2lucHV0U2hhcGVbYXhpc119IDogaWR4O1xuICAgICAgICByZXR1cm4gX0EoaW5wdXRJZHgpO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogR2F0aGVyQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSB7IC4uLmdhdGhlclByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH07XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUdhdGhlclByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMuYXhpcykgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF4aXM6IG51bWJlcik6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHYXRoZXIgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cbiAgY29uc3QgdGVuc29yUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgaWYgKHRlbnNvclJhbmsgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChheGlzIDwgLXRlbnNvclJhbmsgfHwgYXhpcyA+IHRlbnNvclJhbmsgLSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGF4aXMuJyk7XG4gIH1cbiAgaWYgKE5VTUJFUl9UWVBFUy5pbmRleE9mKGlucHV0c1swXS50eXBlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJyAmJiBpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDE2Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgR2VtbVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBHZW1tQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHRyYW5zQTogYm9vbGVhbjtcbiAgdHJhbnNCOiBib29sZWFuO1xuICBhbHBoYTogbnVtYmVyO1xuICBiZXRhOiBudW1iZXI7XG4gIGlzT3B0aW9uYWxDOiBib29sZWFuOyAvLyBpbiBvcHNldCAxMSwgQyBiZWNvbWVzIG9wdGlvbmFsXG59XG5cbmV4cG9ydCBjb25zdCBnZW1tOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlR2VtbVByb2dyYW1JbmZvTG9hZGVyKGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IHBhcnNlR2VtbUF0dHJpYnV0ZXMgPSAobm9kZTogR3JhcGguTm9kZSwgaXNPcHRpb25hbEM6IGJvb2xlYW4pOiBHZW1tQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IHRyYW5zQSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3RyYW5zQScsIDApICE9PSAwO1xuICBjb25zdCB0cmFuc0IgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCd0cmFuc0InLCAwKSAhPT0gMDtcbiAgY29uc3QgYWxwaGEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2FscGhhJywgMS4wKTtcbiAgY29uc3QgYmV0YSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYmV0YScsIDEuMCk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyB0cmFuc0EsIHRyYW5zQiwgYWxwaGEsIGJldGEsIGlzT3B0aW9uYWxDIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2VtbUF0dHJpYnV0ZXNWNzogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxHZW1tQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IEdlbW1BdHRyaWJ1dGVzID0+XG4gIHBhcnNlR2VtbUF0dHJpYnV0ZXMobm9kZSwgZmFsc2UpO1xuXG5leHBvcnQgY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlc1YxMTogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxHZW1tQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IEdlbW1BdHRyaWJ1dGVzID0+XG4gIHBhcnNlR2VtbUF0dHJpYnV0ZXMobm9kZSwgdHJ1ZSk7XG5cbmNvbnN0IGNyZWF0ZUdlbW1Qcm9ncmFtSW5mb0xvYWRlciA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ0dlbW0nLFxuICAgIGlucHV0TmFtZXM6IGlucHV0cy5sZW5ndGggPT09IDMgPyBbJ0EnLCAnQicsICdDJ10gOiBbJ0EnLCAnQiddLFxuICAgIGlucHV0VHlwZXM6XG4gICAgICBpbnB1dHMubGVuZ3RoID09PSAzXG4gICAgICAgID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdXG4gICAgICAgIDogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAga2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICB9O1xuXG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUdlbW1Qcm9ncmFtSW5mbyhtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzKSB9O1xufTtcblxuY29uc3QgY3JlYXRlR2VtbVByb2dyYW1JbmZvID0gKFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgYVNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgW00sIE5dID0gR2VtbVV0aWwuZ2V0U2hhcGVPZkdlbW1SZXN1bHQoXG4gICAgYVNoYXBlLFxuICAgIGF0dHJpYnV0ZXMudHJhbnNBLFxuICAgIGJTaGFwZSxcbiAgICBhdHRyaWJ1dGVzLnRyYW5zQixcbiAgICBpbnB1dHMubGVuZ3RoID09PSAzID8gaW5wdXRzWzJdLmRpbXMgOiB1bmRlZmluZWQsXG4gICk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW00sIE5dO1xuICBpZiAoIW91dHB1dFNoYXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgdXNlIGdlbW0gb24gdGhlIGdpdmVuIHRlbnNvcnNcIik7XG4gIH1cbiAgbGV0IHNoYXJlZERpbSA9IGFTaGFwZVthU2hhcGUubGVuZ3RoIC0gMV07XG4gIGxldCBsaW5lID0gJyc7XG4gIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSkge1xuICAgIHNoYXJlZERpbSA9IGFTaGFwZVswXTtcbiAgfVxuICBpZiAoYXR0cmlidXRlcy50cmFuc0EgJiYgYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICBsaW5lID0gJ3ZhbHVlICs9IF9BX1QoYSkgKiBfQl9UKGIpOyc7XG4gIH0gZWxzZSBpZiAoYXR0cmlidXRlcy50cmFuc0EgJiYgIWF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgbGluZSA9ICd2YWx1ZSArPSBfQV9UKGEpICogX0IoYik7JztcbiAgfSBlbHNlIGlmICghYXR0cmlidXRlcy50cmFuc0EgJiYgYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICBsaW5lID0gJ3ZhbHVlICs9IF9BKGEpICogX0JfVChiKTsnO1xuICB9IGVsc2UgaWYgKCFhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICBsaW5lID0gJ3ZhbHVlICs9IF9BKGEpICogX0IoYik7JztcbiAgfVxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBkZWNsYXJlQyA9IGlucHV0cy5sZW5ndGggPT09IDMgPyBgaW50IGNbJHtpbnB1dHNbMl0uZGltcy5sZW5ndGh9XTtgIDogJyc7XG4gIGNvbnN0IGJyb2FkY2FzdEMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gJ2JjYXN0SW5kaWNlc19DKGluZGljZXMsIGMpOycgOiAnJztcbiAgY29uc3QgY2FsY3VsYXRlQyA9IGlucHV0cy5sZW5ndGggPT09IDMgPyAndmFsdWUgKz0gYmV0YSAqIF9DKGMpOycgOiAnJztcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBhWyR7cmFua31dO1xuICAgICAgICAgIGludCBiWyR7cmFua31dO1xuICAgICAgICAgICR7ZGVjbGFyZUN9XG5cbiAgICAgICAgICBjb3B5VmVjKGluZGljZXMsIGEpO1xuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgYik7XG4gICAgICAgICAgJHticm9hZGNhc3RDfVxuXG4gICAgICAgICAgZmxvYXQgdmFsdWUgPSAwLjA7XG4gICAgICAgICAgZm9yIChpbnQgaz0wOyBrPCR7c2hhcmVkRGltfTsgKytrKSB7XG4gICAgICAgICAgICAgIGFbJHtyYW5rIC0gMX1dID0gaztcbiAgICAgICAgICAgICAgYlske3JhbmsgLSAyfV0gPSBrO1xuICAgICAgICAgICAgICAke2xpbmV9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZSAqIGFscGhhO1xuICAgICAgICAgICR7Y2FsY3VsYXRlQ31cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICB2YXJpYWJsZXM6IFtcbiAgICAgIHsgbmFtZTogJ2FscGhhJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogYXR0cmlidXRlcy5hbHBoYSB9LFxuICAgICAgeyBuYW1lOiAnYmV0YScsIHR5cGU6ICdmbG9hdCcsIGRhdGE6IGF0dHJpYnV0ZXMuYmV0YSB9LFxuICAgIF0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGlzIG1pc3NpbmcnKTtcbiAgfVxuICBpZiAoYXR0cmlidXRlcy5pc09wdGlvbmFsQyAmJiAoaW5wdXRzLmxlbmd0aCA8IDIgfHwgaW5wdXRzLmxlbmd0aCA+IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKCFhdHRyaWJ1dGVzLmlzT3B0aW9uYWxDICYmIGlucHV0cy5sZW5ndGggIT09IDMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dlbW0gcmVxdWlyZXMgMyBpbnB1dHMnKTtcbiAgfVxuXG4gIC8vICdDJyBjYW4gYmUgb2YgZGltZW5zaW9uYWxpdHkgMSBvciAyIG9ubHlcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxICYmIGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZSBvZiBDJyk7XG4gIH1cblxuICBpZiAoXG4gICAgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzJdLnR5cGUgIT09ICdmbG9hdDY0JylcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1sxXS50eXBlIHx8IChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1swXS50eXBlICE9PSBpbnB1dHNbMl0udHlwZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHR5cGVzIGFyZSBtaXNtYXRjaGVkJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEltYWdlU2NhbGVyQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHNjYWxlOiBudW1iZXI7XG4gIGJpYXM6IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgaW1hZ2VTY2FsZXI6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248SW1hZ2VTY2FsZXJBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZUltYWdlU2NhbGVyUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEltYWdlU2NhbGVyQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBzY2FsZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnc2NhbGUnKTtcbiAgY29uc3QgYmlhcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdHMoJ2JpYXMnKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHNjYWxlLCBiaWFzIH0pO1xufTtcblxuY29uc3QgaW1hZ2VTY2FsZXJQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdJbWFnZVNjYWxlcicsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlSW1hZ2VTY2FsZXJQcm9ncmFtSW5mbyA9IChcbiAgX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGdldEJpYXNNZXRob2QgPSBjcmVhdGVHZXRCaWFzTWV0aG9kKGF0dHJpYnV0ZXMuYmlhcy5sZW5ndGgpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke2dldEJpYXNNZXRob2R9XG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIHJldHVybiBfWChpbmRpY2VzKSAqIHNjYWxlICsgZ2V0QmlhcyhiaWFzLCBpbmRpY2VzWzFdKTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHZhcmlhYmxlczogW1xuICAgICAgeyBuYW1lOiAnYmlhcycsIHR5cGU6ICdmbG9hdCcsIGFycmF5TGVuZ3RoOiBhdHRyaWJ1dGVzLmJpYXMubGVuZ3RoLCBkYXRhOiBhdHRyaWJ1dGVzLmJpYXMgfSxcbiAgICAgIHsgbmFtZTogJ3NjYWxlJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogYXR0cmlidXRlcy5zY2FsZSB9LFxuICAgIF0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlSW1hZ2VTY2FsZXJQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0geyAuLi5pbWFnZVNjYWxlclByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH07XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUltYWdlU2NhbGVyUHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcykgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUdldEJpYXNNZXRob2QgPSAobnVtQ2hhbm5lbHM6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNvZGVMaW5lczogc3RyaW5nW10gPSBbYGZsb2F0IGdldEJpYXMoZmxvYXQgYmlhc1ske251bUNoYW5uZWxzfV0sIGludCBjaGFubmVsKSB7YF07XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ2hhbm5lbHM7ICsraSkge1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBpZiAoY2hhbm5lbCA9PSAke2l9KSB7IHJldHVybiBiaWFzWyR7aX1dOyB9YCk7XG4gICAgfSBlbHNlIGlmIChpID09PSBudW1DaGFubmVscyAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgeyByZXR1cm4gYmlhc1ske2l9XTsgfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIGlmIChjaGFubmVsID09ICR7aX0pIHsgcmV0dXJuIGJpYXNbJHtpfV07IH1gKTtcbiAgICB9XG4gIH1cbiAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyAnfScpO1xuICByZXR1cm4gY29kZUxpbmVzLmpvaW4oJ1xcbicpO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbWFnZVNjYWxlciByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBpbnN0YW5jZU5vcm1hbGl6YXRpb246IE9wZXJhdG9ySW1wbGVtZW50YXRpb248bnVtYmVyPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBlcHNpbG9uOiBudW1iZXIsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgbWVhbkFuZFZhcmlhbmNlID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzWzBdKSwgaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlQ29tcHV0ZU91dHB1dFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgZXBzaWxvbiwgbWVhbkFuZFZhcmlhbmNlLmRpbXMpLFxuICAgIFtpbnB1dHNbMF0sIG1lYW5BbmRWYXJpYW5jZSwgaW5wdXRzWzFdLCBpbnB1dHNbMl1dLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VJbnN0YW5jZU5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPG51bWJlcj4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlciA9PlxuICBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2Vwc2lsb24nLCAxZS01KTtcblxuY29uc3QgbWVhbkFuZFZhcmlhbmNlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnSW5zdGFuY2VOb3JtYWxpemF0aW9uX01lYW5BbmRWYXJpYW5jZScsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm8gPSAobWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeERpbXMgPSBpbnB1dC5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGNoYW5uZWwgPSB4RGltc1sxXTtcbiAgY29uc3QgY2hhbm5lbFNpemUgPSB4RGltc1syXSAqIHhEaW1zWzNdO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFt4RGltc1swXSwgY2hhbm5lbF07XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgdmVjNCBwcm9jZXNzKGludFsyXSBpbmRpY2VzKSB7XG4gICAgICAgIHZlYzQgdiA9IHZlYzQoMC4wKTtcbiAgICAgICAgaW50IGFbNF07XG4gICAgICAgIGFbMF0gPSBpbmRpY2VzWzBdO1xuICAgICAgICBhWzFdID0gaW5kaWNlc1sxXTtcbiAgICAgICAgZmxvYXQgdGVtcCA9IDAuMDtcbiAgICAgICAgZm9yKGludCBhMj0wOyBhMjwke3hEaW1zWzJdfTsgYTIrKykge1xuICAgICAgICAgIGFbMl0gPSBhMjtcbiAgICAgICAgICBmb3IoaW50IGEzPTA7IGEzPCR7eERpbXNbM119OyBhMysrKSB7XG4gICAgICAgICAgICBhWzNdID0gYTM7XG4gICAgICAgICAgICBmbG9hdCB4ID0gX1goYSk7XG4gICAgICAgICAgICB0ZW1wICs9IHg7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZsb2F0IG1lYW4gPSB0ZW1wIC8gZmxvYXQoJHtjaGFubmVsU2l6ZX0pO1xuICAgICAgICB0ZW1wID0gMC4wO1xuICAgICAgICBmb3IoaW50IGEyPTA7IGEyPCR7eERpbXNbMl19OyBhMisrKSB7XG4gICAgICAgICAgYVsyXSA9IGEyO1xuICAgICAgICAgIGZvcihpbnQgYTM9MDsgYTM8JHt4RGltc1szXX07IGEzKyspIHtcbiAgICAgICAgICAgIGFbM10gPSBhMztcbiAgICAgICAgICAgIGZsb2F0IHggPSBfWChhKTtcbiAgICAgICAgICAgIHRlbXAgKz0gKHggLSBtZWFuKSAqICh4IC0gbWVhbik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHYuciA9IG1lYW47XG4gICAgICAgIHYuZyA9IHRlbXAgLyBmbG9hdCgke2NoYW5uZWxTaXplfSk7XG5cbiAgICAgICAgcmV0dXJuIHY7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvTG9hZGVyID0+ICh7XG4gIC4uLm1lYW5BbmRWYXJpYW5jZVByb2dyYW1NZXRhZGF0YSxcbiAgZ2V0OiAoKSA9PiBjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mbyhtZWFuQW5kVmFyaWFuY2VQcm9ncmFtTWV0YWRhdGEsIGlucHV0KSxcbn0pO1xuXG5jb25zdCBjb21wdXRlT3V0cHV0UHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnSW5zdGFuY2VOb3JtYWxpemF0aW9uX0NvbXB1dGVPdXRwdXQnLFxuICBpbnB1dE5hbWVzOiBbJ1gnLCAnTWVhbkFuZFZhcmlhbmNlJywgJ1NjYWxlJywgJ0InXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlQ29tcHV0ZU91dHB1dFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGVwc2lsb246IG51bWJlcixcbiAgbWVhbkFuZFZhcmlhbmNlU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IFt0ZXh0dXJlV2lkdGgsIHRleHR1cmVIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgbWVhbkFuZFZhcmlhbmNlU2hhcGUsXG4gICAgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbixcbiAgKTtcbiAgY29uc3QgW21lYW5BbmRWYXJpYW5jZVdpZHRoLCBtZWFuQW5kVmFyaWFuY2VIZWlnaHRdID0gW3RleHR1cmVXaWR0aCAvIDQsIHRleHR1cmVIZWlnaHRdO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICB2ZWM0IGdldF9NZWFuQW5kVmFyaWFuY2UoaW50WzJdIG12KSB7XG4gICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXRfTWVhbkFuZFZhcmlhbmNlKG12KTtcbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7bWVhbkFuZFZhcmlhbmNlV2lkdGh9LCAke21lYW5BbmRWYXJpYW5jZUhlaWdodH0pO1xuICAgICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oTWVhbkFuZFZhcmlhbmNlLCBjb29yZHMpO1xuICAgICAgfVxuXG4gICAgICBmbG9hdCBwcm9jZXNzKGludFs0XSBpbmRpY2VzKSB7XG4gICAgICAgIGludCBtdlsyXTtcbiAgICAgICAgbXZbMF0gPSBpbmRpY2VzWzBdO1xuICAgICAgICBtdlsxXSA9IGluZGljZXNbMV07XG4gICAgICAgIHZlYzQgbWVhbl9hbmRfdmFyaWFuY2UgPSBnZXRfTWVhbkFuZFZhcmlhbmNlKG12KTtcbiAgICAgICAgZmxvYXQgbWVhbiA9IG1lYW5fYW5kX3ZhcmlhbmNlLnI7XG4gICAgICAgIGZsb2F0IHZhcmlhbmNlID0gbWVhbl9hbmRfdmFyaWFuY2UuZztcblxuICAgICAgICBpbnQgc2JbMV07XG4gICAgICAgIHNiWzBdID0gaW5kaWNlc1sxXTtcbiAgICAgICAgZmxvYXQgc2NhbGUgPSBfU2NhbGUoc2IpO1xuICAgICAgICBmbG9hdCBiID0gX0Ioc2IpO1xuXG4gICAgICAgIHJldHVybiBzY2FsZSAqIChfWChpbmRpY2VzKSAtIG1lYW4pIC8gc3FydCh2YXJpYW5jZSArIGVwc2lsb24pICsgYjtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICB2YXJpYWJsZXM6IFt7IG5hbWU6ICdlcHNpbG9uJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogZXBzaWxvbiB9XSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgZXBzaWxvbjogbnVtYmVyLFxuICBtZWFuQW5kVmFyaWFuY2VTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0geyAuLi5jb21wdXRlT3V0cHV0UHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGAke2Vwc2lsb259YCB9O1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlQ29tcHV0ZU91dHB1dFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dCwgZXBzaWxvbiwgbWVhbkFuZFZhcmlhbmNlU2hhcGUpLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnN0YW5jZU5vcm1hbGl6YXRpb24gcmVxdWlyZXMgMyBpbnB1dHMuJyk7XG4gIH1cblxuICBjb25zdCBYID0gaW5wdXRzWzBdO1xuICBjb25zdCBzY2FsZSA9IGlucHV0c1sxXTtcbiAgY29uc3QgQiA9IGlucHV0c1syXTtcblxuICAvLyBpbnB1dCBzaG91bGQgYXQgbGVhc3QgaGF2ZSB0aHJlZSBkaW1lbnNpb25zIC0gTixDLGRpbTEsLi4uLGRpbW5cbiAgLy8gb3RoZXIgaW5wdXRzIGNhbiBoYXZlIG9ubHkgb25lIGRpbWVuc2lvbnNcbiAgaWYgKFguZGltcy5sZW5ndGggPCAzIHx8IHNjYWxlLmRpbXMubGVuZ3RoICE9PSAxIHx8IEIuZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKHNjYWxlLmRpbXNbMF0gIT09IFguZGltc1sxXSB8fCBCLmRpbXNbMF0gIT09IFguZGltc1sxXSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgc2hhcGVzIGFyZSBtaXNtYXRjaGVkLicpO1xuICB9XG4gIGlmIChcbiAgICAoWC50eXBlICE9PSAnZmxvYXQzMicgJiYgWC50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKHNjYWxlLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBzY2FsZS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKEIudHlwZSAhPT0gJ2Zsb2F0MzInICYmIEIudHlwZSAhPT0gJ2Zsb2F0NjQnKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IHN1cHBvcnQgNC1EIGlucHV0IHNoYXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTHJuQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGFscGhhOiBudW1iZXI7XG4gIGJldGE6IG51bWJlcjtcbiAgYmlhczogbnVtYmVyO1xuICBzaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBscm46IE9wZXJhdG9ySW1wbGVtZW50YXRpb248THJuQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogTHJuQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICAvLyBpZiAoaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLnBhY2spIHtcbiAgLy8gICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZVBhY2tlZExyblByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gIC8vICAgaW5wdXRzKV07XG4gIC8vIH0gZWxzZSB7XG4gIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTHJuUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKV07XG4gIC8vfVxufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTHJuQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxMcm5BdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogTHJuQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGFscGhhID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdhbHBoYScsIDAuMDAwMSk7XG4gIGNvbnN0IGJldGEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2JldGEnLCAwLjc1KTtcbiAgY29uc3QgYmlhcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYmlhcycsIDEuMCk7XG4gIGNvbnN0IHNpemUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdzaXplJyk7XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGFscGhhLCBiZXRhLCBiaWFzLCBzaXplIH0pO1xufTtcblxuY29uc3QgbHJuUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnTFJOJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5mdW5jdGlvbiBjcmVhdGVMcm5Qcm9ncmFtSW5mbyhpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBMcm5BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8ge1xuICBjb25zdCBDID0gaW5wdXRzWzBdLmRpbXNbMV07XG4gIGNvbnN0IHJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGNvbnN0IGZyb20gPSAtTWF0aC5mbG9vcigoYXR0cmlidXRlcy5zaXplIC0gMSkgLyAyKTtcbiAgY29uc3QgdG8gPSBNYXRoLmNlaWwoKGF0dHJpYnV0ZXMuc2l6ZSAtIDEpIC8gMik7XG4gIGNvbnN0IGFscGhhID0gYGZsb2F0KCR7YXR0cmlidXRlcy5hbHBoYX0pIC8gZmxvYXQoJHthdHRyaWJ1dGVzLnNpemV9KWA7XG4gIGNvbnN0IGJpYXMgPSBgZmxvYXQoJHthdHRyaWJ1dGVzLmJpYXN9KWA7XG4gIGNvbnN0IGJldGEgPSBgZmxvYXQoJHthdHRyaWJ1dGVzLmJldGF9KWA7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGMgPSBpbmRpY2VzWzFdO1xuICAgICAgICBmbG9hdCB4ID0gX1goaW5kaWNlcyk7XG4gICAgICAgIGZsb2F0IHNxdWFyZV9zdW0gPSAwLjA7XG5cbiAgICAgICAgZm9yIChpbnQgaSA9ICR7ZnJvbX07IGkgPD0gJHt0b307IGkrKykge1xuICAgICAgICAgIGludCBpZHggPSBjICsgaTtcbiAgICAgICAgICBpZiAoYyA+PSAwICYmIGMgPCAke0N9KSB7XG4gICAgICAgICAgICBpbmRpY2VzWzFdID0gaWR4O1xuICAgICAgICAgICAgZmxvYXQgaiA9IF9YKGluZGljZXMpO1xuICAgICAgICAgICAgc3F1YXJlX3N1bSArPSBqICogajtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggLyBwb3coJHtiaWFzfSArICR7YWxwaGF9ICogc3F1YXJlX3N1bSwgJHtiZXRhfSk7XG4gICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubHJuUHJvZ3JhbU1ldGFkYXRhLFxuICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXRzWzBdLmRpbXMsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVMcm5Qcm9ncmFtSW5mb0xvYWRlcihpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBMcm5BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIge1xuICByZXR1cm4geyAuLi5scm5Qcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBjcmVhdGVMcm5Qcm9ncmFtSW5mbyhpbnB1dHMsIGF0dHJpYnV0ZXMpIH07XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTFJOIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG9ubHkgc3VwcG9ydCBMUk4gZm9yIGlucHV0IHdpdGggXCJOQ0hXXCIgZm9ybWF0Jyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHNob3VsZCBiZSBmbG9hdCB0eXBlJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBnZXRHbHNsLCBHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhZEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBtb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBhZHM6IG51bWJlcltdO1xuICByZWFkb25seSB2YWx1ZTogbnVtYmVyO1xufVxuXG5jb25zdCBwYWRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdQYWQnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBwYWRWMjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxQYWRBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBQYWRBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0c1YyKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnBhZFByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlUGFkUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUGFkQXR0cmlidXRlc1YyOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFBhZEF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBQYWRBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgbW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnY29uc3RhbnQnKTtcbiAgY29uc3QgdmFsdWUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ3ZhbHVlJywgMC4wKTtcbiAgY29uc3QgcGFkcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJyk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBtb2RlLCB2YWx1ZSwgcGFkcyB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYWRWMTE6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248c3RyaW5nPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBtb2RlOiBzdHJpbmcsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjExKGlucHV0cyk7XG4gIGNvbnN0IGF0dHJ1YnV0ZXMgPSBnZW5lcmF0ZVBhZEF0dHJpYnV0ZXNGcm9tSW5wdXRzKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgbW9kZSk7XG4gIHJldHVybiBwYWRWMihpbmZlcmVuY2VIYW5kbGVyLCBbaW5wdXRzWzBdXSwgYXR0cnVidXRlcyk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VQYWRBdHRyaWJ1dGVzVjExOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPHN0cmluZz4gPSAobm9kZTogR3JhcGguTm9kZSk6IHN0cmluZyA9PlxuICBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdtb2RlJywgJ2NvbnN0YW50Jyk7XG5cbmNvbnN0IGdlbmVyYXRlUGFkQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgbW9kZTogc3RyaW5nLFxuKTogUGFkQXR0cmlidXRlcyA9PiB7XG4gIGlmIChcbiAgICAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzFdLmRhdGFJZCkgfHxcbiAgICAoaW5wdXRzLmxlbmd0aCA+PSAzICYmICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMl0uZGF0YUlkKSlcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkeW5hbWljIHBhZCBhdHRyaWJ1dGVzIGFyZSBub3QgYWxsb3dlZCcpO1xuICB9XG5cbiAgY29uc3QgcGFkcyA9IEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKTtcbiAgY29uc3QgdmFsdWUgPSBpbnB1dHMubGVuZ3RoID49IDMgPyBpbnB1dHNbMl0uZmxvYXREYXRhWzBdIDogMC4wO1xuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBtb2RlLCBwYWRzLCB2YWx1ZSB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZVBhZFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGF0dHJpYnV0ZXM6IFBhZEF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gU2hhcGVVdGlsLnBhZFNoYXBlKGlucHV0LmRpbXMuc2xpY2UoKSwgYXR0cmlidXRlcy5wYWRzKTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgcGFkRnVuY3Rpb24gPSBnZXRQYWRGdW5jdGlvbihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dCwgYXR0cmlidXRlcyk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7cGFkRnVuY3Rpb259XG4gICAgICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgICAgICAgcmV0dXJuIHBhZEEoaW5kaWNlcyk7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnUGFkJyxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMiA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhZCByZXF1aXJlcyAxIGlucHV0Jyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YxMSA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IChpbnB1dHMubGVuZ3RoICE9PSAyICYmIGlucHV0cy5sZW5ndGggIT09IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQYWQgcmVxdWlyZXMgMiBvciAzIGlucHV0cycpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID49IDMgJiYgaW5wdXRzWzJdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdldFBhZEZ1bmN0aW9uID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvciwgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgW3dpZHRoLCBoZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoaW5wdXQuZGltcywgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGlucHV0LmRpbXMpO1xuXG4gIHN3aXRjaCAoYXR0cmlidXRlcy5tb2RlKSB7XG4gICAgY2FzZSAnY29uc3RhbnQnOlxuICAgICAgcmV0dXJuIGdldFBhZENvbnN0YW50KGdsc2wsIGlucHV0LmRpbXMsIHN0cmlkZXMsIHdpZHRoLCBoZWlnaHQsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy52YWx1ZSk7XG4gICAgY2FzZSAncmVmbGVjdCc6XG4gICAgICByZXR1cm4gZ2V0UGFkUmVmbGVjdChnbHNsLCBpbnB1dC5kaW1zLCBzdHJpZGVzLCB3aWR0aCwgaGVpZ2h0LCBhdHRyaWJ1dGVzLnBhZHMpO1xuICAgIGNhc2UgJ2VkZ2UnOlxuICAgICAgcmV0dXJuIGdldFBhZEVkZ2UoZ2xzbCwgaW5wdXQuZGltcywgc3RyaWRlcywgd2lkdGgsIGhlaWdodCwgYXR0cmlidXRlcy5wYWRzKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1vZGUnKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0UGFkQ29uc3RhbnQgPSAoXG4gIGdsc2w6IEdsc2wsXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHdpZHRoOiBudW1iZXIsXG4gIGhlaWdodDogbnVtYmVyLFxuICBwYWRzOiBudW1iZXJbXSxcbiAgdmFsdWU6IG51bWJlcixcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gcmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBrID0gbVske2l9XSAtICR7cGFkc1tpXX07XG4gICAgICAgIGlmIChrIDwgMCkgIHJldHVybiBjb25zdGFudDtcbiAgICAgICAgaWYgKGsgPj0gJHtzaGFwZVtpXX0pIHJldHVybiBjb25zdGFudDtcbiAgICAgICAgb2Zmc2V0ICs9IGsgKiAke3N0cmlkZXNbaV19O1xuICAgICAgICBgO1xuICB9XG4gIHJldHVybiBgXG4gICAgICBmbG9hdCBwYWRBKGludCBtWyR7cmFua31dKSB7XG4gICAgICAgIGNvbnN0IGZsb2F0IGNvbnN0YW50ID0gZmxvYXQoJHt2YWx1ZX0pO1xuICAgICAgICBpbnQgb2Zmc2V0ID0gMDtcbiAgICAgICAgaW50IGsgPSAwO1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIGNvb3JkcykpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBgO1xufTtcblxuY29uc3QgZ2V0UGFkUmVmbGVjdCA9IChcbiAgZ2xzbDogR2xzbCxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgd2lkdGg6IG51bWJlcixcbiAgaGVpZ2h0OiBudW1iZXIsXG4gIHBhZHM6IG51bWJlcltdLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICBsZXQgYmxvY2sgPSAnJztcbiAgZm9yIChsZXQgaSA9IHJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgIGJsb2NrICs9IGBcbiAgICAgICAgayA9IG1bJHtpfV0gLSAke3BhZHNbaV19O1xuICAgICAgICBpZiAoayA8IDApIHsgayA9IC1rOyB9XG4gICAgICAgIHtcbiAgICAgICAgICBjb25zdCBpbnQgXzJuXzEgPSAkezIgKiAoc2hhcGVbaV0gLSAxKX07XG4gICAgICAgICAgayA9IGludCggbW9kKCBmbG9hdChrKSwgZmxvYXQoXzJuXzEpICkgKSA7XG4gICAgICAgICAgaWYoayA+PSAke3NoYXBlW2ldfSkgeyBrID0gXzJuXzEgLSBrOyB9XG4gICAgICAgIH1cbiAgICAgICAgb2Zmc2V0ICs9IGsgKiAke3N0cmlkZXNbaV19O1xuICAgICAgICBgO1xuICB9XG4gIHJldHVybiBgXG4gICAgICBmbG9hdCBwYWRBKGludCBtWyR7cmFua31dKSB7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICBpbnQgayA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG59O1xuXG5jb25zdCBnZXRQYWRFZGdlID0gKFxuICBnbHNsOiBHbHNsLFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICB3aWR0aDogbnVtYmVyLFxuICBoZWlnaHQ6IG51bWJlcixcbiAgcGFkczogbnVtYmVyW10sXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gcmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBrID0gbVske2l9XSAtICR7cGFkc1tpXX07XG4gICAgICAgIGlmIChrIDwgMCkgIGsgPSAwO1xuICAgICAgICBpZiAoayA+PSAke3NoYXBlW2ldfSkgayA9ICR7c2hhcGVbaV0gLSAxfTtcbiAgICAgICAgb2Zmc2V0ICs9IGsgKiAke3N0cmlkZXNbaV19O1xuICAgICAgYDtcbiAgfVxuICByZXR1cm4gYFxuICAgICAgZmxvYXQgcGFkQShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gMDtcbiAgICAgICAgaW50IGsgPSAwO1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIGNvb3JkcykpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBgO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBQb29sQ29udlV0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXV0b1BhZDogc3RyaW5nO1xuICByZWFkb25seSBjZWlsTW9kZTogbnVtYmVyO1xuICByZWFkb25seSBjb3VudEluY2x1ZGVQYWQ6IGJvb2xlYW47XG4gIHJlYWRvbmx5IGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHBhZHM6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgYXZlcmFnZVBvb2w6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248QXZlcmFnZVBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdBdmVyYWdlUG9vbCcsXG4gICAgaW5wdXROYW1lczogWydYJ10sXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gIH07XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlQXZlcmFnZVBvb2xQcm9ncmFtSW5mbyhpbnB1dHMsIG1ldGFkYXRhLCBmYWxzZSwgYXR0cmlidXRlcykgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUF2ZXJhZ2VQb29sQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXV0b1BhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICBjb25zdCBjZWlsTW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NlaWxfbW9kZScsIDApO1xuICBjb25zdCBjb3VudEluY2x1ZGVQYWQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdjb3VudF9pbmNsdWRlX3BhZCcsIDApID09PSAwID8gZmFsc2UgOiB0cnVlO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdrZXJuZWxfc2hhcGUnKTtcbiAgY29uc3Qgc3RyaWRlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgW10pO1xuICBjb25zdCBwYWRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbXSk7XG5cbiAgLy8gVE9ETzogc3VwcG9ydCBhdHRyaWJ1dGUgJ2NlaWxfbW9kZSdcbiAgaWYgKGNlaWxNb2RlICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2luZyBjZWlsKCkgaW4gc2hhcGUgY29tcHV0YXRpb24gaXMgbm90IHlldCBzdXBwb3J0ZWQgZm9yIEF2ZXJhZ2VQb29sJyk7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXV0b1BhZCwgY2VpbE1vZGUsIGNvdW50SW5jbHVkZVBhZCwga2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHMgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFthZGp1c3RlZEF0dHJpYnV0ZXMsIG91dHB1dFNoYXBlXSA9IGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZShcbiAgICBpbnB1dHMsXG4gICAgYXR0cmlidXRlcyxcbiAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICApO1xuICBjb25zdCBrZXJuZWxTaXplID0gU2hhcGVVdGlsLnNpemUoYWRqdXN0ZWRBdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgY29uc3Qgb3AxID0gJ3ZhbHVlICs9IF9YKHgpOyc7XG4gIGxldCBvcDIgPSAnJztcbiAgaWYgKGFkanVzdGVkQXR0cmlidXRlcy5jb3VudEluY2x1ZGVQYWQpIHtcbiAgICBvcDIgKz0gYHZhbHVlIC89IGZsb2F0KCR7a2VybmVsU2l6ZX0pO2A7XG4gIH0gZWxzZSB7XG4gICAgb3AyICs9IGB2YWx1ZSAvPSBmbG9hdCgke2tlcm5lbFNpemV9IC0gcGFkKTtgO1xuICB9XG4gIGNvbnN0IHBvb2xpbmdDb2RlID0gZ2VuZXJhdGVQb29saW5nQ29kZShpbnB1dHNbMF0uZGltcywgYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvcDEsIG9wMiwgJzAuMCcpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICR7cG9vbGluZ0NvZGV9XG4gICAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnbG9iYWxBdmVyYWdlUG9vbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ0dsb2JhbEF2ZXJhZ2VQb29sJyxcbiAgICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIGNhY2hlSGludDogYCR7YXR0cmlidXRlcy5jb3VudEluY2x1ZGVQYWR9YCxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvKGlucHV0cywgbWV0YWRhdGEsIHRydWUsIGF0dHJpYnV0ZXMpIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHbG9iYWxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248QXZlcmFnZVBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGNvdW50SW5jbHVkZVBhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NvdW50X2luY2x1ZGVfcGFkJywgMCkgPT09IDAgPyBmYWxzZSA6IHRydWU7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIGF1dG9QYWQ6ICcnLFxuICAgIGNlaWxNb2RlOiAwLFxuICAgIGNvdW50SW5jbHVkZVBhZCxcbiAgICBrZXJuZWxTaGFwZTogW10sXG4gICAgc3RyaWRlczogW10sXG4gICAgcGFkczogW10sXG4gIH0pO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBNYXhQb29sQXR0cmlidXRlcyBleHRlbmRzIEF2ZXJhZ2VQb29sQXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IHN0b3JhZ2VPcmRlcjogbnVtYmVyO1xuICByZWFkb25seSBkaWxhdGlvbnM6IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgbWF4UG9vbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxNYXhQb29sQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogTWF4UG9vbEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdNYXhQb29sJyxcbiAgICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBtZXRhZGF0YSwgZmFsc2UsIGF0dHJpYnV0ZXMpIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VNYXhQb29sQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxNYXhQb29sQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBNYXhQb29sQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF1dG9QYWQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhdXRvX3BhZCcsICdOT1RTRVQnKTtcbiAgY29uc3QgY2VpbE1vZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdjZWlsX21vZGUnLCAwKTtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygna2VybmVsX3NoYXBlJyk7XG4gIGNvbnN0IHN0cmlkZXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3RyaWRlcycsIFtdKTtcbiAgY29uc3QgcGFkcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgW10pO1xuICBjb25zdCBzdG9yYWdlT3JkZXIgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdzdG9yYWdlX29yZGVyJywgMCk7XG4gIGNvbnN0IGRpbGF0aW9ucyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdkaWxhdGlvbnMnLCBbXSk7XG5cbiAgLy8gVE9ETzogc3VwcG9ydCBhdHRyaWJ1dGUgJ2NlaWxfbW9kZScgYW5kICdzdG9yYWdlX29yZGVyJ1xuICBpZiAoc3RvcmFnZU9yZGVyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjb2x1bW4gbWFqb3Igc3RvcmFnZSBvcmRlciBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgTWF4UG9vbCcpO1xuICB9XG4gIGlmIChjZWlsTW9kZSAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndXNpbmcgY2VpbCgpIGluIHNoYXBlIGNvbXB1dGF0aW9uIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciBNYXhQb29sJyk7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBhdXRvUGFkLFxuICAgIGNlaWxNb2RlLFxuICAgIGNvdW50SW5jbHVkZVBhZDogZmFsc2UsXG4gICAga2VybmVsU2hhcGUsXG4gICAgc3RyaWRlcyxcbiAgICBwYWRzLFxuICAgIHN0b3JhZ2VPcmRlcixcbiAgICBkaWxhdGlvbnMsXG4gIH0pO1xufTtcblxuY29uc3QgY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICBhdHRyaWJ1dGVzOiBNYXhQb29sQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW2FkanVzdGVkQXR0cmlidXRlcywgb3V0cHV0U2hhcGVdID0gZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlKFxuICAgIGlucHV0cyxcbiAgICBhdHRyaWJ1dGVzLFxuICAgIGlzR2xvYmFsT3BlcmF0b3IsXG4gICk7XG4gIGNvbnN0IG9wMSA9IGBcbiAgICAgIHZhbHVlID0gbWF4KF9YKHgpLCB2YWx1ZSk7XG4gICAgYDtcbiAgY29uc3Qgb3AyID0gJyc7XG4gIGNvbnN0IHBvb2xpbmdDb2RlID0gZ2VuZXJhdGVQb29saW5nQ29kZShpbnB1dHNbMF0uZGltcywgYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvcDEsIG9wMiwgJy0xZTUnKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtwb29saW5nQ29kZX1cbiAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZSA9IChcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIHwgTWF4UG9vbEF0dHJpYnV0ZXMsXG4gIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4pOiBbQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIHwgTWF4UG9vbEF0dHJpYnV0ZXMsIG51bWJlcltdXSA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBoYXNEaWxhdGlvbnMgPSBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChhdHRyaWJ1dGVzLCAnZGlsYXRpb25zJyk7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5zdHJpZGVzLnNsaWNlKCk7XG4gIGNvbnN0IGRpbGF0aW9uczogbnVtYmVyW10gPSBoYXNEaWxhdGlvbnMgPyAoYXR0cmlidXRlcyBhcyBNYXhQb29sQXR0cmlidXRlcykuZGlsYXRpb25zLnNsaWNlKCkgOiBbXTtcbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5zbGljZSgpO1xuICBQb29sQ29udlV0aWwuYWRqdXN0UG9vbEF0dHJpYnV0ZXMoaXNHbG9iYWxPcGVyYXRvciwgaW5wdXRTaGFwZSwga2VybmVsU2hhcGUsIHN0cmlkZXMsIGRpbGF0aW9ucywgcGFkcyk7XG5cbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBQb29sQ29udlV0aWwuY29tcHV0ZVBvb2xPdXRwdXRTaGFwZShcbiAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICAgIGlucHV0U2hhcGUsXG4gICAgc3RyaWRlcyxcbiAgICBkaWxhdGlvbnMsXG4gICAga2VybmVsU2hhcGUsXG4gICAgcGFkcyxcbiAgICBhdHRyaWJ1dGVzLmF1dG9QYWQsXG4gICk7XG5cbiAgY29uc3QgbmV3QXR0cmlidXRlcyA9IE9iamVjdC5hc3NpZ24oe30sIGF0dHJpYnV0ZXMpO1xuICBpZiAoaGFzRGlsYXRpb25zKSB7XG4gICAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBzdHJpZGVzLCBwYWRzLCBkaWxhdGlvbnMsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH0pO1xuICB9IGVsc2Uge1xuICAgIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywgeyBrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkcywgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfSk7XG4gIH1cbiAgcmV0dXJuIFtuZXdBdHRyaWJ1dGVzLCBvdXRwdXRTaGFwZV07XG59O1xuXG5jb25zdCBnbG9iYWxNYXhQb29sQXR0cmlidXRlcyA9IHtcbiAgYXV0b1BhZDogJycsXG4gIGNlaWxNb2RlOiAwLFxuICBjb3VudEluY2x1ZGVQYWQ6IGZhbHNlLFxuICBrZXJuZWxTaGFwZTogW10sXG4gIHN0cmlkZXM6IFtdLFxuICBwYWRzOiBbXSxcbiAgc3RvcmFnZU9yZGVyOiAwLFxuICBkaWxhdGlvbnM6IFtdLFxuICBjYWNoZUtleTogJycsXG59O1xuXG5jb25zdCBnbG9iYWxNYXhQb29sTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdHbG9iYWxNYXhQb29sJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgZ2xvYmFsTWF4UG9vbCA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLmdsb2JhbE1heFBvb2xNZXRhZGF0YSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvKGlucHV0cywgZ2xvYmFsTWF4UG9vbE1ldGFkYXRhLCB0cnVlLCBnbG9iYWxNYXhQb29sQXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUG9vbCBvcHMgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdlbmVyYXRlUG9vbGluZ0NvZGUgPSAoXG4gIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbiAgb3AxOiBzdHJpbmcsXG4gIG9wMjogc3RyaW5nLFxuICBzdGFydDogc3RyaW5nLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmFuayA9IGlucHV0RGltcy5sZW5ndGg7XG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA8PSAyKSB7XG4gICAgY29uc3Qga3cgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2F0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIC0gMV07XG4gICAgY29uc3Qgc3cgPSBhdHRyaWJ1dGVzLnN0cmlkZXNbYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IHB3U3RhcnQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAvIDIgLSAxXTtcbiAgICBjb25zdCBwd0VuZCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC0gMV07XG4gICAgY29uc3QgZGltVyA9IGlucHV0RGltc1tyYW5rIC0gMV07XG4gICAgbGV0IGNvZGVXID0gJyc7XG4gICAgbGV0IGNvZGVIID0gJyc7XG4gICAgbGV0IGNvZGVIRW5kID0gJyc7XG4gICAgaWYgKHB3U3RhcnQgKyBwd0VuZCAhPT0gMCkge1xuICAgICAgY29kZVcgPSBgXG4gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2t3fTsgaSsrKSB7XG4gICAgICAgICAgICB4WyR7cmFua30gLSAxXSA9IGluZGljZXNbJHtyYW5rfSAtIDFdICogJHtzd30gLSAke3B3U3RhcnR9ICsgaTtcbiAgICAgICAgICAgIGlmICh4WyR7cmFua30gLSAxXSA8IDAgfHwgeFske3Jhbmt9IC0gMV0gPj0gJHtkaW1XfSkge1xuICAgICAgICAgICAgICBwYWQrKztcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAke29wMX1cbiAgICAgICAgICB9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZVcgPSBgXG4gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2t3fTsgaSsrKSB7XG4gICAgICAgICAgICB4WyR7cmFua30gLSAxXSA9IGluZGljZXNbJHtyYW5rfSAtIDFdICogJHtzd30gLSAke3B3U3RhcnR9ICsgaTtcbiAgICAgICAgICAgICR7b3AxfVxuICAgICAgICAgIH1gO1xuICAgIH1cblxuICAgIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMikge1xuICAgICAgY29uc3Qga2ggPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2F0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIC0gMl07XG4gICAgICBjb25zdCBzaCA9IGF0dHJpYnV0ZXMuc3RyaWRlc1thdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoIC0gMl07XG4gICAgICBjb25zdCBwaFN0YXJ0ID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLyAyIC0gMl07XG4gICAgICBjb25zdCBwaEVuZCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC0gMl07XG4gICAgICBjb25zdCBkaW1IID0gaW5wdXREaW1zW3JhbmsgLSAyXTtcbiAgICAgIGlmIChwaFN0YXJ0ICsgcGhFbmQgIT09IDApIHtcbiAgICAgICAgY29kZUggPSBgXG4gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8ICR7a2h9OyBqKyspIHtcbiAgICAgICAgICAgICAgeFske3Jhbmt9IC0gMl0gPSBpbmRpY2VzWyR7cmFua30gLSAyXSAqICR7c2h9IC0gJHtwaFN0YXJ0fSArIGo7XG4gICAgICAgICAgICAgIGlmICh4WyR7cmFua30gLSAyXSA8IDAgfHwgeFske3Jhbmt9IC0gMl0gPj0gJHtkaW1IfSkge1xuICAgICAgICAgICAgICAgIHBhZCs9ICR7a3d9O1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvZGVIID0gYFxuICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCAke2tofTsgaisrKSB7XG4gICAgICAgICAgICAgIHhbJHtyYW5rfSAtIDJdID0gaW5kaWNlc1ske3Jhbmt9IC0gMl0gKiAke3NofSAtICR7cGhTdGFydH0gKyBqO1xuICAgICAgICAgICAgYDtcbiAgICAgIH1cbiAgICAgIGNvZGVIRW5kID0gYFxuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICB9XG5cbiAgICBjb25zdCBwb29saW5nQ29kZSA9IGBcbiAgICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCB4WyR7cmFua31dO1xuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgeCk7XG5cbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9ICR7c3RhcnR9O1xuICAgICAgICAgIGludCBwYWQgPSAwO1xuICAgICAgICAgICR7Y29kZUh9XG4gICAgICAgICAgJHtjb2RlV31cbiAgICAgICAgICAke2NvZGVIRW5kfVxuICAgICAgICAgICR7b3AyfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gcG9vbGluZ0NvZGU7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qga2VybmVsU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUpO1xuICAgIGNvbnN0IGtlcm5lbFN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoYXR0cmlidXRlcy5rZXJuZWxTaGFwZSk7XG4gICAgY29uc3Qgc3RyaWRlc1JhbmsgPSBrZXJuZWxTdHJpZGVzLmxlbmd0aDtcbiAgICBjb25zdCBwYWRzUmFuayA9IGF0dHJpYnV0ZXMucGFkcy5sZW5ndGg7XG4gICAgY29uc3Qgb2Zmc2V0VG9JbmRpY2VzRnVuY3Rpb24gPSBvZmZzZXRUb0luZGljZXMoc3RyaWRlc1JhbmspO1xuICAgIGNvbnN0IGNvcHlJbnB1dERpbXMgPSBjb3B5QXJyYXkoaW5wdXREaW1zLCAnaW5wdXREaW1zJyk7XG4gICAgY29uc3QgY29weVBhZHMgPSBjb3B5QXJyYXkoYXR0cmlidXRlcy5wYWRzLCAncGFkcycpO1xuICAgIGNvbnN0IGNvcHlLZXJuZWxTdHJpZGVzID0gY29weUFycmF5KGtlcm5lbFN0cmlkZXMsICdrZXJuZWxTdHJpZGVzJyk7XG4gICAgY29uc3QgY29weVN0cmlkZXMgPSBjb3B5QXJyYXkoYXR0cmlidXRlcy5zdHJpZGVzLCAnc3RyaWRlcycpO1xuICAgIGNvbnN0IGhhc1BhZHMgPSBhdHRyaWJ1dGVzLnBhZHMucmVkdWNlKChzdW0sIGN1cikgPT4gc3VtICsgY3VyKTtcbiAgICBsZXQgcGFkQ29kZSA9ICcnO1xuICAgIGlmIChoYXNQYWRzKSB7XG4gICAgICBwYWRDb2RlID0gYFxuICAgICAgICAgICAgaWYgKHhbal0gPj0gaW5wdXREaW1zW2pdIHx8IHhbal0gPCAwKSB7XG4gICAgICAgICAgICAgIHBhZCsrO1xuICAgICAgICAgICAgICBpc1BhZCA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWlzUGFkKSB7XG4gICAgICAgICAgICAke29wMX1cbiAgICAgICAgICB9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcGFkQ29kZSA9IGBcbiAgICAgICAgICB9XG4gICAgICAgICAgJHtvcDF9XG4gICAgICAgIGA7XG4gICAgfVxuICAgIGNvbnN0IHBvb2xpbmdDb2RlID0gYFxuICAgICAgICAke29mZnNldFRvSW5kaWNlc0Z1bmN0aW9ufVxuICAgICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IHhbJHtyYW5rfV07XG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCB4KTtcbiAgICAgICAgICBpbnQgb2Zmc2V0WyR7c3RyaWRlc1Jhbmt9XTtcbiAgICAgICAgICBpbnQgcGFkc1ske3BhZHNSYW5rfV07XG4gICAgICAgICAgaW50IGlucHV0RGltc1ske3Jhbmt9XTtcbiAgICAgICAgICBpbnQga2VybmVsU3RyaWRlc1ske3N0cmlkZXNSYW5rfV07XG4gICAgICAgICAgaW50IHN0cmlkZXNbJHtzdHJpZGVzUmFua31dO1xuICAgICAgICAgICR7Y29weVBhZHN9XG4gICAgICAgICAgJHtjb3B5SW5wdXREaW1zfVxuICAgICAgICAgICR7Y29weVN0cmlkZXN9XG4gICAgICAgICAgJHtjb3B5S2VybmVsU3RyaWRlc31cblxuICAgICAgICAgIGZsb2F0IHZhbHVlID0gJHtzdGFydH07XG4gICAgICAgICAgaW50IHBhZCA9IDA7XG4gICAgICAgICAgYm9vbCBpc1BhZCA9IGZhbHNlO1xuICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtrZXJuZWxTaXplfTsgaSsrKSB7XG4gICAgICAgICAgICBvZmZzZXRUb0luZGljZXMoaSwga2VybmVsU3RyaWRlcywgb2Zmc2V0KTtcbiAgICAgICAgICAgIGlzUGFkID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGludCBqID0gJHtyYW5rfSAtICR7c3RyaWRlc1Jhbmt9OyBqIDwgJHtyYW5rfTsgaisrKSB7XG4gICAgICAgICAgICAgIHhbal0gPSBpbmRpY2VzW2pdICogc3RyaWRlc1tqIC0gJHtyYW5rfSArICR7c3RyaWRlc1Jhbmt9XVxuICAgICAgICAgICAgICAgICsgb2Zmc2V0W2ogLSAke3Jhbmt9ICsgJHtzdHJpZGVzUmFua31dIC0gcGFkc1tqIC0gMl07XG4gICAgICAgICAgICAgICR7cGFkQ29kZX1cbiAgICAgICAgICB9XG4gICAgICAgICAgJHtvcDJ9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIHBvb2xpbmdDb2RlO1xuICB9XG59O1xuXG5jb25zdCBjb3B5QXJyYXkgPSAoYXJyYXk6IHJlYWRvbmx5IG51bWJlcltdLCBhcnJheU5hbWU6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgJHthcnJheU5hbWV9WyR7aX1dID0gJHthcnJheVtpXX07XG4gICAgYDtcbiAgfVxuICByZXR1cm4gYmxvY2s7XG59O1xuXG5jb25zdCBvZmZzZXRUb0luZGljZXMgPSAocmFuazogbnVtYmVyKTogc3RyaW5nID0+IGBcbiAgdm9pZCBvZmZzZXRUb0luZGljZXMoaW50IG9mZnNldCwgaW50WyR7cmFua31dIHN0cmlkZXMsIG91dCBpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgIGlmICgke3Jhbmt9ID09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3Jhbmt9IC0gMTsgKytpKSB7XG4gICAgICBpbmRpY2VzW2ldID0gb2Zmc2V0IC8gc3RyaWRlc1tpXTtcbiAgICAgIG9mZnNldCAtPSBpbmRpY2VzW2ldICogc3RyaWRlc1tpXTtcbiAgICB9XG4gICAgaW5kaWNlc1ske3Jhbmt9IC0gMV0gPSBvZmZzZXQ7XG4gIH1gO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE5VTUJFUl9UWVBFUywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBSZWR1Y2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhlczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGtlZXBEaW1zOiBib29sZWFuO1xufVxuXG4vLyByZXR1cm4gW2luaXQgb3BzLCByZWR1Y2Ugb3BzLCBmaW5hbCBvcHNdXG50eXBlIFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKSA9PiBzdHJpbmdbXTtcblxuY29uc3QgcmVkdWNlID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4gIG5hbWU6IHN0cmluZyxcbiAgcmVkdWNlT3A6IFJlZHVjZU9wLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IHJlZHVjZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgICBuYW1lLFxuICAgIGlucHV0TmFtZXM6IFsnQSddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIH07XG5cbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4ucmVkdWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVSZWR1Y2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsIG5hbWUsIHJlZHVjZU9wLCByZWR1Y2VQcm9ncmFtTWV0YWRhdGEpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBSZWR1Y2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXhlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJywgW10pO1xuICBjb25zdCBrZWVwRGltcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2tlZXBkaW1zJywgMSkgPT09IDE7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGVzLCBrZWVwRGltcyB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvID0gKFxuICBfaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuICBfbmFtZTogc3RyaW5nLFxuICByZWR1Y2VPcDogUmVkdWNlT3AsXG4gIHJlZHVjZVByb2dyYW1NZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaVJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggfHwgMTtcblxuICBjb25zdCBpZHhDb3B5ID0gW107IC8vIGNvcHkgb3V0cHV0IGluZGV4ZXMgdG8gaW5wdXQgaW5kZXhlc1xuXG4gIGNvbnN0IGF4ZXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhlcyhhdHRyaWJ1dGVzLmF4ZXMsIGlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG4gIGNvbnN0IG9wcyA9IHJlZHVjZU9wKGlucHV0cywgYXhlcyk7XG4gIGxldCByZWR1Y2VPcHMgPSBvcHNbMV07XG5cbiAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgIC8vIGlmIHRoaXMgYXhpcyBpcyByZWR1Y2VkXG4gICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZiAoYXR0cmlidXRlcy5rZWVwRGltcykge1xuICAgICAgICBvdXRwdXRTaGFwZS5wdXNoKDEpO1xuICAgICAgfSAvLyBlbHNlIHsgcmVtb3ZlIHRoZSBheGlzIGZyb20gb3V0cHV0U2hhcGU7IH1cblxuICAgICAgLy8gbG9vcCBvdmVyIHRoZSBkLXRoIGF4aXNcbiAgICAgIHJlZHVjZU9wcyA9IGBcbiAgICAgICAgICBmb3IoaW50IGoke2t9ID0gMDsgaiR7a30gPCAke2lucHV0c1swXS5kaW1zW2tdfTsgaiR7a30rKykge1xuICAgICAgICAgICAgaW5wdXRJZHhbJHtrfV0gPSBqJHtrfTtcbiAgICAgICAgICAgICR7cmVkdWNlT3BzfVxuICAgICAgICAgIH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZHhDb3B5LnB1c2goYGlucHV0SWR4WyR7a31dID0gb3V0cHV0SWR4WyR7b3V0cHV0U2hhcGUubGVuZ3RofV07YCk7XG5cbiAgICAgIG91dHB1dFNoYXBlLnB1c2goaW5wdXRzWzBdLmRpbXNba10pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG9SYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoIHx8IDE7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgb3V0cHV0SWR4WyR7b1Jhbmt9XSkge1xuICAgICAgICBmbG9hdCB2YWx1ZTsgICAgICAgICAgICAgICAgIC8vIGZpbmFsIHJlc3VsdFxuICAgICAgICBpbnQgaW5wdXRJZHhbJHtpUmFua31dOyAgICAgIC8vIGFkZHJlc3NpbmcgaW5wdXQgZGF0YVxuICAgICAgICAke2lkeENvcHkuam9pbignXFxuJyl9XG4gICAgICAgICR7b3BzWzBdfSAgICAgICAvLyBpbml0IG9wcyBmb3IgcmVkdWNlIG1heC9taW5cbiAgICAgICAgJHtyZWR1Y2VPcHN9XG4gICAgICAgICR7b3BzWzJdfSAgICAgICAvLyBmaW5hbCBjb21wdXRhdGlvbiBmb3IgcmVkdWNlIG1lYW5cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfWA7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5yZWR1Y2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICAvLyBUT0RPOiBzdXBwb3J0IFJlZHVjZSogb3BlcmF0b3JzIHdpdGggMiBpbnB1dHMuXG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlZHVjZSBvcCByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKE5VTUJFUl9UWVBFUy5pbmRleE9mKGlucHV0c1swXS50eXBlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZVN1bTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoKTogc3RyaW5nW10gPT4gWyd2YWx1ZSA9IDAuMDsnLCAndmFsdWUgKz0gX0EoaW5wdXRJZHgpOycsICcnXTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VTdW0nLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWVhbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBzdHJpbmdbXSA9PiB7XG4gICAgbGV0IHNpemUgPSAxLjA7XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHNpemUgKj0gaW5wdXRzWzBdLmRpbXNba107XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFsndmFsdWUgPSAwLjA7JywgJ3ZhbHVlICs9IF9BKGlucHV0SWR4KTsnLCBgdmFsdWUgLz0gJHtzaXplfS47YF07IC8vIGVuc3VyZSByZWFsIG51bWJlciB3aXRoIGAuYFxuICB9O1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZU1lYW4nLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWF4OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dHM6IFRlbnNvcltdLCBheGVzOiBudW1iZXJbXSk6IHN0cmluZ1tdID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGlkeFplcm8ucHVzaChgaW5wdXRJZHhbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfVxcbnZhbHVlID0gX0EoaW5wdXRJZHgpO2AsICd2YWx1ZSA9IG1heCh2YWx1ZSwgX0EoaW5wdXRJZHgpKTsnLCAnJ107XG4gIH07XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTWF4JywgcmVkdWNlT3ApO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZU1pbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBzdHJpbmdbXSA9PiB7XG4gICAgY29uc3QgaWR4WmVybyA9IFtdO1xuICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0SWR4WyR7a31dID0gMDtgKTsgLy8gZmlyc3QgZWxlbWVudFxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbYCR7aWR4WmVyby5qb2luKCdcXG4nKX1cXG52YWx1ZSA9IF9BKGlucHV0SWR4KTtgLCAndmFsdWUgPSBtaW4odmFsdWUsIF9BKGlucHV0SWR4KSk7JywgJyddO1xuICB9O1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZU1pbicsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VQcm9kOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ3ZhbHVlID0gMS4wOycsICd2YWx1ZSAqPSBfQShpbnB1dElkeCk7JywgJyddO1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZVByb2QnLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ3ZhbHVlID0gMC4wOycsICd2YWx1ZSArPSBfQShpbnB1dElkeCk7JywgJ3ZhbHVlID0gbG9nKHZhbHVlKTsnXTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VMb2dTdW0nLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtU3F1YXJlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ2Zsb2F0IHQ7IHZhbHVlID0gMC4wOycsICd0ID0gX0EoaW5wdXRJZHgpOyB2YWx1ZSArPSB0ICogdDsnLCAnJ107XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTG9nU3VtU3F1YXJlJywgcmVkdWNlT3ApO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgcmVzaGFwZSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlc2hhcGVkRGltcyA9IFNoYXBlVXRpbC5jYWxjdWxhdGVSZXNoYXBlZERpbXMoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5pbnRlZ2VyRGF0YSk7XG4gIGlmIChoYW5kbGVyLnNlc3Npb24ucGFjaykge1xuICAgIHJldHVybiBbaGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1swXSwgcmVzaGFwZWREaW1zKV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtoYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIHJlc2hhcGVkRGltcyldO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBzYW1wbGVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgb3BzZXQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgaXNSZXNpemU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IG1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgc2NhbGVzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZXh0cmFwb2xhdGlvblZhbHVlOiBudW1iZXI7XG4gIHJlYWRvbmx5IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVzZUV4dHJhcG9sYXRpb246IGJvb2xlYW47XG4gIHJlYWRvbmx5IG5lZWRSb2lJbnB1dDogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbmVhcmVzdE1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgY3ViaWNDb2VmZmljaWVudEE6IG51bWJlcjtcbiAgcmVhZG9ubHkgZXhjbHVkZU91dHNpZGU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IHVzZU5lYXJlc3QyeE9wdGltaXphdGlvbjogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcm9pSW5wdXRJZHg6IG51bWJlcjtcbiAgcmVhZG9ubHkgc2NhbGVzSW5wdXRJZHg6IG51bWJlcjtcbiAgcmVhZG9ubHkgc2l6ZXNJbnB1dElkeDogbnVtYmVyO1xufVxuXG5jb25zdCB1cHNhbXBsZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1Vwc2FtcGxlJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgdXBzYW1wbGU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnVwc2FtcGxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVVcHNhbXBsZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y3OiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4gcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMobm9kZSwgNyk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y5OiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4gcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMobm9kZSwgOSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlLCBvcHNldDogbnVtYmVyKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgaXNSZXNpemUgPSBvcHNldCA+PSAxMDtcblxuICAvLyBwcm9jZXNzaW5nIG5vZGUgYXR0cmlidXRlc1xuICBjb25zdCBtb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICduZWFyZXN0Jyk7XG4gIGlmIChtb2RlICE9PSAnbmVhcmVzdCcgJiYgbW9kZSAhPT0gJ2xpbmVhcicgJiYgKG9wc2V0IDwgMTEgfHwgbW9kZSAhPT0gJ2N1YmljJykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBtb2RlOiAke21vZGV9YCk7XG4gIH1cblxuICBsZXQgc2NhbGVzOiBudW1iZXJbXSA9IFtdO1xuICBpZiAob3BzZXQgPCA5KSB7XG4gICAgc2NhbGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0cygnc2NhbGVzJyk7XG4gICAgc2NhbGVzVmFsaWRhdGlvbihzY2FsZXMsIG1vZGUsIGlzUmVzaXplKTtcbiAgfVxuXG4gIGNvbnN0IGV4dHJhcG9sYXRpb25WYWx1ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnZXh0cmFwb2xhdGlvbl92YWx1ZScsIDAuMCk7XG5cbiAgY29uc3QgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPVxuICAgIG9wc2V0ID4gMTAgPyBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdjb29yZGluYXRlX3RyYW5zZm9ybWF0aW9uX21vZGUnLCAnaGFsZl9waXhlbCcpIDogJ2FzeW1tZXRyaWMnO1xuICBpZiAoXG4gICAgW1xuICAgICAgJ2FzeW1tZXRyaWMnLFxuICAgICAgJ3B5dG9yY2hfaGFsZl9waXhlbCcsXG4gICAgICAndGZfaGFsZl9waXhlbF9mb3Jfbm4nLFxuICAgICAgJ2FsaWduX2Nvcm5lcnMnLFxuICAgICAgJ3RmX2Nyb3BfYW5kX3Jlc2l6ZScsXG4gICAgICAnaGFsZl9waXhlbCcsXG4gICAgXS5pbmRleE9mKGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlKSA9PT0gLTFcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjb29yZGluYXRlX3RyYW5zZm9ybV9tb2RlICcke2Nvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlfScgaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG4gIGNvbnN0IG5lZWRSb2lJbnB1dCA9IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID09PSAndGZfY3JvcF9hbmRfcmVzaXplJztcbiAgY29uc3QgdXNlRXh0cmFwb2xhdGlvbiA9IG5lZWRSb2lJbnB1dDtcblxuICBjb25zdCBuZWFyZXN0TW9kZSA9XG4gICAgbW9kZSA9PT0gJ25lYXJlc3QnICYmIG9wc2V0ID49IDExID8gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbmVhcmVzdF9tb2RlJywgJ3JvdW5kX3ByZWZlcl9mbG9vcicpIDogJyc7XG4gIGlmIChbJ3JvdW5kX3ByZWZlcl9mbG9vcicsICdyb3VuZF9wcmVmZXJfY2VpbCcsICdmbG9vcicsICdjZWlsJywgJyddLmluZGV4T2YobmVhcmVzdE1vZGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgbmVhcmVzdF9tb2RlICcke25lYXJlc3RNb2RlfScgaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG5cbiAgY29uc3QgY3ViaWNDb2VmZmljaWVudEEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2N1YmljX2NvZWZmX2EnLCAtMC43NSk7XG4gIGNvbnN0IGV4Y2x1ZGVPdXRzaWRlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnZXhjbHVkZV9vdXRzaWRlJywgMCkgIT09IDA7XG4gIGlmIChleGNsdWRlT3V0c2lkZSAmJiBtb2RlICE9PSAnY3ViaWMnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdleGNsdWRlX291dHNpZGUgY2FuIGJlIHNldCB0byAxIG9ubHkgd2hlbiBtb2RlIGlzIENVQklDLicpO1xuICB9XG5cbiAgY29uc3QgdXNlTmVhcmVzdDJ4T3B0aW1pemF0aW9uID1cbiAgICBvcHNldCA8IDExID8gdHJ1ZSA6IG1vZGUgPT09ICduZWFyZXN0JyAmJiBjb29yZGluYXRlVHJhbnNmb3JtTW9kZSA9PT0gJ2FzeW1tZXRyaWMnICYmIG5lYXJlc3RNb2RlID09PSAnZmxvb3InO1xuXG4gIGxldCByb2lJbnB1dElkeCA9IDA7XG4gIGxldCBzY2FsZXNJbnB1dElkeCA9IDA7XG4gIGxldCBzaXplc0lucHV0SWR4ID0gMDtcblxuICBpZiAob3BzZXQgPiAxMCkge1xuICAgIC8vIGhhbmRsZSB3aGVuIHJvaUlucHV0IGlzIG5vdCBnaXZlblxuICAgIGlmIChub2RlLmlucHV0cy5sZW5ndGggPiAyKSB7XG4gICAgICByb2lJbnB1dElkeCA9IDE7XG4gICAgICBzY2FsZXNJbnB1dElkeCA9IDI7XG4gICAgICBzaXplc0lucHV0SWR4ID0gMztcbiAgICB9IGVsc2Uge1xuICAgICAgc2NhbGVzSW5wdXRJZHggPSAxO1xuICAgICAgc2l6ZXNJbnB1dElkeCA9IDI7XG4gICAgfVxuICB9IGVsc2UgaWYgKG9wc2V0ID09PSA5KSB7XG4gICAgc2NhbGVzSW5wdXRJZHggPSAxO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgb3BzZXQsXG4gICAgaXNSZXNpemUsXG4gICAgbW9kZSxcbiAgICBzY2FsZXMsXG4gICAgZXh0cmFwb2xhdGlvblZhbHVlLFxuICAgIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlLFxuICAgIHVzZUV4dHJhcG9sYXRpb24sXG4gICAgbmVlZFJvaUlucHV0LFxuICAgIG5lYXJlc3RNb2RlLFxuICAgIGN1YmljQ29lZmZpY2llbnRBLFxuICAgIGV4Y2x1ZGVPdXRzaWRlLFxuICAgIHVzZU5lYXJlc3QyeE9wdGltaXphdGlvbixcbiAgICByb2lJbnB1dElkeCxcbiAgICBzY2FsZXNJbnB1dElkeCxcbiAgICBzaXplc0lucHV0SWR4LFxuICB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZVVwc2FtcGxlUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IFtpbnB1dFdpZHRoLCBpbnB1dEhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBpbnB1dHNbMF0uZGltcyxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgKTtcblxuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLm1hcCgoZGltLCBpKSA9PiBNYXRoLmZsb29yKGRpbSAqIGF0dHJpYnV0ZXMuc2NhbGVzW2ldKSk7XG4gIGNvbnN0IFtvdXRwdXRXaWR0aCwgb3V0cHV0SGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIG91dHB1dFNoYXBlLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuICBjb25zdCBkaW0gPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3Qgb3V0cHV0UGl0Y2hlcyA9IG5ldyBBcnJheTxudW1iZXI+KGRpbSk7XG4gIGNvbnN0IGlucHV0UGl0Y2hlcyA9IG5ldyBBcnJheTxudW1iZXI+KGRpbSk7XG4gIGxldCBwcmVjYWxjdWxhdGVkUGl0Y2hlcyA9IGBcbiAgICAgIGludCBvdXRwdXRfcGl0Y2hlc1ske2RpbX1dO1xuICAgICAgaW50IGlucHV0X3BpdGNoZXNbJHtkaW19XTtcbiAgICAgIGA7XG4gIGZvciAobGV0IGQgPSBkaW0gLSAxOyBkID49IDA7IGQtLSkge1xuICAgIG91dHB1dFBpdGNoZXNbZF0gPSBkID09PSBkaW0gLSAxID8gMSA6IG91dHB1dFBpdGNoZXNbZCArIDFdICogb3V0cHV0U2hhcGVbZCArIDFdO1xuICAgIGlucHV0UGl0Y2hlc1tkXSA9IGQgPT09IGRpbSAtIDEgPyAxIDogaW5wdXRQaXRjaGVzW2QgKyAxXSAqIGlucHV0c1swXS5kaW1zW2QgKyAxXTtcblxuICAgIHByZWNhbGN1bGF0ZWRQaXRjaGVzICs9IGBcbiAgICAgICAgb3V0cHV0X3BpdGNoZXNbJHtkfV0gPSAke291dHB1dFBpdGNoZXNbZF19O1xuICAgICAgICBpbnB1dF9waXRjaGVzWyR7ZH1dID0gJHtpbnB1dFBpdGNoZXNbZF19O1xuICAgICAgICBgO1xuICB9XG4gIGNvbnN0IGdldElucHV0RmxvYXRGdW5jdGlvbiA9IGBcbiAgICAgIGZsb2F0IGdldElucHV0RmxvYXQoaW50IGluZGV4KSB7XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMoaW5kZXgsICR7aW5wdXRXaWR0aH0sICR7aW5wdXRIZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oWCwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID1cbiAgICBhdHRyaWJ1dGVzLm1vZGUgPT09ICduZWFyZXN0J1xuICAgICAgPyAvLyBuZWFyZXN0XG4gICAgICAgIGBcbiAgICAke2dldElucHV0RmxvYXRGdW5jdGlvbn1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7ZGltfV0pIHtcbiAgICAgIGludCBpbnB1dF9pbmRleCA9IDA7XG4gICAgICBpbnQgb3V0cHV0X2luZGV4ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke291dHB1dFdpZHRofSwgJHtvdXRwdXRIZWlnaHR9KTtcblxuICAgICAgJHtwcmVjYWxjdWxhdGVkUGl0Y2hlc31cblxuICAgICAgaW50IGQsIG07XG4gICAgICBmb3IgKGludCBkaW0gPSAwOyBkaW0gPCAke2RpbX07ICsrZGltKSB7XG4gICAgICAgIGQgPSBvdXRwdXRfaW5kZXggLyBvdXRwdXRfcGl0Y2hlc1tkaW1dO1xuICAgICAgICBtID0gb3V0cHV0X2luZGV4IC0gZCAqIG91dHB1dF9waXRjaGVzW2RpbV07XG4gICAgICAgIG91dHB1dF9pbmRleCA9IG07XG5cbiAgICAgICAgaWYgKHNjYWxlc1tkaW1dICE9IDEgJiYgZCA+IDApIHtcbiAgICAgICAgICBpbnQgZDIgPSBkIC8gc2NhbGVzW2RpbV07XG4gICAgICAgICAgbSA9IGQgLSBkMiAqIHNjYWxlc1tkaW1dO1xuICAgICAgICAgIGQgPSBkMjtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dF9pbmRleCArPSBpbnB1dF9waXRjaGVzW2RpbV0gKiBkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCk7XG4gICAgfWBcbiAgICAgIDogZGltID09PSA0XG4gICAgICAgID8gLy8gYmlsaW5lYXIgNERcbiAgICAgICAgICBgXG4gICAgJHtnZXRJbnB1dEZsb2F0RnVuY3Rpb259XG4gICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1s0XSkge1xuICAgICAgaW50IGlucHV0X2luZGV4ID0gMDtcbiAgICAgIGludCBvdXRwdXRfaW5kZXggPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7b3V0cHV0V2lkdGh9LCAke291dHB1dEhlaWdodH0pO1xuXG4gICAgICAke3ByZWNhbGN1bGF0ZWRQaXRjaGVzfVxuXG4gICAgICBpbnQgbTtcbiAgICAgIGludCBpbmRleF9vZl9kaW0wLCBpbmRleF9vZl9kaW0xLCBpbmRleF9vZl9kaW0yLCBpbmRleF9vZl9kaW0zO1xuICAgICAgaW5kZXhfb2ZfZGltMCA9IG91dHB1dF9pbmRleCAvIG91dHB1dF9waXRjaGVzWzBdO1xuICAgICAgbSA9IG91dHB1dF9pbmRleCAtIGluZGV4X29mX2RpbTAgKiBvdXRwdXRfcGl0Y2hlc1swXTtcbiAgICAgIGluZGV4X29mX2RpbTEgPSBtIC8gb3V0cHV0X3BpdGNoZXNbMV07XG4gICAgICBtID0gbSAtIGluZGV4X29mX2RpbTEgKiBvdXRwdXRfcGl0Y2hlc1sxXTtcbiAgICAgIGluZGV4X29mX2RpbTIgPSBtIC8gb3V0cHV0X3BpdGNoZXNbMl07XG4gICAgICBtID0gbSAtIGluZGV4X29mX2RpbTIgKiBvdXRwdXRfcGl0Y2hlc1syXTtcbiAgICAgIGluZGV4X29mX2RpbTMgPSBtO1xuXG4gICAgICBpbnQgaW5kZXhfb2ZfaW5wdXRfZGltMiwgaW5kZXhfb2ZfaW5wdXRfZGltMywgeF9vZmZzZXQsIHlfb2Zmc2V0O1xuICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMiA9IGluZGV4X29mX2RpbTIgLyBzY2FsZXNbMl07XG4gICAgICB5X29mZnNldCA9IGluZGV4X29mX2RpbTIgLSBpbmRleF9vZl9pbnB1dF9kaW0yICogc2NhbGVzWzJdO1xuICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMyA9IGluZGV4X29mX2RpbTMgLyBzY2FsZXNbM107XG4gICAgICB4X29mZnNldCA9IGluZGV4X29mX2RpbTMgLSBpbmRleF9vZl9pbnB1dF9kaW0zICogc2NhbGVzWzNdO1xuXG4gICAgICBpbnB1dF9pbmRleCA9IGluZGV4X29mX2RpbTAgKiBpbnB1dF9waXRjaGVzWzBdICtcbiAgICAgICAgICAgIGluZGV4X29mX2RpbTEgKiBpbnB1dF9waXRjaGVzWzFdICtcbiAgICAgICAgICAgIGluZGV4X29mX2lucHV0X2RpbTIgKiBpbnB1dF9waXRjaGVzWzJdICtcbiAgICAgICAgICAgIGluZGV4X29mX2lucHV0X2RpbTM7XG5cbiAgICAgIGZsb2F0IHgwMCA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXgpO1xuICAgICAgZmxvYXQgeDEwLCB4MDEsIHgxMTtcblxuICAgICAgYm9vbCBlbmRfb2ZfZGltMiA9IGZhbHNlO1xuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTIgPT0gKCR7aW5wdXRzWzBdLmRpbXNbMl19IC0gMSkpIHtcbiAgICAgICAgLy8gSXQncyB0aGUgZW5kIGluIGRpbWVuc2lvbiAyXG4gICAgICAgIHgwMSA9IHgwMDtcbiAgICAgICAgZW5kX29mX2RpbTIgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeDAxID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMl0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5kZXhfb2ZfaW5wdXRfZGltMyA9PSAoaW5wdXRfcGl0Y2hlc1syXSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gM1xuICAgICAgICB4MTAgPSB4MDA7XG4gICAgICAgIHgxMSA9IHgwMTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB4MTAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgMSk7XG4gICAgICAgIHgxMSA9IGVuZF9vZl9kaW0yID8geDEwIDogZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMl0gKyAxKTtcbiAgICAgIH1cblxuICAgICAgZmxvYXQgeTAgPSB4MDAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDAxIC0geDAwKSAvIGZsb2F0KHNjYWxlc1syXSk7XG4gICAgICBmbG9hdCB5MSA9IHgxMCArIGZsb2F0KHlfb2Zmc2V0KSAqICh4MTEgLSB4MTApIC8gZmxvYXQoc2NhbGVzWzJdKTtcbiAgICAgIHJldHVybiB5MCArIGZsb2F0KHhfb2Zmc2V0KSAqICh5MSAtIHkwKSAvIGZsb2F0KHNjYWxlc1szXSk7XG4gICAgfWBcbiAgICAgICAgOiAvLyBiaWxpbmVhciAyRFxuICAgICAgICAgIGBcbiAgICAke2dldElucHV0RmxvYXRGdW5jdGlvbn1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWzJdKSB7XG4gICAgICBpbnQgaW5wdXRfaW5kZXggPSAwO1xuICAgICAgaW50IG91dHB1dF9pbmRleCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHtvdXRwdXRXaWR0aH0sICR7b3V0cHV0SGVpZ2h0fSk7XG5cbiAgICAgICR7cHJlY2FsY3VsYXRlZFBpdGNoZXN9XG5cbiAgICAgIGludCBtO1xuICAgICAgaW50IGluZGV4X29mX2RpbTAsIGluZGV4X29mX2RpbTE7XG4gICAgICBpbmRleF9vZl9kaW0wID0gb3V0cHV0X2luZGV4IC8gb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBtID0gb3V0cHV0X2luZGV4IC0gaW5kZXhfb2ZfZGltMCAqIG91dHB1dF9waXRjaGVzWzBdO1xuICAgICAgaW5kZXhfb2ZfZGltMSA9IG07XG5cbiAgICAgIGludCBpbmRleF9vZl9pbnB1dF9kaW0wLCBpbmRleF9vZl9pbnB1dF9kaW0xLCB4X29mZnNldCwgeV9vZmZzZXQ7XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0wID0gaW5kZXhfb2ZfZGltMCAvIHNjYWxlc1swXTtcbiAgICAgIHlfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMCAtIGluZGV4X29mX2lucHV0X2RpbTAgKiBzY2FsZXNbMF07XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0xID0gaW5kZXhfb2ZfZGltMSAvIHNjYWxlc1sxXTtcbiAgICAgIHhfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMSAtIGluZGV4X29mX2lucHV0X2RpbTEgKiBzY2FsZXNbMV07XG5cbiAgICAgIGlucHV0X2luZGV4ID0gaW5kZXhfb2ZfaW5wdXRfZGltMCAqIGlucHV0X3BpdGNoZXNbMF0gKyBpbmRleF9vZl9pbnB1dF9kaW0xO1xuXG4gICAgICBmbG9hdCB4MDAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4KTtcbiAgICAgIGZsb2F0IHgxMCwgeDAxLCB4MTE7XG5cbiAgICAgIGJvb2wgZW5kX29mX2RpbTAgPSBmYWxzZTtcbiAgICAgIGlmIChpbmRleF9vZl9pbnB1dF9kaW0wID09ICgke2lucHV0c1swXS5kaW1zWzBdfSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gMFxuICAgICAgICB4MDEgPSB4MDA7XG4gICAgICAgIGVuZF9vZl9kaW0wID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHgwMSA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzBdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTEgPT0gKGlucHV0X3BpdGNoZXNbMF0gLSAxKSkge1xuICAgICAgICAvLyBJdCdzIHRoZSBlbmQgaW4gZGltZW5zaW9uIDFcbiAgICAgICAgeDEwID0geDAwO1xuICAgICAgICB4MTEgPSB4MDE7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgeDEwID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIDEpO1xuICAgICAgICB4MTEgPSBlbmRfb2ZfZGltMCA/IHgxMCA6IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzBdICsgMSk7XG4gICAgICB9XG5cbiAgICAgIGZsb2F0IHkwID0geDAwICsgZmxvYXQoeV9vZmZzZXQpICogKHgwMSAtIHgwMCkgLyBmbG9hdChzY2FsZXNbMF0pO1xuICAgICAgZmxvYXQgeTEgPSB4MTAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDExIC0geDEwKSAvIGZsb2F0KHNjYWxlc1swXSk7XG4gICAgICByZXR1cm4geTAgKyBmbG9hdCh4X29mZnNldCkgKiAoeTEgLSB5MCkgLyBmbG9hdChzY2FsZXNbMV0pO1xuICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnVwc2FtcGxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICB2YXJpYWJsZXM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3NjYWxlcycsXG4gICAgICAgIHR5cGU6ICdpbnQnLFxuICAgICAgICBhcnJheUxlbmd0aDogYXR0cmlidXRlcy5zY2FsZXMubGVuZ3RoLFxuICAgICAgICBkYXRhOiBhdHRyaWJ1dGVzLnNjYWxlcy5tYXAoKHgpID0+IE1hdGguY2VpbCh4KSksXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlOiBVcHNhbXBsZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgaWYgKFxuICAgICFpbnB1dHMgfHxcbiAgICAoYXR0cmlidXRlLm9wc2V0IDwgOSAmJiBpbnB1dHMubGVuZ3RoICE9PSAxKSB8fFxuICAgIChhdHRyaWJ1dGUub3BzZXQgPj0gOSAmJiBhdHRyaWJ1dGUub3BzZXQgPCAxMSAmJiBpbnB1dHMubGVuZ3RoICE9PSAyKSB8fFxuICAgIChhdHRyaWJ1dGUub3BzZXQgPj0gMTEgJiYgaW5wdXRzLmxlbmd0aCA8IDIpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoYXR0cmlidXRlLnNjYWxlcy5sZW5ndGggPiAwICYmIGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gYXR0cmlidXRlLnNjYWxlcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHNjYWxlc1ZhbGlkYXRpb24gPSAoc2NhbGVzOiBudW1iZXJbXSwgbW9kZTogc3RyaW5nLCBpc1Jlc2l6ZTogYm9vbGVhbik6IHZvaWQgPT4ge1xuICBpZiAoIWlzUmVzaXplKSB7XG4gICAgZm9yIChjb25zdCBzY2FsZSBvZiBzY2FsZXMpIHtcbiAgICAgIGlmIChzY2FsZSA8IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTY2FsZSB2YWx1ZSBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEuJyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAoY29uc3Qgc2NhbGUgb2Ygc2NhbGVzKSB7XG4gICAgICBpZiAoc2NhbGUgPD0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjYWxlIHZhbHVlIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKG1vZGUgPT09ICdsaW5lYXInIHx8IG1vZGUgPT09ICdjdWJpYycpIHtcbiAgICBpZiAoc2NhbGVzLmxlbmd0aCAhPT0gMiAmJiAoc2NhbGVzLmxlbmd0aCAhPT0gNCB8fCBzY2FsZXNbMF0gIT09IDEgfHwgc2NhbGVzWzFdICE9PSAxKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAnTGluZWFyJyBtb2RlIGFuZCAnQ3ViaWMnIG1vZGUgb25seSBzdXBwb3J0IDItRCBpbnB1dHMgKCdCaWxpbmVhcicsICdCaWN1YmljJykgXFxcbiAgICAgICAgb3IgNC1EIGlucHV0cyB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIG91dGVybW9zdCAyIHNjYWxlIHZhbHVlcyBiZWluZyAxIFxcXG4gICAgICAgIGluIHRoZSAke2lzUmVzaXplID8gJ1Jlc2l6ZScgOiAnVXBzYW1wbGUnfSBvcGVhcnRvci5gKTtcbiAgICB9XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyB1bnBhY2tGcm9tQ2hhbm5lbCB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5pbXBvcnQgeyBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcywgc2NhbGVzVmFsaWRhdGlvbiwgVXBzYW1wbGVBdHRyaWJ1dGVzLCB2YWxpZGF0ZUlucHV0cyB9IGZyb20gJy4vdXBzYW1wbGUnO1xuXG5jb25zdCByZXNpemVQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdSZXNpemUnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgcmVzaXplOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5yZXNpemVQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZFJlc2l6ZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTA6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCAxMCk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTE6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCAxMSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2l6ZVByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBbc2NhbGVzLCBvdXRwdXRTaGFwZV0gPSBwcmVwYXJlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG5cbiAgY29uc3QgaXNTYW1lID0gc2NhbGVzLmV2ZXJ5KChzOiBudW1iZXIpID0+IHMgPT09IDEpICYmIGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgIT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnO1xuICBpZiAoaXNTYW1lKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICAgIGhhc01haW46IHRydWUsXG4gICAgICBzaGFkZXJTb3VyY2U6IGB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAgICAgICAgIHZlYzQgdiA9ICR7Z2xzbC50ZXh0dXJlMkR9KFgsIFRleENvb3Jkcyk7XG4gICAgICAgICAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdjtcbiAgICAgICAgICAgICAgICB9YCxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgZGltID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBpZiAoZGltIDwgMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgb3V0cHV0IGRpbWVuc2lvbiBzaG91bGQgYmUgYXQgbGVhc3QgMiwgYnV0IGdvdCAke2RpbX1gKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dEhlaWdodCA9IG91dHB1dFNoYXBlW2RpbSAtIDJdO1xuICBjb25zdCBvdXRwdXRXaWR0aCA9IG91dHB1dFNoYXBlW2RpbSAtIDFdO1xuXG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgaWYgKGRpbSAhPT0gaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dCBkaW1lbnNpb24gc2hvdWxkIG1hdGNoIGlucHV0ICR7aW5wdXRTaGFwZS5sZW5ndGh9LCBidXQgZ290ICR7ZGltfWApO1xuICB9XG4gIGNvbnN0IGlucHV0SGVpZ2h0ID0gaW5wdXRTaGFwZVtkaW0gLSAyXTtcbiAgY29uc3QgaW5wdXRXaWR0aCA9IGlucHV0U2hhcGVbZGltIC0gMV07XG5cbiAgY29uc3Qgc2NhbGVzSGVpZ2h0ID0gc2NhbGVzW2RpbSAtIDJdO1xuICBjb25zdCBzY2FsZXNXaWR0aCA9IHNjYWxlc1tkaW0gLSAxXTtcblxuICBsZXQgZ2V0U291cmNlRnJhY0luZGV4ID0gJyc7XG5cbiAgaWYgKGF0dHJpYnV0ZXMubW9kZSAhPT0gJ2xpbmVhcicpIHtcbiAgICAvLyBUT0RPOiBzdXBwb3J0IG90aGVyIG1vZGVzXG4gICAgdGhyb3cgbmV3IEVycm9yKGByZXNpemUgKHBhY2tlZCkgZG9lcyBub3Qgc3VwcG9ydCBtb2RlOiAnJHthdHRyaWJ1dGVzLm1vZGV9J2ApO1xuICB9XG4gIHN3aXRjaCAoYXR0cmlidXRlcy5jb29yZGluYXRlVHJhbnNmb3JtTW9kZSkge1xuICAgIGNhc2UgJ2FzeW1tZXRyaWMnOlxuICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0KGNvb3JkcykgLyBzY2FsZVdIV0g7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnaGFsZl9waXhlbCc6XG4gICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2ZWM0KGNvb3JkcykgKyAwLjUpIC8gc2NhbGVXSFdIIC0gMC41O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3B5dG9yY2hfaGFsZl9waXhlbCc6XG4gICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCBmY29vcmRzID0gdmVjNChjb29yZHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZlYzQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRXaWR0aH0uMCA+IDEuMCA/IChmY29vcmRzLnggKyAwLjUpIC8gc2NhbGVXSFdILnggLSAwLjUgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgPiAxLjAgPyAoZmNvb3Jkcy55ICsgMC41KSAvIHNjYWxlV0hXSC55IC0gMC41IDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0V2lkdGh9LjAgPiAxLjAgPyAoZmNvb3Jkcy56ICsgMC41KSAvIHNjYWxlV0hXSC56IC0gMC41IDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0SGVpZ2h0fS4wID4gMS4wID8gKGZjb29yZHMudyArIDAuNSkgLyBzY2FsZVdIV0gudyAtIDAuNSA6IDAuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2FsaWduX2Nvcm5lcnMnOlxuICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQgcmVzaXplZCA9IHZlYzQoJHtvdXRwdXRXaWR0aH0uMCAtIDEuMCwgJHtvdXRwdXRIZWlnaHR9LjAgLSAxLjAsICR7b3V0cHV0V2lkdGh9LjAgLSAxLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgLSAxLjApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCBvcmlnaW5hbCA9IHZlYzQoJHtpbnB1dFdpZHRofS4wIC0gMS4wLCAke2lucHV0SGVpZ2h0fS4wIC0gMS4wLCAke2lucHV0V2lkdGh9LjAgLSAxLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpbnB1dEhlaWdodH0uMCAtIDEuMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWM0IG5ld19zY2FsZSA9IG9yaWdpbmFsIC8gcmVzaXplZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0KGNvb3JkcykgKiBuZXdfc2NhbGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIFRPRE86c3VwcG9ydGluZyBvdGhlciBjb29yZGluYXRlVHJhbnNmb3JtTW9kZXNcbiAgICAgIHRocm93IG5ldyBFcnJvcihgcmVzaXplIChwYWNrZWQpIGRvZXMgbm90IHN1cHBvcnQgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGU6IFxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcke2F0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGV9J2ApO1xuICB9XG5cbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShkaW0pO1xuICBjb25zdCB1bnBhY2tDaGFubmVsID0gdW5wYWNrRnJvbUNoYW5uZWwoKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAgICAgY29uc3QgdmVjMiBpbnB1dFdIID0gdmVjMigke2lucHV0SGVpZ2h0fS4wLCAke2lucHV0V2lkdGh9LjApO1xuICAgICAgICAgICAgY29uc3QgdmVjNCBzY2FsZVdIV0ggPSB2ZWM0KGZsb2F0KCR7c2NhbGVzSGVpZ2h0fSksIGZsb2F0KCR7c2NhbGVzV2lkdGh9KSwgZmxvYXQoJHtzY2FsZXNIZWlnaHR9KSwgZmxvYXQoJHtcbiAgICAgICAgICAgICAgc2NhbGVzV2lkdGhcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICR7dW5wYWNrQ2hhbm5lbH1cbiAgICAgICAgICAgICR7Z2V0U291cmNlRnJhY0luZGV4fVxuICAgICAgICAgICAgZmxvYXQgZ2V0QVZhbHVlKGludCB4MTAsIGludCByLCBpbnQgYywgaW50IGQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChnZXRBKHgxMCwgciwgYywgZCksIHZlYzIoYywgZCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICAgICAgICAgICR7Y29vcmRzRGF0YVR5cGV9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAgICAgICAgICBpbnQgYmF0Y2ggPSByY1swXTtcbiAgICAgICAgICAgICAgICBpbnQgZGVwdGggPSByY1sxXTtcblxuICAgICAgICAgICAgICAgIC8vIHJldHJpZXZlIHRoZSA0IGNvb3JkaW5hdGVzIHRoYXQgaXMgdXNlZCBpbiB0aGUgNCBwYWNrZWQgb3V0cHV0IHZhbHVlcy5cbiAgICAgICAgICAgICAgICBpdmVjNCBjb29yZHMgPSBpdmVjNChyYy53eiwgcmMudyArIDEsIHJjLnogKyAxKTtcblxuICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgc291cmNlIGluZGV4IGluIGZyYWN0aW9uXG4gICAgICAgICAgICAgICAgdmVjNCBzb3VyY2VGcmFjID0gZ2V0U291cmNlRnJhY0luZGV4KGNvb3Jkcyk7XG5cbiAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGxvd2VyIGFuZCB1cHBlciBib3VuZCBvZiB0aGUgNCB2YWx1ZXMgdGhhdCB3aWxsIGJlIHBhY2tlZCBpbnRvIG9uZSB0ZXhlbC5cbiAgICAgICAgICAgICAgICBpdmVjNCB4MDAgPSBpdmVjNChtYXgoc291cmNlRnJhYy54eSwgdmVjMigwLjApKSwgbWluKGlucHV0V0ggLSAxLjAsIGNlaWwoc291cmNlRnJhYy54eSkpKTtcbiAgICAgICAgICAgICAgICBpdmVjNCB4MDEgPSBpdmVjNChtYXgoc291cmNlRnJhYy54dywgdmVjMigwLjApKSwgbWluKGlucHV0V0ggLSAxLjAsIGNlaWwoc291cmNlRnJhYy54dykpKTtcbiAgICAgICAgICAgICAgICBpdmVjNCB4MTAgPSBpdmVjNChtYXgoc291cmNlRnJhYy56eSwgdmVjMigwLjApKSwgbWluKGlucHV0V0ggLSAxLjAsIGNlaWwoc291cmNlRnJhYy56eSkpKTtcbiAgICAgICAgICAgICAgICBpdmVjNCB4MTEgPSBpdmVjNChtYXgoc291cmNlRnJhYy56dywgdmVjMigwLjApKSwgbWluKGlucHV0V0ggLSAxLjAsIGNlaWwoc291cmNlRnJhYy56dykpKTtcblxuICAgICAgICAgICAgICAgIGJvb2wgaGFzTmV4dFJvdyA9IHJjLncgPCAke291dHB1dEhlaWdodCAtIDF9O1xuICAgICAgICAgICAgICAgIGJvb2wgaGFzTmV4dENvbCA9IHJjLnogPCAke291dHB1dFdpZHRoIC0gMX07XG5cbiAgICAgICAgICAgICAgICAvLyBwYWNrIHgwMCwgeDAxLCB4MTAsIHgxMSdzIHRvcC1sZWZ0IGNvcm5lciBpbnRvIG9uZSB2ZWM0IHN0cnVjdHVyZVxuICAgICAgICAgICAgICAgIHZlYzQgdG9wTGVmdCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC54LCB4MDAueSksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueCwgeDAxLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLngsIHgxMC55KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueCwgeDExLnkpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgdG9wLXJpZ2h0IGNvcm5lciBpbnRvIG9uZSB2ZWM0IHN0cnVjdHVyZVxuICAgICAgICAgICAgICAgIHZlYzQgdG9wUmlnaHQgPSB2ZWM0KFxuICAgICAgICAgICAgICAgICAgICBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDAueCwgeDAwLncpLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Q29sID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAxLngsIHgwMS53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMC54LCB4MTAudykgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIChoYXNOZXh0Um93ICYmIGhhc05leHRDb2wpID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDExLngsIHgxMS53KSA6IDAuMCk7XG5cbiAgICAgICAgICAgICAgICAvLyBwYWNrIHgwMCwgeDAxLCB4MTAsIHgxMSdzIGJvdHRvbS1sZWZ0IGNvcm5lciBpbnRvIG9uZSB2ZWM0IHN0cnVjdHVyZVxuICAgICAgICAgICAgICAgIHZlYzQgYm90dG9tTGVmdCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC56LCB4MDAueSksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueiwgeDAxLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLnosIHgxMC55KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueiwgeDExLnkpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgYm90dG9tLXJpZ2h0IGNvcm5lciBpbnRvIG9uZSB2ZWM0IHN0cnVjdHVyZVxuICAgICAgICAgICAgICAgIHZlYzQgYm90dG9tUmlnaHQgPSB2ZWM0KFxuICAgICAgICAgICAgICAgICAgICBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDAueiwgeDAwLncpLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Q29sID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAxLnosIHgwMS53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMC56LCB4MTAudykgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIChoYXNOZXh0Um93ICYmIGhhc05leHRDb2wpID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDExLnosIHgxMS53KSA6IDAuMCk7XG5cbiAgICAgICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIGludGVycG9sYXRpb24gZnJhY3Rpb24gb24gdSBhbmQgdiBkaXJlY3Rpb25cbiAgICAgICAgICAgICAgICB2ZWM0IGZyYWMgPSB2ZWM0KHNvdXJjZUZyYWMpIC0gZmxvb3Ioc291cmNlRnJhYyk7XG4gICAgICAgICAgICAgICAgdmVjNCBjbGFtcEZyYWMgPSBjbGFtcChmcmFjLCB2ZWM0KDAuMCksIHZlYzQoMS4wKSk7XG5cbiAgICAgICAgICAgICAgICB2ZWM0IHRvcCA9IG1peCh0b3BMZWZ0LCB0b3BSaWdodCwgY2xhbXBGcmFjLnl3eXcpO1xuICAgICAgICAgICAgICAgIHZlYzQgYm90dG9tID0gbWl4KGJvdHRvbUxlZnQsIGJvdHRvbVJpZ2h0LCBjbGFtcEZyYWMueXd5dyk7XG4gICAgICAgICAgICAgICAgdmVjNCBuZXdWYWx1ZSA9IG1peCh0b3AsIGJvdHRvbSwgY2xhbXBGcmFjLnh4enopO1xuXG4gICAgICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KG5ld1ZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5yZXNpemVQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIGhhc01haW46IHRydWUsXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgcHJlcGFyZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMpOiBbcmVhZG9ubHkgbnVtYmVyW10sIHJlYWRvbmx5IG51bWJlcltdXSA9PiB7XG4gIGNvbnN0IHggPSBpbnB1dHNbMF07XG4gIGNvbnN0IHhEaW1zID0geC5kaW1zO1xuXG4gIGxldCBzY2FsZXMgPSBhdHRyaWJ1dGVzLnNjYWxlcztcbiAgbGV0IG91dHB1dFNpemVzOiBudW1iZXJbXSB8IHVuZGVmaW5lZDtcbiAgaWYgKHNjYWxlcy5sZW5ndGggPT09IDApIHtcbiAgICBjb25zdCBzY2FsZXNUZW5zb3IgPSBpbnB1dHNbYXR0cmlidXRlcy5zY2FsZXNJbnB1dElkeF07XG4gICAgaWYgKHNjYWxlc1RlbnNvciAmJiBzY2FsZXNUZW5zb3Iuc2l6ZSAhPT0gMCkge1xuICAgICAgaWYgKGlucHV0c1thdHRyaWJ1dGVzLnNpemVzSW5wdXRJZHhdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2Ygc2NhbGVzIG9yIHNpemVzIG11c3QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgICB9XG4gICAgICBzY2FsZXMgPSBwYXJzZVNjYWxlc0RhdGEoc2NhbGVzVGVuc29yLCBhdHRyaWJ1dGVzLm1vZGUsIGF0dHJpYnV0ZXMuaXNSZXNpemUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzaXplc1RlbnNvciA9IGlucHV0c1thdHRyaWJ1dGVzLnNpemVzSW5wdXRJZHhdO1xuICAgICAgaWYgKCFzaXplc1RlbnNvciB8fCBzaXplc1RlbnNvci5zaXplID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRWl0aGVyIHNjYWxlcyBvciBzaXplcyBNVVNUIGJlIHByb3ZpZGVkIGFzIGlucHV0LicpO1xuICAgICAgfVxuXG4gICAgICBvdXRwdXRTaXplcyA9IEFycmF5LmZyb20oc2l6ZXNUZW5zb3IuaW50ZWdlckRhdGEpO1xuICAgICAgc2NhbGVzID0gcGFyc2VTY2FsZXNEYXRhRnJvbU91dHB1dFNpemUob3V0cHV0U2l6ZXMsIHhEaW1zLCBhdHRyaWJ1dGVzLm1vZGUsIGF0dHJpYnV0ZXMuaXNSZXNpemUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoaW5wdXRzW2F0dHJpYnV0ZXMuc2l6ZXNJbnB1dElkeF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2Ygc2NhbGVzIG9yIHNpemVzIG11c3QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgeURpbXMgPSBvdXRwdXRTaXplcyB8fCB4RGltcy5tYXAoKGRpbSwgaSkgPT4gTWF0aC5mbG9vcihkaW0gKiBzY2FsZXNbaV0pKTtcblxuICByZXR1cm4gW3NjYWxlcywgeURpbXNdO1xufTtcblxuY29uc3QgcGFyc2VTY2FsZXNEYXRhID0gKHNjYWxlOiBUZW5zb3IsIG1vZGU6IHN0cmluZywgaXNSZXNpemU6IGJvb2xlYW4pOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IHNjYWxlcyA9IEFycmF5LmZyb20oc2NhbGUuZmxvYXREYXRhKTtcbiAgc2NhbGVzVmFsaWRhdGlvbihzY2FsZXMsIG1vZGUsIGlzUmVzaXplKTtcbiAgcmV0dXJuIHNjYWxlcztcbn07XG5cbmNvbnN0IHBhcnNlU2NhbGVzRGF0YUZyb21PdXRwdXRTaXplID0gKFxuICB5RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHhEaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgbW9kZTogc3RyaW5nLFxuICBpc1Jlc2l6ZTogYm9vbGVhbixcbik6IG51bWJlcltdID0+IHtcbiAgY29uc3QgbGVuZ3RoID0geERpbXMubGVuZ3RoO1xuICBjb25zdCBzY2FsZXMgPSBuZXcgQXJyYXk8bnVtYmVyPihsZW5ndGgpO1xuXG4gIGZvciAobGV0IGkgPSAwLCBlbmQgPSBsZW5ndGg7IGkgPCBlbmQ7IGkrKykge1xuICAgIGlmICh4RGltc1tpXSA9PT0gMCkge1xuICAgICAgaWYgKHlEaW1zW2ldICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgZGltIGlzIHplcm8gYnV0IHJlcXVpcmVkIG91dHB1dCBkaW0gaXMgbm9uLXplcm8uJyk7XG4gICAgICB9XG4gICAgICBzY2FsZXNbaV0gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZXNbaV0gPSB5RGltc1tpXSAvIHhEaW1zW2ldO1xuICAgIH1cbiAgfVxuICBzY2FsZXNWYWxpZGF0aW9uKHNjYWxlcywgbW9kZSwgaXNSZXNpemUpO1xuICByZXR1cm4gc2NhbGVzO1xufTtcblxuLy8gcm9pIGRhdGEgaXMgbm90IHVzZWQgeWV0LiBidXQgbGVhdmUgaGVyZSBmb3IgZnV0dXJlIHVzYWdlLlxuLy8gY29uc3QgZ2V0Um9pID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcykgOiBudW1iZXJbXSA9PiB7XG4vLyAgICAgbGV0IHJvaTogbnVtYmVyW10gPSBbXTtcbi8vICAgICBpZiAoYXR0cmlidXRlcy5uZWVkUm9pSW5wdXQpIHtcbi8vICAgICAgICAgaWYgKGF0dHJpYnV0ZXMucm9pSW5wdXRJZHggPD0gMCkge1xuLy8gICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJvaSBpbnB1dCBpbmRleC4nKTtcbi8vICAgICAgICAgfVxuLy8gICAgICAgICBjb25zdCByb2lUZW5zb3IgPSBpbnB1dHNbYXR0cmlidXRlcy5yb2lJbnB1dElkeF07XG4vLyAgICAgICAgIHJvaSA9IHJvaVRlbnNvci5zaXplID4gMCA/IEFycmF5LmZyb20ocm9pVGVuc29yLmZsb2F0RGF0YSkgOiBbXTtcbi8vICAgICB9IGVsc2Uge1xuLy8gICAgICAgICByb2kgPSBuZXcgQXJyYXkoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICogMikuZmlsbCgwKTtcbi8vICAgICB9XG4vLyAgICAgcmV0dXJuIHJvaTtcbi8vIH07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBzaGFwZSA9IChfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICByZXR1cm4gW25ldyBUZW5zb3IoW2lucHV0c1swXS5kaW1zLmxlbmd0aF0sICdpbnQzMicsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBuZXcgSW50MzJBcnJheShpbnB1dHNbMF0uZGltcykpXTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBOVU1CRVJfVFlQRVMsIE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNsaWNlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4ZXM6IG51bWJlcltdO1xuICByZWFkb25seSBlbmRzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgc3RhcnRzOiBudW1iZXJbXTtcbn1cblxuY29uc3Qgc2xpY2VQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTbGljZScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHNsaWNlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNsaWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5zbGljZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTbGljZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U2xpY2VBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogU2xpY2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3Qgc3RhcnRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3N0YXJ0cycpO1xuICBjb25zdCBlbmRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2VuZHMnKTtcbiAgY29uc3QgYXhlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJywgW10pO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgc3RhcnRzLCBlbmRzLCBheGVzIH0pO1xufTtcblxuY29uc3QgY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyA9IChcbiAgX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBheGVzID0gYXR0cmlidXRlcy5heGVzLmxlbmd0aCA9PT0gMCA/IGlucHV0LmRpbXMuc2xpY2UoMCkubWFwKChfdmFsLCBpKSA9PiBpKSA6IGF0dHJpYnV0ZXMuYXhlcztcbiAgY29uc3Qgbm9ybWFsaXplZEF4ZXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhlcyhheGVzLCBpbnB1dC5kaW1zLmxlbmd0aCk7XG4gIGNvbnN0IHN0YXJ0cyA9IGF0dHJpYnV0ZXMuc3RhcnRzLm1hcCgoc3RhcnQsIGkpID0+IHtcbiAgICBpZiAoc3RhcnQgPiBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSAtIDEpIHtcbiAgICAgIHJldHVybiBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXTtcbiAgICB9XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKHN0YXJ0LCBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSk7XG4gIH0pO1xuICBjb25zdCBlbmRzID0gYXR0cmlidXRlcy5lbmRzLm1hcCgoZW5kLCBpKSA9PiB7XG4gICAgaWYgKGVuZCA+IGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dIC0gMSkge1xuICAgICAgcmV0dXJuIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoZW5kLCBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSk7XG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXQuZGltcy5zbGljZSgpO1xuXG4gIGNvbnN0IHNsaWNlT3BzOiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5vcm1hbGl6ZWRBeGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0cHV0U2hhcGVbbm9ybWFsaXplZEF4ZXNbaV1dID0gZW5kc1tpXSAtIHN0YXJ0c1tpXTtcbiAgICBpZiAoc3RhcnRzW2ldID4gMCkge1xuICAgICAgc2xpY2VPcHMucHVzaChgb3V0cHV0SWR4WyR7bm9ybWFsaXplZEF4ZXNbaV19XSArPSAke3N0YXJ0c1tpXX07YCk7XG4gICAgfSAvLyBlbHNlIHsgc2xpY2VPcHMucHVzaChgb3V0cHV0SWR4WyR7bm9ybWFsaXplZEF4ZXNbaV19XSArPSAwO2ApOyB9XG4gIH1cblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtyYW5rfV0pIHtcbiAgICAgICAgJHtzbGljZU9wcy5qb2luKCdcXG4gICAgICAnKX1cbiAgICAgICAgcmV0dXJuIF9BKG91dHB1dElkeCk7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zbGljZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2xpY2UgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2xpY2VWMTAgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0c1YxMChpbnB1dHMpO1xuICBjb25zdCBhdHRyaWJ1dGVzID0gZ2VuZXJhdGVTbGljZUF0dHJpYnV0ZXNGcm9tSW5wdXRzKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnNsaWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVTbGljZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBbaW5wdXRzWzBdXSxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgZ2VuZXJhdGVTbGljZUF0dHJpYnV0ZXNGcm9tSW5wdXRzID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4pOiBTbGljZUF0dHJpYnV0ZXMgPT4ge1xuICBpZiAoXG4gICAgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1sxXS5kYXRhSWQpIHx8XG4gICAgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1syXS5kYXRhSWQpIHx8XG4gICAgKGlucHV0cy5sZW5ndGggPj0gNCAmJiAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzNdLmRhdGFJZCkpIHx8XG4gICAgKGlucHV0cy5sZW5ndGggPj0gNSAmJiAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzRdLmRhdGFJZCkpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignZHluYW1pYyBzbGljZSBhdHRyaWJ1dGVzIGFyZSBub3QgYWxsb3dlZCcpO1xuICB9XG5cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gNSAmJiBpbnB1dHNbNF0uaW50ZWdlckRhdGEuc29tZSgoaTogbnVtYmVyKSA9PiBpICE9PSAxKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG5vbi0xIHN0ZXBzIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIFNsaWNlJyk7XG4gIH1cblxuICBjb25zdCBzdGFydHMgPSBBcnJheS5mcm9tKGlucHV0c1sxXS5pbnRlZ2VyRGF0YSk7XG4gIGNvbnN0IGVuZHMgPSBBcnJheS5mcm9tKGlucHV0c1syXS5pbnRlZ2VyRGF0YSk7XG4gIGNvbnN0IGF4ZXMgPSBpbnB1dHMubGVuZ3RoID49IDQgPyBBcnJheS5mcm9tKGlucHV0c1szXS5pbnRlZ2VyRGF0YSkgOiBbXTtcbiAgY29uc3QgY2FjaGVLZXkgPSBgJHtheGVzfTske3N0YXJ0c307JHtlbmRzfWA7XG4gIHJldHVybiB7IHN0YXJ0cywgZW5kcywgYXhlcywgY2FjaGVLZXkgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjEwID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA8IDMgfHwgaW5wdXRzLmxlbmd0aCA+IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgbnVtYmVyLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJyB8fCBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzJdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gNCAmJiAoaW5wdXRzWzNdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzNdLmRpbXMubGVuZ3RoICE9PSAxKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID49IDUgJiYgKGlucHV0c1s0XS50eXBlICE9PSAnaW50MzInIHx8IGlucHV0c1s0XS5kaW1zLmxlbmd0aCAhPT0gMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IHRyYW5zcG9zZSwgVHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuZXhwb3J0IGludGVyZmFjZSBTb2Z0bWF4QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4aXM6IG51bWJlcjtcbn1cblxuY29uc3Qgc29mdG1heENvbXB1dGVNYXhQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTb2Z0bWF4Q29tcHV0ZU1heCcsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3Qgc29mdG1heENvbXB1dGVTY2FsZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NvZnRtYXhDb21wdXRlU2NhbGUnLFxuICBpbnB1dE5hbWVzOiBbJ0EnLCAnTWF4J10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3Qgc29mdG1heFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NvZnRNYXgnLFxuICBpbnB1dE5hbWVzOiBbJ0EnLCAnTWF4JywgJ05vcm0nXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHNvZnRtYXg6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFNvZnRtYXhBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXR0cmlidXRlcy5heGlzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IGxvZ2ljYWxSb3dDb3VudCA9IFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24oaW5wdXRTaGFwZSwgYXhpcyk7XG4gIGNvbnN0IGZlYXR1cmVDb3VudCA9IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbihpbnB1dFNoYXBlLCBheGlzKTtcblxuICBjb25zdCBvdXRwdXQgPSBjb21wdXRlU29mdG1heChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsIGxvZ2ljYWxSb3dDb3VudCwgZmVhdHVyZUNvdW50KTtcbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFNvZnRtYXhBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFNvZnRtYXhBdHRyaWJ1dGVzID0+IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXM6IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAxKSB9KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU29mdG1heEF0dHJpYnV0ZXNWMTM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogU29mdG1heEF0dHJpYnV0ZXMgPT4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIC0xKSB9KTtcblxuLy8gVGhlIFwic2VtYW50aWNcIiBtZWFuaW5nIG9mIGF4aXMgaGFzIGNoYW5nZWQgaW4gb3BzZXQtMTMuXG4vLyBQbGVhc2UgY29tcGFyZTogaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjU29mdG1heFxuLy8gd2l0aCBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL0NoYW5nZWxvZy5tZCNTb2Z0bWF4LTExIGZvciBkZXRhaWxlZCBleHBsYW5hdGlvbnNcbi8vIFRvIGFjY291bnQgZm9yIHRoZSBvcHNldC0xMyBiZWhhdmlvciwgb3VyIHBsYW4gd2lsbCBiZSB0byB0cmFuc3Bvc2UgdGhlIFwiYXhpc1wiIGRpbSB0byB0aGUgaW5uZXJtb3N0IGRpbVxuLy8gYW5kIHBlcmZvcm0gc29mdG1heCBhbmQgdGhlbiByZXZlcnNlIHRoZSB0cmFuc3Bvc2UuIFdlIGNhbiBza2lwIHRoZSB0cmFuc3Bvc2luZyBhc3BlY3QgaWYgdGhlIGF4aXMgaXMgYWxyZWFkeVxuLy8gdGhlIGlubmVybW9zdCBkaW1cbmV4cG9ydCBjb25zdCBzb2Z0bWF4VjEzOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNvZnRtYXhBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBTb2Z0bWF4QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCByYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3QgaXNUcmFuc3Bvc2VSZXF1aXJlZCA9IGF4aXMgIT09IHJhbmsgLSAxID8gdHJ1ZSA6IGZhbHNlO1xuICBjb25zdCB0cmFuc3Bvc2VkSW5wdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgbGV0IHBlcm06IG51bWJlcltdID0gW107XG4gIGxldCB0cmFuc3Bvc2VkSW5wdXRzOiBUZW5zb3JbXSA9IFtdO1xuICBsZXQgdHJhbnNwb3NlQXR0cmlidXRlOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzO1xuXG4gIGlmIChpc1RyYW5zcG9zZVJlcXVpcmVkKSB7XG4gICAgcGVybSA9IEFycmF5LmZyb20oeyBsZW5ndGg6IHJhbmsgfSkubWFwKChfLCBpKSA9PiBpKTtcblxuICAgIC8vIHN3YXAgdGhlIGlubmVybW9zdCBkaW0gd2l0aCB0aGUgZGltIGNvcnJlc3BvbmRpbmcgdG8gYXhpc1xuICAgIHBlcm1bYXhpc10gPSByYW5rIC0gMTtcbiAgICBwZXJtW3JhbmsgLSAxXSA9IGF4aXM7XG5cbiAgICBwZXJtLm1hcCgocCkgPT4gdHJhbnNwb3NlZElucHV0U2hhcGUucHVzaChpbnB1dFNoYXBlW3BdKSk7XG5cbiAgICB0cmFuc3Bvc2VBdHRyaWJ1dGUgPSBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBwZXJtIH0pO1xuICAgIHRyYW5zcG9zZWRJbnB1dHMgPSB0cmFuc3Bvc2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCB0cmFuc3Bvc2VBdHRyaWJ1dGUpO1xuICB9XG5cbiAgY29uc3QgbG9naWNhbFJvd0NvdW50ID0gaXNUcmFuc3Bvc2VSZXF1aXJlZFxuICAgID8gU2hhcGVVdGlsLnNpemVUb0RpbWVuc2lvbih0cmFuc3Bvc2VkSW5wdXRTaGFwZSwgcmFuayAtIDEpXG4gICAgOiBTaGFwZVV0aWwuc2l6ZVRvRGltZW5zaW9uKGlucHV0U2hhcGUsIHJhbmsgLSAxKTtcbiAgY29uc3QgZmVhdHVyZUNvdW50ID0gaXNUcmFuc3Bvc2VSZXF1aXJlZFxuICAgID8gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKHRyYW5zcG9zZWRJbnB1dFNoYXBlLCByYW5rIC0gMSlcbiAgICA6IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbihpbnB1dFNoYXBlLCByYW5rIC0gMSk7XG5cbiAgY29uc3Qgb3V0cHV0ID0gY29tcHV0ZVNvZnRtYXgoXG4gICAgaW5mZXJlbmNlSGFuZGxlcixcbiAgICBpc1RyYW5zcG9zZVJlcXVpcmVkID8gdHJhbnNwb3NlZElucHV0cyA6IGlucHV0cyxcbiAgICBhdHRyaWJ1dGVzLFxuICAgIGxvZ2ljYWxSb3dDb3VudCxcbiAgICBmZWF0dXJlQ291bnQsXG4gICk7XG5cbiAgaWYgKGlzVHJhbnNwb3NlUmVxdWlyZWQpIHtcbiAgICBjb25zdCByZXZlcnNlZE91dHB1dCA9IHRyYW5zcG9zZShpbmZlcmVuY2VIYW5kbGVyLCBvdXRwdXQsIHRyYW5zcG9zZUF0dHJpYnV0ZSEpO1xuICAgIHJldHVybiByZXZlcnNlZE91dHB1dDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG59O1xuXG5jb25zdCBjb21wdXRlU29mdG1heCA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBTb2Z0bWF4QXR0cmlidXRlcyxcbiAgbG9naWNhbFJvd0NvdW50OiBudW1iZXIsXG4gIGZlYXR1cmVDb3VudDogbnVtYmVyLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBjb21wdXRlTWF4UHJvZ3JhbUluZm8gPSBjcmVhdGVDb21wdXRlTWF4UHJvZ3JhbUluZm8oXG4gICAgaW5mZXJlbmNlSGFuZGxlcixcbiAgICBpbnB1dHNbMF0sXG4gICAgbG9naWNhbFJvd0NvdW50LFxuICAgIGZlYXR1cmVDb3VudCxcbiAgICBbbG9naWNhbFJvd0NvdW50XSxcbiAgKTtcbiAgY29uc3QgbWF4ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5zb2Z0bWF4Q29tcHV0ZU1heFByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBnZXQ6ICgpID0+IGNvbXB1dGVNYXhQcm9ncmFtSW5mbyB9LFxuICAgIGlucHV0cyxcbiAgKTtcblxuICBjb25zdCBjb21wdXRlU2NhbGVQcm9ncmFtSW5mbyA9IGNyZWF0ZUNvbXB1dFNjYWxlUHJvZ3JhbUluZm8oXG4gICAgaW5mZXJlbmNlSGFuZGxlcixcbiAgICBpbnB1dHNbMF0sXG4gICAgbG9naWNhbFJvd0NvdW50LFxuICAgIGZlYXR1cmVDb3VudCxcbiAgICBjb21wdXRlTWF4UHJvZ3JhbUluZm8ub3V0cHV0LmRpbXMsXG4gICAgW2xvZ2ljYWxSb3dDb3VudF0sXG4gICk7XG4gIGNvbnN0IHNjYWxlID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5zb2Z0bWF4Q29tcHV0ZVNjYWxlUHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGdldDogKCkgPT4gY29tcHV0ZVNjYWxlUHJvZ3JhbUluZm8gfSxcbiAgICBbaW5wdXRzWzBdLCBtYXhdLFxuICApO1xuXG4gIGNvbnN0IHNvZnRNYXhQcm9ncmFtSW5mbyA9IGNyZWF0ZVNvZnRNYXhQcm9ncmFtSW5mbyhcbiAgICBpbmZlcmVuY2VIYW5kbGVyLFxuICAgIGlucHV0c1swXSxcbiAgICBsb2dpY2FsUm93Q291bnQsXG4gICAgZmVhdHVyZUNvdW50LFxuICAgIGNvbXB1dGVNYXhQcm9ncmFtSW5mby5vdXRwdXQuZGltcyxcbiAgICBjb21wdXRlU2NhbGVQcm9ncmFtSW5mby5vdXRwdXQuZGltcyxcbiAgKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5zb2Z0bWF4UHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGdldDogKCkgPT4gc29mdE1heFByb2dyYW1JbmZvIH0sXG4gICAgW2lucHV0c1swXSwgbWF4LCBzY2FsZV0sXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgdGV4dHVyZSB0aGF0IGNvbnRhaW5zIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGVhY2ggb2YgdGhlICdOJyByb3dzXG4gKi9cbmNvbnN0IGNyZWF0ZUNvbXB1dGVNYXhQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBsb2dpY2FsUm93Q291bnQ6IG51bWJlcixcbiAgZmVhdHVyZUNvdW50OiBudW1iZXIsXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBpbnB1dC5kaW1zLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gIGlmIChsb2dpY2FsUm93Q291bnQgPCAxIHx8IGZlYXR1cmVDb3VudCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvZ2ljYWwgcm93IGNvdW50IE4gYW5kIGZlYXR1cmUgY291bnQgRCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gIH1cblxuICBpZiAob3V0cHV0U2hhcGUubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSAxJyk7XG4gIH1cblxuICBpZiAob3V0cHV0U2hhcGVbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgfVxuXG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgICAgICBpbnQgbG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ID0gaW5kaWNlc1swXSAqICR7ZmVhdHVyZUNvdW50fTtcblxuICAgICAgICBmbG9hdCBtYXggPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgb2Zmc2V0VG9Db29yZHMobG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0LCAke3RleHR1cmVXaWR0aH0sXG4gICAgICAgICR7dGV4dHVyZUhlaWdodH0gKSkpO1xuICAgICAgICBmb3IoaW50IGk9MTsgaTwke2ZlYXR1cmVDb3VudH07ICsraSlcbiAgICAgICAge1xuICAgICAgICAgIGZsb2F0IGN1cnJlbnQgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgb2Zmc2V0VG9Db29yZHMobG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ICsgaSxcbiAgICAgICAgICAgICR7dGV4dHVyZVdpZHRofSwgJHt0ZXh0dXJlSGVpZ2h0fSkpKTtcbiAgICAgICAgICBpZihjdXJyZW50ID4gbWF4KVxuICAgICAgICAgIG1heCA9IGN1cnJlbnQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWF4O1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4uc29mdG1heENvbXB1dGVNYXhQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIHRleHR1cmUgdGhhdCBjb250YWlucyB0aGUgbm9ybWFsaXphdGlvbiBmYWN0b3IgZm9yIGVhY2ggb2YgdGhlICdOJyByb3dzXG4gKi9cbmNvbnN0IGNyZWF0ZUNvbXB1dFNjYWxlUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgbG9naWNhbFJvd0NvdW50OiBudW1iZXIsXG4gIGZlYXR1cmVDb3VudDogbnVtYmVyLFxuICBtYXhFbGVtZW50UGVyTG9naWNhbFJvdzogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBpbnB1dC5kaW1zLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gIGlmIChsb2dpY2FsUm93Q291bnQgPCAxIHx8IGZlYXR1cmVDb3VudCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvZ2ljYWwgcm93IGNvdW50IE4gYW5kIGZlYXR1cmUgY291bnQgRCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gIH1cblxuICBpZiAob3V0cHV0U2hhcGUubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSAxJyk7XG4gIH1cblxuICBpZiAob3V0cHV0U2hhcGVbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgfVxuXG4gIGlmIChtYXhFbGVtZW50UGVyTG9naWNhbFJvdy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgMScpO1xuICB9XG5cbiAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93WzBdICE9PSBsb2dpY2FsUm93Q291bnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgfVxuXG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgICAgICBpbnQgbG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ID0gaW5kaWNlc1swXSAqICR7ZmVhdHVyZUNvdW50fTtcblxuICAgICAgICBmbG9hdCBub3JtX2ZhY3RvciA9IDAuMDtcbiAgICAgICAgZmxvYXQgbWF4ID0gX01heChpbmRpY2VzKTtcbiAgICAgICAgZm9yKGludCBpPTA7IGk8JHtmZWF0dXJlQ291bnR9OyArK2kpXG4gICAgICAgIHtcbiAgICAgICAgICBub3JtX2ZhY3RvciArPSBleHAoZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIG9mZnNldFRvQ29vcmRzKGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCArIGksXG4gICAgICAgICAgICAke3RleHR1cmVXaWR0aH0sICR7dGV4dHVyZUhlaWdodH0pKSkgLSBtYXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vcm1fZmFjdG9yO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4uc29mdG1heENvbXB1dGVTY2FsZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZVNvZnRNYXhQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBsb2dpY2FsUm93Q291bnQ6IG51bWJlcixcbiAgZmVhdHVyZUNvdW50OiBudW1iZXIsXG4gIG1heEVsZW1lbnRQZXJMb2dpY2FsUm93OiByZWFkb25seSBudW1iZXJbXSxcbiAgbm9ybWFsaXphdGlvblBlckxvZ2ljYWxSb3c6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIGlucHV0LmRpbXMsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG4gIGNvbnN0IHJhbmsgPSBpbnB1dC5kaW1zLmxlbmd0aDtcblxuICBpZiAobG9naWNhbFJvd0NvdW50IDwgMSB8fCBmZWF0dXJlQ291bnQgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdMb2dpY2FsIHJvdyBjb3VudCBOIGFuZCBmZWF0dXJlIGNvdW50IEQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICB9XG5cbiAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93Lmxlbmd0aCAhPT0gMSB8fCBub3JtYWxpemF0aW9uUGVyTG9naWNhbFJvdy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgMScpO1xuICB9XG5cbiAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93WzBdICE9PSBsb2dpY2FsUm93Q291bnQgfHwgbm9ybWFsaXphdGlvblBlckxvZ2ljYWxSb3dbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIGludGVybWVkaWF0ZSByZXN1bHRzIHNob3VsZCBiZSBlcXVhbCB0byBsb2dpY2FsIHJvdyBjb3VudCcpO1xuICB9XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuXG4gICAgICAvLyBnZXQgb2Zmc2V0IG9mIGN1cnJlbnQgbG9naWNhbCB0ZW5zb3IgaW5kZXggZnJvbSB0aGUgMi1EIHRleHR1cmUgY29vcmRpbmF0ZXMgKFRleENvb3JkcylcbiAgICAgIGludCBvZmZzZXQgPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7dGV4dHVyZVdpZHRofSwgJHt0ZXh0dXJlSGVpZ2h0fSk7XG5cbiAgICAgIC8vZGV0ZXJtaW5lIHRoZSBsb2dpY2FsIHJvdyBmb3IgdGhpcyBpbmRleFxuICAgICAgaW50IGxvZ2ljYWxfcm93X2luZGV4WzFdO1xuICAgICAgbG9naWNhbF9yb3dfaW5kZXhbMF0gPSBvZmZzZXQgLyAke2ZlYXR1cmVDb3VudH07XG5cbiAgICAgIGZsb2F0IG5vcm1fZmFjdG9yID0gX05vcm0obG9naWNhbF9yb3dfaW5kZXgpO1xuXG4gICAgICAvLyBhdm9pZCBwb3NzaWJsZSBkaXZpc2lvbiBieSAwXG4gICAgICAvLyBpZiBub3JtX2ZhY29yIGlzIDAsIGFsbCBlbGVtZW50cyBhcmUgemVyb1xuICAgICAgLy8gaWYgc28sIHJldHVybiAwXG4gICAgICBpZihub3JtX2ZhY3RvciA9PSAwLjApXG4gICAgICAgIHJldHVybiAwLjA7XG5cbiAgICAgIHJldHVybiBleHAoX0EoaW5kaWNlcykgLSBfTWF4KGxvZ2ljYWxfcm93X2luZGV4KSkgLyBub3JtX2ZhY3RvcjtcbiAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zb2Z0bWF4UHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvZnRtYXggcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZScpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCwgU3BsaXRVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3BsaXRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xuICByZWFkb25seSBzcGxpdDogbnVtYmVyW107XG4gIHJlYWRvbmx5IG51bU91dHB1dHM6IG51bWJlcjtcbn1cblxuY29uc3Qgc3BsaXRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTcGxpdCcsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHNwbGl0OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNwbGl0QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG4gIGNvbnN0IGNvdW50ID0gZ2V0UHJvZ3JhbUNvdW50KGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXhpcywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IG91dHB1dDogVGVuc29yW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7XG4gICAgb3V0cHV0LnB1c2goXG4gICAgICBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAge1xuICAgICAgICAgIC4uLnNwbGl0UHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICAgIGNhY2hlSGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX07JHtpfWAsXG4gICAgICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVTcGxpdFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcywgYXhpcywgaSksXG4gICAgICAgIH0sXG4gICAgICAgIGlucHV0cyxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTcGxpdEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U3BsaXRBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogU3BsaXRBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXhpcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAwKTtcbiAgY29uc3Qgc3BsaXQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3BsaXQnLCBbXSk7XG4gIGNvbnN0IG51bU91dHB1dHMgPSBub2RlLm91dHB1dHMubGVuZ3RoO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpcywgc3BsaXQsIG51bU91dHB1dHMgfSk7XG59O1xuXG5jb25zdCBnZXRQcm9ncmFtQ291bnQgPSAoXG4gIF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4aXM6IG51bWJlcixcbiAgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzLFxuKTogbnVtYmVyID0+IHtcbiAgY29uc3QgWywgb2Zmc2V0c10gPSBTcGxpdFV0aWwuc3BsaXRTaGFwZShpbnB1dHNbMF0uZGltcywgYXhpcywgYXR0cmlidXRlcy5zcGxpdCwgYXR0cmlidXRlcy5udW1PdXRwdXRzKTtcbiAgcmV0dXJuIG9mZnNldHMubGVuZ3RoO1xufTtcblxuY29uc3QgY3JlYXRlU3BsaXRQcm9ncmFtSW5mbyA9IChcbiAgX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzLFxuICBheGlzOiBudW1iZXIsXG4gIGluZGV4OiBudW1iZXIsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFtzaGFwZXMsIG9mZnNldHNdID0gU3BsaXRVdGlsLnNwbGl0U2hhcGUoaW5wdXQuZGltcywgYXhpcywgYXR0cmlidXRlcy5zcGxpdCwgYXR0cmlidXRlcy5udW1PdXRwdXRzKTtcbiAgY29uc3Qgb2Zmc2V0ID0gb2Zmc2V0c1tpbmRleF07XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gc2hhcGVzW2luZGV4XTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbmRpY2VzWyR7YXhpc31dICs9ICR7b2Zmc2V0fTtcbiAgICAgICAgcmV0dXJuIF9BKGluZGljZXMpO1xuICAgICAgfVxuICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4uc3BsaXRQcm9ncmFtTWV0YWRhdGEsXG4gICAgY2FjaGVIaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fToke2luZGV4fWAsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NwbGl0IHJlcXVpcmVzIG9uZSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2ludDgnICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICd1aW50OCcgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2ludDE2JyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAndWludDE2JyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAnaW50MzInICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICd1aW50MzInICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2Jvb2wnXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3Qgc3F1ZWV6ZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxudW1iZXJbXT4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhlczogbnVtYmVyW10sXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gU2hhcGVVdGlsLnNxdWVlemVTaGFwZShpbnB1dHNbMF0uZGltcywgYXhlcyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgb3V0cHV0U2hhcGUpO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3Qgc3F1ZWV6ZVYxMyA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjEzKGlucHV0cyk7XG4gIHJldHVybiBzcXVlZXplKGluZmVyZW5jZUhhbmRsZXIsIFtpbnB1dHNbMF1dLCBBcnJheS5mcm9tKGlucHV0c1sxXS5pbnRlZ2VyRGF0YSkpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU3F1ZWV6ZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyW10+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBudW1iZXJbXSA9PlxuICBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnYXhlcycpO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NxdWVlemUgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgdGVuc29yIHR5cGVzLicpO1xuICB9XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YxMyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NxdWVlemUgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IHN1bSA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3Qgc3VtUHJvZ3JhbU1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdTdW0nLFxuICAgIGlucHV0TmFtZXM6IGlucHV0cy5tYXAoKF92LCBpKSA9PiBgWCR7aX1gKSxcbiAgICBpbnB1dFR5cGVzOiBuZXcgQXJyYXkoaW5wdXRzLmxlbmd0aCkuZmlsbChUZXh0dXJlVHlwZS51bnBhY2tlZCksXG4gIH07XG5cbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi5zdW1Qcm9ncmFtTWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlU3VtUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBzdW1Qcm9ncmFtTWV0YWRhdGEpIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5jb25zdCBjcmVhdGVTdW1Qcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBzdW1Qcm9ncmFtTWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IHN1bUxpbmUgPSBpbnB1dHMubWFwKChfdiwgaSkgPT4gYCR7Z2xzbC50ZXh0dXJlMkR9KFgke2l9LFRleENvb3JkcylgKS5qb2luKCcgKyAnKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICB2ZWM0IHJlc3VsdCA9ICR7c3VtTGluZX07XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfVxuICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4uc3VtUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIGhhc01haW46IHRydWUsXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTdW0gcmVxdWlyZXMgaW5wdXRzLicpO1xuICB9XG5cbiAgY29uc3QgbGVuZ3RoID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChsZW5ndGggIT09IGlucHV0c1tpXS5kaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBzaGFwZXMgYXJlIG1pc21hdGNoZWQuJyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBsZW5ndGg7IGorKykge1xuICAgICAgaWYgKGlucHV0c1swXS5kaW1zW2pdICE9PSBpbnB1dHNbaV0uZGltc1tqXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHNoYXBlcyBhcmUgbm90IG1hdGNoZWQuJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGlucHV0c1swXS50eXBlICE9PSBpbnB1dHNbaV0udHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCB0eXBlcyBhcmUgbm90IG1hdGNoZWQuJyk7XG4gICAgfVxuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBOVU1CRVJfVFlQRVMgfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgdGlsZSA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgdGlsZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgICBuYW1lOiAnVGlsZScsXG4gICAgaW5wdXROYW1lczogWydBJ10sXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgfTtcblxuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLnRpbGVQcm9ncmFtTWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlVGlsZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgdGlsZVByb2dyYW1NZXRhZGF0YSkgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IGNyZWF0ZVRpbGVQcm9ncmFtSW5mbyA9IChcbiAgX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgdGlsZVByb2dyYW1NZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBuZXcgQXJyYXkoaW5wdXRTaGFwZS5sZW5ndGgpO1xuXG4gIGNvbnN0IHRpbGVPcHM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgIG91dHB1dFNoYXBlW2ldID0gaW5wdXRTaGFwZVtpXSAqIGlucHV0c1sxXS5udW1iZXJEYXRhW2ldO1xuICAgIHRpbGVPcHMucHVzaChgaW5wdXRJZHhbJHtpfV0gPSBpbnQobW9kKGZsb2F0KG91dHB1dElkeFske2l9XSksICR7aW5wdXRTaGFwZVtpXX0uKSk7YCk7XG4gIH1cblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGlucHV0SWR4WyR7cmFua31dO1xuICAgICAgICAke3RpbGVPcHMuam9pbignXFxuJyl9XG4gICAgICAgIHJldHVybiBfQShpbnB1dElkeCk7XG4gICAgICB9XG4gICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi50aWxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignVGlsZSByZXF1aXJlcyAyIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBzZWNvbmQgaW5wdXQgc2hhcGUgbXVzdCAxIGRpbWVuc2lvbi4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLmRpbXNbMF0gIT09IGlucHV0c1swXS5kaW1zLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJyAmJiBpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDE2Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCByZXBlYXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IHVuc3F1ZWV6ZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxudW1iZXJbXT4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhlczogbnVtYmVyW10sXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gU2hhcGVVdGlsLnVuc3F1ZWV6ZVNoYXBlKGlucHV0c1swXS5kaW1zLCBheGVzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBvdXRwdXRTaGFwZSk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCB1bnNxdWVlemVWMTMgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0c1YxMyhpbnB1dHMpO1xuICByZXR1cm4gdW5zcXVlZXplKGluZmVyZW5jZUhhbmRsZXIsIFtpbnB1dHNbMF1dLCBBcnJheS5mcm9tKGlucHV0c1sxXS5pbnRlZ2VyRGF0YSkpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVW5zcXVlZXplQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXJbXT4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlcltdID0+XG4gIG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJyk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5zcXVlZXplIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnNxdWVlemUgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgT3BTZXQgfSBmcm9tICcuLi8uLi9vcHNldCc7XG5cbmltcG9ydCB7IGJhdGNoTm9ybWFsaXphdGlvbiwgcGFyc2VCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvYmF0Y2gtbm9ybWFsaXphdGlvbic7XG5pbXBvcnQgKiBhcyBiaW5hcnlPcHMgZnJvbSAnLi9vcHMvYmluYXJ5LW9wJztcbmltcG9ydCB7IGNhc3QsIHBhcnNlQ2FzdEF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jYXN0JztcbmltcG9ydCB7IGNvbmNhdCwgcGFyc2VDb25jYXRBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvY29uY2F0JztcbmltcG9ydCB7IGNvbnYsIHBhcnNlQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jb252JztcbmltcG9ydCB7IGNvbnZUcmFuc3Bvc2UsIHBhcnNlQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jb252LXRyYW5zcG9zZSc7XG5pbXBvcnQgeyBkZXB0aFRvU3BhY2UsIHBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2RlcHRoLXRvLXNwYWNlJztcbmltcG9ydCB7IGZsYXR0ZW4sIHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9mbGF0dGVuJztcbmltcG9ydCB7IGdhdGhlciwgcGFyc2VHYXRoZXJBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZ2F0aGVyJztcbmltcG9ydCB7IGdlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNWMTEsIHBhcnNlR2VtbUF0dHJpYnV0ZXNWNyB9IGZyb20gJy4vb3BzL2dlbW0nO1xuaW1wb3J0IHsgaW1hZ2VTY2FsZXIsIHBhcnNlSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvaW1hZ2Utc2NhbGVyJztcbmltcG9ydCB7IGluc3RhbmNlTm9ybWFsaXphdGlvbiwgcGFyc2VJbnN0YW5jZU5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvaW5zdGFuY2Utbm9ybWFsaXphdGlvbic7XG5pbXBvcnQgeyBscm4sIHBhcnNlTHJuQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2xybic7XG5pbXBvcnQgeyBtYXRNdWwsIHBhcnNlTWF0TXVsQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL21hdG11bCc7XG5pbXBvcnQgeyBwYWRWMTEsIHBhZFYyLCBwYXJzZVBhZEF0dHJpYnV0ZXNWMTEsIHBhcnNlUGFkQXR0cmlidXRlc1YyIH0gZnJvbSAnLi9vcHMvcGFkJztcbmltcG9ydCB7XG4gIGF2ZXJhZ2VQb29sLFxuICBnbG9iYWxBdmVyYWdlUG9vbCxcbiAgZ2xvYmFsTWF4UG9vbCxcbiAgbWF4UG9vbCxcbiAgcGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4gIHBhcnNlR2xvYmFsQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLFxuICBwYXJzZU1heFBvb2xBdHRyaWJ1dGVzLFxufSBmcm9tICcuL29wcy9wb29sJztcbmltcG9ydCB7XG4gIHBhcnNlUmVkdWNlQXR0cmlidXRlcyxcbiAgcmVkdWNlTG9nU3VtLFxuICByZWR1Y2VMb2dTdW1TcXVhcmUsXG4gIHJlZHVjZU1heCxcbiAgcmVkdWNlTWVhbixcbiAgcmVkdWNlTWluLFxuICByZWR1Y2VQcm9kLFxuICByZWR1Y2VTdW0sXG59IGZyb20gJy4vb3BzL3JlZHVjZSc7XG5pbXBvcnQgeyByZXNoYXBlIH0gZnJvbSAnLi9vcHMvcmVzaGFwZSc7XG5pbXBvcnQgeyBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTAsIHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMSwgcmVzaXplIH0gZnJvbSAnLi9vcHMvcmVzaXplLXBhY2tlZCc7XG5pbXBvcnQgeyBzaGFwZSB9IGZyb20gJy4vb3BzL3NoYXBlJztcbmltcG9ydCB7IHBhcnNlU2xpY2VBdHRyaWJ1dGVzLCBzbGljZSwgc2xpY2VWMTAgfSBmcm9tICcuL29wcy9zbGljZSc7XG5pbXBvcnQgeyBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzLCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzVjEzLCBzb2Z0bWF4LCBzb2Z0bWF4VjEzIH0gZnJvbSAnLi9vcHMvc29mdG1heCc7XG5pbXBvcnQgeyBwYXJzZVNwbGl0QXR0cmlidXRlcywgc3BsaXQgfSBmcm9tICcuL29wcy9zcGxpdCc7XG5pbXBvcnQgeyBwYXJzZVNxdWVlemVBdHRyaWJ1dGVzLCBzcXVlZXplLCBzcXVlZXplVjEzIH0gZnJvbSAnLi9vcHMvc3F1ZWV6ZSc7XG5pbXBvcnQgeyBzdW0gfSBmcm9tICcuL29wcy9zdW0nO1xuaW1wb3J0IHsgdGlsZSB9IGZyb20gJy4vb3BzL3RpbGUnO1xuaW1wb3J0IHsgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzLCB0cmFuc3Bvc2UgfSBmcm9tICcuL29wcy90cmFuc3Bvc2UnO1xuaW1wb3J0ICogYXMgdW5hcnlPcHMgZnJvbSAnLi9vcHMvdW5hcnktb3AnO1xuaW1wb3J0IHsgcGFyc2VVbnNxdWVlemVBdHRyaWJ1dGVzLCB1bnNxdWVlemUsIHVuc3F1ZWV6ZVYxMyB9IGZyb20gJy4vb3BzL3Vuc3F1ZWV6ZSc7XG5pbXBvcnQgeyBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y3LCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y5LCB1cHNhbXBsZSB9IGZyb20gJy4vb3BzL3Vwc2FtcGxlJztcblxuZXhwb3J0IGNvbnN0IFdFQkdMX09QX1JFU09MVkVfUlVMRVM6IHJlYWRvbmx5IE9wU2V0LlJlc29sdmVSdWxlW10gPSBbXG4gIFsnQWJzJywgJycsICc2KycsIHVuYXJ5T3BzLmFic10sXG4gIFsnQWNvcycsICcnLCAnNysnLCB1bmFyeU9wcy5hY29zXSxcbiAgWydBZGQnLCAnJywgJzcrJywgYmluYXJ5T3BzLmFkZF0sXG4gIFsnQW5kJywgJycsICc3KycsIGJpbmFyeU9wcy5hbmRdLFxuICBbJ0FzaW4nLCAnJywgJzcrJywgdW5hcnlPcHMuYXNpbl0sXG4gIFsnQXRhbicsICcnLCAnNysnLCB1bmFyeU9wcy5hdGFuXSxcbiAgLy8gVE9ETzogc3VwcG9ydCBuZXcgYXR0cmlidXRlcyBmb3IgQXZlcmFnZVBvb2wtMTBcbiAgWydBdmVyYWdlUG9vbCcsICcnLCAnNysnLCBhdmVyYWdlUG9vbCwgcGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXNdLFxuICBbJ0JhdGNoTm9ybWFsaXphdGlvbicsICcnLCAnNysnLCBiYXRjaE5vcm1hbGl6YXRpb24sIHBhcnNlQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlc10sXG4gIFsnQ2FzdCcsICcnLCAnNisnLCBjYXN0LCBwYXJzZUNhc3RBdHRyaWJ1dGVzXSxcbiAgWydDZWlsJywgJycsICc2KycsIHVuYXJ5T3BzLmNlaWxdLFxuICBbJ0NsaXAnLCAnJywgJzYtMTAnLCB1bmFyeU9wcy5jbGlwLCB1bmFyeU9wcy5wYXJzZUNsaXBBdHRyaWJ1dGVzXSxcbiAgWydDbGlwJywgJycsICcxMSsnLCB1bmFyeU9wcy5jbGlwVjExXSxcbiAgWydDb25jYXQnLCAnJywgJzQrJywgY29uY2F0LCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXNdLFxuICBbJ0NvbnYnLCAnJywgJzErJywgY29udiwgcGFyc2VDb252QXR0cmlidXRlc10sXG4gIFsnQ29udlRyYW5zcG9zZScsICcnLCAnMSsnLCBjb252VHJhbnNwb3NlLCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzXSxcbiAgWydDb3MnLCAnJywgJzcrJywgdW5hcnlPcHMuY29zXSxcbiAgWydEaXYnLCAnJywgJzcrJywgYmluYXJ5T3BzLmRpdl0sXG4gIFsnRHJvcG91dCcsICcnLCAnNysnLCB1bmFyeU9wcy5pZGVudGl0eV0sXG4gIFsnRGVwdGhUb1NwYWNlJywgJycsICcxKycsIGRlcHRoVG9TcGFjZSwgcGFyc2VEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzXSxcbiAgWydFcXVhbCcsICcnLCAnNysnLCBiaW5hcnlPcHMuZXF1YWxdLFxuICBbJ0VsdScsICcnLCAnNisnLCB1bmFyeU9wcy5lbHUsIHVuYXJ5T3BzLnBhcnNlRWx1QXR0cmlidXRlc10sXG4gIFsnRXhwJywgJycsICc2KycsIHVuYXJ5T3BzLmV4cF0sXG4gIFsnRmxhdHRlbicsICcnLCAnMSsnLCBmbGF0dGVuLCBwYXJzZUZsYXR0ZW5BdHRyaWJ1dGVzXSxcbiAgWydGbG9vcicsICcnLCAnNisnLCB1bmFyeU9wcy5mbG9vcl0sXG4gIFsnRnVzZWRDb252JywgJ2NvbS5taWNyb3NvZnQnLCAnMSsnLCBjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzXSxcbiAgWydHYXRoZXInLCAnJywgJzErJywgZ2F0aGVyLCBwYXJzZUdhdGhlckF0dHJpYnV0ZXNdLFxuICBbJ0dlbW0nLCAnJywgJzctMTAnLCBnZW1tLCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjddLFxuICBbJ0dlbW0nLCAnJywgJzExKycsIGdlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNWMTFdLFxuICBbJ0dsb2JhbEF2ZXJhZ2VQb29sJywgJycsICcxKycsIGdsb2JhbEF2ZXJhZ2VQb29sLCBwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlc10sXG4gIFsnR2xvYmFsTWF4UG9vbCcsICcnLCAnMSsnLCBnbG9iYWxNYXhQb29sXSxcbiAgWydHcmVhdGVyJywgJycsICc3KycsIGJpbmFyeU9wcy5ncmVhdGVyXSxcbiAgWydJZGVudGl0eScsICcnLCAnMSsnLCB1bmFyeU9wcy5pZGVudGl0eV0sXG4gIFsnSW1hZ2VTY2FsZXInLCAnJywgJzErJywgaW1hZ2VTY2FsZXIsIHBhcnNlSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzXSxcbiAgWydJbnN0YW5jZU5vcm1hbGl6YXRpb24nLCAnJywgJzYrJywgaW5zdGFuY2VOb3JtYWxpemF0aW9uLCBwYXJzZUluc3RhbmNlTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXNdLFxuICBbJ0xlYWt5UmVsdScsICcnLCAnNisnLCB1bmFyeU9wcy5sZWFreVJlbHUsIHVuYXJ5T3BzLnBhcnNlTGVha3lSZWx1QXR0cmlidXRlc10sXG4gIFsnTGVzcycsICcnLCAnNysnLCBiaW5hcnlPcHMubGVzc10sXG4gIFsnTFJOJywgJycsICcxKycsIGxybiwgcGFyc2VMcm5BdHRyaWJ1dGVzXSxcbiAgWydMb2cnLCAnJywgJzYrJywgdW5hcnlPcHMubG9nXSxcbiAgWydNYXRNdWwnLCAnJywgJzErJywgbWF0TXVsLCBwYXJzZU1hdE11bEF0dHJpYnV0ZXNdLFxuICAvLyBUT0RPOiBzdXBwb3J0IG5ldyBhdHRyaWJ1dGVzIGZvciBNYXhQb29sLTggYW5kIE1heFBvb2wtMTBcbiAgWydNYXhQb29sJywgJycsICcxKycsIG1heFBvb2wsIHBhcnNlTWF4UG9vbEF0dHJpYnV0ZXNdLFxuICBbJ011bCcsICcnLCAnNysnLCBiaW5hcnlPcHMubXVsXSxcbiAgWydOZWcnLCAnJywgJzYrJywgdW5hcnlPcHMubmVnXSxcbiAgWydOb3QnLCAnJywgJzErJywgdW5hcnlPcHMubm90XSxcbiAgWydPcicsICcnLCAnNysnLCBiaW5hcnlPcHMub3JdLFxuICBbJ1BhZCcsICcnLCAnMi0xMCcsIHBhZFYyLCBwYXJzZVBhZEF0dHJpYnV0ZXNWMl0sXG4gIFsnUGFkJywgJycsICcxMSsnLCBwYWRWMTEsIHBhcnNlUGFkQXR0cmlidXRlc1YxMV0sXG4gIFsnUG93JywgJycsICc3KycsIGJpbmFyeU9wcy5wb3ddLFxuICBbJ1BSZWx1JywgJycsICc3KycsIGJpbmFyeU9wcy5wUmVsdV0sXG4gIFsnUmVkdWNlTG9nU3VtJywgJycsICcxKycsIHJlZHVjZUxvZ1N1bSwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VNYXgnLCAnJywgJzErJywgcmVkdWNlTWF4LCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZU1lYW4nLCAnJywgJzErJywgcmVkdWNlTWVhbiwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VNaW4nLCAnJywgJzErJywgcmVkdWNlTWluLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZVByb2QnLCAnJywgJzErJywgcmVkdWNlUHJvZCwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VTdW0nLCAnJywgJzEtMTInLCByZWR1Y2VTdW0sIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlU3VtU3F1YXJlJywgJycsICcxKycsIHJlZHVjZUxvZ1N1bVNxdWFyZSwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWx1JywgJycsICc2KycsIHVuYXJ5T3BzLnJlbHVdLFxuICBbJ1Jlc2hhcGUnLCAnJywgJzUrJywgcmVzaGFwZV0sXG4gIFsnUmVzaXplJywgJycsICcxMCcsIHJlc2l6ZSwgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjEwXSxcbiAgWydSZXNpemUnLCAnJywgJzExKycsIHJlc2l6ZSwgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjExXSxcbiAgWydTaGFwZScsICcnLCAnMSsnLCBzaGFwZV0sXG4gIFsnU2lnbW9pZCcsICcnLCAnNisnLCB1bmFyeU9wcy5zaWdtb2lkXSxcbiAgWydTaW4nLCAnJywgJzcrJywgdW5hcnlPcHMuc2luXSxcbiAgWydTbGljZScsICcnLCAnMTArJywgc2xpY2VWMTBdLCAvLyBUT0RPOiBzdXBwb3J0ICdzdGVwcycgZm9yIFNsaWNlLTEwXG4gIFsnU2xpY2UnLCAnJywgJzEtOScsIHNsaWNlLCBwYXJzZVNsaWNlQXR0cmlidXRlc10sXG4gIC8vIFRoZSBcInNlbWFudGljXCIgbWVhbmluZyBvZiBheGlzIGhhcyBjaGFuZ2VkIGluIG9wc2V0LTEzLlxuICBbJ1NvZnRtYXgnLCAnJywgJzEtMTInLCBzb2Z0bWF4LCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzXSxcbiAgWydTb2Z0bWF4JywgJycsICcxMysnLCBzb2Z0bWF4VjEzLCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzVjEzXSxcbiAgLy8gJ1NwbGl0JyBvcGVyYXRvciBoYXMgYW4gb3B0aW9uYWwgYXR0cmlidXRlICdzcGxpdCdcbiAgLy8gdGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyBob3cgdGhlIHNwZWNpZmllZCBheGlzIG9mIGlucHV0IGRhdGEgaXMgc3BsaXQuXG4gIC8vIFdoZW4gdGhlIGF0dHJpYnV0ZSBpcyBtaXNzaW5nLCB3ZSBuZWVkIHRoZSBjb3VudCBvZiBudW1iZXIgb2Ygb3V0cHV0c1xuICAvLyBzbyB0aGF0IHdlIGNhbiBkZXRlcm1pbmUgdGhlICdzcGxpdCcgYXR0cmlidXRlIGZyb20gdGhlIHJ1bnRpbWUgaW5wdXQgdG8gdGhlIE9wZXJhdG9yXG4gIFsnU3BsaXQnLCAnJywgJzItMTInLCBzcGxpdCwgcGFyc2VTcGxpdEF0dHJpYnV0ZXNdLFxuICBbJ1NxcnQnLCAnJywgJzYrJywgdW5hcnlPcHMuc3FydF0sXG4gIFsnU3F1ZWV6ZScsICcnLCAnMS0xMicsIHNxdWVlemUsIHBhcnNlU3F1ZWV6ZUF0dHJpYnV0ZXNdLFxuICBbJ1NxdWVlemUnLCAnJywgJzEzKycsIHNxdWVlemVWMTNdLFxuICBbJ1N1YicsICcnLCAnNysnLCBiaW5hcnlPcHMuc3ViXSxcbiAgWydTdW0nLCAnJywgJzYrJywgc3VtXSxcbiAgWydUYW4nLCAnJywgJzcrJywgdW5hcnlPcHMudGFuXSxcbiAgWydUYW5oJywgJycsICc2KycsIHVuYXJ5T3BzLnRhbmhdLFxuICBbJ1RpbGUnLCAnJywgJzYrJywgdGlsZV0sXG4gIFsnVHJhbnNwb3NlJywgJycsICcxKycsIHRyYW5zcG9zZSwgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzXSxcbiAgWydVcHNhbXBsZScsICcnLCAnNy04JywgdXBzYW1wbGUsIHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjddLFxuICBbJ1Vwc2FtcGxlJywgJycsICc5JywgdXBzYW1wbGUsIHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjldLFxuICBbJ1Vuc3F1ZWV6ZScsICcnLCAnMS0xMicsIHVuc3F1ZWV6ZSwgcGFyc2VVbnNxdWVlemVBdHRyaWJ1dGVzXSxcbiAgWydVbnNxdWVlemUnLCAnJywgJzEzKycsIHVuc3F1ZWV6ZVYxM10sXG4gIFsnWG9yJywgJycsICc3KycsIGJpbmFyeU9wcy54b3JdLFxuXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuY29uc3QgSU5MSU5FX0ZVTkNfREVGX1JFR0VYID0gL0BpbmxpbmVbXFxzXFxuXFxyXSsoXFx3KylbXFxzXFxuXFxyXSsoWzAtOWEtekEtWl9dKylcXHMqXFwoKFteKV0qKVxcKVxccyp7KChbXn1dfFtcXG5cXHJdKSopfS9nbTtcbmNvbnN0IEZVTkNfQ0FMTF9SRUdFWCA9ICcoXFxcXHcrKT9cXFxccysoW18wLTlhLXpBLVpdKylcXFxccys9XFxcXHMrX19GVU5DX19cXFxcKCguKilcXFxcKVxcXFxzKjsnO1xuLyoqXG4gKiBHTFNMIHByZXByb2Nlc3NvciByZXNwb25zaWJsZSBmb3IgcmVzb2x2aW5nIEBpbmxpbmUgZGlyZWN0aXZlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZUlubGluZXMoc2NyaXB0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBpbmxpbmVEZWZzOiB7IFtuYW1lOiBzdHJpbmddOiB7IHBhcmFtczogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IG5hbWU6IHN0cmluZyB9IHwgbnVsbD47IGJvZHk6IHN0cmluZyB9IH0gPSB7fTtcbiAgbGV0IG1hdGNoO1xuICB3aGlsZSAoKG1hdGNoID0gSU5MSU5FX0ZVTkNfREVGX1JFR0VYLmV4ZWMoc2NyaXB0KSkgIT09IG51bGwpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBtYXRjaFszXVxuICAgICAgLnNwbGl0KCcsJylcbiAgICAgIC5tYXAoKHMpID0+IHtcbiAgICAgICAgY29uc3QgdG9rZW5zID0gcy50cmltKCkuc3BsaXQoJyAnKTtcbiAgICAgICAgaWYgKHRva2VucyAmJiB0b2tlbnMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgcmV0dXJuIHsgdHlwZTogdG9rZW5zWzBdLCBuYW1lOiB0b2tlbnNbMV0gfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKCh2KSA9PiB2ICE9PSBudWxsKTtcbiAgICBpbmxpbmVEZWZzW21hdGNoWzJdXSA9IHsgcGFyYW1zLCBib2R5OiBtYXRjaFs0XSB9O1xuICB9XG4gIGZvciAoY29uc3QgbmFtZSBpbiBpbmxpbmVEZWZzKSB7XG4gICAgY29uc3QgcmVnZXhTdHJpbmcgPSBGVU5DX0NBTExfUkVHRVgucmVwbGFjZSgnX19GVU5DX18nLCBuYW1lKTtcbiAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAocmVnZXhTdHJpbmcsICdnbScpO1xuICAgIHdoaWxlICgobWF0Y2ggPSByZWdleC5leGVjKHNjcmlwdCkpICE9PSBudWxsKSB7XG4gICAgICBjb25zdCB0eXBlID0gbWF0Y2hbMV07XG4gICAgICBjb25zdCB2YXJpYWJsZSA9IG1hdGNoWzJdO1xuICAgICAgY29uc3QgcGFyYW1zID0gbWF0Y2hbM10uc3BsaXQoJywnKTtcbiAgICAgIGNvbnN0IGRlY2xMaW5lID0gdHlwZSA/IGAke3R5cGV9ICR7dmFyaWFibGV9O2AgOiAnJztcbiAgICAgIGxldCBuZXdCb2R5OiBzdHJpbmcgPSBpbmxpbmVEZWZzW25hbWVdLmJvZHk7XG4gICAgICBsZXQgcGFyYW1SZWRlY0xpbmUgPSAnJztcbiAgICAgIGlubGluZURlZnNbbmFtZV0ucGFyYW1zLmZvckVhY2goKHYsIGkpID0+IHtcbiAgICAgICAgaWYgKHYpIHtcbiAgICAgICAgICBwYXJhbVJlZGVjTGluZSArPSBgJHt2LnR5cGV9ICR7di5uYW1lfSA9ICR7cGFyYW1zW2ldfTtcXG5gO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIG5ld0JvZHkgPSBgJHtwYXJhbVJlZGVjTGluZX1cXG4gJHtuZXdCb2R5fWA7XG4gICAgICBuZXdCb2R5ID0gbmV3Qm9keS5yZXBsYWNlKCdyZXR1cm4nLCBgJHt2YXJpYWJsZX0gPSBgKTtcbiAgICAgIGNvbnN0IHJlcGxhY2VtZW50ID0gYFxuICAgICAgJHtkZWNsTGluZX1cbiAgICAgIHtcbiAgICAgICAgJHtuZXdCb2R5fVxuICAgICAgfVxuICAgICAgYDtcbiAgICAgIHNjcmlwdCA9IHNjcmlwdC5yZXBsYWNlKG1hdGNoWzBdLCByZXBsYWNlbWVudCk7XG4gICAgfVxuICB9XG4gIHNjcmlwdCA9IHNjcmlwdC5yZXBsYWNlKElOTElORV9GVU5DX0RFRl9SRUdFWCwgJycpO1xuICByZXR1cm4gc2NyaXB0O1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG4vKiogTGF5b3V0IHByZWZlcmVuY2VzICovXG5leHBvcnQgaW50ZXJmYWNlIFdpZHRoSGVpZ2h0UHJlZnMge1xuICBicmVha0F4aXM/OiBudW1iZXI7XG4gIGlzUGFja2VkPzogYm9vbGVhbjtcbiAgcmV2ZXJzZVdIPzogYm9vbGVhbjtcbn1cbi8qKlxuICogVGV4dHVyZUxheW91dFN0cmF0ZWd5IGlzIGFuIGFic3RyYWN0aW9uIGZvciBkaWZmZXJlbnQgcGxhbnNcbiAqIGZvciBtYXBwaW5nIG4tZGltZW5zaW9uYWwgYXJyYXlzIHRvIDJEIHRleHR1cmVzIChhbmQgYmFjaylcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kge1xuICBjb21wdXRlVGV4dHVyZVdIKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXTtcbn1cblxuLyoqXG4gKiBUaGlzIHN0cmF0ZWd5IHRyeSB0byBmaW5kIHRoZSBtaW5pbWFsIG1heChXLEgpIHRoYXQgZnVsZmlsbHMgKFcgKiBIID09IHRvdGFsU2l6ZSlcbiAqL1xuZXhwb3J0IGNsYXNzIEFsd2F5c0tlZXBPcmlnaW5hbFNpemVTdHJhdGVneSBpbXBsZW1lbnRzIFRleHR1cmVMYXlvdXRTdHJhdGVneSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBtYXhUZXh0dXJlU2l6ZTogbnVtYmVyKSB7fVxuICBjb21wdXRlVGV4dHVyZVdIKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgLy8gc2NhbGFyIHRlbnNvclxuICAgIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbMSwgMV07XG4gICAgfVxuICAgIGNvbnN0IG1heFRleHR1cmVTaXplID0gdGhpcy5tYXhUZXh0dXJlU2l6ZTtcbiAgICBpZiAocHJlZnMgJiYgcHJlZnMuYnJlYWtBeGlzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiBkaW1zIGZpdFxuICAgICAgY29uc3Qgd3NpemUgPSBwcmVmcy5icmVha0F4aXMgPj0gc2hhcGUubGVuZ3RoID8gMSA6IHNoYXBlLnNsaWNlKHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBjb25zdCBoc2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA8PSAwID8gMSA6IHNoYXBlLnNsaWNlKDAsIHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBpZiAod3NpemUgPiBtYXhUZXh0dXJlU2l6ZSB8fCBoc2l6ZSA+IG1heFRleHR1cmVTaXplKSB7XG4gICAgICAgIC8vIGlnbm9yZSBwcmVmZXJlbmNlc1xuICAgICAgICAvLyBjb250aW51ZSB3aXRoIGRlZmF1bHQgbGF5b3V0XG4gICAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICdUZXh0dXJlTGF5b3V0JyxcbiAgICAgICAgICBgR2l2ZW4gd2lkdGgvaGVpZ2h0IHByZWZlcmVuY2VzIHdlcmUgdW5hdHRhaW5hYmxlOiBzaGFwZToke3NoYXBlfSwgYnJlYWtBeGlzOiR7cHJlZnMuYnJlYWtBeGlzfWAsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gW3dzaXplLCBoc2l6ZV07XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHRvdGFsU2l6ZSA9IHNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuXG4gICAgbGV0IHdpZHRoID0gTWF0aC5mbG9vcihNYXRoLnNxcnQodG90YWxTaXplKSk7XG5cbiAgICBmb3IgKDsgd2lkdGggPCBtYXhUZXh0dXJlU2l6ZSAmJiB3aWR0aCA8IHRvdGFsU2l6ZTsgd2lkdGgrKykge1xuICAgICAgaWYgKHRvdGFsU2l6ZSAlIHdpZHRoID09PSAwKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3aWR0aCA+PSBtYXhUZXh0dXJlU2l6ZSB8fCB0b3RhbFNpemUgJSB3aWR0aCAhPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgZ2l2ZW4gZGltZW5zaW9ucyBhcmUgb3V0c2lkZSB0aGlzIEdQVSdzIGJvdW5kYXJpZXM6ICR7c2hhcGV9YCk7XG4gICAgfVxuICAgIHJldHVybiBbd2lkdGgsIHRvdGFsU2l6ZSAvIHdpZHRoXTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUHJlZmVyTG9naWNhbFN0cmF0ZWd5IGltcGxlbWVudHMgVGV4dHVyZUxheW91dFN0cmF0ZWd5IHtcbiAgY29uc3RydWN0b3IocHVibGljIG1heFRleHR1cmVTaXplOiBudW1iZXIpIHt9XG4gIGNvbXB1dGVUZXh0dXJlV0goc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCB3aCA9IHRoaXMuY29tcHV0ZVRleHR1cmUoc2hhcGUsIHByZWZzKTtcbiAgICBpZiAocHJlZnMgJiYgcHJlZnMuaXNQYWNrZWQpIHtcbiAgICAgIHdoWzBdIC89IDI7XG4gICAgICB3aFsxXSAvPSAyO1xuICAgIH1cbiAgICBpZiAocHJlZnMgJiYgcHJlZnMucmV2ZXJzZVdIKSB7XG4gICAgICByZXR1cm4gW3doWzFdLCB3aFswXV07XG4gICAgfVxuICAgIHJldHVybiB3aDtcbiAgfVxuXG4gIGNvbXB1dGVUZXh0dXJlKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3QgaXNQYWNrZWQgPSBwcmVmcyAmJiBwcmVmcy5pc1BhY2tlZDtcbiAgICAvLyBzY2FsYXIgdGVuc29yXG4gICAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGlzUGFja2VkID8gWzIsIDJdIDogWzEsIDFdO1xuICAgIH1cbiAgICBsZXQgbWF4VGV4dHVyZVNpemUgPSB0aGlzLm1heFRleHR1cmVTaXplO1xuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5icmVha0F4aXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gY2hlY2sgdG8gc2VlIGlmIGRpbXMgZml0XG4gICAgICBjb25zdCB3c2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA+PSBzaGFwZS5sZW5ndGggPyAxIDogc2hhcGUuc2xpY2UocHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGNvbnN0IGhzaXplID0gcHJlZnMuYnJlYWtBeGlzIDw9IDAgPyAxIDogc2hhcGUuc2xpY2UoMCwgcHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGlmICh3c2l6ZSA+IG1heFRleHR1cmVTaXplIHx8IGhzaXplID4gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgICAgLy8gaWdub3JlIHByZWZlcmVuY2VzXG4gICAgICAgIC8vIGNvbnRpbnVlIHdpdGggZGVmYXVsdCBsYXlvdXRcbiAgICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgJ1RleHR1cmVMYXlvdXQnLFxuICAgICAgICAgIGBHaXZlbiB3aWR0aC9oZWlnaHQgcHJlZmVyZW5jZXMgd2VyZSB1bmF0dGFpbmFibGU6IHNoYXBlOiR7c2hhcGV9LCBicmVha0F4aXM6JHtwcmVmcy5icmVha0F4aXN9YCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbd3NpemUsIGhzaXplXTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGxvZ1NoYXBlID0gc2hhcGUuc2xpY2UoMCk7XG4gICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICBtYXhUZXh0dXJlU2l6ZSA9IG1heFRleHR1cmVTaXplICogMjtcblxuICAgICAgLy8gVGhpcyBsb2dpYyBlbnN1cmVzIHdlIGFjY3VyYXRlbHkgY291bnQgdGhlIG51bWJlciBvZiBwYWNrZWQgdGV4ZWxzIG5lZWRlZFxuICAgICAgLy8gdG8gYWNjb21tb2RhdGUgdGhlIHRlbnNvci4gV2UgY2FuIG9ubHkgcGFjayB2YWx1ZXMgaW4gdGhlIHNhbWUgdGV4ZWwgaWZcbiAgICAgIC8vIHRoZXkgYXJlIGZyb20gYWRqYWNlbnQgcGFpcnMgb2Ygcm93cy9jb2xzIHdpdGhpbiB0aGUgc2FtZSBiYXRjaC4gU28gaWYgYVxuICAgICAgLy8gdGVuc29yIGhhcyAzIHJvd3MsIHdlIHByZXRlbmQgaXQgaGFzIDQgcm93cyBpbiBvcmRlciB0byBhY2NvdW50IGZvciB0aGVcbiAgICAgIC8vIGZhY3QgdGhhdCB0aGUgdGV4ZWxzIGNvbnRhaW5pbmcgdGhlIHRoaXJkIHJvdyBhcmUgaGFsZiBlbXB0eS5cbiAgICAgIGxvZ1NoYXBlID0gbG9nU2hhcGUubWFwKChfZCwgaSkgPT5cbiAgICAgICAgaSA+PSBsb2dTaGFwZS5sZW5ndGggLSAyID8gKGxvZ1NoYXBlW2ldICUgMiA9PT0gMCA/IGxvZ1NoYXBlW2ldIDogbG9nU2hhcGVbaV0gKyAxKSA6IGxvZ1NoYXBlW2ldLFxuICAgICAgKTtcblxuICAgICAgLy8gUGFja2VkIHRleHR1cmUgaGVpZ2h0IGlzIGF0IGxlYXN0IDIgKHRoZSBjaGFubmVsIGhlaWdodCBvZiBhIHNpbmdsZVxuICAgICAgLy8gdGV4ZWwpLlxuICAgICAgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBsb2dTaGFwZSA9IFsyLCBsb2dTaGFwZVswXV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgbG9naWNhbCBzaGFwZSBpcyAyLCB3ZSBkb24ndCBzcXVlZXplLCBzaW5jZSB3ZSB3YW50IHRvIG1hdGNoIHBoeXNpY2FsLlxuICAgIGlmIChsb2dTaGFwZS5sZW5ndGggIT09IDIpIHtcbiAgICAgIGNvbnN0IHNxdWVlemVSZXN1bHQgPSBzcXVlZXplU2hhcGUobG9nU2hhcGUpO1xuICAgICAgbG9nU2hhcGUgPSBzcXVlZXplUmVzdWx0Lm5ld1NoYXBlO1xuICAgIH1cblxuICAgIGNvbnN0IHNpemUgPSBzaXplRnJvbVNoYXBlKGxvZ1NoYXBlKTtcbiAgICBpZiAobG9nU2hhcGUubGVuZ3RoIDw9IDEgJiYgc2l6ZSA8PSBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgcmV0dXJuIFsxLCBzaXplXTtcbiAgICB9IGVsc2UgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMiAmJiBsb2dTaGFwZVswXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJiBsb2dTaGFwZVsxXSA8PSBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgcmV0dXJuIGxvZ1NoYXBlIGFzIFtudW1iZXIsIG51bWJlcl07XG4gICAgfSBlbHNlIGlmIChsb2dTaGFwZS5sZW5ndGggPT09IDMgJiYgbG9nU2hhcGVbMF0gKiBsb2dTaGFwZVsxXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJiBsb2dTaGFwZVsyXSA8PSBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgcmV0dXJuIFtsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdLCBsb2dTaGFwZVsyXV07XG4gICAgfSBlbHNlIGlmIChsb2dTaGFwZS5sZW5ndGggPT09IDMgJiYgbG9nU2hhcGVbMF0gPD0gbWF4VGV4dHVyZVNpemUgJiYgbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSA8PSBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgcmV0dXJuIFtsb2dTaGFwZVswXSwgbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXV07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGxvZ1NoYXBlLmxlbmd0aCA9PT0gNCAmJlxuICAgICAgbG9nU2hhcGVbMF0gKiBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdIDw9IG1heFRleHR1cmVTaXplICYmXG4gICAgICBsb2dTaGFwZVszXSA8PSBtYXhUZXh0dXJlU2l6ZVxuICAgICkge1xuICAgICAgcmV0dXJuIFtsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0sIGxvZ1NoYXBlWzNdXTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgbG9nU2hhcGUubGVuZ3RoID09PSA0ICYmXG4gICAgICBsb2dTaGFwZVswXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJlxuICAgICAgbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSAqIGxvZ1NoYXBlWzNdIDw9IG1heFRleHR1cmVTaXplXG4gICAgKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdLCBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdICogbG9nU2hhcGVbM11dO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgICAgLy8gRm9yIHBhY2tlZCB0ZXh0dXJlcyBzaXplIGVxdWFscyB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzIHJlcXVpcmVkIHRvXG4gICAgICAgIC8vIGFjY29tbW9kYXRlIHRoZSB0ZXh0dXJlIGRhdGEuIEhvd2V2ZXIgaW4gb3JkZXIgdG8gc3F1YXJpZnkgc3VjaCB0aGF0XG4gICAgICAgIC8vIGlubmVyIGRpbWVuc2lvbnMgc3RheSBldmVuLCB3ZSByZXdyaXRlIHNpemUgdG8gZXF1YWwgdGhlIG51bWJlciBvZlxuICAgICAgICAvLyB0ZXhlbHMuIFRoZW4gaW4gdGhlIHJldHVybiBzdGF0ZW1lbnQgd2UgcmVoeWRyYXRlIHRoZSBzcXVhcmlmaWVkXG4gICAgICAgIC8vIGRpbWVuc2lvbnMgdG8gY2hhbm5lbCB1bml0cy5cbiAgICAgICAgcmV0dXJuIHNpemVUb1NxdWFyaXNoU2hhcGUoc2l6ZSAvIDQpLm1hcCgoZCkgPT4gZCAqIDIpIGFzIFtudW1iZXIsIG51bWJlcl07XG4gICAgICB9XG4gICAgICByZXR1cm4gc2l6ZVRvU3F1YXJpc2hTaGFwZShzaXplKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNxdWVlemVTaGFwZShzaGFwZTogbnVtYmVyW10sIGF4aXM/OiBudW1iZXJbXSk6IHsgbmV3U2hhcGU6IG51bWJlcltdOyBrZXB0RGltczogbnVtYmVyW10gfSB7XG4gIGNvbnN0IG5ld1NoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBrZXB0RGltczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaXNFbXB0eUFycmF5ID0gYXhpcyAhPSBudWxsICYmIEFycmF5LmlzQXJyYXkoYXhpcykgJiYgYXhpcy5sZW5ndGggPT09IDA7XG4gIGNvbnN0IGF4ZXMgPSBheGlzID09IG51bGwgfHwgaXNFbXB0eUFycmF5ID8gbnVsbCA6IHBhcnNlQXhpc1BhcmFtKGF4aXMsIHNoYXBlKS5zb3J0KCk7XG4gIGxldCBqID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaGFwZS5sZW5ndGg7ICsraSkge1xuICAgIGlmIChheGVzICE9IG51bGwpIHtcbiAgICAgIGlmIChheGVzW2pdID09PSBpICYmIHNoYXBlW2ldICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3Qgc3F1ZWV6ZSBheGlzICR7aX0gc2luY2UgaXRzIGRpbSAnJHtzaGFwZVtpXX0nIGlzIG5vdCAxYCk7XG4gICAgICB9XG4gICAgICBpZiAoKGF4ZXNbal0gPT0gbnVsbCB8fCBheGVzW2pdID4gaSkgJiYgc2hhcGVbaV0gPT09IDEpIHtcbiAgICAgICAgbmV3U2hhcGUucHVzaChzaGFwZVtpXSk7XG4gICAgICAgIGtlcHREaW1zLnB1c2goaSk7XG4gICAgICB9XG4gICAgICBpZiAoYXhlc1tqXSA8PSBpKSB7XG4gICAgICAgIGorKztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNoYXBlW2ldICE9PSAxKSB7XG4gICAgICBuZXdTaGFwZS5wdXNoKHNoYXBlW2ldKTtcbiAgICAgIGtlcHREaW1zLnB1c2goaSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IG5ld1NoYXBlLCBrZXB0RGltcyB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VBeGlzUGFyYW0oYXhpczogbnVtYmVyIHwgbnVtYmVyW10sIHNoYXBlOiBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAvLyBOb3JtYWxpemUgaW5wdXRcbiAgYXhpcyA9IGF4aXMgPT0gbnVsbCA/IHNoYXBlLm1hcCgoX3MsIGkpID0+IGkpIDogKFtdIGFzIG51bWJlcltdKS5jb25jYXQoYXhpcyk7XG5cbiAgLy8gQ2hlY2sgZm9yIHZhbGlkIHJhbmdlXG4gIGFzc2VydChcbiAgICBheGlzLmV2ZXJ5KChheCkgPT4gYXggPj0gLXJhbmsgJiYgYXggPCByYW5rKSxcbiAgICAoKSA9PiBgQWxsIHZhbHVlcyBpbiBheGlzIHBhcmFtIG11c3QgYmUgaW4gcmFuZ2UgWy0ke3Jhbmt9LCAke3Jhbmt9KSBidXQgYCArIGBnb3QgYXhpcyAke2F4aXN9YCxcbiAgKTtcblxuICAvLyBDaGVjayBmb3Igb25seSBpbnRlZ2Vyc1xuICBhc3NlcnQoYXhpcy5ldmVyeShpc0ludCksICgpID0+ICdBbGwgdmFsdWVzIGluIGF4aXMgcGFyYW0gbXVzdCBiZSBpbnRlZ2VycyBidXQgJyArIGBnb3QgYXhpcyAke2F4aXN9YCk7XG5cbiAgLy8gSGFuZGxlIG5lZ2F0aXZlIGF4aXMuXG4gIHJldHVybiBheGlzLm1hcCgoYSkgPT4gKGEgPCAwID8gcmFuayArIGEgOiBhKSk7XG59XG5leHBvcnQgZnVuY3Rpb24gaXNJbnQoYTogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHJldHVybiBhICUgMSA9PT0gMDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzaXplRnJvbVNoYXBlKHNoYXBlOiBudW1iZXJbXSk6IG51bWJlciB7XG4gIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAvLyBTY2FsYXIuXG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgbGV0IHNpemUgPSBzaGFwZVswXTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBzaGFwZS5sZW5ndGg7IGkrKykge1xuICAgIHNpemUgKj0gc2hhcGVbaV07XG4gIH1cbiAgcmV0dXJuIHNpemU7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0Um93c0NvbHMoc2hhcGU6IG51bWJlcltdKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBFcnJvcignQ2Fubm90IGdldCByb3dzIGFuZCBjb2x1bW5zIG9mIGFuIGVtcHR5IHNoYXBlIGFycmF5LicpO1xuICB9XG5cbiAgcmV0dXJuIFtzaGFwZS5sZW5ndGggPiAxID8gc2hhcGVbc2hhcGUubGVuZ3RoIC0gMl0gOiAxLCBzaGFwZVtzaGFwZS5sZW5ndGggLSAxXV07XG59XG5leHBvcnQgZnVuY3Rpb24gc2l6ZVRvU3F1YXJpc2hTaGFwZShzaXplOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgY29uc3Qgd2lkdGggPSBNYXRoLmNlaWwoTWF0aC5zcXJ0KHNpemUpKTtcbiAgcmV0dXJuIFt3aWR0aCwgTWF0aC5jZWlsKHNpemUgLyB3aWR0aCldO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldEJhdGNoRGltKHNoYXBlOiBudW1iZXJbXSwgZGltc1RvU2tpcCA9IDIpOiBudW1iZXIge1xuICByZXR1cm4gc2l6ZUZyb21TaGFwZShzaGFwZS5zbGljZSgwLCBzaGFwZS5sZW5ndGggLSBkaW1zVG9Ta2lwKSk7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEFycmF5VXRpbCwgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZSB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBzcXVlZXplU2hhcGUgfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7IFRleHR1cmVMYXlvdXQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7XG4gIGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZSxcbiAgZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lQXRPdXRDb29yZHMsXG4gIGdldENvb3Jkc0RhdGFUeXBlLFxuICBnZXRHbENoYW5uZWxzLFxuICBnZXRTcXVlZXplZFBhcmFtcyxcbiAgc3F1ZWV6ZUlucHV0U2hhcGUsXG59IGZyb20gJy4vdXRpbHMnO1xuXG4vKipcbiAqIEdMU0wgTGlicmFyeSByZXNwb25zaWJsZSBmb3IgZGF0YSB0eXBlcyBhbmQgcm91dGluZXMgZm9yIG1hbmlwdWxhdGluZ1xuICogY29vcmRpbmF0ZXMgYW5kIG1hcHBpbmcgdG8vZnJvbSB0ZW5zb3IgaW5kaWNlc1xuICovXG5leHBvcnQgY2xhc3MgQ29vcmRzR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICByZXR1cm5UeXBlOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMub2Zmc2V0VG9Db29yZHMoKSxcbiAgICAgIC4uLnRoaXMuY29vcmRzVG9PZmZzZXQoKSxcbiAgICAgIC4uLnRoaXMudG9WZWMoKSxcbiAgICAgIC4uLnRoaXMudmFsdWVGcm9tKCksXG4gICAgICAvLyBUT0RPIHJldHVybiB0aGVzZSBvbmx5IHdoZW4gcGFja2luZyBpcyBlbmFibGVkLlxuICAgICAgLi4udGhpcy5nZXRDb21tb25VdGlsRnVuY3MoKSxcbiAgICAgIC4uLnRoaXMuZ2V0SW5wdXRzU2FtcGxpbmdTbmlwcGV0cygpLFxuICAgICAgLi4udGhpcy5nZXRPdXRwdXRTYW1wbGluZ1NuaXBwZXQoKSxcbiAgICB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICAvKipcbiAgICogUHJvZHVjZXMgYSBmdW5jdGlvbiB0aGF0IGNhbiBtYXAgZnJvbVxuICAgKiAyRCBub3JtYWx6aWVkIGNvb3JkaW5hdGVzIChzLHQpIHRvIGEgZmxhdCBvZmZzZXRcbiAgICovXG4gIHByb3RlY3RlZCBvZmZzZXRUb0Nvb3JkcygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdvZmZzZXRUb0Nvb3Jkcyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9mZnNldFRvQ29vcmRzOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgdmVjMiAke2Z1bmNOYW1lfShpbnQgb2Zmc2V0LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHtcbiAgICAgICAgaW50IHQgPSBvZmZzZXQgLyB3aWR0aDtcbiAgICAgICAgaW50IHMgPSBvZmZzZXQgLSB0KndpZHRoO1xuICAgICAgICB2ZWMyIGNvb3JkcyA9ICh2ZWMyKHMsdCkgKyB2ZWMyKDAuNSwwLjUpKSAvIHZlYzIod2lkdGgsIGhlaWdodCk7XG4gICAgICAgIHJldHVybiBjb29yZHM7XG4gICAgICB9XG4gICAgICBgKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEgZnVuY3Rpb24gdGhhdCBjYW4gbWFwIGZyb21cbiAgICogMkQgbm9ybWFsemllZCBjb29yZGluYXRlcyAocyx0KSB0byBhIGZsYXQgb2Zmc2V0XG4gICAqL1xuICBwcm90ZWN0ZWQgY29vcmRzVG9PZmZzZXQoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgZnVuY05hbWUgPSAnY29vcmRzVG9PZmZzZXQnO1xuICAgIHJldHVybiB7XG4gICAgICBjb29yZHNUb09mZnNldDogbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIGludCAke2Z1bmNOYW1lfSh2ZWMyIGNvb3JkcywgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7XG4gICAgICAgIGZsb2F0IHMgPSBjb29yZHMucyAqIGZsb2F0KHdpZHRoKTtcbiAgICAgICAgZmxvYXQgdCA9IGNvb3Jkcy50ICogZmxvYXQoaGVpZ2h0KTtcbiAgICAgICAgaW50IG9mZnNldCA9IGludCh0KSAqIHdpZHRoICsgaW50KHMpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0O1xuICAgICAgfVxuICAgICAgYCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3Igb3V0cHV0IHNhbXBsZXIuXG4gICAqL1xuXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRTYW1wbGluZ1NuaXBwZXQoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgaWYgKG91dHB1dExheW91dC5pc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciBwYWNrZWQgb3V0cHV0IHNhbXBsZXIuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgb3V0VGV4U2hhcGUgPSBbb3V0cHV0TGF5b3V0LndpZHRoLCBvdXRwdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdnZXRPdXRwdXRDb29yZHMnO1xuICAgIHN3aXRjaCAob3V0U2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFNjYWxhckNvb3JkcygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0UGFja2VkMURDb29yZHMob3V0U2hhcGUgYXMgW251bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0UGFja2VkMkRDb29yZHMob3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWQzRENvb3JkcyhcbiAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWRORENvb3JkcyhvdXRTaGFwZSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgLy8gVE9ETyB3ZSBuZWVkIHRoaXMgdG8gcHJvcGVybHkgcmV0dXJuIGEgcGFja2VkIHZlYzQgZnJvbSBrZXJuZWxzLlxuICAgIC8vIFJlcGxhY2UgYWxsICd7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0JyB3aXRoICdzZXRPdXRwdXQocmVzdWx0KScgaW4gYWxsIGtlcm5lbHMuXG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UkdCQVNvdXJjZSA9IGBcbiAgICAgIHZvaWQgc2V0T3V0cHV0KHZlYzQgdmFsKSB7XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmFsO1xuICAgICAgfVxuICAgIGA7XG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UkdCQUZ1bmNOYW1lID0gJ2Zsb2F0VGV4dHVyZVNldFJHQkEnO1xuICAgIHJlc3VsdFtmbG9hdFRleHR1cmVTZXRSR0JBRnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGZsb2F0VGV4dHVyZVNldFJHQkFTb3VyY2UpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGNvZGUgZm9yIHVucGFja2VkIG91dHB1dCBzYW1wbGVyLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgb3V0VGV4U2hhcGUgPSBbb3V0cHV0TGF5b3V0LndpZHRoLCBvdXRwdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdnZXRPdXRwdXRDb29yZHMnO1xuICAgIHN3aXRjaCAob3V0U2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFNjYWxhckNvb3JkcygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQxRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDJEQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkM0RDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA0OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDREQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA1OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDVEQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDY6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkNkRDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBvdXRwdXQgZGltZW5zaW9uYWxpdHk6ICR7b3V0U2hhcGUubGVuZ3RofWApO1xuICAgIH1cbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIC8vIFRPRE8gd2UgbmVlZCB0aGlzIHRvIHByb3Blcmx5IHJldHVybiBhIHBhY2tlZCB2ZWM0IGZyb20ga2VybmVscy5cbiAgICAvLyBSZXBsYWNlIGFsbCAne2dsc2wub3V0cHV0fSA9IHJlc3VsdCcgd2l0aCAnc2V0T3V0cHV0KHJlc3VsdCknIGluIGFsbCBrZXJuZWxzLlxuICAgIGNvbnN0IGZsb2F0VGV4dHVyZVNldFJTb3VyY2UgPSBgXG4gICAgICAgIHZvaWQgc2V0T3V0cHV0KGZsb2F0IHZhbCkge1xuICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCh2YWwsIDAsIDAsIDApO1xuICAgICAgICB9XG4gICAgYDtcbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSRnVuY05hbWUgPSAnZmxvYXRUZXh0dXJlU2V0Uic7XG4gICAgcmVzdWx0W2Zsb2F0VGV4dHVyZVNldFJGdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoZmxvYXRUZXh0dXJlU2V0UlNvdXJjZSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTY2FsYXIgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFNjYWxhckNvb3JkcygpOiBHbHNsTGliUm91dGluZSB7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICBgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAxRCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZDFEQ29vcmRzKF9zaGFwZTogW251bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gdGV4U2hhcGU7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGlmIChwYWNrZWRUZXhTaGFwZVswXSA9PT0gMSkge1xuICAgICAgc291cmNlID0gYFxuICAgICAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gMiAqIGludChUZXhDb29yZHMueSAqICR7cGFja2VkVGV4U2hhcGVbMV19LjApO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgICB9XG5cbiAgICBpZiAocGFja2VkVGV4U2hhcGVbMV0gPT09IDEpIHtcbiAgICAgIHNvdXJjZSA9IGBcbiAgICAgICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIDIgKiBpbnQoVGV4Q29vcmRzLnggKiAke3BhY2tlZFRleFNoYXBlWzBdfS4wKTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gICAgfVxuXG4gICAgc291cmNlID0gYFxuICAgICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7cGFja2VkVGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgcmV0dXJuIDIgKiAocmVzVGV4UkMueSAqICR7cGFja2VkVGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueCk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIDJEIHBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0UGFja2VkMkRDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBpZiAoQXJyYXlVdGlsLmFycmF5c0VxdWFsKHNoYXBlLCB0ZXhTaGFwZSkpIHtcbiAgICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIHJldHVybiAyICogaXZlYzIoVGV4Q29vcmRzLnh5ICogdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IHRleFNoYXBlO1xuICAgIC8vIHRleGVscyBuZWVkZWQgdG8gYWNjb21tb2RhdGUgYSBsb2dpY2FsIHJvd1xuICAgIGNvbnN0IHRleGVsc0luTG9naWNhbFJvdyA9IE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuXG4gICAgLyoqXG4gICAgICogZ2V0T3V0cHV0Q29vcmRzXG4gICAgICpcbiAgICAgKiByZXNUZXhSQzogVGhlIHJvd3MgYW5kIGNvbHVtbnMgb2YgdGhlIHRleGVscy4gSWYgeW91IG1vdmUgb3ZlciBvbmVcbiAgICAgKiB0ZXhlbCB0byB0aGUgcmlnaHQgaW4gdGhlIHBhY2tlZCB0ZXh0dXJlLCB5b3UgYXJlIG1vdmluZyBvdmVyIG9uZSBjb2x1bW5cbiAgICAgKiAobm90IHR3bykuXG4gICAgICpcbiAgICAgKiBpbmRleDogVGhlIHRleGVsIGluZGV4XG4gICAgICovXG4gICAgc291cmNlID0gYFxuICAgICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuXG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7cGFja2VkVGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcblxuICAgICAgICAgIC8vIHJldmVyc2UgciBhbmQgYyBvcmRlciBmb3IgcGFja2VkIHRleHR1cmVcbiAgICAgICAgICBpbnQgciA9IGltb2QoaW5kZXgsICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSkgKiAyO1xuICAgICAgICAgIGludCBjID0gMiAqIChpbmRleCAvICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSk7XG5cbiAgICAgICAgICByZXR1cm4gaXZlYzIociwgYyk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIDNEIHBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0UGFja2VkM0RDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSBbdGV4U2hhcGVbMF0sIHRleFNoYXBlWzFdXTtcbiAgICBjb25zdCB0ZXhlbHNJbkxvZ2ljYWxSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMl0gLyAyKTtcbiAgICBjb25zdCB0ZXhlbHNJbkJhdGNoID0gdGV4ZWxzSW5Mb2dpY2FsUm93ICogTWF0aC5jZWlsKHNoYXBlWzFdIC8gMik7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBpdmVjMyBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG5cbiAgICAgICAgICBpbnQgYiA9IGluZGV4IC8gJHt0ZXhlbHNJbkJhdGNofTtcbiAgICAgICAgICBpbmRleCAtPSBiICogJHt0ZXhlbHNJbkJhdGNofTtcblxuICAgICAgICAgIC8vIHJldmVyc2UgciBhbmQgYyBvcmRlciBmb3IgcGFja2VkIHRleHR1cmVcbiAgICAgICAgICBpbnQgciA9IGltb2QoaW5kZXgsICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSkgKiAyO1xuICAgICAgICAgIGludCBjID0gMiAqIChpbmRleCAvICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSk7XG5cbiAgICAgICAgICByZXR1cm4gaXZlYzMoYiwgciwgYyk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIE5EIHBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0UGFja2VkTkRDb29yZHMoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV1dO1xuXG4gICAgY29uc3QgdGV4ZWxzSW5Mb2dpY2FsUm93ID0gTWF0aC5jZWlsKHNoYXBlW3NoYXBlLmxlbmd0aCAtIDFdIC8gMik7XG4gICAgY29uc3QgdGV4ZWxzSW5CYXRjaCA9IHRleGVsc0luTG9naWNhbFJvdyAqIE1hdGguY2VpbChzaGFwZVtzaGFwZS5sZW5ndGggLSAyXSAvIDIpO1xuICAgIGxldCB0ZXhlbHNJbkJhdGNoTiA9IHRleGVsc0luQmF0Y2g7XG4gICAgbGV0IGJhdGNoZXMgPSAnJztcbiAgICBsZXQgY29vcmRzID0gJ2IsIHIsIGMnO1xuXG4gICAgZm9yIChsZXQgYiA9IDI7IGIgPCBzaGFwZS5sZW5ndGggLSAxOyBiKyspIHtcbiAgICAgIHRleGVsc0luQmF0Y2hOICo9IHNoYXBlW3NoYXBlLmxlbmd0aCAtIGIgLSAxXTtcbiAgICAgIGJhdGNoZXMgPVxuICAgICAgICBgXG4gICAgICBpbnQgYiR7Yn0gPSBpbmRleCAvICR7dGV4ZWxzSW5CYXRjaE59O1xuICAgICAgaW5kZXggLT0gYiR7Yn0gKiAke3RleGVsc0luQmF0Y2hOfTtcbiAgICBgICsgYmF0Y2hlcztcbiAgICAgIGNvb3JkcyA9IGBiJHtifSwgYCArIGNvb3JkcztcbiAgICB9XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgaXZlYyR7c2hhcGUubGVuZ3RofSBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7cGFja2VkVGV4U2hhcGVbMV19KSk7XG4gICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG5cbiAgICAgICAgJHtiYXRjaGVzfVxuXG4gICAgICAgIGludCBiID0gaW5kZXggLyAke3RleGVsc0luQmF0Y2h9O1xuICAgICAgICBpbmRleCAtPSBiICogJHt0ZXhlbHNJbkJhdGNofTtcblxuICAgICAgICAvLyByZXZlcnNlIHIgYW5kIGMgb3JkZXIgZm9yIHBhY2tlZCB0ZXh0dXJlXG4gICAgICAgIGludCByID0gaW1vZChpbmRleCwgJHt0ZXhlbHNJbkxvZ2ljYWxSb3d9KSAqIDI7XG4gICAgICAgIGludCBjID0gMiAqIChpbmRleCAvICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSk7XG5cbiAgICAgICAgcmV0dXJuIGl2ZWMke3NoYXBlLmxlbmd0aH0oJHtjb29yZHN9KTtcbiAgICAgIH1cbiAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAxRCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQxRENvb3Jkcyhfc2hhcGU6IFtudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIHJldHVybiByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAyRCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQyRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgaW50IHIgPSBpbmRleCAvICR7c2hhcGVbMV19O1xuICAgICAgICAgIGludCBjID0gaW5kZXggLSByICogJHtzaGFwZVsxXX07XG4gICAgICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAzRCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQzRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAgIGxldCBzdHJpZGVzID0gbnVsbDtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHN0cmlkZXMgPSBbXTtcbiAgICB9XG5cbiAgICBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmsgLSAxKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IHNoYXBlW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBzaGFwZVtpICsgMV07XG4gICAgfVxuICAgIGNvbnN0IGNvb3Jkc1RvQ29tcHV0ZSA9IFsncicsICdjJywgJ2QnXTtcbiAgICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID0gc3RyaWRlc1xuICAgICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gPSBpbmRleCAvICR7c3RyaWRlfWA7XG4gICAgICAgIGNvbnN0IGxpbmUyID1cbiAgICAgICAgICBpID09PSBzdHJpZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICAgID8gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpICsgMV19ID0gaW5kZXggLSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gXG4gICAgICAgICAgICA6IGBpbmRleCAtPSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gO1xuICAgICAgICByZXR1cm4gYCR7bGluZTF9OyAke2xpbmUyfTtgO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcnKTtcblxuICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzMgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgICByZXR1cm4gaXZlYzMociwgYywgZCk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDREIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDREQ29vcmRzKFxuICAgIHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCcsICdkMiddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgPyBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWBcbiAgICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICAgaXZlYzQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgICByZXR1cm4gaXZlYzQociwgYywgZCwgZDIpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA1RCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQ1RENvb3JkcyhcbiAgICBzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCcsICdkMicsICdkMyddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgPyBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWBcbiAgICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICAgaXZlYzUgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgICByZXR1cm4gaXZlYzUociwgYywgZCwgZDIsIGQzKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNkQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkNkRDb29yZHMoXG4gICAgc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSxcbiAgKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCcsICdkMicsICdkMycsICdkNCddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPSBzdHJpZGVzXG4gICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgY29uc3QgbGluZTIgPVxuICAgICAgICAgIGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMVxuICAgICAgICAgICAgPyBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWBcbiAgICAgICAgICAgIDogYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICBpdmVjNiBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAke2Nvb3Jkc0Zyb21JbmRleFNuaXBwZXR9XG4gICAgICAgICByZXR1cm4gaXZlYzYociwgYywgZCwgZDIsIGQzLCBkNCk7XG4gICAgICAgfVxuICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3IgY29tbW9uIFVWIGNvb3JkcyBjb21wdXRhdGlvbiB1dGlsaXR5IGZ1bmN0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRDb21tb25VdGlsRnVuY3MoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgbGV0IGZ1bmNOYW1lID0gJ3V2RnJvbUZsYXQnO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgIHZlYzIgdXZGcm9tRmxhdChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsIGludCBpbmRleCkge1xuICAgICAgaW50IHRleEMgPSBpbmRleCAvIHRleE51bVI7XG4gICAgICBpbnQgdGV4UiA9IGluZGV4IC0gdGV4QyAqIHRleE51bVI7XG4gICAgICAvLyBUT0RPOiBzd2FwIHRleFIsIHRleEMgb3JkZXIgaW4gZm9sbG93aW5nIGZ1bmN0aW9uIHNvIHJvdyBpcyBjb3JyZXNwb25kaW5nIHRvIHUgYW5kIGNvbHVtbiBpcyBjb3JyZXNwb25kaW5nIHRvXG4gICAgICAvLyAgICAgICB2LlxuICAgICAgcmV0dXJuICh2ZWMyKHRleFIsIHRleEMpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtUiwgdGV4TnVtQyk7XG4gICAgfVxuICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3BhY2tlZFVWZnJvbTFEJztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgcGFja2VkVVZmcm9tMUQoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLCBpbnQgaW5kZXgpIHtcbiAgICAgICAgaW50IHRleGVsSW5kZXggPSBpbmRleCAvIDI7XG4gICAgICAgIGludCB0ZXhSID0gdGV4ZWxJbmRleCAvIHRleE51bUM7XG4gICAgICAgIGludCB0ZXhDID0gdGV4ZWxJbmRleCAtIHRleFIgKiB0ZXhOdW1DO1xuICAgICAgICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTtcbiAgICAgIH1cbiAgICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3BhY2tlZFVWZnJvbTJEJztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgcGFja2VkVVZmcm9tMkQoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLCBpbnQgdGV4ZWxzSW5Mb2dpY2FsUm93LCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIGludCB0ZXhlbEluZGV4ID0gKHJvdyAvIDIpICogdGV4ZWxzSW5Mb2dpY2FsUm93ICsgKGNvbCAvIDIpO1xuICAgICAgICBpbnQgdGV4UiA9IHRleGVsSW5kZXggLyB0ZXhOdW1DO1xuICAgICAgICBpbnQgdGV4QyA9IHRleGVsSW5kZXggLSB0ZXhSICogdGV4TnVtQztcbiAgICAgICAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7XG4gICAgICB9XG4gICAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdwYWNrZWRVVmZyb20zRCc7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICB2ZWMyIHBhY2tlZFVWZnJvbTNEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQyxcbiAgICAgICAgICBpbnQgdGV4ZWxzSW5CYXRjaCwgaW50IHRleGVsc0luTG9naWNhbFJvdywgaW50IGIsXG4gICAgICAgICAgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICBpbnQgaW5kZXggPSBiICogdGV4ZWxzSW5CYXRjaCArIChyb3cgLyAyKSAqIHRleGVsc0luTG9naWNhbFJvdyArIChjb2wgLyAyKTtcbiAgICAgICAgaW50IHRleFIgPSBpbmRleCAvIHRleE51bUM7XG4gICAgICAgIGludCB0ZXhDID0gaW5kZXggLSB0ZXhSICogdGV4TnVtQztcbiAgICAgICAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7XG4gICAgICB9XG4gICAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdzYW1wbGVUZXh0dXJlJztcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgICBmbG9hdCBzYW1wbGVUZXh0dXJlKHNhbXBsZXIyRCB0ZXh0dXJlU2FtcGxlciwgdmVjMiB1dikge1xuICAgICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KHRleHR1cmVTYW1wbGVyLCB1dikucjtcbiAgICAgICAgfWApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciBpbnB1dHNcbiAgICovXG4gIHByb3RlY3RlZCBnZXRJbnB1dHNTYW1wbGluZ1NuaXBwZXRzKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKHNhbXBsZXJOYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBpbnB1dExheW91dCA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldO1xuICAgICAgY29uc3QgZnVuY05hbWUgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUoc2FtcGxlck5hbWUpO1xuICAgICAgaWYgKGlucHV0TGF5b3V0LmlzUGFja2VkKSB7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldFBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIHNhbXBsZXJOYW1lLCBpbnB1dExheW91dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIHNhbXBsZXJOYW1lLCBpbnB1dExheW91dCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dENvb3JkRnVuY05hbWUgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcyhzYW1wbGVyTmFtZSk7XG4gICAgICBpZiAoaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGggPD0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoKSB7XG4gICAgICAgIGlmIChpbnB1dExheW91dC5pc1BhY2tlZCkge1xuICAgICAgICAgIHJlc3VsdFtvdXRDb29yZEZ1bmNOYW1lXSA9IHRoaXMuZ2V0UGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgICAgICAgICAgb3V0Q29vcmRGdW5jTmFtZSxcbiAgICAgICAgICAgIGlucHV0TGF5b3V0LFxuICAgICAgICAgICAgb3V0cHV0TGF5b3V0LFxuICAgICAgICAgICAgc2FtcGxlck5hbWUsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHRbb3V0Q29vcmRGdW5jTmFtZV0gPSB0aGlzLmdldFVucGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgICAgICAgICAgb3V0Q29vcmRGdW5jTmFtZSxcbiAgICAgICAgICAgIGlucHV0TGF5b3V0LFxuICAgICAgICAgICAgb3V0cHV0TGF5b3V0LFxuICAgICAgICAgICAgc2FtcGxlck5hbWUsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIG91dHB1dCBjb29yZGluYXRlcyBvZiBzYW1wbGVyc1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJBdE91dHB1dENvb3JkcyhcbiAgICBmdW5jTmFtZTogc3RyaW5nLFxuICAgIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBpblNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleE5hbWUgPSBuYW1lO1xuICAgIGNvbnN0IHRleEZ1bmNTbmlwcGV0ID0gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lKHRleE5hbWUpO1xuXG4gICAgY29uc3QgaW5SYW5rID0gaW5TaGFwZS5sZW5ndGg7XG4gICAgY29uc3Qgb3V0UmFuayA9IG91dFNoYXBlLmxlbmd0aDtcblxuICAgIGNvbnN0IGJyb2FkY2FzdERpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5TaGFwZSwgb3V0U2hhcGUpO1xuXG4gICAgY29uc3QgdHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dFJhbmspO1xuICAgIGNvbnN0IHJhbmtEaWZmID0gb3V0UmFuayAtIGluUmFuaztcbiAgICBsZXQgY29vcmRzU25pcHBldDogc3RyaW5nO1xuICAgIGNvbnN0IGZpZWxkcyA9IGdldEdsQ2hhbm5lbHMoKTtcblxuICAgIGlmIChpblJhbmsgPT09IDApIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICB9IGVsc2UgaWYgKG91dFJhbmsgPCAyICYmIGJyb2FkY2FzdERpbXMubGVuZ3RoID49IDEpIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnY29vcmRzID0gMDsnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gYnJvYWRjYXN0RGltcy5tYXAoKGQpID0+IGBjb29yZHMuJHtmaWVsZHNbZCArIHJhbmtEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICAgIH1cbiAgICBsZXQgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJyc7XG4gICAgaWYgKG91dFJhbmsgPCAyICYmIGluUmFuayA+IDApIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9ICdjb29yZHMnO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSBpblNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHtmaWVsZHNbaSArIHJhbmtEaWZmXX1gKS5qb2luKCcsICcpO1xuICAgIH1cblxuICAgIGxldCBvdXRwdXQgPSAncmV0dXJuIG91dHB1dFZhbHVlOyc7XG4gICAgY29uc3QgaW5TaXplID0gU2hhcGVVdGlsLnNpemUoaW5TaGFwZSk7XG4gICAgY29uc3QgaXNJbnB1dFNjYWxhciA9IGluU2l6ZSA9PT0gMTtcbiAgICBjb25zdCBvdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0U2hhcGUpO1xuICAgIGNvbnN0IGlzT3V0cHV0U2NhbGFyID0gb3V0U2l6ZSA9PT0gMTtcblxuICAgIGlmIChpblJhbmsgPT09IDEgJiYgIWlzSW5wdXRTY2FsYXIgJiYgIWlzT3V0cHV0U2NhbGFyKSB7XG4gICAgICBvdXRwdXQgPSBgXG4gICAgICAgIHJldHVybiB2ZWM0KG91dHB1dFZhbHVlLnh5LCBvdXRwdXRWYWx1ZS54eSk7XG4gICAgICBgO1xuICAgIH0gZWxzZSBpZiAoaXNJbnB1dFNjYWxhciAmJiAhaXNPdXRwdXRTY2FsYXIpIHtcbiAgICAgIGlmIChvdXRSYW5rID09PSAxKSB7XG4gICAgICAgIG91dHB1dCA9IGBcbiAgICAgICAgICByZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54LCBvdXRwdXRWYWx1ZS54LCAwLiwgMC4pO1xuICAgICAgICBgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0ID0gYFxuICAgICAgICAgIHJldHVybiB2ZWM0KG91dHB1dFZhbHVlLngpO1xuICAgICAgICBgO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYnJvYWRjYXN0RGltcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHJvd3MgPSBpblJhbmsgLSAyO1xuICAgICAgY29uc3QgY29scyA9IGluUmFuayAtIDE7XG5cbiAgICAgIGlmIChicm9hZGNhc3REaW1zLmluZGV4T2Yocm93cykgPiAtMSAmJiBicm9hZGNhc3REaW1zLmluZGV4T2YoY29scykgPiAtMSkge1xuICAgICAgICBvdXRwdXQgPSAncmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCk7JztcbiAgICAgIH0gZWxzZSBpZiAoYnJvYWRjYXN0RGltcy5pbmRleE9mKHJvd3MpID4gLTEpIHtcbiAgICAgICAgb3V0cHV0ID0gJ3JldHVybiB2ZWM0KG91dHB1dFZhbHVlLngsIG91dHB1dFZhbHVlLnksICcgKyAnb3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueSk7JztcbiAgICAgIH0gZWxzZSBpZiAoYnJvYWRjYXN0RGltcy5pbmRleE9mKGNvbHMpID4gLTEpIHtcbiAgICAgICAgb3V0cHV0ID0gJ3JldHVybiB2ZWM0KG91dHB1dFZhbHVlLnh4LCBvdXRwdXRWYWx1ZS56eik7JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzd2FwTGFzdERpbXNTbmlwcGV0ID0gYFxuICAgICAgICBpbnQgbGFzdERpbSA9IGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMV19O1xuICAgICAgICBjb29yZHMuJHtmaWVsZHNbb3V0UmFuayAtIDFdfSA9IGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMl19O1xuICAgICAgICBjb29yZHMuJHtmaWVsZHNbb3V0UmFuayAtIDJdfSA9IGxhc3REaW07XG4gICAgICBgO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgIHZlYzQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICR7dHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICR7c3dhcExhc3REaW1zU25pcHBldH1cbiAgICAgICAgJHtjb29yZHNTbmlwcGV0fVxuICAgICAgICB2ZWM0IG91dHB1dFZhbHVlID0gJHt0ZXhGdW5jU25pcHBldH0oJHt1bnBhY2tlZENvb3Jkc1NuaXBwZXR9KTtcbiAgICAgICAgJHtvdXRwdXR9XG4gICAgICB9XG4gICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5nZXRPdXRwdXRDb29yZHMnXSk7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciB1bnBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMgb2Ygc2FtcGxlcnNcbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXJBdE91dHB1dENvb3JkcyhcbiAgICBmdW5jTmFtZTogc3RyaW5nLFxuICAgIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBvdXRUZXhTaGFwZSA9IFtvdXRwdXRMYXlvdXQud2lkdGgsIG91dHB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IGluVGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgaW5SYW5rID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGg7XG4gICAgY29uc3Qgb3V0UmFuayA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBpblNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleEZ1bmNTbmlwcGV0ID0gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lKG5hbWUpO1xuXG4gICAgaWYgKGluUmFuayA9PT0gb3V0UmFuayAmJiBBcnJheVV0aWwuYXJyYXlzRXF1YWwoaW5UZXhTaGFwZSwgb3V0VGV4U2hhcGUpKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBUZXhDb29yZHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dFJhbmspO1xuICAgIGNvbnN0IGJyb2FkY2FzdERpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5TaGFwZSwgb3V0U2hhcGUpO1xuICAgIGNvbnN0IHJhbmtEaWZmID0gb3V0UmFuayAtIGluUmFuaztcbiAgICBsZXQgY29vcmRzU25pcHBldDogc3RyaW5nO1xuICAgIGNvbnN0IGZpZWxkcyA9IGdldEdsQ2hhbm5lbHMoKTtcblxuICAgIGlmIChpblJhbmsgPT09IDApIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICB9IGVsc2UgaWYgKG91dFJhbmsgPCAyICYmIGJyb2FkY2FzdERpbXMubGVuZ3RoID49IDEpIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnY29vcmRzID0gMDsnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gYnJvYWRjYXN0RGltcy5tYXAoKGQpID0+IGBjb29yZHMuJHtmaWVsZHNbZCArIHJhbmtEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICAgIH1cbiAgICBsZXQgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJyc7XG4gICAgaWYgKG91dFJhbmsgPCAyICYmIGluUmFuayA+IDApIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9ICdjb29yZHMnO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHtmaWVsZHNbaSArIHJhbmtEaWZmXX1gKS5qb2luKCcsICcpO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICR7dHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICAgJHtjb29yZHNTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiAke3RleEZ1bmNTbmlwcGV0fSgke3VucGFja2VkQ29vcmRzU25pcHBldH0pO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLmdldE91dHB1dENvb3JkcyddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIHBhY2tlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBzd2l0Y2ggKGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXJTY2FsYXIoZnVuY05hbWUsIG5hbWUpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyMUQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXIzRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlck5EKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3IgdW5wYWNrZWQgb3BlcmF0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgc3dpdGNoIChzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjREKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDU6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjVEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDY6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjZEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBUT0RPIHN1cHBvcnQgbW9yZSBkaW1lbnNpb25hbGl0aWVzXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZGltZW5zaW9uICR7c2hhcGUubGVuZ3RofS1EYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhY2tlZCBzY2FsYXIgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICB2ZWM0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIGhhbGZDUik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgMUQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyMUQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCB0ZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVsxXSwgdGV4U2hhcGVbMF1dO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMUQoXG4gICAgICAke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0sIGluZGV4KTtcbiAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgfWA7XG4gICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5wYWNrZWRVVmZyb20xRCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgMkQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyMkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICBjb25zdCB0ZXhOdW1SID0gdGV4U2hhcGVbMF07XG4gICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzFdO1xuXG4gICAgaWYgKHRleFNoYXBlICE9IG51bGwgJiYgQXJyYXlVdGlsLmFycmF5c0VxdWFsKHNoYXBlLCB0ZXhTaGFwZSkpIHtcbiAgICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIHZlYzIgdXYgPSAodmVjMihjb2wsIHJvdykgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bUN9LjAsICR7dGV4TnVtUn0uMCk7XG4gICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgICB9YDtcblxuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShwYWNrZWRTYW1wbGVyKTtcbiAgICB9XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSB0ZXhTaGFwZTtcbiAgICBjb25zdCB2YWx1ZXNQZXJSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgdmVjMiB1diA9IHBhY2tlZFVWZnJvbTJEKCR7cGFja2VkVGV4U2hhcGVbMV19LCAke3BhY2tlZFRleFNoYXBlWzBdfSwgJHt2YWx1ZXNQZXJSb3d9LCByb3csIGNvbCk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgIH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMucGFja2VkVVZmcm9tMkQnXSk7XG4gIH1cblxuICAvKipcbiAgICogUGFja2VkIDNEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgIGlmIChzaGFwZVswXSA9PT0gMSkge1xuICAgICAgY29uc3Qgc3F1ZWV6ZWRTaGFwZSA9IHNoYXBlLnNsaWNlKDEpO1xuICAgICAgY29uc3Qga2VwdERpbXMgPSBbMSwgMl07XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydiJywgJ3JvdycsICdjb2wnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG4gICAgICBjb25zdCBzYW1wbGVyUm91dGluZSA9IHRoaXMuZ2V0UGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpO1xuICAgICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGAke3NhbXBsZXJSb3V0aW5lLnJvdXRpbmVCb2R5fVxuICAgICAgdmVjNCAke2Z1bmNOYW1lfShpbnQgYiwgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgfSBgO1xuICAgICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBzYW1wbGVyUm91dGluZS5kZXBlbmRlbmNpZXMpO1xuICAgIH1cbiAgICBjb25zdCB0ZXhOdW1SID0gcGFja2VkVGV4U2hhcGVbMF07XG4gICAgY29uc3QgdGV4TnVtQyA9IHBhY2tlZFRleFNoYXBlWzFdO1xuXG4gICAgY29uc3QgdmFsdWVzUGVyUm93ID0gTWF0aC5jZWlsKHNoYXBlWzJdIC8gMik7XG4gICAgY29uc3QgdGV4ZWxzSW5CYXRjaCA9IHZhbHVlc1BlclJvdyAqIE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuXG4gICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGB2ZWM0ICR7ZnVuY05hbWV9KGludCBiLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tM0QoXG4gICAgICAgICR7dGV4TnVtQ30sICR7dGV4TnVtUn0sICR7dGV4ZWxzSW5CYXRjaH0sICR7dmFsdWVzUGVyUm93fSwgYiwgcm93LCBjb2wpO1xuICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTt9YDtcbiAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnBhY2tlZFVWZnJvbTNEJ10pO1xuICB9XG4gIC8qXG4gICAqIFBhY2tlZCBORCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJORChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV1dO1xuICAgIGNvbnN0IHRleE51bVIgPSBwYWNrZWRUZXhTaGFwZVsxXTtcbiAgICBjb25zdCB0ZXhOdW1DID0gcGFja2VkVGV4U2hhcGVbMF07XG4gICAgY29uc3QgdmFsdWVzUGVyUm93ID0gTWF0aC5jZWlsKHNoYXBlW3JhbmsgLSAxXSAvIDIpO1xuICAgIGxldCB0ZXhlbHNJbkJhdGNoID0gdmFsdWVzUGVyUm93ICogTWF0aC5jZWlsKHNoYXBlW3JhbmsgLSAyXSAvIDIpO1xuICAgIGxldCBwYXJhbXMgPSAnaW50IGIsIGludCByb3csIGludCBjb2wnO1xuICAgIGxldCBpbmRleCA9IGBiICogJHt0ZXhlbHNJbkJhdGNofSArIChyb3cgLyAyKSAqICR7dmFsdWVzUGVyUm93fSArIChjb2wgLyAyKWA7XG4gICAgZm9yIChsZXQgYiA9IDI7IGIgPCByYW5rIC0gMTsgYisrKSB7XG4gICAgICBwYXJhbXMgPSBgaW50IGIke2J9LCBgICsgcGFyYW1zO1xuICAgICAgdGV4ZWxzSW5CYXRjaCAqPSBzaGFwZVtyYW5rIC0gYiAtIDFdO1xuICAgICAgaW5kZXggPSBgYiR7Yn0gKiAke3RleGVsc0luQmF0Y2h9ICsgYCArIGluZGV4O1xuICAgIH1cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oJHtwYXJhbXN9KSB7XG4gICAgICBpbnQgaW5kZXggPSAke2luZGV4fTtcbiAgICAgIGludCB0ZXhSID0gaW5kZXggLyAke3RleE51bUN9O1xuICAgICAgaW50IHRleEMgPSBpbmRleCAtIHRleFIgKiAke3RleE51bUN9O1xuICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIoJHt0ZXhOdW1DfSwgJHt0ZXhOdW1SfSk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgIH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIHNjYWxhciBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlclNjYWxhcihmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IFt0ZXhOdW1SLCB0ZXhOdW1DXSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBpZiAodGV4TnVtUiA9PT0gMSAmJiB0ZXhOdW1DID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBoYWxmQ1IpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICBpbnQgb2Zmc2V0XyR7bmFtZX0gPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7dGV4TnVtUn0sICR7dGV4TnVtQ30pO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIG9mZnNldF8ke25hbWV9KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFtcbiAgICAgICdjb29yZGluYXRlcy51dkZyb21GbGF0JyxcbiAgICAgICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJyxcbiAgICAgICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCcsXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMUQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXIxRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHROdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdE51bUMgPSBpbnB1dExheW91dC5oZWlnaHQ7XG5cbiAgICBpZiAodE51bUMgPT09IDEgJiYgdE51bVIgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgaGFsZkNSKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgaWYgKHROdW1DID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdmVjMigoZmxvYXQoaW5kZXgpICsgMC41KSAvICR7dE51bVJ9LjAsIDAuNSk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG4gICAgaWYgKHROdW1SID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdmVjMigwLjUsIChmbG9hdChpbmRleCkgKyAwLjUpIC8gJHt0TnVtQ30uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3ROdW1SfSwgJHt0TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDJEIHNuaXBwZXQuXG4gICAqL1xuXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXIyRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcblxuICAgIC8vIFRPRE86IG1vZGlmeSByb3cvY29sIG9yZGVyIGZvciBvdGhlciBkaW1lbnNpb25zLlxuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LmhlaWdodCwgaW5wdXRMYXlvdXQud2lkdGhdO1xuXG4gICAgaWYgKHRleFNoYXBlICE9IG51bGwgJiYgQXJyYXlVdGlsLmFycmF5c0VxdWFsKHNoYXBlLCB0ZXhTaGFwZSkpIHtcbiAgICAgIGNvbnN0IHRleE51bVIgPSB0ZXhTaGFwZVsxXTtcbiAgICAgIGNvbnN0IHRleE51bUMgPSB0ZXhTaGFwZVswXTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gKHZlYzIocm93LCBjb2wpICsgaGFsZkNSKSAvIHZlYzIoJHt0ZXhOdW1SfS4wLCAke3RleE51bUN9LjApO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBuZXdTaGFwZSwga2VwdERpbXMgfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgY29uc3Qgc3F1ZWV6ZWRTaGFwZSA9IG5ld1NoYXBlO1xuICAgIGlmIChzcXVlZXplZFNoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBzcXVlZXplZFNoYXBlKTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IFsnY29sJywgJ3JvdyddO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IHRleFNoYXBlWzFdO1xuICAgIGNvbnN0IHRleE51bUMgPSB0ZXhTaGFwZVswXTtcbiAgICBpZiAodGV4TnVtQyA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCBvZmZzZXRfJHtuYW1lfSksIHZlYzMoJHtzaGFwZVsxXX0sIDEsIDEpKTtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKDAuNSwgKGluZGV4ICsgMC41KSAvICR7dGV4TnVtUn0uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICB9XG5cbiAgICBpZiAodGV4TnVtUiA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCBvZmZzZXRfJHtuYW1lfSksIHZlYzMoJHtzaGFwZVsxXX0sIDEsIDEpKTtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKChpbmRleCArIDAuNSkgLyAke3RleE51bUN9LjAsIDAuNSk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICBpbnQgaW5kZXggPSBjb2wgKiAke3NoYXBlWzFdfSArIHJvdztcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbXG4gICAgICAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsXG4gICAgICAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsXG4gICAgICAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDNEIHNuaXBwZXQuXG4gICAqL1xuXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXIzRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBzdHJpZGUwID0gc2hhcGVbMV0gKiBzaGFwZVsyXTtcbiAgICBjb25zdCBzdHJpZGUxID0gc2hhcGVbMl07XG5cbiAgICBjb25zdCB7IG5ld1NoYXBlLCBrZXB0RGltcyB9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICBjb25zdCBzcXVlZXplZFNoYXBlID0gbmV3U2hhcGU7XG4gICAgaWYgKHNxdWVlemVkU2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydiYXRjaCcsICdjb2wnLCAncm93J107XG4gICAgICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuICAgICAgY29uc3Qgcm91dGluZSA9IHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCk7XG4gICAgICAvLyBUT0RPOiByZXZpc2l0IHRoZSBsb2dpYyBoZXJlIHRvIG1ha2UgaXQgc2ltcGxlclxuICAgICAgY29uc3QgcmV2RGltcyA9IGtlcHREaW1zLnJldmVyc2UoKTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAke3JvdXRpbmUucm91dGluZUJvZHl9XG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGJhdGNoLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIHJldkRpbXMpfSk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIHJvdXRpbmUuZGVwZW5kZW5jaWVzKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGRlcHRoLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICAvLyBFeHBsaWNpdGx5IHVzZSBpbnRlZ2VyIG9wZXJhdGlvbnMgYXMgZG90KCkgb25seSB3b3JrcyBvbiBmbG9hdHMuXG4gICAgICAgICAgICBpbnQgaW5kZXggPSBkZXB0aCAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgcm93O1xuICAgICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFtcbiAgICAgICdjb29yZGluYXRlcy51dkZyb21GbGF0JyxcbiAgICAgICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJyxcbiAgICAgICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCcsXG4gICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNEQgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjREKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHN0cmlkZTIgPSBzaGFwZVszXTtcbiAgICBjb25zdCBzdHJpZGUxID0gc2hhcGVbMl0gKiBzdHJpZGUyO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHN0cmlkZTE7XG5cbiAgICAvL1xuICAgIC8vIFRPRE86IHJlLWVuYWJsZSB0aGlzIHNob3J0Y3V0IG9uY2UgdGhlIGluZGV4IGNhbGN1bGF0aW9uIGJ1ZyBpcyBmaXhlZC5cbiAgICAvL1xuICAgIC8vIGNvbnN0IHtuZXdTaGFwZSwga2VwdERpbXN9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICAvLyBpZiAobmV3U2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgLy8gICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIG5ld1NoYXBlKTtcbiAgICAvLyAgIGNvbnN0IHBhcmFtcyA9IFsncm93JywgJ2NvbCcsICdkZXB0aCcsICdkZXB0aDInXTtcbiAgICAvLyAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAvLyAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgIC8vICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG4gICAgLy8gICBjb25zdCBzb3VyY2UgPSBgXG4gICAgLy8gICAgICAgJHt0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpLnJvdXRpbmVCb2R5fVxuICAgIC8vICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikge1xuICAgIC8vICAgICAgICAgcmV0dXJuICR7ZnVuY05hbWV9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zLCBrZXB0RGltcyl9KTtcbiAgICAvLyAgICAgICB9XG4gICAgLy8gICAgIGA7XG4gICAgLy8gICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgIC8vICAgICAgIHNvdXJjZSwgWydjb29yZGluYXRlcy51dkZyb21GbGF0JywgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSk7XG4gICAgLy8gfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IGlucHV0TGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IHRleE51bUMgPSBpbnB1dExheW91dC5oZWlnaHQ7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIpIHtcbiAgICAgICAgICBpbnQgaW5kZXggPSByb3cgKiAke3N0cmlkZTB9ICsgY29sICogJHtzdHJpZGUxfSArXG4gICAgICAgICAgICAgIGRlcHRoMiAqICR7c3RyaWRlMn0gKyBkZXB0aDtcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA1RCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjVEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHN0cmlkZTMgPSBzaGFwZVs0XTtcbiAgICBjb25zdCBzdHJpZGUyID0gc2hhcGVbM10gKiBzdHJpZGUzO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXSAqIHN0cmlkZTI7XG4gICAgY29uc3Qgc3RyaWRlMCA9IHNoYXBlWzFdICogc3RyaWRlMTtcblxuICAgIGNvbnN0IHsgbmV3U2hhcGUsIGtlcHREaW1zIH0gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMicsICdkZXB0aDMnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMiwgaW50IGRlcHRoMykge1xuICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgZGVwdGggKiAke3N0cmlkZTJ9ICtcbiAgICAgICAgICBkZXB0aDMgKiAke3N0cmlkZTN9ICsgZGVwdGgyO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy51dkZyb21GbGF0J10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDZEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlNCA9IHNoYXBlWzVdO1xuICAgIGNvbnN0IHN0cmlkZTMgPSBzaGFwZVs0XSAqIHN0cmlkZTQ7XG4gICAgY29uc3Qgc3RyaWRlMiA9IHNoYXBlWzNdICogc3RyaWRlMztcbiAgICBjb25zdCBzdHJpZGUxID0gc2hhcGVbMl0gKiBzdHJpZGUyO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHN0cmlkZTE7XG5cbiAgICBjb25zdCB7IG5ld1NoYXBlLCBrZXB0RGltcyB9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICBpZiAobmV3U2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIG5ld1NoYXBlKTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IFsncm93JywgJ2NvbCcsICdkZXB0aCcsICdkZXB0aDInLCAnZGVwdGgzJywgJ2RlcHRoNCddO1xuICAgICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcblxuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICAgJHt0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpLnJvdXRpbmVCb2R5fVxuICAgICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLFxuICAgICAgICAgICAgICBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzLCBpbnQgZGVwdGg0KSB7XG4gICAgICAgICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywga2VwdERpbXMpfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLFxuICAgICAgICAgICAgaW50IGRlcHRoMiwgaW50IGRlcHRoMywgaW50IGRlcHRoNCkge1xuICAgICAgICAgICAgaW50IGluZGV4ID0gcm93ICogJHtzdHJpZGUwfSArIGNvbCAqICR7c3RyaWRlMX0gKyBkZXB0aCAqICR7c3RyaWRlMn0gK1xuICAgICAgICAgICAgZGVwdGgyICogJHtzdHJpZGUzfSArIGRlcHRoMyAqICR7c3RyaWRlNH0gKyBkZXB0aDQ7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbXG4gICAgICAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsXG4gICAgICAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsXG4gICAgICAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgdGhlIG1haW4gZnVuY3Rpb24gdG8gbWFwIGZyb20gdGhlIGdpdmVuIHRleHR1cmUgY29vcmRpbmF0ZXMgKHMsdClcbiAgICogdG8gbG9naWNhbCBpbmRpY2VzIGZvciB0aGUgb3V0cHV0XG4gICAqIFRoZXJlIHdpbGwgb25seSBiZSBvbmUgc2luZ2xlIHZhcmlhdGlvbiBvZiB0aGlzXG4gICAqIEFsc28gc2VlIGNvb3Jkc1RvT2Zmc2V0IGFuZCBvZmZzZXRUb0luZGljZXMgZm9yIGlucHV0LXNwZWNpZmljIHZlcnNpb25zXG4gICAqL1xuICBwcm90ZWN0ZWQgdG9WZWMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3Qgc3RyaWRlcyA9IG91dHB1dC5zdHJpZGVzO1xuICAgIGNvbnN0IHhTY2FsZSA9IG91dHB1dC53aWR0aDtcbiAgICBjb25zdCB5U2NhbGUgPSBvdXRwdXQuaGVpZ2h0O1xuXG4gICAgY29uc3Qgc3RyaWRlc0Jsb2NrID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMTsgKytpKSB7XG4gICAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICAgIGNbJHtpfV0gPSBvZmZzZXQgLyAke3N0cmlkZXNbaV19O2ApO1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBvZmZzZXQgLT0gY1ske2l9XSAqICR7c3RyaWRlc1tpXX07YCk7XG4gICAgfVxuICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgICAgY1ske3JhbmsgLSAxfV0gPSBvZmZzZXQ7YCk7XG4gICAgY29uc3QgYm9keSA9IGBcbiAgICAgIHZvaWQgdG9WZWModmVjMiB0ZXhDb29yZHMsIG91dCBpbnQgY1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gY29vcmRzVG9PZmZzZXQodGV4Q29vcmRzLCAke3hTY2FsZX0sICR7eVNjYWxlfSk7XG4gICAgICAgICR7c3RyaWRlc0Jsb2NrLmpvaW4oJycpfVxuICAgICAgfVxuICAgICAgdm9pZCB0b1ZlYyhpbnQgb2Zmc2V0LCBvdXQgaW50IGNbJHtyYW5rfV0pIHtcbiAgICAgICAgJHtzdHJpZGVzQmxvY2suam9pbignJyl9XG4gICAgICB9XG4gICAgYDtcbiAgICByZXR1cm4geyB0b1ZlYzogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHksIFsnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSkgfTtcbiAgfVxuICAvKipcbiAgICogVGhlc2UgYXJlIHZhbHVlIGdldHRlciBmdW5jdGlvbnMgZ2VuZXJhdGVkIGZvciBlYWNoIGlucHV0XG4gICAqIEVhY2ggZnVuY3Rpb24gaXMgaGFyZHdpcmVkIHRvIHRoZSBuYW1lIGFuZCBkaW1lbnNpb25zIG9mIHRoZSBpbnB1dFxuICAgKiBBbiAnX1QnIHZhcmlhdGlvbiBpcyBhbHNvIHByb2R1Y2VkIHdoaWNoIGFjY2Vzc2VzIHZhbHVlcyBhcyBpZiB0aGVcbiAgICogaW5wdXQgd2FzIHRyYW5zcG9zZWRcbiAgICovXG4gIHByb3RlY3RlZCB2YWx1ZUZyb20oKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3QgbGF5b3V0ID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV07XG4gICAgICBjb25zdCBzaGFwZSA9IGxheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aCA+IDAgPyBsYXlvdXQudW5wYWNrZWRTaGFwZSA6IGxheW91dC5zaGFwZTtcbiAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICBsZXQgZnVuY05hbWUgPSBgXyR7bmFtZX1gO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZSh0aGlzLmdldFZhbHVlRnJvbVNpbmdsZShuYW1lLCByYW5rLCBsYXlvdXQud2lkdGgsIGxheW91dC5oZWlnaHQsIGZhbHNlKSwgW1xuICAgICAgICBgc2hhcGVVdGlscy5pbmRpY2VzVG9PZmZzZXQke2Z1bmNOYW1lfWAsXG4gICAgICAgICdjb29yZGluYXRlcy5vZmZzZXRUb0Nvb3JkcycsXG4gICAgICAgICdmcmFnY29sb3IuZ2V0Q29sb3JBc0Zsb2F0JyxcbiAgICAgIF0pO1xuICAgICAgZnVuY05hbWUgPSBmdW5jTmFtZSArICdfVCc7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKHRoaXMuZ2V0VmFsdWVGcm9tU2luZ2xlKG5hbWUsIHJhbmssIGxheW91dC53aWR0aCwgbGF5b3V0LmhlaWdodCwgdHJ1ZSksIFtcbiAgICAgICAgYHNoYXBlVXRpbHMuaW5kaWNlc1RvT2Zmc2V0JHtmdW5jTmFtZX1gLFxuICAgICAgICAnY29vcmRpbmF0ZXMub2Zmc2V0VG9Db29yZHMnLFxuICAgICAgICAnZnJhZ2NvbG9yLmdldENvbG9yQXNGbG9hdCcsXG4gICAgICBdKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIC8qKlxuICAgKiBQcm9kdWNlcyBvbmUgdmFsdWUgZ2V0dGVyIGZ1bmN0aW9uIGZvciB0aGUgbmFtZSBhbmQgcmFuayBnaXZlblxuICAgKiBJZiBhIHRyYW5zcG9zZSBpcyBzZXQgcHJvcGVyIG9mZnNldFRvQ29vcmRzIG1hcHBpbmcgd2lsbCBiZSB1c2VkXG4gICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSByYW5rIHJhbmsgb2YgdGhlIGlucHV0XG4gICAqIEBwYXJhbSB0cmFuc3Bvc2Ugd2hldGhlciBvciBub3Qgc2hvdWxkIGdlbmVyYXRlIGEgdHJhbnNwb3NlIHZhcmlhdGlvblxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFZhbHVlRnJvbVNpbmdsZShcbiAgICB2YXJOYW1lOiBzdHJpbmcsXG4gICAgcmFuazogbnVtYmVyLFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgdHJhbnNwb3NlOiBib29sZWFuLFxuICApOiBzdHJpbmcge1xuICAgIGxldCBuYW1lID0gYF8ke3Zhck5hbWV9YDtcbiAgICBpZiAodHJhbnNwb3NlKSB7XG4gICAgICBuYW1lID0gbmFtZSArICdfVCc7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgZmxvYXQgJHtuYW1lfShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXQke25hbWV9KG0pO1xuICAgICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfSgke3Zhck5hbWV9LCBjb29yZHMpKTtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIHBhY2tlZCB2YWx1ZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIHRoZSBuYW1lIGFuZCByYW5rIGdpdmVuXG4gICAqIElmIGEgdHJhbnNwb3NlIGlzIHNldCBwcm9wZXIgb2Zmc2V0VG9Db29yZHMgbWFwcGluZyB3aWxsIGJlIHVzZWRcbiAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZnVuY3Rpb25cbiAgICogQHBhcmFtIHJhbmsgcmFuayBvZiB0aGUgaW5wdXRcbiAgICogQHBhcmFtIHRyYW5zcG9zZSB3aGV0aGVyIG9yIG5vdCBzaG91bGQgZ2VuZXJhdGUgYSB0cmFuc3Bvc2UgdmFyaWF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkVmFsdWVGcm9tKFxuICAgIHZhck5hbWU6IHN0cmluZyxcbiAgICByYW5rOiBudW1iZXIsXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICB0cmFuc3Bvc2U6IGJvb2xlYW4sXG4gICk6IHN0cmluZyB7XG4gICAgbGV0IG5hbWUgPSBgXyR7dmFyTmFtZX1fUGFja2A7XG4gICAgaWYgKHRyYW5zcG9zZSkge1xuICAgICAgbmFtZSA9IG5hbWUgKyAnX1QnO1xuICAgIH1cbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJldHVybiBgXG4gICAgICAgIHZlYzQgJHtuYW1lfShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXRfJHt2YXJOYW1lfShtKTtcbiAgICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7dmFyTmFtZX0sIGNvb3Jkcyk7XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmUgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuXG4vKipcbiAqIFRoaXMgR0xTTCBsaWJyYXJ5IGhhbmRsZXMgcm91dGluZXMgY29udmVydGluZ1xuICogZmxvYXQzMiB0by9mcm9tIFVuc2lnbmVkIGJ5dGUgb3IgZmxvYXQgMTZcbiAqL1xuZXhwb3J0IGNsYXNzIEVuY29kaW5nR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4geyAuLi50aGlzLmVuY29kZUZsb2F0MzIoKSwgLi4udGhpcy5kZWNvZGVGbG9hdDMyKCkgfTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIHByb3RlY3RlZCBlbmNvZGVGbG9hdDMyKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBlbmNvZGU6IG5ldyBHbHNsTGliUm91dGluZShgaGlnaHAgdmVjNCBlbmNvZGUoaGlnaHAgZmxvYXQgZikge1xuICAgICAgICByZXR1cm4gdmVjNChmLCAwLjAsIDAuMCwgMC4wKTtcbiAgICAgIH1cbiAgICAgICAgYCksXG4gICAgfTtcbiAgfVxuICBwcm90ZWN0ZWQgZGVjb2RlRmxvYXQzMigpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4ge1xuICAgICAgZGVjb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYGhpZ2hwIGZsb2F0IGRlY29kZShoaWdocCB2ZWM0IHJnYmEpIHtcbiAgICAgICAgcmV0dXJuIHJnYmEucjtcbiAgICAgIH1cbiAgICAgICAgYCksXG4gICAgfTtcbiAgfVxuICAvKipcbiAgICogcmV0dXJucyB0aGUgcm91dGluZSB0byBlbmNvZGUgZW5jb2RlIGEgMzJiaXQgZmxvYXQgdG8gYSB2ZWM0IChvZiB1bnNpZ25lZCBieXRlcylcbiAgICogQGNyZWRpdDogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzA1OTk2Mi9ob3ctZG8taS1jb252ZXJ0LWEtdmVjNC1yZ2JhLXZhbHVlLXRvLWEtZmxvYXRcbiAgICovXG4gIHByb3RlY3RlZCBlbmNvZGVVaW50OCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBlbmRpYW5uZXNzID0gRW5jb2RpbmdHbHNsTGliLmlzTGl0dGxlRW5kaWFuKCkgPyAncmdiYS5yZ2JhPXJnYmEuYWJncjsnIDogJyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVuY29kZTogbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIGhpZ2hwIHZlYzQgZW5jb2RlKGhpZ2hwIGZsb2F0IGYpIHtcbiAgICAgICAgaGlnaHAgZmxvYXQgRiA9IGFicyhmKTtcbiAgICAgICAgaGlnaHAgZmxvYXQgU2lnbiA9IHN0ZXAoMC4wLC1mKTtcbiAgICAgICAgaGlnaHAgZmxvYXQgRXhwb25lbnQgPSBmbG9vcihsb2cyKEYpKTtcbiAgICAgICAgaGlnaHAgZmxvYXQgTWFudGlzc2EgPSAoZXhwMigtIEV4cG9uZW50KSAqIEYpO1xuICAgICAgICBFeHBvbmVudCA9IGZsb29yKGxvZzIoRikgKyAxMjcuMCkgKyBmbG9vcihsb2cyKE1hbnRpc3NhKSk7XG4gICAgICAgIGhpZ2hwIHZlYzQgcmdiYTtcbiAgICAgICAgcmdiYVswXSA9IDEyOC4wICogU2lnbiAgKyBmbG9vcihFeHBvbmVudCpleHAyKC0xLjApKTtcbiAgICAgICAgcmdiYVsxXSA9IDEyOC4wICogbW9kKEV4cG9uZW50LDIuMCkgKyBtb2QoZmxvb3IoTWFudGlzc2EqMTI4LjApLDEyOC4wKTtcbiAgICAgICAgcmdiYVsyXSA9IGZsb29yKG1vZChmbG9vcihNYW50aXNzYSpleHAyKDIzLjAgLTguMCkpLGV4cDIoOC4wKSkpO1xuICAgICAgICByZ2JhWzNdID0gZmxvb3IoZXhwMigyMy4wKSptb2QoTWFudGlzc2EsZXhwMigtMTUuMCkpKTtcbiAgICAgICAgJHtlbmRpYW5uZXNzfVxuICAgICAgICByZ2JhID0gcmdiYSAvIDI1NS4wOyAvLyB2YWx1ZXMgbmVlZCB0byBiZSBub3JtYWxpemVkIHRvIFswLDFdXG4gICAgICAgIHJldHVybiByZ2JhO1xuICAgIH1cbiAgICAgICAgYCksXG4gICAgfTtcbiAgfVxuICAvKipcbiAgICogcmV0dXJucyB0aGUgcm91dGluZSB0byBlbmNvZGUgYSB2ZWM0IG9mIHVuc2lnbmVkIGJ5dGVzIHRvIGZsb2F0MzJcbiAgICogQGNyZWRpdDogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzA1OTk2Mi9ob3ctZG8taS1jb252ZXJ0LWEtdmVjNC1yZ2JhLXZhbHVlLXRvLWEtZmxvYXRcbiAgICovXG4gIHByb3RlY3RlZCBkZWNvZGVVaW50OCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBlbmRpYW5uZXNzID0gRW5jb2RpbmdHbHNsTGliLmlzTGl0dGxlRW5kaWFuKCkgPyAncmdiYS5yZ2JhPXJnYmEuYWJncjsnIDogJyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRlY29kZTogbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgICAgaGlnaHAgZmxvYXQgZGVjb2RlKGhpZ2hwIHZlYzQgcmdiYSkge1xuICAgICAgICAgIHJnYmEgPSByZ2JhICogMjU1LjA7IC8vIHZhbHVlcyBuZWVkIHRvIGJlIGRlLW5vcm1hbGl6ZWQgZnJvbSBbMCwxXSB0byBbMCwyNTVdXG4gICAgICAgICAgJHtlbmRpYW5uZXNzfVxuICAgICAgICAgIGhpZ2hwIGZsb2F0IFNpZ24gPSAxLjAgLSBzdGVwKDEyOC4wLHJnYmFbMF0pKjIuMDtcbiAgICAgICAgICBoaWdocCBmbG9hdCBFeHBvbmVudCA9IDIuMCAqIG1vZChyZ2JhWzBdLDEyOC4wKSArIHN0ZXAoMTI4LjAscmdiYVsxXSkgLSAxMjcuMDtcbiAgICAgICAgICBoaWdocCBmbG9hdCBNYW50aXNzYSA9IG1vZChyZ2JhWzFdLDEyOC4wKSo2NTUzNi4wICsgcmdiYVsyXSoyNTYuMCArcmdiYVszXSArIGZsb2F0KDB4ODAwMDAwKTtcbiAgICAgICAgICBoaWdocCBmbG9hdCBSZXN1bHQgPSAgU2lnbiAqIGV4cDIoRXhwb25lbnQpICogKE1hbnRpc3NhICogZXhwMigtMjMuMCApKTtcbiAgICAgICAgICByZXR1cm4gUmVzdWx0O1xuICAgICAgfVxuICAgICAgICBgKSxcbiAgICB9O1xuICB9XG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBtYWNoaW5lIGlzIGxpdHRsZSBlbmRpYW4gb3Igbm90XG4gICAqIEBjcmVkaXQ6IGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL1Rvb1RhbGxOYXRlLzQ3NTA5NTNcbiAgICovXG4gIHN0YXRpYyBpc0xpdHRsZUVuZGlhbigpOiBib29sZWFuIHtcbiAgICBjb25zdCBiID0gbmV3IEFycmF5QnVmZmVyKDQpO1xuICAgIGNvbnN0IGEgPSBuZXcgVWludDMyQXJyYXkoYik7XG4gICAgY29uc3QgYyA9IG5ldyBVaW50OEFycmF5KGIpO1xuICAgIGFbMF0gPSAweGRlYWRiZWVmO1xuICAgIGlmIChjWzBdID09PSAweGVmKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGNbMF0gPT09IDB4ZGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGVuZGlhbm5lc3MnKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmUgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4vZ2xzbC1zb3VyY2UnO1xuXG4vKipcbiAqIFRoaXMgR0xTTCBsaWJyYXJ5IGhhbmRsZXMgcm91dGluZXMgYXJvdW5kIHJlYWRpbmcgYSB0ZXhsZXQgYW5kIHdyaXRpbmcgdG8gaXRcbiAqIFJlYWRpbmcgYW5kIHdyaXRpbmcgY291bGQgYmUgbW9yZSB0aGFuIGp1c3QgZGVhbGluZyB3aXRoIG9uZSBjaGFubmVsXG4gKiBJdCBtYXkgcmVxdWlyZSBlbmNvZGluZy9kZWNvZGluZyB0by9mcm9tIDQgY2hhbm5lbHMgaW50byBvbmVcbiAqL1xuZXhwb3J0IGNsYXNzIEZyYWdDb2xvckdsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHsgLi4udGhpcy5zZXRGcmFnQ29sb3IoKSwgLi4udGhpcy5nZXRDb2xvckFzRmxvYXQoKSB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgcHJvdGVjdGVkIHNldEZyYWdDb2xvcigpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJldHVybiB7XG4gICAgICBzZXRGcmFnQ29sb3I6IG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgYFxuICAgICAgICB2b2lkIHNldEZyYWdDb2xvcihmbG9hdCB2YWx1ZSkge1xuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSBlbmNvZGUodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGAsXG4gICAgICAgIFsnZW5jb2RpbmcuZW5jb2RlJ10sXG4gICAgICApLFxuICAgIH07XG4gIH1cbiAgcHJvdGVjdGVkIGdldENvbG9yQXNGbG9hdCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4ge1xuICAgICAgZ2V0Q29sb3JBc0Zsb2F0OiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgIGBcbiAgICAgICAgZmxvYXQgZ2V0Q29sb3JBc0Zsb2F0KHZlYzQgY29sb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBkZWNvZGUoY29sb3IpO1xuICAgICAgICB9XG4gICAgICAgIGAsXG4gICAgICAgIFsnZW5jb2RpbmcuZGVjb2RlJ10sXG4gICAgICApLFxuICAgIH07XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcblxuLyoqXG4gKiBHTFNMIExpYnJhcnkgcmVzcG9uc2libGUgZm9yIGRhdGEgdHlwZXMgYW5kIHJvdXRpbmVzIGZvciBtYW5pcHVsYXRpbmdcbiAqIGNvb3JkaW5hdGVzIGFuZCBtYXBwaW5nIHRvL2Zyb20gdGVuc29yIGluZGljZXNcbiAqL1xuZXhwb3J0IGNsYXNzIFNoYXBlVXRpbHNHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEdsc2xDb250ZXh0KSB7XG4gICAgc3VwZXIoY29udGV4dCk7XG4gIH1cbiAgZ2V0RnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmJjYXN0SW5kZXgoKSxcbiAgICAgIC4uLnRoaXMuYmNhc3RNYXRtdWxJbmRleCgpLFxuICAgICAgLi4udGhpcy5vZmZzZXRUb0luZGljZXMoKSxcbiAgICAgIC4uLnRoaXMuaW5kaWNlc1RvT2Zmc2V0KCksXG4gICAgICAuLi50aGlzLmluY3JlbWVudEluZGljZXMoKSxcbiAgICB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBwcm90ZWN0ZWQgYmNhc3RJbmRleCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRSYW5rID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0udW5wYWNrZWRTaGFwZTtcbiAgICAgIGlmIChzaGFwZS5sZW5ndGggPD0gb3V0cHV0UmFuaykge1xuICAgICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgICBjb25zdCBkaW1PZmZzZXQgPSBvdXRwdXRSYW5rIC0gcmFuaztcbiAgICAgICAgY29uc3QgZnVuY05hbWUgPSBgYmNhc3RJbmRpY2VzXyR7bmFtZX1gO1xuICAgICAgICBsZXQgYmxvY2sgPSAnJztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAgICAgICBibG9jayArPSBgXG4gICAgICAgICAgcmVhbEluZGljZXNbJHtpfV0gPSBpbnQoIG1vZChmbG9hdChiY2FzdGVkSW5kaWNlc1ske2RpbU9mZnNldCArIGl9XSksICR7c2hhcGVbaV19LjApICk7XG4gICAgICAgICAgYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7ZnVuY05hbWV9IChpbnQgYmNhc3RlZEluZGljZXNbJHtvdXRwdXRSYW5rfV0sIG91dCBpbnQgcmVhbEluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICAke2Jsb2NrfVxuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBwcm90ZWN0ZWQgYmNhc3RNYXRtdWxJbmRleCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRSYW5rID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBpZiAoIShzaGFwZS5sZW5ndGggPCAyIHx8IHNoYXBlLmxlbmd0aCA+IG91dHB1dFJhbmspKSB7XG4gICAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGRpbU9mZnNldCA9IG91dHB1dFJhbmsgLSByYW5rO1xuICAgICAgICBjb25zdCBmdW5jTmFtZSA9IGBiY2FzdE1hdG11bEluZGljZXNfJHtuYW1lfWA7XG4gICAgICAgIGxldCBibG9jayA9ICcnO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAyOyArK2kpIHtcbiAgICAgICAgICBibG9jayArPSBgXG4gICAgICAgICAgcmVhbEluZGljZXNbJHtpfV0gPSBpbnQoIG1vZChmbG9hdChiY2FzdGVkSW5kaWNlc1ske2RpbU9mZnNldCArIGl9XSksICR7c2hhcGVbaV19LjApICk7XG4gICAgICAgICAgYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7ZnVuY05hbWV9KGludCBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmt9XSwgb3V0IGludCByZWFsSW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgICR7YmxvY2t9XG4gICAgICAgICAgcmVhbEluZGljZXNbJHtyYW5rIC0gMX1dID0gYmNhc3RlZEluZGljZXNbJHtvdXRwdXRSYW5rIC0gMX1dO1xuICAgICAgICAgIHJlYWxJbmRpY2VzWyR7cmFuayAtIDJ9XSA9IGJjYXN0ZWRJbmRpY2VzWyR7b3V0cHV0UmFuayAtIDJ9XTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcHJvdGVjdGVkIGluZGljZXNUb09mZnNldCgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgY29uc3Qgc3RyaWRlcyA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnN0cmlkZXM7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgbGV0IGZ1bmNOYW1lID0gYGluZGljZXNUb09mZnNldF8ke25hbWV9YDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoU2hhcGVVdGlsc0dsc2xMaWIuaW5kZXhUb09mZnNldFNpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcykpO1xuICAgICAgZnVuY05hbWUgPSBgaW5kaWNlc1RvT2Zmc2V0XyR7bmFtZX1fVGA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICBTaGFwZVV0aWxzR2xzbExpYi5pbmRleFRvT2Zmc2V0U2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzLnNsaWNlKCkucmV2ZXJzZSgpKSxcbiAgICAgICk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBzdGF0aWMgaW5kZXhUb09mZnNldFNpbmdsZShuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlciwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10pOiBzdHJpbmcge1xuICAgIGxldCBibG9jayA9ICcnO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgb2Zmc2V0ICs9IGluZGljZXNbJHtpfV0gKiAke3N0cmlkZXNbaV19O1xuICAgICAgICBgO1xuICAgIH1cbiAgICByZXR1cm4gYFxuICAgICAgaW50ICR7bmFtZX0oaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgICB9XG4gICAgICBgO1xuICB9XG4gIHByb3RlY3RlZCBvZmZzZXRUb0luZGljZXMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zaGFwZTtcbiAgICAgIGNvbnN0IHN0cmlkZXMgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zdHJpZGVzO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBmdW5jTmFtZSA9IGBvZmZzZXRUb0luZGljZXNfJHtuYW1lfWA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKFNoYXBlVXRpbHNHbHNsTGliLm9mZnNldFRvSW5kaWNlc1NpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcykpO1xuICAgICAgZnVuY05hbWUgPSBgb2Zmc2V0VG9JbmRpY2VzXyR7bmFtZX1fVGA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICBTaGFwZVV0aWxzR2xzbExpYi5vZmZzZXRUb0luZGljZXNTaW5nbGUoZnVuY05hbWUsIHJhbmssIHN0cmlkZXMuc2xpY2UoKS5yZXZlcnNlKCkpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHN0YXRpYyBvZmZzZXRUb0luZGljZXNTaW5nbGUobmFtZTogc3RyaW5nLCByYW5rOiBudW1iZXIsIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdHJpZGVzQmxvY2sgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAxOyArK2kpIHtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgIGluZGljZXNbJHtpfV0gPSBvZmZzZXQgLyAke3N0cmlkZXNbaV19O2ApO1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBvZmZzZXQgLT0gaW5kaWNlc1ske2l9XSAqICR7c3RyaWRlc1tpXX07YCk7XG4gICAgfVxuICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgIGluZGljZXNbJHtyYW5rIC0gMX1dID0gb2Zmc2V0O2ApO1xuICAgIHJldHVybiBgXG4gICAgICB2b2lkICR7bmFtZX0oaW50IG9mZnNldCwgb3V0IGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICR7c3RyaWRlc0Jsb2NrLmpvaW4oJycpfVxuICAgICAgfVxuICAgICAgYDtcbiAgfVxuICBwcm90ZWN0ZWQgaW5jcmVtZW50SW5kaWNlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IGZ1bmNOYW1lID0gYGluY3JlbWVudEluZGljZXNfJHtuYW1lfWA7XG4gICAgICBsZXQgc2hhcGVJbml0ID0gJyc7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgICBzaGFwZUluaXQgKz0gYFxuICAgICAgICBzaGFwZVske2l9XSA9ICR7c2hhcGVbaV19O2A7XG4gICAgICB9XG4gICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7ZnVuY05hbWV9KGludCBheGlzLCBvdXQgaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgc2hhcGVbJHtyYW5rfV07XG4gICAgICAgICAgJHtzaGFwZUluaXR9O1xuICAgICAgICAgIGZvcihpbnQgaSA9ICR7cmFua30gLTEgOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgaWYoaSA+IGF4aXMpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaW5kaWNlc1tpXSArPSAxO1xuICAgICAgICAgICAgaWYoaW5kaWNlc1tpXSA8IHNoYXBlW2ldKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kaWNlc1tpXSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcblxuLyoqXG4gKiBHTFNMIExpYnJhcnkgcmVzcG9uc2libGUgZm9yIHZlYyByb3V0aW5lc1xuICogVmVjIGlzIGFuIHZhcmlhYmxlIGxlbmd0aCBpbnQgYXJyYXkuIFRoZSBsZW5ndGggaXMgZml4ZWQgYXQgdGhlIHRpbWUgb2ZcbiAqIGdlbmVyYXRpbmcgdGhlIGxpYnJhcnkgZnVuY3Rpb25zIGZyb20gdGhlIGRpbWVuc2lvbnMgb2YgdGhlIG91dHB1dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4geyAuLi50aGlzLmJpbmFyeVZlY0Z1bmN0aW9ucygpLCAuLi50aGlzLmNvcHlWZWMoKSwgLi4udGhpcy5zZXRWZWNJdGVtKCksIC4uLnRoaXMuZ2V0VmVjSXRlbSgpIH07XG4gIH1cbiAgcHJvdGVjdGVkIGJpbmFyeVZlY0Z1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBuYW1lT3A6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9ID0geyBhZGQ6ICcrPScsIHN1YjogJy09JywgbXVsOiAnKj0nLCBkaXY6ICcvPScgfTtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gbmFtZU9wKSB7XG4gICAgICBjb25zdCBmbmFtZSA9IGAke25hbWV9VmVjYDtcbiAgICAgIGxldCBhc3NpZ25tZW50QmxvY2sgPSAnJztcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICAgIGFzc2lnbm1lbnRCbG9jayArPSBgXG4gICAgICAgICAgZGVzdFske2l9XSAke25hbWVPcFtuYW1lXX0gc3JjWyR7aX1dO1xuICAgICAgICAgIGA7XG4gICAgICB9XG4gICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7Zm5hbWV9KGludCBzcmNbJHtyYW5rfV0sIG91dCBpbnQgZGVzdFske3Jhbmt9XSkge1xuICAgICAgICAgICR7YXNzaWdubWVudEJsb2NrfVxuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXN1bHRbZm5hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcHJvdGVjdGVkIGNvcHlWZWMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgbGV0IGFzc2lnbm1lbnRCbG9jayA9ICcnO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICBhc3NpZ25tZW50QmxvY2sgKz0gYFxuICAgICAgICBkZXN0WyR7aX1dID0gc3JjWyR7aX1dO1xuICAgICAgICBgO1xuICAgIH1cbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgdm9pZCBjb3B5VmVjKGludCBzcmNbJHtyYW5rfV0sIG91dCBpbnQgZGVzdFske3Jhbmt9XSkge1xuICAgICAgICAke2Fzc2lnbm1lbnRCbG9ja31cbiAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIHsgY29weVZlYzogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0VmVjSXRlbSgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBsZXQgYmxvY2sgPSBgXG4gICAgICAgIGlmKGluZGV4IDwgMClcbiAgICAgICAgICAgIGluZGV4ID0ke3Jhbmt9ICsgaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA9PSAwKVxuICAgICAgICAgICAgbVswXSA9IHZhbHVlO1xuICAgICAgICBgO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PSAke2l9KVxuICAgICAgICAgICAgbVske2l9XSA9IHZhbHVlO1xuICAgICAgICAgICAgYDtcbiAgICB9XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBtWyR7cmFuayAtIDF9XSA9IHZhbHVlO1xuICAgICAgICBgO1xuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICB2b2lkIHNldFZlY0l0ZW0ob3V0IGludCBtWyR7cmFua31dLCBpbnQgaW5kZXgsIGludCB2YWx1ZSkge1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgfVxuICAgICAgICBgO1xuICAgIHJldHVybiB7IHNldFZlY0l0ZW06IG5ldyBHbHNsTGliUm91dGluZShib2R5KSB9O1xuICB9XG4gIHByb3RlY3RlZCBnZXRWZWNJdGVtKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGxldCBibG9jayA9IGBcbiAgICAgICAgaWYoaW5kZXggPCAwKVxuICAgICAgICAgICAgaW5kZXggPSAke3Jhbmt9ICsgaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIG1bMF07XG4gICAgICBgO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PSAke2l9KVxuICAgICAgICAgICAgcmV0dXJuIG1bJHtpfV07XG4gICAgICBgO1xuICAgIH1cbiAgICBibG9jayArPSBgXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBtWyR7cmFuayAtIDF9XTtcbiAgICAgICAgYDtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgaW50IGdldFZlY0l0ZW0oaW50IG1bJHtyYW5rfV0sIGludCBpbmRleCkge1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIHsgZ2V0VmVjSXRlbTogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpIH07XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQ29vcmRzR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1jb29yZGluYXRlLWxpYic7XG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBFbmNvZGluZ0dsc2xMaWIgfSBmcm9tICcuL2dsc2wtZW5jb2RpbmctbGliJztcbmltcG9ydCB7IEZyYWdDb2xvckdsc2xMaWIgfSBmcm9tICcuL2dsc2wtZnJhZ2NvbG9yLWxpYic7XG5pbXBvcnQgeyBTaGFwZVV0aWxzR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1zaGFwZS11dGlscy1saWInO1xuaW1wb3J0IHsgVmVjR2xzbExpYiB9IGZyb20gJy4vZ2xzbC12ZWMtbGliJztcblxuZXhwb3J0IGNvbnN0IGdsc2xSZWdpc3RyeTogeyBbbmFtZTogc3RyaW5nXTogbmV3IChjb250ZXh0OiBHbHNsQ29udGV4dCkgPT4gR2xzbExpYiB9ID0ge1xuICBlbmNvZGluZzogRW5jb2RpbmdHbHNsTGliLFxuICBmcmFnY29sb3I6IEZyYWdDb2xvckdsc2xMaWIsXG4gIHZlYzogVmVjR2xzbExpYixcbiAgc2hhcGVVdGlsczogU2hhcGVVdGlsc0dsc2xMaWIsXG4gIGNvb3JkaW5hdGVzOiBDb29yZHNHbHNsTGliLFxuICAvLyAgJ2FycmF5cyc6IEFycmF5R2xzbFNMaWJcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZU5vZGUsIFRvcG9sb2dpY2FsU29ydEdsc2xSb3V0aW5lcyB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyByZXBsYWNlSW5saW5lcyB9IGZyb20gJy4vZ2xzbC1mdW5jdGlvbi1pbmxpbmVyJztcbmltcG9ydCB7IGdsc2xSZWdpc3RyeSB9IGZyb20gJy4vZ2xzbC1yZWdpc3RlcmVkLWxpYnMnO1xuaW1wb3J0IHsgZ2V0RGVmYXVsdEZyYWdTaGFkZXJNYWluLCBnZXRGcmFnU2hhZGVyUHJlYW1ibGUgfSBmcm9tICcuL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlTGF5b3V0LCBWYXJpYWJsZUluZm8gfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qKlxuICogUHJlcHJvY2Vzc29yIGZvciB0aGUgYWRkaXRpb25zIHRvIHRoZSBHTFNMIGxhbmd1YWdlXG4gKiBJdCBkZWFscyB3aXRoOlxuICogIEBpbmNsdWRlIGRpcmVjdGl2ZXNcbiAqICBAaW5saW5lXG4gKiAgTG9vcCB1bnJvbGxpbmcgKG5vdCBpbXBsZW1lbnRlZClcbiAqICBNYWNybyByZXNvbHV0aW9uIChub3QgaW1wbGVtZW50ZWQpXG4gKi9cbmV4cG9ydCBjbGFzcyBHbHNsUHJlcHJvY2Vzc29yIHtcbiAgcmVhZG9ubHkgY29udGV4dDogR2xzbENvbnRleHQ7XG4gIHJlYWRvbmx5IGxpYnM6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWIgfSA9IHt9O1xuICByZWFkb25seSBnbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaDogeyBbcm91dGluZU5hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lTm9kZSB9ID0ge307XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvLFxuICAgIGlucHV0VGV4dHVyZUxheW91dHM6IFRleHR1cmVMYXlvdXRbXSxcbiAgICBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICApIHtcbiAgICB0aGlzLmNvbnRleHQgPSBuZXcgR2xzbENvbnRleHQoZ2xDb250ZXh0LCBwcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlTGF5b3V0cywgb3V0cHV0VGV4dHVyZUxheW91dCk7XG5cbiAgICAvLyBjb25zdHJ1Y3QgR2xzbExpYnNcbiAgICBPYmplY3Qua2V5cyhnbHNsUmVnaXN0cnkpLmZvckVhY2goKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbGliID0gbmV3IGdsc2xSZWdpc3RyeVtuYW1lXSh0aGlzLmNvbnRleHQpO1xuICAgICAgdGhpcy5saWJzW25hbWVdID0gbGliO1xuICAgIH0pO1xuXG4gICAgLy8gY29uc3RydWN0IEdsc2xSb3V0aW5lRGVwZW5kZW5jeUdyYXBoXG4gICAgY29uc3QgbWFwID0gdGhpcy5nbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaDtcbiAgICBmb3IgKGNvbnN0IGxpYk5hbWUgaW4gdGhpcy5saWJzKSB7XG4gICAgICBjb25zdCBsaWIgPSB0aGlzLmxpYnNbbGliTmFtZV07XG4gICAgICBjb25zdCByb3V0aW5lc0luTGliID0gbGliLmdldEZ1bmN0aW9ucygpO1xuICAgICAgZm9yIChjb25zdCByb3V0aW5lIGluIHJvdXRpbmVzSW5MaWIpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gbGliTmFtZSArICcuJyArIHJvdXRpbmU7XG4gICAgICAgIGxldCBjdXJyZW50Tm9kZTogR2xzbExpYlJvdXRpbmVOb2RlO1xuICAgICAgICBpZiAobWFwW2tleV0pIHtcbiAgICAgICAgICBjdXJyZW50Tm9kZSA9IG1hcFtrZXldO1xuICAgICAgICAgIGN1cnJlbnROb2RlLnJvdXRpbmVCb2R5ID0gcm91dGluZXNJbkxpYltyb3V0aW5lXS5yb3V0aW5lQm9keTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50Tm9kZSA9IG5ldyBHbHNsTGliUm91dGluZU5vZGUoa2V5LCByb3V0aW5lc0luTGliW3JvdXRpbmVdLnJvdXRpbmVCb2R5KTtcbiAgICAgICAgICBtYXBba2V5XSA9IGN1cnJlbnROb2RlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IHJvdXRpbmVzSW5MaWJbcm91dGluZV0uZGVwZW5kZW5jaWVzO1xuICAgICAgICBpZiAoZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXBlbmRlbmNpZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICghbWFwW2RlcGVuZGVuY2llc1tpXV0pIHtcbiAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IG5ldyBHbHNsTGliUm91dGluZU5vZGUoZGVwZW5kZW5jaWVzW2ldKTtcbiAgICAgICAgICAgICAgbWFwW2RlcGVuZGVuY2llc1tpXV0gPSBub2RlO1xuICAgICAgICAgICAgICBjdXJyZW50Tm9kZS5hZGREZXBlbmRlbmN5KG5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY3VycmVudE5vZGUuYWRkRGVwZW5kZW5jeShtYXBbZGVwZW5kZW5jaWVzW2ldXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJlcHJvY2VzcygpOiBzdHJpbmcge1xuICAgIGNvbnN0IHByb2dyYW1JbmZvID0gdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvO1xuICAgIGxldCBzb3VyY2UgPSBwcm9ncmFtSW5mby5zaGFkZXJTb3VyY2U7XG5cbiAgICAvLyBhcHBlbmQgbWFpbigpIGZ1bmN0aW9uXG4gICAgaWYgKCF0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaGFzTWFpbikge1xuICAgICAgc291cmNlID0gYCR7c291cmNlfVxuICAgICAgJHtnZXREZWZhdWx0RnJhZ1NoYWRlck1haW4odGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uLCB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dC5zaGFwZS5sZW5ndGgpfWA7XG4gICAgfVxuICAgIC8vIHJlcGxhY2UgaW5saW5lc1xuICAgIHNvdXJjZSA9IHJlcGxhY2VJbmxpbmVzKHNvdXJjZSk7XG5cbiAgICAvLyBjb25jYXQgZmluYWwgc291cmNlIHN0cmluZ1xuICAgIHJldHVybiBgJHtnZXRGcmFnU2hhZGVyUHJlYW1ibGUodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKX1cbiAgICAke3RoaXMuZ2V0VW5pZm9ybXMocHJvZ3JhbUluZm8uaW5wdXROYW1lcywgcHJvZ3JhbUluZm8udmFyaWFibGVzKX1cbiAgICAke3RoaXMuZ2V0SW1wb3J0cyhzb3VyY2UpfVxuICAgICR7c291cmNlfWA7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0SW1wb3J0cyhzY3JpcHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3Qgcm91dGluZXNJbmNsdWRlZCA9IHRoaXMuc2VsZWN0R2xzbExpYlJvdXRpbmVzVG9CZUluY2x1ZGVkKHNjcmlwdCk7XG5cbiAgICBpZiAocm91dGluZXNJbmNsdWRlZC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBsZXQgcm91dGluZXMgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvdXRpbmVzSW5jbHVkZWQubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChyb3V0aW5lc0luY2x1ZGVkW2ldLnJvdXRpbmVCb2R5KSB7XG4gICAgICAgIHJvdXRpbmVzICs9IHJvdXRpbmVzSW5jbHVkZWRbaV0ucm91dGluZUJvZHkgKyAnXFxuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyBib2R5IGZvciB0aGUgR2xzbCBMaWJyYXJ5IHJvdXRpbmU6ICR7cm91dGluZXNJbmNsdWRlZFtpXS5uYW1lfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByb3V0aW5lcztcbiAgfVxuICBwcml2YXRlIHNlbGVjdEdsc2xMaWJSb3V0aW5lc1RvQmVJbmNsdWRlZChzY3JpcHQ6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lTm9kZVtdIHtcbiAgICBjb25zdCBub2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10gPSBbXTtcblxuICAgIE9iamVjdC5rZXlzKHRoaXMuZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGgpLmZvckVhY2goKGNsYXNzQW5kUm91dGluZSkgPT4ge1xuICAgICAgY29uc3Qgcm91dGluZSA9IGNsYXNzQW5kUm91dGluZS5zcGxpdCgnLicpWzFdO1xuICAgICAgaWYgKHNjcmlwdC5pbmRleE9mKHJvdXRpbmUpICE9PSAtMSkge1xuICAgICAgICBub2Rlcy5wdXNoKHRoaXMuZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGhbY2xhc3NBbmRSb3V0aW5lXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gVG9wb2xvZ2ljYWxTb3J0R2xzbFJvdXRpbmVzLnJldHVybk9yZGVyZWROb2Rlcyhub2Rlcyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0VW5pZm9ybXMoc2FtcGxlcnM/OiBzdHJpbmdbXSwgdmFyaWFibGVzPzogVmFyaWFibGVJbmZvW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHVuaWZvcm1MaW5lczogc3RyaW5nW10gPSBbXTtcbiAgICBpZiAoc2FtcGxlcnMpIHtcbiAgICAgIGZvciAoY29uc3Qgc2FtcGxlciBvZiBzYW1wbGVycykge1xuICAgICAgICB1bmlmb3JtTGluZXMucHVzaChgdW5pZm9ybSBzYW1wbGVyMkQgJHtzYW1wbGVyfTtgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHZhcmlhYmxlcykge1xuICAgICAgZm9yIChjb25zdCB2YXJpYWJsZSBvZiB2YXJpYWJsZXMpIHtcbiAgICAgICAgdW5pZm9ybUxpbmVzLnB1c2goXG4gICAgICAgICAgYHVuaWZvcm0gJHt2YXJpYWJsZS50eXBlfSAke3ZhcmlhYmxlLm5hbWV9JHt2YXJpYWJsZS5hcnJheUxlbmd0aCA/IGBbJHt2YXJpYWJsZS5hcnJheUxlbmd0aH1dYCA6ICcnfTtgLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5pZm9ybUxpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IExvZ2dlciwgUHJvZmlsZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcblxuaW1wb3J0IHsgR2xzbFByZXByb2Nlc3NvciB9IGZyb20gJy4vZ2xzbC1wcmVwcm9jZXNzb3InO1xuaW1wb3J0IHsgZ2V0VmVydGV4U2hhZGVyU291cmNlIH0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kgfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7IEFydGlmYWN0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVZhcmlhYmxlLCBUZXh0dXJlRGF0YSwgVGV4dHVyZUxheW91dCwgVmFyaWFibGVJbmZvIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsLWNvbnRleHQnO1xuXG4vKipcbiAqIFByb2dyYW1NYW5hZ2VyIGlzIHRoZSBtYWluIGNsYXNzIGJlaGluZCBydW5uaW5nIGNvbXB1dGF0aW9uc1xuICogSXQgYnVpbGRzIFByb2dyYW1JbmZvJ3MgaW50byBBcnRpZmFjdHNcbiAqIEl0IGNvbXBpbGVzIGdpdmVuIFByb2dyYW1JbmZvJ3MgaW50byBXZWJHTCBQcm9yYW1zIChjYWNoZWQgYXMgQXJ0aWZhY3RzKVxuICogVXNlcyB0aGUgYXJ0aWZhY3QgdG8gcnVuIHRoZSBjb21wdXRhdGlvbiBieSBjYWxsaW5nIERyYXcgb25cbiAqIHRoZSBXZWJHTCBkcmF3aW5nIGJ1ZmZlclxuICogUHJvZ3JhbU1hbmFnZXIgYXV0b21hdGljYWxseSBtYXBzIChiaW5kcykgaW5wdXQgdmFyaWFibGVzIHRvIHRoZWlyXG4gKiBjb3JyZXNwb25kaW5nIExvY2F0aW9uJ3MgaW4gdGhlIGJpbmFyeSBwcm9ncmFtXG4gKi9cbmV4cG9ydCBjbGFzcyBQcm9ncmFtTWFuYWdlciB7XG4gIHJlcG86IE1hcDx1bmtub3duLCBBcnRpZmFjdD47IC8vIHRoaXMgc2hvdWxkIGJlIHBlci1zZXNzaW9uIG9iamVjdFxuICB2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyO1xuICBhdHRyaWJ1dGVzQm91bmQ6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj4sXG4gICAgcHVibGljIGdsQ29udGV4dDogV2ViR0xDb250ZXh0LFxuICAgIHB1YmxpYyB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgKSB7XG4gICAgdGhpcy5yZXBvID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuYXR0cmlidXRlc0JvdW5kID0gZmFsc2U7XG4gIH1cbiAgZ2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duKTogQXJ0aWZhY3QgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJlcG8uZ2V0KGtleSk7XG4gIH1cbiAgc2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duLCBhcnRpZmFjdDogQXJ0aWZhY3QpOiB2b2lkIHtcbiAgICB0aGlzLnJlcG8uc2V0KGtleSwgYXJ0aWZhY3QpO1xuICB9XG4gIHJ1bihidWlsZEFydGlmYWN0OiBBcnRpZmFjdCwgaW5wdXRzOiBUZXh0dXJlRGF0YVtdLCBvdXRwdXQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgdGhpcy5wcm9maWxlci5ldmVudChcbiAgICAgICdvcCcsXG4gICAgICBgUHJvZ3JhbU1hbmFnZXIucnVuICR7YnVpbGRBcnRpZmFjdC5wcm9ncmFtSW5mby5uYW1lID8/ICd1bmtub3duIGtlcm5lbCd9YCxcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICAgICAgY29uc3QgcHJvZ3JhbSA9IGJ1aWxkQXJ0aWZhY3QucHJvZ3JhbTtcbiAgICAgICAgZ2wudXNlUHJvZ3JhbShwcm9ncmFtKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmJpbmRPdXRwdXQob3V0cHV0KTtcbiAgICAgICAgICBpZiAoIXRoaXMuYXR0cmlidXRlc0JvdW5kKSB7XG4gICAgICAgICAgICB0aGlzLmJpbmRBdHRyaWJ1dGVzKGJ1aWxkQXJ0aWZhY3QuYXR0cmliTG9jYXRpb25zKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5iaW5kVW5pZm9ybXMoYnVpbGRBcnRpZmFjdC51bmlmb3JtTG9jYXRpb25zLCBidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLnZhcmlhYmxlcyA/PyBbXSwgaW5wdXRzKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgTG9nZ2VyLmVycm9yKCdQcm9ncmFtTWFuYWdlcicsIGJ1aWxkQXJ0aWZhY3QucHJvZ3JhbUluZm8uc2hhZGVyU291cmNlKTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdHbENvbnRleHQuZHJhdygpJywgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuZ2xDb250ZXh0LmRyYXcoKTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgdGhpcy5nbENvbnRleHQsXG4gICAgKTtcbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZlcnRleFNoYWRlcikge1xuICAgICAgdGhpcy5nbENvbnRleHQuZGVsZXRlU2hhZGVyKHRoaXMudmVydGV4U2hhZGVyKTtcbiAgICB9XG4gICAgdGhpcy5yZXBvLmZvckVhY2goKGEpID0+IHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVByb2dyYW0oYS5wcm9ncmFtKSk7XG4gIH1cbiAgYnVpbGQocHJvZ3JhbUluZm86IFByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVMYXlvdXRzOiBUZXh0dXJlTGF5b3V0W10sIG91dHB1dFRleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBBcnRpZmFjdCB7XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnUHJvZ3JhbU1hbmFnZXIuYnVpbGQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcmVwcm9jZXNzb3IgPSBuZXcgR2xzbFByZXByb2Nlc3Nvcih0aGlzLmdsQ29udGV4dCwgcHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZUxheW91dHMsIG91dHB1dFRleHR1cmVMYXlvdXQpO1xuICAgICAgY29uc3QgZnJhZ1NjcmlwdCA9IHByZXByb2Nlc3Nvci5wcmVwcm9jZXNzKCk7XG4gICAgICBjb25zdCBwcm9ncmFtID0gdGhpcy5jb21waWxlKGZyYWdTY3JpcHQpO1xuICAgICAgY29uc3QgYXJ0aWZhY3QgPSB7XG4gICAgICAgIHByb2dyYW1JbmZvLFxuICAgICAgICBwcm9ncmFtLFxuICAgICAgICB1bmlmb3JtTG9jYXRpb25zOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbnMoXG4gICAgICAgICAgcHJvZ3JhbSxcbiAgICAgICAgICBwcmVwcm9jZXNzb3IuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLFxuICAgICAgICAgIHByZXByb2Nlc3Nvci5jb250ZXh0LnByb2dyYW1JbmZvLnZhcmlhYmxlcyxcbiAgICAgICAgKSxcbiAgICAgICAgYXR0cmliTG9jYXRpb25zOiB0aGlzLmdldEF0dHJpYkxvY2F0aW9ucyhwcm9ncmFtKSxcbiAgICAgIH07XG4gICAgICByZXR1cm4gYXJ0aWZhY3Q7XG4gICAgfSk7XG4gIH1cbiAgcHJvdGVjdGVkIGNvbXBpbGUoZnJhZ1NoYWRlclNjcmlwdDogc3RyaW5nKTogV2ViR0xQcm9ncmFtIHtcbiAgICBpZiAoIXRoaXMudmVydGV4U2hhZGVyKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnUHJvcmdyYW1NYW5hZ2VyJywgJ0NvbXBpbGluZyBhbmQgY2FjaGluZyBWZXJ0ZXggc2hhZGVyIGZvciB0aGUgZmlyc3QgdGltZScpO1xuICAgICAgY29uc3QgdmVydGV4U2hhZGVyU2NyaXB0ID0gZ2V0VmVydGV4U2hhZGVyU291cmNlKHRoaXMuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgdGhpcy52ZXJ0ZXhTaGFkZXIgPSB0aGlzLmdsQ29udGV4dC5jb21waWxlU2hhZGVyKHZlcnRleFNoYWRlclNjcmlwdCwgdGhpcy5nbENvbnRleHQuZ2wuVkVSVEVYX1NIQURFUik7XG4gICAgfVxuICAgIGlmIChlbnYuZGVidWcpIHtcbiAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAnUHJvcmdyYW1NYW5hZ2VyJyxcbiAgICAgICAgYEZyYWdTaGFkZXI6XG4ke2ZyYWdTaGFkZXJTY3JpcHR9XG5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZnJhZ1NoYWRlciA9IHRoaXMuZ2xDb250ZXh0LmNvbXBpbGVTaGFkZXIoZnJhZ1NoYWRlclNjcmlwdCwgdGhpcy5nbENvbnRleHQuZ2wuRlJBR01FTlRfU0hBREVSKTtcbiAgICBjb25zdCBwcm9ncmFtID0gdGhpcy5nbENvbnRleHQuY3JlYXRlUHJvZ3JhbSh0aGlzLnZlcnRleFNoYWRlciwgZnJhZ1NoYWRlcik7XG4gICAgdGhpcy5nbENvbnRleHQuZGVsZXRlU2hhZGVyKGZyYWdTaGFkZXIpO1xuICAgIHJldHVybiBwcm9ncmFtO1xuICB9XG4gIGJpbmRPdXRwdXQodGQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgY29uc3Qgd2lkdGggPSB0ZC53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0ZC5oZWlnaHQ7XG4gICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAnUHJvcmdyYW1NYW5hZ2VyJyxcbiAgICAgIGBCaW5kaW5nIG91dHB1dCB0ZXh0dXJlIHRvIEZyYW1lYnVmZmVyOiB3L2g9JHt3aWR0aH0vJHtoZWlnaHR9LCBzaGFwZT0ke3RkLnNoYXBlfSwgdHlwZT0ke3RkLnRlbnNvci50eXBlfWAsXG4gICAgKTtcbiAgICB0aGlzLmdsQ29udGV4dC5hdHRhY2hGcmFtZWJ1ZmZlcih0ZC50ZXh0dXJlLCB3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuICBiaW5kQXR0cmlidXRlcyhhdHRyaWJMb2NhdGlvbnM6IEFydGlmYWN0LkF0dHJpYkxvY2F0aW9ucyk6IHZvaWQge1xuICAgIGNvbnN0IHBvc2l0aW9uSGFuZGxlID0gYXR0cmliTG9jYXRpb25zLnBvc2l0aW9uO1xuICAgIGNvbnN0IHRleHR1cmVDb29yZEhhbmRsZSA9IGF0dHJpYkxvY2F0aW9ucy50ZXh0dXJlQ29vcmQ7XG4gICAgdGhpcy5nbENvbnRleHQuc2V0VmVydGV4QXR0cmlidXRlcyhwb3NpdGlvbkhhbmRsZSwgdGV4dHVyZUNvb3JkSGFuZGxlKTtcbiAgICB0aGlzLmF0dHJpYnV0ZXNCb3VuZCA9IHRydWU7XG4gIH1cbiAgYmluZFVuaWZvcm1zKFxuICAgIHVuaWZvcm1Mb2NhdGlvbnM6IEFydGlmYWN0LlVuaWZvcm1Mb2NhdGlvbnMsXG4gICAgdmFyaWFibGVzOiBQcm9ncmFtVmFyaWFibGVbXSxcbiAgICB0ZXh0dXJlczogVGV4dHVyZURhdGFbXSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICBsZXQgdGV4dHVyZVBvc2l0aW9uID0gMDtcbiAgICBmb3IgKGNvbnN0IHsgbmFtZSwgdHlwZSwgbG9jYXRpb24sIGFycmF5TGVuZ3RoIH0gb2YgdW5pZm9ybUxvY2F0aW9ucykge1xuICAgICAgY29uc3QgdmFsdWUgPSB2YXJpYWJsZXMuZmluZCgodikgPT4gdi5uYW1lID09PSBuYW1lKT8uZGF0YTtcbiAgICAgIGlmICh0eXBlICE9PSAnc2FtcGxlcjJEJyAmJiAhdmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB2YXJpYWJsZSAnJHtuYW1lfScgZG9lcyBub3QgaGF2ZSBkYXRhIGRlZmluZWQgaW4gcHJvZ3JhbSBpbmZvYCk7XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSAnc2FtcGxlcjJEJzpcbiAgICAgICAgICB0aGlzLmJpbmRUZXh0dXJlKHRleHR1cmVzW3RleHR1cmVQb3NpdGlvbl0sIGxvY2F0aW9uLCB0ZXh0dXJlUG9zaXRpb24pO1xuICAgICAgICAgIHRleHR1cmVQb3NpdGlvbisrO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdmbG9hdCc6XG4gICAgICAgICAgaWYgKGFycmF5TGVuZ3RoKSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWZ2KGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXJbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xZihsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2ludCc6XG4gICAgICAgICAgaWYgKGFycmF5TGVuZ3RoKSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWl2KGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXJbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xaShsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmlmb3JtIG5vdCBpbXBsZW1lbnRlZDogJHt0eXBlfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBiaW5kVGV4dHVyZSh0ZDogVGV4dHVyZURhdGEsIHVuaWZvcm1IYW5kbGU6IFdlYkdMVW5pZm9ybUxvY2F0aW9uLCBwb3NpdGlvbjogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5nbENvbnRleHQuYmluZFRleHR1cmVUb1VuaWZvcm0odGQudGV4dHVyZSwgcG9zaXRpb24sIHVuaWZvcm1IYW5kbGUpO1xuICB9XG4gIGdldEF0dHJpYkxvY2F0aW9ucyhwcm9ncmFtOiBXZWJHTFByb2dyYW0pOiBBcnRpZmFjdC5BdHRyaWJMb2NhdGlvbnMge1xuICAgIHJldHVybiB7XG4gICAgICBwb3NpdGlvbjogdGhpcy5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAncG9zaXRpb24nKSxcbiAgICAgIHRleHR1cmVDb29yZDogdGhpcy5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAndGV4dHVyZUNvb3JkJyksXG4gICAgfTtcbiAgfVxuICBnZXRVbmlmb3JtTG9jYXRpb25zKFxuICAgIHByb2dyYW06IFdlYkdMUHJvZ3JhbSxcbiAgICBzYW1wbGVycz86IHN0cmluZ1tdLFxuICAgIHZhcmlhYmxlcz86IFZhcmlhYmxlSW5mb1tdLFxuICApOiBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zIHtcbiAgICBjb25zdCB1bmlmb3JtTG9jYXRpb25zOiBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zID0gW107XG4gICAgaWYgKHNhbXBsZXJzKSB7XG4gICAgICBmb3IgKGNvbnN0IHNhbXBsZXIgb2Ygc2FtcGxlcnMpIHtcbiAgICAgICAgdW5pZm9ybUxvY2F0aW9ucy5wdXNoKHtcbiAgICAgICAgICBuYW1lOiBzYW1wbGVyLFxuICAgICAgICAgIHR5cGU6ICdzYW1wbGVyMkQnLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBzYW1wbGVyKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh2YXJpYWJsZXMpIHtcbiAgICAgIGZvciAoY29uc3QgdmFyaWFibGUgb2YgdmFyaWFibGVzKSB7XG4gICAgICAgIHVuaWZvcm1Mb2NhdGlvbnMucHVzaCh7IC4uLnZhcmlhYmxlLCBsb2NhdGlvbjogdGhpcy5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgdmFyaWFibGUubmFtZSkgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmlmb3JtTG9jYXRpb25zO1xuICB9XG4gIGdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtOiBXZWJHTFByb2dyYW0sIG5hbWU6IHN0cmluZyk6IFdlYkdMVW5pZm9ybUxvY2F0aW9uIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2xDb250ZXh0LmdsO1xuICAgIGNvbnN0IHJlZmVyZW5jZSA9IGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBuYW1lKTtcbiAgICBpZiAocmVmZXJlbmNlID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuaWZvcm0gJHtuYW1lfSBub3QgZm91bmQuYCk7XG4gICAgfVxuICAgIHJldHVybiByZWZlcmVuY2U7XG4gIH1cbiAgZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCBuYW1lOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbENvbnRleHQuZ2w7XG4gICAgY29uc3QgYXR0cmlidXRlTG9jYXRpb246IG51bWJlciA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sIG5hbWUpO1xuICAgIHJldHVybiBhdHRyaWJ1dGVMb2NhdGlvbjtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIsIFByb2ZpbGVyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuXG5pbXBvcnQgeyBFbmNvZGVyLCBFbmNvZGVyVXNhZ2UgfSBmcm9tICcuL3RleHR1cmUtZGF0YS1lbmNvZGVyJztcbmltcG9ydCB7IFRleHR1cmVMYXlvdXRTdHJhdGVneSB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZURhdGEsIFRleHR1cmVMYXlvdXQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZU1hbmFnZXJDb25maWcge1xuICByZXVzZVRleHR1cmVzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUZXh0dXJlTWFuYWdlciBpcyB0aGUgbWFpbmx5IHJlc3BvbnNpYmxlIGZvciBjYWNoaW5nIFRleHR1cmVzXG4gKiBUZXh0dXJlcyBhcmUgY2FjaGVkIGluIDIgbGV2ZWxzOlxuICogICAxLiB0aGUgdGV4dHVyZXMgd2hpY2ggYXJlIGFzc29jaWF0ZWQgd2l0aCBhIGRhdGFJZCAoZnJvbSBUZW5zb3IpXG4gKiAgICBDYWNoaW5nIHRoZXNlIGlzIGNydWNpYWwgdG8gcGVyZm9ybWFuY2UuIFRoZXNlIGFyZSBJbi11c2UgVGV4dHVyZXNcbiAqICAgMi4gdGV4dHVyZXMgd2hpY2ggYXJlIG5vdCBpbiB1c2UgYnkgYW55IGN1cnJlbnQgUHJvZ3JhbUluZm8vVGVuc29yXG4gKiAgICAgVGhlc2UgYXJlIGNhbGxlZCBGcmVlIFRleHR1cmVzXG4gKiBUZXh0dXJlTWFuYWdlciBpcyBhbHNvIHVzZWQgdG8gaGVscCBjcmVhdGluZyB0ZXh0dXJlcy4gRm9yIHRoaXMgaXRcbiAqIHVzZXMgV2ViR0xDb250ZXh0IGFuZCBUZXh0dXJlTGF5b3V0U3RyYXRlZ3lcbiAqL1xuZXhwb3J0IGNsYXNzIFRleHR1cmVNYW5hZ2VyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBpblVzZVRleHR1cmVzOiBNYXA8c3RyaW5nLCBXZWJHTFRleHR1cmVbXT47XG4gIHByaXZhdGUgcmVhZG9ubHkgaWRsZVRleHR1cmVzOiBNYXA8c3RyaW5nLCBXZWJHTFRleHR1cmVbXT47XG4gIHByaXZhdGUgcmVhZG9ubHkgdGV4dHVyZUxvb2t1cDogTWFwPFdlYkdMVGV4dHVyZSwgc3RyaW5nPjtcbiAgcHJpdmF0ZSByZWFkb25seSBwZW5kaW5nUmVhZDogTWFwPFRlbnNvci5JZCwgQXJyYXk8KGFycjogVGVuc29yLk51bWJlclR5cGUpID0+IHZvaWQ+PiA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgcHVibGljIGxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksXG4gICAgcHVibGljIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj4sXG4gICAgcHJpdmF0ZSBjb25maWc6IFRleHR1cmVNYW5hZ2VyQ29uZmlnLFxuICApIHtcbiAgICBpZiAoY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIHRoaXMuaW5Vc2VUZXh0dXJlcyA9IG5ldyBNYXAoKTtcbiAgICAgIHRoaXMuaWRsZVRleHR1cmVzID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy50ZXh0dXJlTG9va3VwID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgfVxuICBjcmVhdGVUZXh0dXJlRnJvbUxheW91dChcbiAgICBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIGxheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBkYXRhPzogVGVuc29yLk51bWJlclR5cGUsXG4gICAgdXNhZ2U/OiBFbmNvZGVyVXNhZ2UsXG4gICkge1xuICAgIGNvbnN0IHRleHR1cmVEYXRhVHlwZSA9IHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSk7XG5cbiAgICBjb25zdCBlbmNvZGVyID0gdGhpcy5nbENvbnRleHQuZ2V0RW5jb2Rlcih0ZXh0dXJlRGF0YVR5cGUsIGxheW91dC5jaGFubmVscyB8fCAxLCB1c2FnZSk7XG4gICAgaWYgKGxheW91dC5pc1BhY2tlZCAmJiB1c2FnZSA9PT0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuICAgIGNvbnN0IHdpZHRoID0gbGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IGhlaWdodCA9IGxheW91dC5oZWlnaHQ7XG5cbiAgICBsZXQga2V5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgbGV0IGluVXNlVGV4dHVyZXM6IFdlYkdMVGV4dHVyZVtdIHwgdW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBrZXkgPSBgJHt3aWR0aH14JHtoZWlnaHR9XyR7ZW5jb2Rlci5mb3JtYXR9XyR7ZW5jb2Rlci5pbnRlcm5hbEZvcm1hdH1fJHtlbmNvZGVyLnRleHR1cmVUeXBlfWA7XG4gICAgICBpblVzZVRleHR1cmVzID0gdGhpcy5pblVzZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgaWYgKCFpblVzZVRleHR1cmVzKSB7XG4gICAgICAgIGluVXNlVGV4dHVyZXMgPSBbXTtcbiAgICAgICAgdGhpcy5pblVzZVRleHR1cmVzLnNldChrZXksIGluVXNlVGV4dHVyZXMpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpZGxlVGV4dHVyZXMgPSB0aGlzLmlkbGVUZXh0dXJlcy5nZXQoa2V5KTtcbiAgICAgIGlmIChpZGxlVGV4dHVyZXMgJiYgaWRsZVRleHR1cmVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgdGV4dHVyZSA9IGlkbGVUZXh0dXJlcy5wb3AoKSE7XG4gICAgICAgIGluVXNlVGV4dHVyZXMucHVzaCh0ZXh0dXJlKTtcbiAgICAgICAgaWYgKHVzYWdlID09PSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSkge1xuICAgICAgICAgIHRoaXMuZ2xDb250ZXh0LnVwZGF0ZVRleHR1cmUodGV4dHVyZSwgd2lkdGgsIGhlaWdodCwgZW5jb2RlciwgdGhpcy50b1RleHR1cmVEYXRhKGRhdGFUeXBlLCBkYXRhKSEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0ZXh0dXJlO1xuICAgICAgfVxuICAgIH1cblxuICAgIExvZ2dlci52ZXJib3NlKCdUZXh0dXJlTWFuYWdlcicsIGBDcmVhdGluZyBuZXcgdGV4dHVyZSBvZiBzaXplICR7bGF5b3V0LndpZHRofXgke2xheW91dC5oZWlnaHR9YCk7XG4gICAgY29uc3QgdGV4dHVyZSA9IHRoaXMuZ2xDb250ZXh0LmFsbG9jYXRlVGV4dHVyZSh3aWR0aCwgaGVpZ2h0LCBlbmNvZGVyLCB0aGlzLnRvVGV4dHVyZURhdGEoZGF0YVR5cGUsIGRhdGEpKTtcblxuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBpblVzZVRleHR1cmVzIS5wdXNoKHRleHR1cmUpO1xuICAgICAgdGhpcy50ZXh0dXJlTG9va3VwLnNldCh0ZXh0dXJlLCBrZXkhKTtcbiAgICB9XG4gICAgcmV0dXJuIHRleHR1cmU7XG4gIH1cbiAgcmVhZFRleHR1cmUodGQ6IFRleHR1cmVEYXRhLCBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBjaGFubmVscz86IG51bWJlcik6IFRlbnNvci5OdW1iZXJUeXBlIHtcbiAgICBpZiAoIWNoYW5uZWxzKSB7XG4gICAgICBjaGFubmVscyA9IDE7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ1RleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlJywgKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YVNpemUgPSB0ZC5zaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKSAqIGNoYW5uZWxzITtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdsQ29udGV4dC5yZWFkVGV4dHVyZShcbiAgICAgICAgdGQudGV4dHVyZSxcbiAgICAgICAgdGQud2lkdGgsXG4gICAgICAgIHRkLmhlaWdodCxcbiAgICAgICAgZGF0YVNpemUsXG4gICAgICAgIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksXG4gICAgICAgIGNoYW5uZWxzISxcbiAgICAgICk7XG4gICAgICByZXR1cm4gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgIH0pO1xuICB9XG4gIGFzeW5jIHJlYWRUZXh0dXJlQXN5bmModGQ6IFRleHR1cmVEYXRhLCBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBjaGFubmVscz86IG51bWJlcik6IFByb21pc2U8VGVuc29yLk51bWJlclR5cGU+IHtcbiAgICBjb25zdCBkYXRhSWQgPSB0ZC50ZW5zb3IuZGF0YUlkO1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGVuZGluZ1JlYWQuaGFzKGRhdGFJZCkpIHtcbiAgICAgIGNvbnN0IHN1YnNjcmliZXJzID0gdGhpcy5wZW5kaW5nUmVhZC5nZXQoZGF0YUlkKTtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxUZW5zb3IuTnVtYmVyVHlwZT4oKHJlc29sdmUpID0+IHN1YnNjcmliZXJzPy5wdXNoKHJlc29sdmUpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnVGV4dHVyZU1hbmFnZXIucmVhZFRleHR1cmVBc3luYycsIGFzeW5jICgpID0+IHtcbiAgICAgIHRoaXMucGVuZGluZ1JlYWQuc2V0KGRhdGFJZCwgW10pO1xuICAgICAgY29uc3QgZGF0YVNpemUgPSB0ZC5zaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKSAqIGNoYW5uZWxzITtcbiAgICAgIC8vIGFkZCBhIGZlbmNlIHdhaXRpbmcgZm9yIHRoZSBkYXRhIHRvIGJlIHJlYWR5XG4gICAgICBhd2FpdCB0aGlzLmdsQ29udGV4dC5jcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKTtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdsQ29udGV4dC5yZWFkVGV4dHVyZShcbiAgICAgICAgdGQudGV4dHVyZSxcbiAgICAgICAgdGQud2lkdGgsXG4gICAgICAgIHRkLmhlaWdodCxcbiAgICAgICAgZGF0YVNpemUsXG4gICAgICAgIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksXG4gICAgICAgIGNoYW5uZWxzISxcbiAgICAgICk7XG4gICAgICBjb25zdCB0ZW5zb3JEYXRhID0gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgICAgY29uc3Qgc3Vic2NyaWJlcnMgPSB0aGlzLnBlbmRpbmdSZWFkLmdldChkYXRhSWQpO1xuICAgICAgdGhpcy5wZW5kaW5nUmVhZC5kZWxldGUoZGF0YUlkKTtcbiAgICAgIHN1YnNjcmliZXJzPy5mb3JFYWNoKChyZXNvbHZlKSA9PiByZXNvbHZlKHRlbnNvckRhdGEpKTtcbiAgICAgIHJldHVybiB0ZW5zb3JEYXRhO1xuICAgIH0pO1xuICB9XG4gIHJlYWRVaW50OFRleHR1cmVBc0Zsb2F0KHRkOiBUZXh0dXJlRGF0YSk6IEZsb2F0MzJBcnJheSB7XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnVGV4dHVyZU1hbmFnZXIucmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkYXRhU2l6ZSA9IHRkLnNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2xDb250ZXh0LnJlYWRUZXh0dXJlKHRkLnRleHR1cmUsIHRkLndpZHRoLCB0ZC5oZWlnaHQsIGRhdGFTaXplICogNCwgJ2J5dGUnLCA0KTtcbiAgICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KGRhdGEuYnVmZmVyLCBkYXRhLmJ5dGVPZmZzZXQsIGRhdGFTaXplKTtcbiAgICB9KTtcbiAgfVxuICByZWxlYXNlVGV4dHVyZSh0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEsIGRlbGV0ZVRleHR1cmU/OiBib29sZWFuKTogdm9pZCB7XG4gICAgbGV0IGtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBrZXkgPSB0aGlzLnRleHR1cmVMb29rdXAuZ2V0KHRleHR1cmVEYXRhLnRleHR1cmUpO1xuICAgICAgaWYgKGtleSkge1xuICAgICAgICBpZiAoZGVsZXRlVGV4dHVyZSkge1xuICAgICAgICAgIHRoaXMudGV4dHVyZUxvb2t1cC5kZWxldGUoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpblVzZVRleHR1cmVzID0gdGhpcy5pblVzZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgICBpZiAoaW5Vc2VUZXh0dXJlcykge1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gaW5Vc2VUZXh0dXJlcy5pbmRleE9mKHRleHR1cmVEYXRhLnRleHR1cmUpO1xuICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGluVXNlVGV4dHVyZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIGxldCBpZGxlVGV4dHVyZXMgPSB0aGlzLmlkbGVUZXh0dXJlcy5nZXQoa2V5KTtcbiAgICAgICAgICAgIGlmICghaWRsZVRleHR1cmVzKSB7XG4gICAgICAgICAgICAgIGlkbGVUZXh0dXJlcyA9IFtdO1xuICAgICAgICAgICAgICB0aGlzLmlkbGVUZXh0dXJlcy5zZXQoa2V5LCBpZGxlVGV4dHVyZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWRsZVRleHR1cmVzLnB1c2godGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFrZXkgfHwgZGVsZXRlVGV4dHVyZSkge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ1RleHR1cmVNYW5hZ2VyJywgYERlbGV0aW5nIHRleHR1cmUgb2Ygc2l6ZSAke3RleHR1cmVEYXRhLndpZHRofXgke3RleHR1cmVEYXRhLmhlaWdodH1gKTtcbiAgICAgIHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVRleHR1cmUodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgfVxuICB9XG4gIHRvVGVuc29yRGF0YShkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBkYXRhOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUpOiBUZW5zb3IuTnVtYmVyVHlwZSB7XG4gICAgc3dpdGNoIChkYXRhVHlwZSkge1xuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEludDE2QXJyYXkgPyBkYXRhIDogSW50MTZBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEludDMyQXJyYXkgPyBkYXRhIDogSW50MzJBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50OEFycmF5ID8gZGF0YSA6IEludDhBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50MTZBcnJheSA/IGRhdGEgOiBVaW50MTZBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50MzJBcnJheSA/IGRhdGEgOiBVaW50MzJBcnJheS5mcm9tKGRhdGEpO1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgY2FzZSAnYm9vbCc6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSA/IGRhdGEgOiBVaW50OEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBkYXRhIDogRmxvYXQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgPyBkYXRhIDogRmxvYXQ2NEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckRhdGEgdHlwZSAke2RhdGFUeXBlfSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gICAgfVxuICB9XG4gIHRvVGV4dHVyZURhdGEoX2RhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGRhdGE6IFRlbnNvci5OdW1iZXJUeXBlIHwgdW5kZWZpbmVkKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWRhdGEpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gZGF0YSA6IG5ldyBGbG9hdDMyQXJyYXkoZGF0YSk7XG4gICAgLypcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBVaW50MzJBcnJheSkgPyBkYXRhIGFzIFVpbnQzMkFycmF5IDogbmV3IFVpbnQzMkFycmF5KGRhdGEpO1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBVaW50OEFycmF5KSA/IGRhdGEgYXMgVWludDhBcnJheSA6IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBGbG9hdDMyQXJyYXkpID8gZGF0YSBhcyBGbG9hdDMyQXJyYXkgOiBuZXcgRmxvYXQzMkFycmF5KGRhdGEpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JEYXRhIHR5cGUgJHtkYXRhVHlwZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIH1cbiAgICAqL1xuICB9XG4gIHRvRW5jb2RlclR5cGUoX2RhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUpOiBFbmNvZGVyLkRhdGFUeXBlIHtcbiAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAvLyBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgLy8gICBjYXNlICdpbnQxNic6XG4gICAgLy8gICBjYXNlICdpbnQzMic6XG4gICAgLy8gICBjYXNlICd1aW50MTYnOlxuICAgIC8vICAgY2FzZSAndWludDMyJzpcbiAgICAvLyAgICAgcmV0dXJuICdpbnQnO1xuICAgIC8vICAgY2FzZSAndWludDgnOlxuICAgIC8vICAgY2FzZSAnYm9vbCc6XG4gICAgLy8gICAgIHJldHVybiAnYnl0ZSc7XG4gICAgLy8gICBjYXNlICdmbG9hdDMyJzpcbiAgICAvLyAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgIC8vICAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAvLyAgIGRlZmF1bHQ6XG4gICAgLy8gICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yRGF0YSB0eXBlICR7ZGF0YVR5cGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICAvLyB9XG4gIH1cbiAgY2xlYXJBY3RpdmVUZXh0dXJlcygpOiB2b2lkIHtcbiAgICB0aGlzLmdsQ29udGV4dC5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBPcGVyYXRvciB9IGZyb20gJy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPcFNldCwgcmVzb2x2ZU9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vb3BzZXQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL3Nlc3Npb24nO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMQmFja2VuZCB9IGZyb20gJy4uL2JhY2tlbmQtd2ViZ2wnO1xuXG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFdFQkdMX09QX1JFU09MVkVfUlVMRVMgfSBmcm9tICcuL29wLXJlc29sdmUtcnVsZXMnO1xuaW1wb3J0IHsgUHJvZ3JhbU1hbmFnZXIgfSBmcm9tICcuL3Byb2dyYW0tbWFuYWdlcic7XG5pbXBvcnQgeyBQcmVmZXJMb2dpY2FsU3RyYXRlZ3ksIFRleHR1cmVMYXlvdXRTdHJhdGVneSB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZU1hbmFnZXIgfSBmcm9tICcuL3RleHR1cmUtbWFuYWdlcic7XG5pbXBvcnQgeyBUZXh0dXJlRGF0YSB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgY2xhc3MgV2ViR0xTZXNzaW9uSGFuZGxlciBpbXBsZW1lbnRzIFNlc3Npb25IYW5kbGVyIHtcbiAgcHJvZ3JhbU1hbmFnZXI6IFByb2dyYW1NYW5hZ2VyO1xuICB0ZXh0dXJlTWFuYWdlcjogVGV4dHVyZU1hbmFnZXI7XG4gIGxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3k7XG4gIHBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgdW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlOiBNYXA8VGVuc29yLklkLCBUZXh0dXJlRGF0YT47XG4gIHBhY2sydW5wYWNrTWFwOiBNYXA8VGVuc29yLklkLCBUZW5zb3IuSWQ+O1xuICB1bnBhY2sycGFja01hcDogTWFwPFRlbnNvci5JZCwgVGVuc29yLklkPjtcbiAgaW5pdGlhbGl6ZXJzOiBTZXQ8VGVuc29yLklkPjtcbiAgcGFjaz86IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGJhY2tlbmQ6IFdlYkdMQmFja2VuZCxcbiAgICBwdWJsaWMgcmVhZG9ubHkgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0LFxuICApIHtcbiAgICB0aGlzLmxheW91dFN0cmF0ZWd5ID0gbmV3IFByZWZlckxvZ2ljYWxTdHJhdGVneShiYWNrZW5kLmdsQ29udGV4dC5tYXhUZXh0dXJlU2l6ZSk7XG4gICAgdGhpcy5wcm9ncmFtTWFuYWdlciA9IG5ldyBQcm9ncmFtTWFuYWdlcih0aGlzLmNvbnRleHQucHJvZmlsZXIsIGJhY2tlbmQuZ2xDb250ZXh0LCB0aGlzLmxheW91dFN0cmF0ZWd5KTtcbiAgICB0aGlzLnRleHR1cmVNYW5hZ2VyID0gbmV3IFRleHR1cmVNYW5hZ2VyKGJhY2tlbmQuZ2xDb250ZXh0LCB0aGlzLmxheW91dFN0cmF0ZWd5LCB0aGlzLmNvbnRleHQucHJvZmlsZXIsIHtcbiAgICAgIHJldXNlVGV4dHVyZXM6IGJhY2tlbmQudGV4dHVyZUNhY2hlTW9kZSA9PT0gJ2Z1bGwnLFxuICAgIH0pO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnBhY2sgPSBiYWNrZW5kLnBhY2s7XG4gICAgdGhpcy5wYWNrMnVucGFja01hcCA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFjazJwYWNrTWFwID0gbmV3IE1hcCgpO1xuICB9XG5cbiAgY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpIHtcbiAgICByZXR1cm4gbmV3IFdlYkdMSW5mZXJlbmNlSGFuZGxlcih0aGlzKTtcbiAgfVxuICBvbkdyYXBoSW5pdGlhbGl6ZWQoZ3JhcGg6IEdyYXBoKTogdm9pZCB7XG4gICAgY29uc3QgaW5pdGlhbGl6ZXJzID0gZ3JhcGhcbiAgICAgIC5nZXRWYWx1ZXMoKVxuICAgICAgLmZpbHRlcigodikgPT4gdi5mcm9tID09PSAtMSAmJiB2LnRlbnNvcilcbiAgICAgIC5tYXAoKHYpID0+IHYudGVuc29yIS5kYXRhSWQpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZXJzID0gbmV3IFNldChpbml0aWFsaXplcnMpO1xuICB9XG4gIGlzSW5pdGlhbGl6ZXIodGVuc29ySWQ6IFRlbnNvci5JZCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxpemVycyA/IHRoaXMuaW5pdGlhbGl6ZXJzLmhhcyh0ZW5zb3JJZCkgOiBmYWxzZTtcbiAgfVxuICBhZGRJbml0aWFsaXplcih0ZW5zb3JJZDogVGVuc29yLklkKTogdm9pZCB7XG4gICAgdGhpcy5pbml0aWFsaXplcnMuYWRkKHRlbnNvcklkKTtcbiAgfVxuICBnZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCBpc1BhY2tlZDogYm9vbGVhbik6IFRleHR1cmVEYXRhIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmdldCh0ZW5zb3JJZCk7XG4gICAgfVxuICB9XG4gIHNldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSwgaXNQYWNrZWQgPSBmYWxzZSk6IHZvaWQge1xuICAgIExvZ2dlci52ZXJib3NlKCdXZWJHTFNlc3Npb25IYW5kbGVyJywgJ1N0b3JpbmcgVGV4dHVyZSBkYXRhIGluIGNhY2hlJyk7XG4gICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuc2V0KHRlbnNvcklkLCB0ZXh0dXJlRGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLnNldCh0ZW5zb3JJZCwgdGV4dHVyZURhdGEpO1xuICAgIH1cbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMucHJvZ3JhbU1hbmFnZXIuZGlzcG9zZSgpO1xuICAgIHRoaXMudGV4dHVyZU1hbmFnZXIuY2xlYXJBY3RpdmVUZXh0dXJlcygpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKCh0ZCkgPT4gdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCwgdHJ1ZSkpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKCh0ZCkgPT4gdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCwgdHJ1ZSkpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICB9XG4gIHJlc29sdmUobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBncmFwaDogR3JhcGgpOiBPcGVyYXRvciB7XG4gICAgY29uc3Qgb3AgPSByZXNvbHZlT3BlcmF0b3Iobm9kZSwgb3BzZXRzLCBXRUJHTF9PUF9SRVNPTFZFX1JVTEVTKTtcbiAgICByZXR1cm4geyBpbXBsOiBvcC5vcEltcGwsIGNvbnRleHQ6IG9wLm9wSW5pdCA/IG9wLm9wSW5pdChub2RlLCBncmFwaCkgOiBub2RlIH07XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0ICogYXMgRGF0YUVuY29kZXJzIGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHsgRGF0YUVuY29kZXIsIEVuY29kZXIsIEVuY29kZXJVc2FnZSB9IGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHsgcmVwZWF0ZWRUcnkgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBGZW5jZUNvbnRleHQge1xuICBxdWVyeTogV2ViR0xTeW5jIHwgbnVsbDtcbiAgaXNGZW5jZVBhc3NlZCgpOiBib29sZWFuO1xufVxuXG50eXBlIFBvbGxJdGVtID0ge1xuICBpc0RvbmVGbjogKCkgPT4gYm9vbGVhbjtcbiAgcmVzb2x2ZUZuOiAoKSA9PiB2b2lkO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclNlYXJjaExhc3RUcnVlKGFycjogQXJyYXk8KCkgPT4gYm9vbGVhbj4pOiBudW1iZXIge1xuICBsZXQgaSA9IDA7XG4gIGZvciAoOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgaXNEb25lID0gYXJyW2ldKCk7XG4gICAgaWYgKCFpc0RvbmUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaSAtIDE7XG59XG5cbi8qKlxuICogQWJzdHJhY3Rpb24gYW5kIHdyYXBwZXIgYXJvdW5kIFdlYkdMUmVuZGVyaW5nQ29udGV4dCBhbmQgaXRzIG9wZXJhdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIFdlYkdMQ29udGV4dCB7XG4gIGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XG4gIHZlcnNpb246IDEgfCAyO1xuXG4gIHByaXZhdGUgdmVydGV4YnVmZmVyOiBXZWJHTEJ1ZmZlcjtcbiAgcHJpdmF0ZSBmcmFtZWJ1ZmZlcjogV2ViR0xGcmFtZWJ1ZmZlcjtcblxuICAvLyBXZWJHTCBmbGFncyBhbmQgdml0YWwgcGFyYW1ldGVyc1xuICBwcml2YXRlIGlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXI6IGJvb2xlYW47XG4gIGlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkOiBib29sZWFuO1xuICBpc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gIGlzQmxlbmRTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gIG1heFRleHR1cmVTaXplOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4Q29tYmluZWRUZXh0dXJlSW1hZ2VVbml0czogbnVtYmVyO1xuICBwcml2YXRlIG1heFRleHR1cmVJbWFnZVVuaXRzOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4Q3ViZU1hcFRleHR1cmVTaXplOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgc2hhZGluZ0xhbmd1YWdlVmVyc2lvbjogc3RyaW5nO1xuICAvLyBwcml2YXRlIHdlYmdsVmVuZG9yOiBzdHJpbmc7XG4gIC8vIHByaXZhdGUgd2ViZ2xWZXJzaW9uOiBzdHJpbmc7XG5cbiAgLy8gV2ViR0wyIGZsYWdzIGFuZCB2aXRhbCBwYXJhbWV0ZXJzXG4gIC8vIHByaXZhdGUgbWF4M0RUZXh0dXJlU2l6ZTogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heEFycmF5VGV4dHVyZUxheWVyczogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heENvbG9yQXR0YWNobWVudHM6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhEcmF3QnVmZmVyczogbnVtYmVyO1xuXG4gIC8vIFdlYkdMIGV4dGVuc2lvbnNcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuICB0ZXh0dXJlRmxvYXRFeHRlbnNpb246IE9FU190ZXh0dXJlX2Zsb2F0IHwgbnVsbDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuICB0ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uOiBPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0IHwgbnVsbDtcblxuICAvLyBXZWJHTDIgZXh0ZW5zaW9uc1xuICBjb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uOiB1bmtub3duIHwgbnVsbDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICBkaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb246IHsgVElNRV9FTEFQU0VEX0VYVDogR0xlbnVtOyBHUFVfRElTSk9JTlRfRVhUOiBHTGVudW0gfSB8IG51bGw7XG5cbiAgcHJpdmF0ZSBkaXNwb3NlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBmcmFtZUJ1ZmZlckJvdW5kID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdmVyc2lvbjogMSB8IDIpIHtcbiAgICB0aGlzLmdsID0gZ2w7XG4gICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjtcblxuICAgIHRoaXMuZ2V0RXh0ZW5zaW9ucygpO1xuICAgIHRoaXMudmVydGV4YnVmZmVyID0gdGhpcy5jcmVhdGVWZXJ0ZXhidWZmZXIoKTtcbiAgICB0aGlzLmZyYW1lYnVmZmVyID0gdGhpcy5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgIHRoaXMucXVlcnlWaXRhbFBhcmFtZXRlcnMoKTtcbiAgfVxuXG4gIGFsbG9jYXRlVGV4dHVyZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgZW5jb2RlcjogRGF0YUVuY29kZXIsIGRhdGE/OiBFbmNvZGVyLkRhdGFBcnJheVR5cGUpOiBXZWJHTFRleHR1cmUge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAvLyBjcmVhdGUgdGhlIHRleHR1cmVcbiAgICBjb25zdCB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgIC8vIGJpbmQgdGhlIHRleHR1cmUgc28gdGhlIGZvbGxvd2luZyBtZXRob2RzIGVmZmVjdCB0aGlzIHRleHR1cmUuXG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5ORUFSRVNUKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9TLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICBjb25zdCBidWZmZXIgPSBkYXRhID8gZW5jb2Rlci5lbmNvZGUoZGF0YSwgd2lkdGggKiBoZWlnaHQpIDogbnVsbDtcbiAgICBnbC50ZXhJbWFnZTJEKFxuICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgIDAsIC8vIExldmVsIG9mIGRldGFpbC5cbiAgICAgIGVuY29kZXIuaW50ZXJuYWxGb3JtYXQsXG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIDAsIC8vIEFsd2F5cyAwIGluIE9wZW5HTCBFUy5cbiAgICAgIGVuY29kZXIuZm9ybWF0LFxuICAgICAgZW5jb2Rlci50ZXh0dXJlVHlwZSxcbiAgICAgIGJ1ZmZlcixcbiAgICApO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIHJldHVybiB0ZXh0dXJlIGFzIFdlYkdMVGV4dHVyZTtcbiAgfVxuICB1cGRhdGVUZXh0dXJlKFxuICAgIHRleHR1cmU6IFdlYkdMVGV4dHVyZSxcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIGVuY29kZXI6IERhdGFFbmNvZGVyLFxuICAgIGRhdGE6IEVuY29kZXIuRGF0YUFycmF5VHlwZSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGVuY29kZXIuZW5jb2RlKGRhdGEsIHdpZHRoICogaGVpZ2h0KTtcbiAgICBnbC50ZXhTdWJJbWFnZTJEKFxuICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgIDAsIC8vIGxldmVsXG4gICAgICAwLCAvLyB4b2Zmc2V0XG4gICAgICAwLCAvLyB5b2Zmc2V0XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIGVuY29kZXIuZm9ybWF0LFxuICAgICAgZW5jb2Rlci50ZXh0dXJlVHlwZSxcbiAgICAgIGJ1ZmZlcixcbiAgICApO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGF0dGFjaEZyYW1lYnVmZmVyKHRleHR1cmU6IFdlYkdMVGV4dHVyZSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgLy8gTWFrZSBpdCB0aGUgdGFyZ2V0IGZvciBmcmFtZWJ1ZmZlciBvcGVyYXRpb25zIC0gaW5jbHVkaW5nIHJlbmRlcmluZy5cbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIHRoaXMuZnJhbWVidWZmZXIpO1xuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSwgMCk7IC8vIDAsIHdlIGFyZW4ndCB1c2luZyBNSVBNQVBzXG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wudmlld3BvcnQoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgZ2wuc2Npc3NvcigwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuICByZWFkVGV4dHVyZShcbiAgICB0ZXh0dXJlOiBXZWJHTFRleHR1cmUsXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICBkYXRhU2l6ZTogbnVtYmVyLFxuICAgIGRhdGFUeXBlOiBFbmNvZGVyLkRhdGFUeXBlLFxuICAgIGNoYW5uZWxzOiBudW1iZXIsXG4gICk6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmZyYW1lQnVmZmVyQm91bmQpIHtcbiAgICAgIHRoaXMuYXR0YWNoRnJhbWVidWZmZXIodGV4dHVyZSwgd2lkdGgsIGhlaWdodCk7XG4gICAgfVxuICAgIGNvbnN0IGVuY29kZXIgPSB0aGlzLmdldEVuY29kZXIoZGF0YVR5cGUsIGNoYW5uZWxzKTtcbiAgICBjb25zdCBidWZmZXIgPSBlbmNvZGVyLmFsbG9jYXRlKHdpZHRoICogaGVpZ2h0KTtcbiAgICAvLyBiaW5kIHRleHR1cmUgdG8gZnJhbWVidWZmZXJcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApOyAvLyAwLCB3ZSBhcmVuJ3QgdXNpbmcgTUlQTUFQc1xuICAgIC8vIFRPRE86IENoZWNrIGlmIGZyYW1lYnVmZmVyIGlzIHJlYWR5XG4gICAgZ2wucmVhZFBpeGVscygwLCAwLCB3aWR0aCwgaGVpZ2h0LCBnbC5SR0JBLCBlbmNvZGVyLnRleHR1cmVUeXBlLCBidWZmZXIpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIC8vIHVuYmluZCBGQlxuICAgIHJldHVybiBlbmNvZGVyLmRlY29kZShidWZmZXIsIGRhdGFTaXplKTtcbiAgfVxuXG4gIGlzRnJhbWVidWZmZXJSZWFkeSgpOiBib29sZWFuIHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgbG9naWMgdG8gY2hlY2sgaWYgdGhlIGZyYW1lYnVmZmVyIGlzIHJlYWR5XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZ2V0QWN0aXZlVGV4dHVyZSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBuID0gZ2wuZ2V0UGFyYW1ldGVyKHRoaXMuZ2wuQUNUSVZFX1RFWFRVUkUpO1xuICAgIHJldHVybiBgVEVYVFVSRSR7biAtIGdsLlRFWFRVUkUwfWA7XG4gIH1cbiAgZ2V0VGV4dHVyZUJpbmRpbmcoKTogV2ViR0xUZXh0dXJlIHtcbiAgICByZXR1cm4gdGhpcy5nbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5URVhUVVJFX0JJTkRJTkdfMkQpO1xuICB9XG4gIGdldEZyYW1lYnVmZmVyQmluZGluZygpOiBXZWJHTEZyYW1lYnVmZmVyIHtcbiAgICByZXR1cm4gdGhpcy5nbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5GUkFNRUJVRkZFUl9CSU5ESU5HKTtcbiAgfVxuICBzZXRWZXJ0ZXhBdHRyaWJ1dGVzKHBvc2l0aW9uSGFuZGxlOiBudW1iZXIsIHRleHR1cmVDb29yZEhhbmRsZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIocG9zaXRpb25IYW5kbGUsIDMsIGdsLkZMT0FULCBmYWxzZSwgMjAsIDApO1xuICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uSGFuZGxlKTtcbiAgICBpZiAodGV4dHVyZUNvb3JkSGFuZGxlICE9PSAtMSkge1xuICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcih0ZXh0dXJlQ29vcmRIYW5kbGUsIDIsIGdsLkZMT0FULCBmYWxzZSwgMjAsIDEyKTtcbiAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRleHR1cmVDb29yZEhhbmRsZSk7XG4gICAgfVxuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGNyZWF0ZVByb2dyYW0odmVydGV4U2hhZGVyOiBXZWJHTFNoYWRlciwgZnJhZ1NoYWRlcjogV2ViR0xTaGFkZXIpOiBXZWJHTFByb2dyYW0ge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBwcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpITtcblxuICAgIC8vIHRoZSBwcm9ncmFtIGNvbnNpc3RzIG9mIG91ciBzaGFkZXJzXG4gICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIHZlcnRleFNoYWRlcik7XG4gICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIGZyYWdTaGFkZXIpO1xuICAgIGdsLmxpbmtQcm9ncmFtKHByb2dyYW0pO1xuICAgIHJldHVybiBwcm9ncmFtO1xuICB9XG4gIGNvbXBpbGVTaGFkZXIoc2hhZGVyU291cmNlOiBzdHJpbmcsIHNoYWRlclR5cGU6IG51bWJlcik6IFdlYkdMU2hhZGVyIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgY29uc3Qgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKHNoYWRlclR5cGUpO1xuICAgIGlmICghc2hhZGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNyZWF0ZVNoYWRlcigpIHJldHVybmVkIG51bGwgd2l0aCB0eXBlICR7c2hhZGVyVHlwZX1gKTtcbiAgICB9XG5cbiAgICBnbC5zaGFkZXJTb3VyY2Uoc2hhZGVyLCBzaGFkZXJTb3VyY2UpO1xuICAgIGdsLmNvbXBpbGVTaGFkZXIoc2hhZGVyKTtcbiAgICBpZiAoZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gY29tcGlsZSBzaGFkZXI6ICR7Z2wuZ2V0U2hhZGVySW5mb0xvZyhzaGFkZXIpfVxuU2hhZGVyIHNvdXJjZTpcbiR7c2hhZGVyU291cmNlfWApO1xuICAgIH1cbiAgICByZXR1cm4gc2hhZGVyO1xuICB9XG4gIGRlbGV0ZVNoYWRlcihzaGFkZXI6IFdlYkdMU2hhZGVyKTogdm9pZCB7XG4gICAgdGhpcy5nbC5kZWxldGVTaGFkZXIoc2hhZGVyKTtcbiAgfVxuICBiaW5kVGV4dHVyZVRvVW5pZm9ybSh0ZXh0dXJlOiBXZWJHTFRleHR1cmUsIHBvc2l0aW9uOiBudW1iZXIsIHVuaWZvcm1IYW5kbGU6IFdlYkdMVW5pZm9ybUxvY2F0aW9uKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLmFjdGl2ZVRleHR1cmUoZ2wuVEVYVFVSRTAgKyBwb3NpdGlvbik7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wudW5pZm9ybTFpKHVuaWZvcm1IYW5kbGUsIHBvc2l0aW9uKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgfVxuICBkcmF3KCk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZHJhd0FycmF5cyh0aGlzLmdsLlRSSUFOR0xFX1NUUklQLCAwLCA0KTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgfVxuICBjaGVja0Vycm9yKCk6IHZvaWQge1xuICAgIGlmIChlbnYuZGVidWcpIHtcbiAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgIGNvbnN0IGVycm9yID0gZ2wuZ2V0RXJyb3IoKTtcbiAgICAgIGxldCBsYWJlbCA9ICcnO1xuICAgICAgc3dpdGNoIChlcnJvcikge1xuICAgICAgICBjYXNlIGdsLk5PX0VSUk9SOlxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY2FzZSBnbC5JTlZBTElEX0VOVU06XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9FTlVNJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5JTlZBTElEX1ZBTFVFOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfVkFMVUUnO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGdsLklOVkFMSURfT1BFUkFUSU9OOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfT1BFUkFUSU9OJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5JTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTjpcbiAgICAgICAgICBsYWJlbCA9ICdJTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTic7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgZ2wuT1VUX09GX01FTU9SWTpcbiAgICAgICAgICBsYWJlbCA9ICdPVVRfT0ZfTUVNT1JZJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5DT05URVhUX0xPU1RfV0VCR0w6XG4gICAgICAgICAgbGFiZWwgPSAnQ09OVEVYVF9MT1NUX1dFQkdMJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBsYWJlbCA9IGBVbmtub3duIFdlYkdMIEVycm9yOiAke2Vycm9yLnRvU3RyaW5nKDE2KX1gO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGxhYmVsKTtcbiAgICB9XG4gIH1cbiAgZGVsZXRlVGV4dHVyZSh0ZXh0dXJlOiBXZWJHTFRleHR1cmUpOiB2b2lkIHtcbiAgICB0aGlzLmdsLmRlbGV0ZVRleHR1cmUodGV4dHVyZSk7XG4gIH1cbiAgZGVsZXRlUHJvZ3JhbShwcm9ncmFtOiBXZWJHTFByb2dyYW0pOiB2b2lkIHtcbiAgICB0aGlzLmdsLmRlbGV0ZVByb2dyYW0ocHJvZ3JhbSk7XG4gIH1cbiAgZ2V0RW5jb2RlcihkYXRhVHlwZTogRW5jb2Rlci5EYXRhVHlwZSwgY2hhbm5lbHM6IG51bWJlciwgdXNhZ2U6IEVuY29kZXJVc2FnZSA9IEVuY29kZXJVc2FnZS5EZWZhdWx0KTogRGF0YUVuY29kZXIge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIHJldHVybiBuZXcgRGF0YUVuY29kZXJzLlJlZEZsb2F0MzJEYXRhRW5jb2Rlcih0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdmbG9hdCc6XG4gICAgICAgIGlmICh1c2FnZSA9PT0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkgfHwgdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5SR0JBRmxvYXREYXRhRW5jb2Rlcih0aGlzLmdsLCBjaGFubmVscyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuUkdCQUZsb2F0RGF0YUVuY29kZXIoXG4gICAgICAgICAgICB0aGlzLmdsLFxuICAgICAgICAgICAgY2hhbm5lbHMsXG4gICAgICAgICAgICB0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24hLkhBTEZfRkxPQVRfT0VTLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2ludCc6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG4gICAgICBjYXNlICdieXRlJzpcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuVWludDhEYXRhRW5jb2Rlcih0aGlzLmdsLCBjaGFubmVscyk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YVR5cGU6ICR7ZGF0YVR5cGV9YCk7XG4gICAgfVxuICB9XG4gIGNsZWFyQWN0aXZlVGV4dHVyZXMoKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGZvciAobGV0IHVuaXQgPSAwOyB1bml0IDwgdGhpcy5tYXhUZXh0dXJlSW1hZ2VVbml0czsgKyt1bml0KSB7XG4gICAgICBnbC5hY3RpdmVUZXh0dXJlKGdsLlRFWFRVUkUwICsgdW5pdCk7XG4gICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBudWxsKTtcbiAgICB9XG4gIH1cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNwb3NlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICBnbC5kZWxldGVGcmFtZWJ1ZmZlcih0aGlzLmZyYW1lYnVmZmVyKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZGVsZXRlQnVmZmVyKHRoaXMudmVydGV4YnVmZmVyKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSLCBudWxsKTtcbiAgICBnbC5maW5pc2goKTtcbiAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGVmYXVsdEdlb21ldHJ5KCk6IEZsb2F0MzJBcnJheSB7XG4gICAgLy8gU2V0cyBvZiB4LHkseig9MCkscyx0IGNvb3JkaW5hdGVzLlxuICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KFtcbiAgICAgIC0xLjAsXG4gICAgICAxLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAxLjAsIC8vIHVwcGVyIGxlZnRcbiAgICAgIC0xLjAsXG4gICAgICAtMS4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wLCAvLyBsb3dlciBsZWZ0XG4gICAgICAxLjAsXG4gICAgICAxLjAsXG4gICAgICAwLjAsXG4gICAgICAxLjAsXG4gICAgICAxLjAsIC8vIHVwcGVyIHJpZ2h0XG4gICAgICAxLjAsXG4gICAgICAtMS4wLFxuICAgICAgMC4wLFxuICAgICAgMS4wLFxuICAgICAgMC4wLCAvLyBsb3dlciByaWdodFxuICAgIF0pO1xuICB9XG4gIHByaXZhdGUgY3JlYXRlVmVydGV4YnVmZmVyKCk6IFdlYkdMQnVmZmVyIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgY29uc3QgYnVmZmVyID0gZ2wuY3JlYXRlQnVmZmVyKCk7XG4gICAgaWYgKCFidWZmZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3JlYXRlQnVmZmVyKCkgcmV0dXJuZWQgbnVsbCcpO1xuICAgIH1cbiAgICBjb25zdCBnZW9tZXRyeSA9IHRoaXMuY3JlYXRlRGVmYXVsdEdlb21ldHJ5KCk7XG4gICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIGJ1ZmZlcik7XG4gICAgZ2wuYnVmZmVyRGF0YShnbC5BUlJBWV9CVUZGRVIsIGdlb21ldHJ5LCBnbC5TVEFUSUNfRFJBVyk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbiAgfVxuICBwcml2YXRlIGNyZWF0ZUZyYW1lYnVmZmVyKCk6IFdlYkdMRnJhbWVidWZmZXIge1xuICAgIGNvbnN0IGZiID0gdGhpcy5nbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgIGlmICghZmIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3JlYXRlRnJhbWVidWZmZXIgcmV0dXJuZWQgbnVsbCcpO1xuICAgIH1cbiAgICByZXR1cm4gZmI7XG4gIH1cblxuICBwcml2YXRlIHF1ZXJ5Vml0YWxQYXJhbWV0ZXJzKCk6IHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcblxuICAgIHRoaXMuaXNGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlciA9IHRoaXMuY2hlY2tGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlcigpO1xuICAgIHRoaXMuaXNSZW5kZXJGbG9hdDMyU3VwcG9ydGVkID0gdGhpcy5jaGVja1JlbmRlckZsb2F0MzIoKTtcbiAgICB0aGlzLmlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkID0gdGhpcy5jaGVja0Zsb2F0MzJEb3dubG9hZCgpO1xuXG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMSAmJiAhdGhpcy50ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uICYmICF0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdib3RoIGZsb2F0MzIgYW5kIGZsb2F0MTYgVGV4dHVyZVR5cGUgYXJlIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzQmxlbmRTdXBwb3J0ZWQgPSAhdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQgfHwgdGhpcy5jaGVja0Zsb2F0MzJCbGVuZCgpO1xuXG4gICAgLy8gdGhpcy5tYXhDb21iaW5lZFRleHR1cmVJbWFnZVVuaXRzID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9DT01CSU5FRF9URVhUVVJFX0lNQUdFX1VOSVRTKTtcbiAgICB0aGlzLm1heFRleHR1cmVTaXplID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9URVhUVVJFX1NJWkUpO1xuICAgIHRoaXMubWF4VGV4dHVyZUltYWdlVW5pdHMgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX1RFWFRVUkVfSU1BR0VfVU5JVFMpO1xuICAgIC8vIHRoaXMubWF4Q3ViZU1hcFRleHR1cmVTaXplID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9DVUJFX01BUF9URVhUVVJFX1NJWkUpO1xuICAgIC8vIHRoaXMuc2hhZGluZ0xhbmd1YWdlVmVyc2lvbiA9IGdsLmdldFBhcmFtZXRlcihnbC5TSEFESU5HX0xBTkdVQUdFX1ZFUlNJT04pO1xuICAgIC8vIHRoaXMud2ViZ2xWZW5kb3IgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuVkVORE9SKTtcbiAgICAvLyB0aGlzLndlYmdsVmVyc2lvbiA9IGdsLmdldFBhcmFtZXRlcihnbC5WRVJTSU9OKTtcblxuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIC8vIHRoaXMubWF4M0RUZXh0dXJlU2l6ZSA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF8zRF9URVhUVVJFX1NJWkUpO1xuICAgICAgLy8gdGhpcy5tYXhBcnJheVRleHR1cmVMYXllcnMgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfQVJSQVlfVEVYVFVSRV9MQVlFUlMpO1xuICAgICAgLy8gdGhpcy5tYXhDb2xvckF0dGFjaG1lbnRzID0gZ2wuZ2V0UGFyYW1ldGVyKFdlYkdMMlJlbmRlcmluZ0NvbnRleHQuTUFYX0NPTE9SX0FUVEFDSE1FTlRTKTtcbiAgICAgIC8vIHRoaXMubWF4RHJhd0J1ZmZlcnMgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfRFJBV19CVUZGRVJTKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBnZXRFeHRlbnNpb25zKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIHRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdFWFRfY29sb3JfYnVmZmVyX2Zsb2F0Jyk7XG4gICAgICB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdFWFRfZGlzam9pbnRfdGltZXJfcXVlcnlfd2ViZ2wyJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGV4dHVyZUZsb2F0RXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ09FU190ZXh0dXJlX2Zsb2F0Jyk7XG4gICAgICB0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24gPSB0aGlzLmdsLmdldEV4dGVuc2lvbignT0VTX3RleHR1cmVfaGFsZl9mbG9hdCcpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlcigpOiBib29sZWFuIHtcbiAgICAvLyB0ZXN0IHdoZXRoZXIgRmxvYXQzMiB0ZXh0dXJlIGlzIHN1cHBvcnRlZDpcbiAgICAvLyBTVEVQLjEgY3JlYXRlIGEgZmxvYXQgdGV4dHVyZVxuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICBjb25zdCBpbnRlcm5hbEZvcm1hdCA9IHRoaXMudmVyc2lvbiA9PT0gMiA/IChnbCBhcyB1bmtub3duIGFzIHsgUkdCQTMyRjogbnVtYmVyIH0pLlJHQkEzMkYgOiBnbC5SR0JBO1xuICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgaW50ZXJuYWxGb3JtYXQsIDEsIDEsIDAsIGdsLlJHQkEsIGdsLkZMT0FULCBudWxsKTtcbiAgICAvLyBTVEVQLjIgYmluZCBhIGZyYW1lIGJ1ZmZlclxuICAgIGNvbnN0IGZyYW1lQnVmZmVyID0gZ2wuY3JlYXRlRnJhbWVidWZmZXIoKTtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIGZyYW1lQnVmZmVyKTtcbiAgICAvLyBTVEVQLjMgYXR0YWNoIHRleHR1cmUgdG8gZnJhbWVidWZmZXJcbiAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApO1xuICAgIC8vIFNURVAuNCB0ZXN0IHdoZXRoZXIgZnJhbWVidWZmZXIgaXMgY29tcGxldGVcbiAgICBjb25zdCBpc0NvbXBsZXRlID0gZ2wuY2hlY2tGcmFtZWJ1ZmZlclN0YXR1cyhnbC5GUkFNRUJVRkZFUikgPT09IGdsLkZSQU1FQlVGRkVSX0NPTVBMRVRFO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlKTtcbiAgICBnbC5kZWxldGVGcmFtZWJ1ZmZlcihmcmFtZUJ1ZmZlcik7XG4gICAgcmV0dXJuIGlzQ29tcGxldGU7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrUmVuZGVyRmxvYXQzMigpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBpZiAoIXRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0Zsb2F0MzJEb3dubG9hZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBpZiAoIXRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmdsLmdldEV4dGVuc2lvbignV0VCR0xfY29sb3JfYnVmZmVyX2Zsb2F0JykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgR0xfQkxFTkQgaXMgc3VwcG9ydGVkXG4gICAqL1xuICBwcml2YXRlIGNoZWNrRmxvYXQzMkJsZW5kKCk6IGJvb2xlYW4ge1xuICAgIC8vIGl0IGxvb2tzIGxpa2UgY3VycmVudGx5ICgyMDE5LTA1LTA4KSB0aGVyZSBpcyBubyBlYXN5IHdheSB0byBkZXRlY3Qgd2hldGhlciBCTEVORCBpcyBzdXBwb3J0ZWRcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhqcy9pc3N1ZXMvMTQ1XG5cbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG5cbiAgICBsZXQgdGV4dHVyZTogV2ViR0xUZXh0dXJlIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZnJhbWVCdWZmZXI6IFdlYkdMRnJhbWVidWZmZXIgfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIGxldCB2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZnJhZ21lbnRTaGFkZXI6IFdlYkdMU2hhZGVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgcHJvZ3JhbTogV2ViR0xQcm9ncmFtIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgIHRyeSB7XG4gICAgICB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgICAgZnJhbWVCdWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICAgIGNvbnN0IGludGVybmFsRm9ybWF0ID0gdGhpcy52ZXJzaW9uID09PSAyID8gKGdsIGFzIHVua25vd24gYXMgeyBSR0JBMzJGOiBudW1iZXIgfSkuUkdCQTMyRiA6IGdsLlJHQkE7XG4gICAgICBnbC50ZXhJbWFnZTJEKGdsLlRFWFRVUkVfMkQsIDAsIGludGVybmFsRm9ybWF0LCAxLCAxLCAwLCBnbC5SR0JBLCBnbC5GTE9BVCwgbnVsbCk7XG5cbiAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgZnJhbWVCdWZmZXIpO1xuICAgICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoZ2wuRlJBTUVCVUZGRVIsIGdsLkNPTE9SX0FUVEFDSE1FTlQwLCBnbC5URVhUVVJFXzJELCB0ZXh0dXJlLCAwKTtcblxuICAgICAgZ2wuZW5hYmxlKGdsLkJMRU5EKTtcblxuICAgICAgdmVydGV4U2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKGdsLlZFUlRFWF9TSEFERVIpO1xuICAgICAgaWYgKCF2ZXJ0ZXhTaGFkZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZ2wuc2hhZGVyU291cmNlKHZlcnRleFNoYWRlciwgJ3ZvaWQgbWFpbigpe30nKTtcbiAgICAgIGdsLmNvbXBpbGVTaGFkZXIodmVydGV4U2hhZGVyKTtcblxuICAgICAgZnJhZ21lbnRTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoZ2wuRlJBR01FTlRfU0hBREVSKTtcbiAgICAgIGlmICghZnJhZ21lbnRTaGFkZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZ2wuc2hhZGVyU291cmNlKGZyYWdtZW50U2hhZGVyLCAncHJlY2lzaW9uIGhpZ2hwIGZsb2F0O3ZvaWQgbWFpbigpe2dsX0ZyYWdDb2xvcj12ZWM0KDAuNSk7fScpO1xuICAgICAgZ2wuY29tcGlsZVNoYWRlcihmcmFnbWVudFNoYWRlcik7XG5cbiAgICAgIHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCk7XG4gICAgICBpZiAoIXByb2dyYW0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIHZlcnRleFNoYWRlcik7XG4gICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgZnJhZ21lbnRTaGFkZXIpO1xuICAgICAgZ2wubGlua1Byb2dyYW0ocHJvZ3JhbSk7XG4gICAgICBnbC51c2VQcm9ncmFtKHByb2dyYW0pO1xuXG4gICAgICBnbC5kcmF3QXJyYXlzKGdsLlBPSU5UUywgMCwgMSk7XG4gICAgICByZXR1cm4gZ2wuZ2V0RXJyb3IoKSA9PT0gZ2wuTk9fRVJST1I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGdsLmRpc2FibGUoZ2wuQkxFTkQpO1xuXG4gICAgICBpZiAocHJvZ3JhbSkge1xuICAgICAgICBnbC5kZWxldGVQcm9ncmFtKHByb2dyYW0pO1xuICAgICAgfVxuICAgICAgaWYgKHZlcnRleFNoYWRlcikge1xuICAgICAgICBnbC5kZWxldGVTaGFkZXIodmVydGV4U2hhZGVyKTtcbiAgICAgIH1cbiAgICAgIGlmIChmcmFnbWVudFNoYWRlcikge1xuICAgICAgICBnbC5kZWxldGVTaGFkZXIoZnJhZ21lbnRTaGFkZXIpO1xuICAgICAgfVxuICAgICAgaWYgKGZyYW1lQnVmZmVyKSB7XG4gICAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7XG4gICAgICAgIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKGZyYW1lQnVmZmVyKTtcbiAgICAgIH1cbiAgICAgIGlmICh0ZXh0dXJlKSB7XG4gICAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgICAgICBnbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGJlZ2luVGltZXIoKTogV2ViR0xRdWVyeSB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMiAmJiB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgY29uc3QgZXh0ID0gdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb247XG5cbiAgICAgIGNvbnN0IHF1ZXJ5ID0gZ2wyLmNyZWF0ZVF1ZXJ5KCkgYXMgV2ViR0xRdWVyeTtcbiAgICAgIGdsMi5iZWdpblF1ZXJ5KGV4dC5USU1FX0VMQVBTRURfRVhULCBxdWVyeSk7XG4gICAgICByZXR1cm4gcXVlcnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRPRE86IGFkZCB3ZWJnbCAxIGhhbmRsaW5nLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHTDEgcHJvZmlsaW5nIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIGVuZFRpbWVyKCkge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIgJiYgdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb24pIHtcbiAgICAgIGNvbnN0IGdsMiA9IHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICAgIGNvbnN0IGV4dCA9IHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uO1xuICAgICAgZ2wyLmVuZFF1ZXJ5KGV4dC5USU1FX0VMQVBTRURfRVhUKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH1cblxuICBpc1RpbWVyUmVzdWx0QXZhaWxhYmxlKHF1ZXJ5OiBXZWJHTFF1ZXJ5KTogYm9vbGVhbiB7XG4gICAgbGV0IGF2YWlsYWJsZSA9IGZhbHNlLFxuICAgICAgZGlzam9pbnQgPSBmYWxzZTtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyICYmIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICBjb25zdCBleHQgPSB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjtcblxuICAgICAgYXZhaWxhYmxlID0gZ2wyLmdldFF1ZXJ5UGFyYW1ldGVyKHF1ZXJ5LCBnbDIuUVVFUllfUkVTVUxUX0FWQUlMQUJMRSk7XG4gICAgICBkaXNqb2ludCA9IGdsMi5nZXRQYXJhbWV0ZXIoZXh0LkdQVV9ESVNKT0lOVF9FWFQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBhdmFpbGFibGUgJiYgIWRpc2pvaW50O1xuICB9XG5cbiAgZ2V0VGltZXJSZXN1bHQocXVlcnk6IFdlYkdMUXVlcnkpOiBudW1iZXIge1xuICAgIGxldCB0aW1lRWxhcHNlZCA9IDA7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgdGltZUVsYXBzZWQgPSBnbDIuZ2V0UXVlcnlQYXJhbWV0ZXIocXVlcnksIGdsMi5RVUVSWV9SRVNVTFQpO1xuICAgICAgZ2wyLmRlbGV0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gICAgLy8gcmV0dXJuIG1pbGxpc2Vjb25kc1xuICAgIHJldHVybiB0aW1lRWxhcHNlZCAvIDEwMDAwMDA7XG4gIH1cblxuICBhc3luYyB3YWl0Rm9yUXVlcnlBbmRHZXRUaW1lKHF1ZXJ5OiBXZWJHTFF1ZXJ5KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBhd2FpdCByZXBlYXRlZFRyeSgoKSA9PiB0aGlzLmlzVGltZXJSZXN1bHRBdmFpbGFibGUocXVlcnkpKTtcbiAgICByZXR1cm4gdGhpcy5nZXRUaW1lclJlc3VsdChxdWVyeSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgY3JlYXRlQW5kV2FpdEZvckZlbmNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGZlbmNlQ29udGV4dCA9IHRoaXMuY3JlYXRlRmVuY2UodGhpcy5nbCk7XG4gICAgcmV0dXJuIHRoaXMucG9sbEZlbmNlKGZlbmNlQ29udGV4dCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUZlbmNlKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQpOiBGZW5jZUNvbnRleHQge1xuICAgIGxldCBpc0ZlbmNlUGFzc2VkOiAoKSA9PiBib29sZWFuO1xuICAgIGNvbnN0IGdsMiA9IGdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgY29uc3QgcXVlcnkgPSBnbDIuZmVuY2VTeW5jKGdsMi5TWU5DX0dQVV9DT01NQU5EU19DT01QTEVURSwgMCk7XG4gICAgZ2wuZmx1c2goKTtcbiAgICBpZiAocXVlcnkgPT09IG51bGwpIHtcbiAgICAgIGlzRmVuY2VQYXNzZWQgPSAoKSA9PiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpc0ZlbmNlUGFzc2VkID0gKCkgPT4ge1xuICAgICAgICBjb25zdCBzdGF0dXMgPSBnbDIuY2xpZW50V2FpdFN5bmMocXVlcnksIDAsIDApO1xuICAgICAgICByZXR1cm4gc3RhdHVzID09PSBnbDIuQUxSRUFEWV9TSUdOQUxFRCB8fCBzdGF0dXMgPT09IGdsMi5DT05ESVRJT05fU0FUSVNGSUVEO1xuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgcXVlcnksIGlzRmVuY2VQYXNzZWQgfTtcbiAgfVxuXG4gIGFzeW5jIHBvbGxGZW5jZShmZW5jZUNvbnRleHQ6IEZlbmNlQ29udGV4dCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgdm9pZCB0aGlzLmFkZEl0ZW1Ub1BvbGwoXG4gICAgICAgICgpID0+IGZlbmNlQ29udGV4dC5pc0ZlbmNlUGFzc2VkKCksXG4gICAgICAgICgpID0+IHJlc29sdmUoKSxcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGl0ZW1zVG9Qb2xsOiBQb2xsSXRlbVtdID0gW107XG5cbiAgcG9sbEl0ZW1zKCk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIGxhc3QgcXVlcnkgdGhhdCBoYXMgZmluaXNoZWQuXG4gICAgY29uc3QgaW5kZXggPSBsaW5lYXJTZWFyY2hMYXN0VHJ1ZSh0aGlzLml0ZW1zVG9Qb2xsLm1hcCgoeCkgPT4geC5pc0RvbmVGbikpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IGluZGV4OyArK2kpIHtcbiAgICAgIGNvbnN0IHsgcmVzb2x2ZUZuIH0gPSB0aGlzLml0ZW1zVG9Qb2xsW2ldO1xuICAgICAgcmVzb2x2ZUZuKCk7XG4gICAgfVxuICAgIHRoaXMuaXRlbXNUb1BvbGwgPSB0aGlzLml0ZW1zVG9Qb2xsLnNsaWNlKGluZGV4ICsgMSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZEl0ZW1Ub1BvbGwoaXNEb25lRm46ICgpID0+IGJvb2xlYW4sIHJlc29sdmVGbjogKCkgPT4gdm9pZCkge1xuICAgIHRoaXMuaXRlbXNUb1BvbGwucHVzaCh7IGlzRG9uZUZuLCByZXNvbHZlRm4gfSk7XG4gICAgaWYgKHRoaXMuaXRlbXNUb1BvbGwubGVuZ3RoID4gMSkge1xuICAgICAgLy8gV2UgYWxyZWFkeSBoYXZlIGEgcnVubmluZyBsb29wIHRoYXQgcG9sbHMuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFN0YXJ0IGEgbmV3IGxvb3AgdGhhdCBwb2xscy5cbiAgICBhd2FpdCByZXBlYXRlZFRyeSgoKSA9PiB7XG4gICAgICB0aGlzLnBvbGxJdGVtcygpO1xuICAgICAgLy8gRW5kIHRoZSBsb29wIGlmIG5vIG1vcmUgaXRlbXMgdG8gcG9sbC5cbiAgICAgIHJldHVybiB0aGlzLml0ZW1zVG9Qb2xsLmxlbmd0aCA9PT0gMDtcbiAgICB9KTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcblxuaW1wb3J0IHsgV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuY29uc3QgY2FjaGU6IHsgW2NvbnRleHRJZDogc3RyaW5nXTogV2ViR0xDb250ZXh0IH0gPSB7fTtcblxuLyoqXG4gKiBUaGlzIGZhY3RvcnkgZnVuY3Rpb24gY3JlYXRlcyBwcm9wZXIgV2ViR0xSZW5kZXJpbmdDb250ZXh0IGJhc2VkIG9uXG4gKiB0aGUgY3VycmVudCBicm93c2VycyBjYXBhYmlsaXRpZXNcbiAqIFRoZSBvcmRlciBpcyBmcm9tIGhpZ2hlci9tb3N0IHJlY2VudCB2ZXJzaW9ucyB0byBtb3N0IGJhc2ljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXZWJHTENvbnRleHQoY29udGV4dElkPzogJ3dlYmdsJyB8ICd3ZWJnbDInKTogV2ViR0xDb250ZXh0IHtcbiAgbGV0IGNvbnRleHQ6IFdlYkdMQ29udGV4dCB8IHVuZGVmaW5lZDtcbiAgaWYgKCghY29udGV4dElkIHx8IGNvbnRleHRJZCA9PT0gJ3dlYmdsMicpICYmICd3ZWJnbDInIGluIGNhY2hlKSB7XG4gICAgY29udGV4dCA9IGNhY2hlLndlYmdsMjtcbiAgfSBlbHNlIGlmICgoIWNvbnRleHRJZCB8fCBjb250ZXh0SWQgPT09ICd3ZWJnbCcpICYmICd3ZWJnbCcgaW4gY2FjaGUpIHtcbiAgICBjb250ZXh0ID0gY2FjaGUud2ViZ2w7XG4gIH1cblxuICBpZiAoIWNvbnRleHQpIHtcbiAgICB0cnkge1xuICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSB3ZWJnbCBjb250ZXh0IGZyb20gYW4gb2Zmc2NyZWVuIGNhbnZhc1xuICAgICAgY29uc3Qgb2Zmc2NyZWVuQ2FudmFzID0gY3JlYXRlT2Zmc2NyZWVuQ2FudmFzKCk7XG4gICAgICBjb250ZXh0ID0gY3JlYXRlTmV3V2ViR0xDb250ZXh0KG9mZnNjcmVlbkNhbnZhcywgY29udGV4dElkKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIGlmIGZhaWxlZCwgZmFsbGJhY2sgdG8gdHJ5IHRvIHVzZSBhIG5vcm1hbCBjYW52YXMgZWxlbWVudFxuICAgICAgY29uc3QgY2FudmFzID0gY3JlYXRlQ2FudmFzKCk7XG4gICAgICBjb250ZXh0ID0gY3JlYXRlTmV3V2ViR0xDb250ZXh0KGNhbnZhcywgY29udGV4dElkKTtcbiAgICB9XG4gIH1cblxuICBjb250ZXh0SWQgPSBjb250ZXh0SWQgfHwgY29udGV4dC52ZXJzaW9uID09PSAxID8gJ3dlYmdsJyA6ICd3ZWJnbDInO1xuICBjb25zdCBnbCA9IGNvbnRleHQuZ2w7XG5cbiAgY2FjaGVbY29udGV4dElkXSA9IGNvbnRleHQ7XG5cbiAgaWYgKGdsLmlzQ29udGV4dExvc3QoKSkge1xuICAgIGRlbGV0ZSBjYWNoZVtjb250ZXh0SWRdO1xuICAgIHJldHVybiBjcmVhdGVXZWJHTENvbnRleHQoY29udGV4dElkKTtcbiAgfVxuXG4gIGdsLmRpc2FibGUoZ2wuREVQVEhfVEVTVCk7XG4gIGdsLmRpc2FibGUoZ2wuU1RFTkNJTF9URVNUKTtcbiAgZ2wuZGlzYWJsZShnbC5CTEVORCk7XG4gIGdsLmRpc2FibGUoZ2wuRElUSEVSKTtcbiAgZ2wuZGlzYWJsZShnbC5QT0xZR09OX09GRlNFVF9GSUxMKTtcbiAgZ2wuZGlzYWJsZShnbC5TQU1QTEVfQ09WRVJBR0UpO1xuICBnbC5lbmFibGUoZ2wuU0NJU1NPUl9URVNUKTtcbiAgZ2wuZW5hYmxlKGdsLkNVTExfRkFDRSk7XG4gIGdsLmN1bGxGYWNlKGdsLkJBQ0spO1xuXG4gIHJldHVybiBjb250ZXh0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTmV3V2ViR0xDb250ZXh0KGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsIGNvbnRleHRJZD86ICd3ZWJnbCcgfCAnd2ViZ2wyJyk6IFdlYkdMQ29udGV4dCB7XG4gIGNvbnN0IGNvbnRleHRBdHRyaWJ1dGVzOiBXZWJHTENvbnRleHRBdHRyaWJ1dGVzID0ge1xuICAgIGFscGhhOiBmYWxzZSxcbiAgICBkZXB0aDogZmFsc2UsXG4gICAgYW50aWFsaWFzOiBmYWxzZSxcbiAgICBzdGVuY2lsOiBmYWxzZSxcbiAgICBwcmVzZXJ2ZURyYXdpbmdCdWZmZXI6IGZhbHNlLFxuICAgIHByZW11bHRpcGxpZWRBbHBoYTogZmFsc2UsXG4gICAgZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdDogZmFsc2UsXG4gIH07XG4gIGxldCBnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0IHwgbnVsbDtcbiAgY29uc3QgY2EgPSBjb250ZXh0QXR0cmlidXRlcztcbiAgaWYgKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wyJykge1xuICAgIGdsID0gY2FudmFzLmdldENvbnRleHQoJ3dlYmdsMicsIGNhKTtcbiAgICBpZiAoZ2wpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgV2ViR0xDb250ZXh0KGdsLCAyKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBMb2dnZXIud2FybmluZygnR2xDb250ZXh0RmFjdG9yeScsIGBmYWlsZWQgdG8gY3JlYXRlIFdlYkdMQ29udGV4dCB1c2luZyBjb250ZXh0SWQgJ3dlYmdsMicuIEVycm9yOiAke2Vycn1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wnKSB7XG4gICAgZ2wgPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnLCBjYSkgfHwgKGNhbnZhcy5nZXRDb250ZXh0KCdleHBlcmltZW50YWwtd2ViZ2wnLCBjYSkgYXMgV2ViR0xSZW5kZXJpbmdDb250ZXh0KTtcbiAgICBpZiAoZ2wpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgV2ViR0xDb250ZXh0KGdsLCAxKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBMb2dnZXIud2FybmluZyhcbiAgICAgICAgICAnR2xDb250ZXh0RmFjdG9yeScsXG4gICAgICAgICAgYGZhaWxlZCB0byBjcmVhdGUgV2ViR0xDb250ZXh0IHVzaW5nIGNvbnRleHRJZCAnd2ViZ2wnIG9yICdleHBlcmltZW50YWwtd2ViZ2wnLiBFcnJvcjogJHtlcnJ9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZGVjbGFyZSBsZXQgT2Zmc2NyZWVuQ2FudmFzOiB7IG5ldyAod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBIVE1MQ2FudmFzRWxlbWVudCB9O1xuXG5mdW5jdGlvbiBjcmVhdGVDYW52YXMoKTogSFRNTENhbnZhc0VsZW1lbnQge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ZhaWxlZCB0byBjcmVhdGUgY2FudmFzOiBkb2N1bWVudCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbiAgY29uc3QgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICBjYW52YXMud2lkdGggPSAxO1xuICBjYW52YXMuaGVpZ2h0ID0gMTtcbiAgcmV0dXJuIGNhbnZhcztcbn1cblxuZnVuY3Rpb24gY3JlYXRlT2Zmc2NyZWVuQ2FudmFzKCk6IEhUTUxDYW52YXNFbGVtZW50IHtcbiAgaWYgKHR5cGVvZiBPZmZzY3JlZW5DYW52YXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZmFpbGVkIHRvIGNyZWF0ZSBvZmZzY3JlZW4gY2FudmFzOiBPZmZzY3JlZW5DYW52YXMgaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG4gIHJldHVybiBuZXcgT2Zmc2NyZWVuQ2FudmFzKDEsIDEpO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBlbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBCYWNrZW5kLCBTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vc2Vzc2lvbic7XG5cbmltcG9ydCB7IFdlYkdMU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL3dlYmdsL3Nlc3Npb24taGFuZGxlcic7XG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsL3dlYmdsLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlV2ViR0xDb250ZXh0IH0gZnJvbSAnLi93ZWJnbC93ZWJnbC1jb250ZXh0LWZhY3RvcnknO1xuXG4vKipcbiAqIFdlYkdMQmFja2VuZCBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIGFsbCBXZWJHTCBvcGVyYXRpb25zXG4gKiBXaGVuIGl0IHN0YXJ0cyBpdCBjcmVhdGVkIHRoZSBXZWJHTFJlbmRlcmluZ0NvbnRleHRcbiAqIGFuZCBvdGhlciBtYWluIGZyYW1ld29yayBjb21wb25lbnRzIHN1Y2ggYXMgUHJvZ3JhbSBhbmQgVGV4dHVyZSBNYW5hZ2Vyc1xuICovXG5leHBvcnQgY2xhc3MgV2ViR0xCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7XG4gIGdsQ29udGV4dDogV2ViR0xDb250ZXh0O1xuXG4gIGdldCBjb250ZXh0SWQoKTogJ3dlYmdsJyB8ICd3ZWJnbDInIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLmNvbnRleHRJZDtcbiAgfVxuICBzZXQgY29udGV4dElkKHZhbHVlOiAnd2ViZ2wnIHwgJ3dlYmdsMicgfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wuY29udGV4dElkID0gdmFsdWU7XG4gIH1cblxuICBnZXQgbWF0bXVsTWF4QmF0Y2hTaXplKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC5tYXRtdWxNYXhCYXRjaFNpemU7XG4gIH1cbiAgc2V0IG1hdG11bE1heEJhdGNoU2l6ZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLm1hdG11bE1heEJhdGNoU2l6ZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHRleHR1cmVDYWNoZU1vZGUoKTogJ2luaXRpYWxpemVyT25seScgfCAnZnVsbCcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wudGV4dHVyZUNhY2hlTW9kZTtcbiAgfVxuICBzZXQgdGV4dHVyZUNhY2hlTW9kZSh2YWx1ZTogJ2luaXRpYWxpemVyT25seScgfCAnZnVsbCcgfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wudGV4dHVyZUNhY2hlTW9kZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHBhY2soKTogYm9vbGVhbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC5wYWNrO1xuICB9XG4gIHNldCBwYWNrKHZhbHVlOiBib29sZWFuIHwgdW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLnBhY2sgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBhc3luYygpOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLmFzeW5jO1xuICB9XG4gIHNldCBhc3luYyh2YWx1ZTogYm9vbGVhbiB8IHVuZGVmaW5lZCkge1xuICAgIGVudi53ZWJnbC5hc3luYyA9IHZhbHVlO1xuICB9XG5cbiAgaW5pdGlhbGl6ZSgpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5nbENvbnRleHQgPSBjcmVhdGVXZWJHTENvbnRleHQodGhpcy5jb250ZXh0SWQpO1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLm1hdG11bE1heEJhdGNoU2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgdGhpcy5tYXRtdWxNYXhCYXRjaFNpemUgPSAxNjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdGhpcy50ZXh0dXJlQ2FjaGVNb2RlICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLnRleHR1cmVDYWNoZU1vZGUgPSAnZnVsbCc7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHRoaXMucGFjayAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRoaXMucGFjayA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmFzeW5jICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhpcy5hc3luYyA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBMb2dnZXIuc2V0V2l0aEVudihlbnYpO1xuXG4gICAgICBpZiAoIWVudi53ZWJnbC5jb250ZXh0KSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbnYud2ViZ2wsICdjb250ZXh0JywgeyB2YWx1ZTogdGhpcy5nbENvbnRleHQuZ2wgfSk7XG4gICAgICB9XG5cbiAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAnV2ViR0xCYWNrZW5kJyxcbiAgICAgICAgYENyZWF0ZWQgV2ViR0xDb250ZXh0OiAke3R5cGVvZiB0aGlzLmdsQ29udGV4dH0gd2l0aCBtYXRtdWxNYXhCYXRjaFNpemU6ICR7XG4gICAgICAgICAgdGhpcy5tYXRtdWxNYXhCYXRjaFNpemVcbiAgICAgICAgfTsgdGV4dHVyZUNhY2hlTW9kZTogJHt0aGlzLnRleHR1cmVDYWNoZU1vZGV9OyBwYWNrOiAke3RoaXMucGFja307IGFzeW5jOiAke3RoaXMuYXN5bmN9LmAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgTG9nZ2VyLndhcm5pbmcoJ1dlYkdMQmFja2VuZCcsIGBVbmFibGUgdG8gaW5pdGlhbGl6ZSBXZWJHTEJhY2tlbmQuICR7ZX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgY3JlYXRlU2Vzc2lvbkhhbmRsZXIoY29udGV4dDogU2Vzc2lvbi5Db250ZXh0KTogU2Vzc2lvbkhhbmRsZXIge1xuICAgIHJldHVybiBuZXcgV2ViR0xTZXNzaW9uSGFuZGxlcih0aGlzLCBjb250ZXh0KTtcbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZ2xDb250ZXh0LmRpc3Bvc2UoKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBXZWJHTEJhY2tlbmQgfSBmcm9tICcuL2JhY2tlbmRzL2JhY2tlbmQtd2ViZ2wnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgT3BTZXQgfSBmcm9tICcuL29wc2V0JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL3Nlc3Npb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEluZmVyZW5jZUhhbmRsZXIge1xuICAvKipcbiAgICogZGlzcG9zZSB0aGUgaW5mZXJlbmNlIGhhbmRsZXIuIGl0IHdpbGwgYmUgY2FsbGVkIGFzIHRoZSBsYXN0IHN0ZXAgaW4gU2Vzc2lvbi5ydW4oKVxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNlc3Npb25IYW5kbGVyIHtcbiAgLyoqXG4gICAqIHRyYW5zZm9ybSB0aGUgZ3JhcGggYXQgaW5pdGlhbGl6YXRpb24gdGltZVxuICAgKiBAcGFyYW0gZ3JhcGhUcmFuc2Zvcm1lciB0aGUgZ3JhcGggdHJhbnNmb3JtZXIgdG8gbWFuaXB1bGF0ZSB0aGUgbW9kZWwgZ3JhcGhcbiAgICovXG4gIHRyYW5zZm9ybUdyYXBoPyhncmFwaFRyYW5zZm9ybWVyOiBHcmFwaC5UcmFuc2Zvcm1lcik6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBJbmZlcmVuY2VIYW5kbGVyIHRvIHVzZSBpbiBhIFNlc3Npb24ucnVuKCkgY2FsbFxuICAgKi9cbiAgY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpOiBJbmZlcmVuY2VIYW5kbGVyO1xuXG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBzZXNzaW9uIGhhbmRsZXIuIGl0IHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBzZXNzaW9uIGlzIGJlaW5nIGRpc3Bvc2VkIGV4cGxpY2l0bHlcbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIG9wZXJhdG9yIGZyb20gdGhlIG5hbWUgYW5kIG9wc2V0IHZlcnNpb247IGJhY2tlbmQgc3BlY2lmaWNcbiAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgdG8gcmVzb2x2ZVxuICAgKiBAcGFyYW0gb3BzZXRzIGEgbGlzdCBvZiBvcHNldHMgdGhhdCBleHBvcnRlZCBmcm9tIHRoZSBtb2RlbFxuICAgKiBAcGFyYW0gZ3JhcGggdGhlIGNvbXBsZXRlbHkgaW5pdGlhbGl6ZWQgZ3JhcGhcbiAgICovXG4gIHJlc29sdmUobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBncmFwaDogR3JhcGgpOiBPcGVyYXRvcjtcblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgbGV0J3MgdGhlIHNlc3Npb25IYW5kbGVyIGtub3cgdGhhdCB0aGUgZ3JhcGggaW5pdGlhbGl6YXRpb24gaXMgY29tcGxldGVcbiAgICogQHBhcmFtIGdyYXBoIHRoZSBjb21wbGV0ZWx5IGluaXRpYWxpemVkIGdyYXBoXG4gICAqL1xuICBvbkdyYXBoSW5pdGlhbGl6ZWQ/KGdyYXBoOiBHcmFwaCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBjb3JyZXNwb25kaW5nIGJhY2tlbmRcbiAgICovXG4gIHJlYWRvbmx5IGJhY2tlbmQ6IEJhY2tlbmQ7XG5cbiAgLyoqXG4gICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBzZXNzaW9uIGNvbnRleHRcbiAgICovXG4gIHJlYWRvbmx5IGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCYWNrZW5kIHtcbiAgLyoqXG4gICAqIGluaXRpYWxpemUgdGhlIGJhY2tlbmQuIHdpbGwgYmUgY2FsbGVkIG9ubHkgb25jZSwgd2hlbiB0aGUgZmlyc3QgdGltZSB0aGVcbiAgICogYmFja2VuZCBpdCB0byBiZSB1c2VkXG4gICAqL1xuICBpbml0aWFsaXplKCk6IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgU2Vzc2lvbkhhbmRsZXIgdG8gdXNlIGluIGEgU2Vzc2lvbiBvYmplY3QncyBsaWZlY3ljbGVcbiAgICovXG4gIGNyZWF0ZVNlc3Npb25IYW5kbGVyKGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dCk6IFNlc3Npb25IYW5kbGVyO1xuXG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBiYWNrZW5kLiBjdXJyZW50bHkgdGhpcyB3aWxsIG5vdCBiZSBjYWxsZWRcbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcbn1cblxuLy8gY2FjaGVzIGFsbCBpbml0aWFsaXplZCBiYWNrZW5kIGluc3RhbmNlc1xuY29uc3QgYmFja2VuZHNDYWNoZTogTWFwPHN0cmluZywgQmFja2VuZD4gPSBuZXcgTWFwKCk7XG5cbmV4cG9ydCBjb25zdCBiYWNrZW5kOiB7IFtuYW1lOiBzdHJpbmddOiBCYWNrZW5kIH0gPSB7XG4gIHdlYmdsOiBuZXcgV2ViR0xCYWNrZW5kKCksXG59O1xuXG4vKipcbiAqIFJlc29sdmUgYSByZWZlcmVuY2UgdG8gdGhlIGJhY2tlbmQuIElmIGEgaGludCBpcyBzcGVjaWZpZWQsIHRoZSBjb3JyZXNwb25kaW5nXG4gKiBiYWNrZW5kIHdpbGwgYmUgdXNlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVCYWNrZW5kKGhpbnQ/OiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXSk6IFByb21pc2U8QmFja2VuZD4ge1xuICBpZiAoIWhpbnQpIHtcbiAgICByZXR1cm4gcmVzb2x2ZUJhY2tlbmQoWyd3ZWJnbCddKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBoaW50cyA9IHR5cGVvZiBoaW50ID09PSAnc3RyaW5nJyA/IFtoaW50XSA6IGhpbnQ7XG5cbiAgICBmb3IgKGNvbnN0IGJhY2tlbmRIaW50IG9mIGhpbnRzKSB7XG4gICAgICBjb25zdCBjYWNoZSA9IGJhY2tlbmRzQ2FjaGUuZ2V0KGJhY2tlbmRIaW50KTtcbiAgICAgIGlmIChjYWNoZSkge1xuICAgICAgICByZXR1cm4gY2FjaGU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJhY2tlbmQgPSBhd2FpdCB0cnlMb2FkQmFja2VuZChiYWNrZW5kSGludCk7XG4gICAgICBpZiAoYmFja2VuZCkge1xuICAgICAgICByZXR1cm4gYmFja2VuZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ25vIGF2YWlsYWJsZSBiYWNrZW5kIHRvIHVzZScpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB0cnlMb2FkQmFja2VuZChiYWNrZW5kSGludDogc3RyaW5nKTogUHJvbWlzZTxCYWNrZW5kIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGJhY2tlbmRPYmogPSBiYWNrZW5kO1xuXG4gIGlmICh0eXBlb2YgYmFja2VuZE9ialtiYWNrZW5kSGludF0gIT09ICd1bmRlZmluZWQnICYmIGlzQmFja2VuZChiYWNrZW5kT2JqW2JhY2tlbmRIaW50XSkpIHtcbiAgICBjb25zdCBiYWNrZW5kID0gYmFja2VuZE9ialtiYWNrZW5kSGludF07XG4gICAgbGV0IGluaXQgPSBiYWNrZW5kLmluaXRpYWxpemUoKTtcbiAgICBpZiAodHlwZW9mIGluaXQgPT09ICdvYmplY3QnICYmICd0aGVuJyBpbiBpbml0KSB7XG4gICAgICBpbml0ID0gYXdhaXQgaW5pdDtcbiAgICB9XG4gICAgaWYgKGluaXQpIHtcbiAgICAgIGJhY2tlbmRzQ2FjaGUuc2V0KGJhY2tlbmRIaW50LCBiYWNrZW5kKTtcbiAgICAgIHJldHVybiBiYWNrZW5kO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGlzQmFja2VuZChvYmo6IHVua25vd24pIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgY29uc3QgbyA9IG9iaiBhcyBhbnk7XG5cbiAgLy8gY2hlY2sgaWYgYW4gb2JqZWN0IGlzIGEgQmFja2VuZCBpbnN0YW5jZVxuICBpZiAoXG4gICAgJ2luaXRpYWxpemUnIGluIG8gJiZcbiAgICB0eXBlb2Ygby5pbml0aWFsaXplID09PSAnZnVuY3Rpb24nICYmIC8vIGluaXRpYWxpemUoKVxuICAgICdjcmVhdGVTZXNzaW9uSGFuZGxlcicgaW4gbyAmJlxuICAgIHR5cGVvZiBvLmNyZWF0ZVNlc3Npb25IYW5kbGVyID09PSAnZnVuY3Rpb24nICYmIC8vIGNyZWF0ZVNlc3Npb25IYW5kbGVyKClcbiAgICAnZGlzcG9zZScgaW4gbyAmJlxuICAgIHR5cGVvZiBvLmRpc3Bvc2UgPT09ICdmdW5jdGlvbicgLy8gZGlzcG9zZSgpXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgdHlwZSBCYWNrZW5kVHlwZSA9IEJhY2tlbmQ7XG5leHBvcnQgdHlwZSBTZXNzaW9uSGFuZGxlclR5cGUgPSBSZXR1cm5UeXBlPEJhY2tlbmRUeXBlWydjcmVhdGVTZXNzaW9uSGFuZGxlciddPjtcbmV4cG9ydCB0eXBlIEluZmVyZW5jZUhhbmRsZXJUeXBlID0gUmV0dXJuVHlwZTxTZXNzaW9uSGFuZGxlclR5cGVbJ2NyZWF0ZUluZmVyZW5jZUhhbmRsZXInXT47XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFNlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQgeyBMb2dnZXIsIFByb2ZpbGVyIH0gZnJvbSAnLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG5jbGFzcyBLZXJuZWxPcCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBvcDogT3BlcmF0b3IsXG4gICAgcHVibGljIG5vZGU6IEdyYXBoLk5vZGUsXG4gICkge31cbn1cblxuZXhwb3J0IGNsYXNzIEV4ZWN1dGlvblBsYW4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGdyYXBoOiBHcmFwaCxcbiAgICBvcHM6IE9wZXJhdG9yW10sXG4gICAgcHJpdmF0ZSBwcm9maWxlcjogUmVhZG9ubHk8UHJvZmlsZXI+LFxuICApIHtcbiAgICB0aGlzLmluaXRpYWxpemUob3BzKTtcbiAgfVxuXG4gIGluaXRpYWxpemUob3BzOiBPcGVyYXRvcltdKSB7XG4gICAgdGhpcy5wcm9maWxlci5ldmVudCgnc2Vzc2lvbicsICdFeGVjdXRpb25QbGFuLmluaXRpYWxpemUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBncmFwaE5vZGVzID0gdGhpcy5ncmFwaC5nZXROb2RlcygpO1xuICAgICAgaWYgKGdyYXBoTm9kZXMubGVuZ3RoICE9PSBvcHMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHNpemUgb2Ygbm9kZXMgYW5kIE9QcyBkbyBub3QgbWF0Y2guJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX29wcyA9IG9wcy5tYXAoKG9wLCBpKSA9PiBuZXcgS2VybmVsT3Aob3AsIGdyYXBoTm9kZXNbaV0pKTtcbiAgICAgIHRoaXMucmVzZXQoKTtcblxuICAgICAgLy8gbG9vayBmb3Igc3RhcnRlciBub2RlKHMpXG4gICAgICB0aGlzLl9zdGFydGVyID0gW107XG4gICAgICB0aGlzLl9vcHMuZm9yRWFjaCgob3AsIGkpID0+IHtcbiAgICAgICAgbGV0IHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgZm9yIChjb25zdCBpbnB1dCBvZiBvcC5ub2RlLmlucHV0cykge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLl92YWx1ZXNbaW5wdXRdICYmIC8vIG5vdCBhbiBpbml0aWFsaXplZCBpbnB1dFxuICAgICAgICAgICAgdGhpcy5ncmFwaC5nZXRJbnB1dEluZGljZXMoKS5pbmRleE9mKGlucHV0KSA9PT0gLTEgLy8gbm90IG1vZGVsIGlucHV0XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXNvbHZlZCA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChyZXNvbHZlZCkge1xuICAgICAgICAgIHRoaXMuX3N0YXJ0ZXIucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLl92YWx1ZXMgPSB0aGlzLmdyYXBoLmdldFZhbHVlcygpLm1hcCgoaSkgPT4gaS50ZW5zb3IpO1xuICB9XG5cbiAgYXN5bmMgZXhlY3V0ZShzZXNzaW9uSGFuZGxlcjogU2Vzc2lvbkhhbmRsZXIsIG1vZGVsSW5wdXRzOiBUZW5zb3JbXSk6IFByb21pc2U8VGVuc29yW10+IHtcbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnc2Vzc2lvbicsICdFeGVjdXRpb25QbGFuLmV4ZWN1dGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyByZXNldCBtZWRpZW0gcmVzdWx0XG4gICAgICB0aGlzLnJlc2V0KCk7XG5cbiAgICAgIC8vIGNyZWF0ZSBpbmZlcmVuY2UgaGFuZGxlclxuICAgICAgY29uc3QgaW5mZXJlbmNlSGFuZGxlciA9IHNlc3Npb25IYW5kbGVyLmNyZWF0ZUluZmVyZW5jZUhhbmRsZXIoKTtcblxuICAgICAgLy8gcG9wdWxhdGUgaW5wdXRzIHZhbHVlXG4gICAgICBjb25zdCBncmFwaElucHV0cyA9IHRoaXMuZ3JhcGguZ2V0SW5wdXRJbmRpY2VzKCk7XG4gICAgICBpZiAobW9kZWxJbnB1dHMubGVuZ3RoICE9PSBncmFwaElucHV0cy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBudW1iZXIgb2YgaW5wdXQgdGVuc29ycyBkb24ndCBtYXRjaCB0aGUgbnVtYmVyIG9mIGlucHV0cyB0byB0aGUgbW9kZWw6IGFjdHVhbDogJHtcbiAgICAgICAgICAgIG1vZGVsSW5wdXRzLmxlbmd0aFxuICAgICAgICAgIH0gZXhwZWN0ZWQ6ICR7Z3JhcGhJbnB1dHMubGVuZ3RofWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIG1vZGVsSW5wdXRzLmZvckVhY2goKGlucHV0LCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gZ3JhcGhJbnB1dHNbaV07XG4gICAgICAgIHRoaXMuX3ZhbHVlc1tpbmRleF0gPSBpbnB1dDtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBwcmVwYXJlIHJ1bm5pbmcgc2VxdWVuY2VcbiAgICAgIGNvbnN0IHNlcXVlbmNlOiBudW1iZXJbXSA9IHRoaXMuX3N0YXJ0ZXIuc2xpY2UoMCk7XG5cbiAgICAgIC8vIGV4ZWN1dGlvbiBpdGVyYXRpb25zXG4gICAgICBjb25zdCBncmFwaFZhbHVlcyA9IHRoaXMuZ3JhcGguZ2V0VmFsdWVzKCk7XG4gICAgICBjb25zdCBncmFwaE5vZGVzID0gdGhpcy5ncmFwaC5nZXROb2RlcygpO1xuXG4gICAgICBsZXQgcmVhciA9IDA7XG4gICAgICB3aGlsZSAocmVhciA8IHNlcXVlbmNlLmxlbmd0aCkge1xuICAgICAgICBjb25zdCB0aGlzT3BJbmRleCA9IHNlcXVlbmNlW3JlYXIrK107XG4gICAgICAgIGNvbnN0IHRoaXNPcCA9IHRoaXMuX29wc1t0aGlzT3BJbmRleF07XG5cbiAgICAgICAgLy8gY2hlY2sgaW5wdXRcbiAgICAgICAgY29uc3QgaW5wdXRMaXN0ID0gdGhpc09wLm5vZGUuaW5wdXRzLm1hcCgoaSkgPT4gdGhpcy5fdmFsdWVzW2ldKTtcbiAgICAgICAgaWYgKGlucHV0TGlzdC5pbmRleE9mKHVuZGVmaW5lZCkgIT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlc29sdmVkIGlucHV0IGRldGVjdGVkOiBvcDogJHt0aGlzT3Aubm9kZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJ1blxuICAgICAgICBjb25zdCBpbnB1dFRlbnNvcnMgPSBpbnB1dExpc3QgYXMgVGVuc29yW107XG4gICAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICdFeGVjUGxhbicsXG4gICAgICAgICAgYFJ1bm5pbmcgb3A6JHt0aGlzT3Aubm9kZS5uYW1lfSAoJHtpbnB1dFRlbnNvcnNcbiAgICAgICAgICAgIC5tYXAoKHQsIGkpID0+IGAnJHt0aGlzT3Aubm9kZS5pbnB1dHNbaV19JzogJHt0LnR5cGV9WyR7dC5kaW1zLmpvaW4oJywnKX1dYClcbiAgICAgICAgICAgIC5qb2luKCcsICcpfSlgLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IG91dHB1dExpc3QgPSBhd2FpdCB0aGlzLnByb2ZpbGVyLmV2ZW50KCdub2RlJywgdGhpc09wLm5vZGUubmFtZSwgYXN5bmMgKCkgPT5cbiAgICAgICAgICB0aGlzT3Aub3AuaW1wbChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dFRlbnNvcnMsIHRoaXNPcC5vcC5jb250ZXh0KSxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBjaGVjayBvdXRwdXRcbiAgICAgICAgaWYgKG91dHB1dExpc3QubGVuZ3RoICE9PSB0aGlzT3Aubm9kZS5vdXRwdXRzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHNpemUgb2Ygb3V0cHV0IGRvZXMgbm90IG1hdGNoIG1vZGVsIGRlZmluaXRpb24uJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaWxsIHZhbHVlXG4gICAgICAgIG91dHB1dExpc3QuZm9yRWFjaCgob3V0cHV0LCBpKSA9PiB7XG4gICAgICAgICAgY29uc3QgaiA9IHRoaXNPcC5ub2RlLm91dHB1dHNbaV07XG4gICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlc1tqXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXQgWyR7an1dIGFscmVhZHkgaGFzIHZhbHVlOiBvcDoke3RoaXNPcC5ub2RlLm5hbWV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuX3ZhbHVlc1tqXSA9IG91dHB1dDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gcmVzb2x2ZSBkb3duc3RyZWFtIG5vZGVzXG4gICAgICAgIGNvbnN0IGRvd25zdHJlYW1Ob2RlcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgICAgICBvdXRwdXRMaXN0LmZvckVhY2goKF9vdXRwdXQsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBqID0gdGhpc09wLm5vZGUub3V0cHV0c1tpXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGN1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4IG9mIGdyYXBoVmFsdWVzW2pdLnRvKSB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RG93bnN0cmVhbU5vZGUgPSBncmFwaE5vZGVzW2N1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4XTtcbiAgICAgICAgICAgIGxldCByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGsgb2YgY3VycmVudERvd25zdHJlYW1Ob2RlLmlucHV0cykge1xuICAgICAgICAgICAgICBpZiAoIXRoaXMuX3ZhbHVlc1trXSkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXNvbHZlZCkge1xuICAgICAgICAgICAgICBkb3duc3RyZWFtTm9kZXMuYWRkKGN1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBzZXF1ZW5jZS5wdXNoKC4uLmRvd25zdHJlYW1Ob2Rlcyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dHB1dDogVGVuc29yW10gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ncmFwaC5nZXRPdXRwdXRJbmRpY2VzKCkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kZXggPSB0aGlzLmdyYXBoLmdldE91dHB1dEluZGljZXMoKVtpXTtcbiAgICAgICAgY29uc3Qgb3V0cHV0VGVuc29yID0gdGhpcy5fdmFsdWVzW291dHB1dEluZGV4XTtcbiAgICAgICAgaWYgKG91dHB1dFRlbnNvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXF1aXJlZCBvdXRwdXQgWyR7b3V0cHV0SW5kZXh9XSBkb2VzIG5vdCBoYXZlIHZhbHVlYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG91dHB1dEluZGV4ID09PSAwKSB7XG4gICAgICAgICAgYXdhaXQgb3V0cHV0VGVuc29yLmdldERhdGEoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2b2lkIG91dHB1dFRlbnNvci5kYXRhO1xuICAgICAgICB9XG4gICAgICAgIG91dHB1dC5wdXNoKG91dHB1dFRlbnNvcik7XG4gICAgICB9XG4gICAgICBMb2dnZXIudmVyYm9zZSgnRXhlY1BsYW4nLCAnZGlzcG9zaW5nIG9mIGluZmVyZW5jZUhhbmRsZXInKTtcbiAgICAgIGluZmVyZW5jZUhhbmRsZXIuZGlzcG9zZSgpO1xuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9KTtcbiAgfVxuXG4gIF92YWx1ZXM6IEFycmF5PFRlbnNvciB8IHVuZGVmaW5lZD47XG4gIF9vcHM6IEtlcm5lbE9wW107XG4gIF9zdGFydGVyOiBudW1iZXJbXTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IExvbmcgZnJvbSAnbG9uZyc7XG5cbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuaW1wb3J0IHsgZGVjb2RlVXRmOFN0cmluZywgTG9uZ1V0aWwgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgQXR0cmlidXRlIHtcbiAgZXhwb3J0IGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgZmxvYXQ6IG51bWJlcjtcbiAgICBpbnQ6IG51bWJlcjtcbiAgICBzdHJpbmc6IHN0cmluZztcbiAgICB0ZW5zb3I6IFRlbnNvcjtcbiAgICBmbG9hdHM6IG51bWJlcltdO1xuICAgIGludHM6IG51bWJlcltdO1xuICAgIHN0cmluZ3M6IHN0cmluZ1tdO1xuICAgIHRlbnNvcnM6IFRlbnNvcltdO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgRGF0YVR5cGUgPSBrZXlvZiBEYXRhVHlwZU1hcDtcbn1cblxudHlwZSBWYWx1ZVR5cGVzID0gQXR0cmlidXRlLkRhdGFUeXBlTWFwW0F0dHJpYnV0ZS5EYXRhVHlwZV07XG5cbnR5cGUgVmFsdWUgPSBbVmFsdWVUeXBlcywgQXR0cmlidXRlLkRhdGFUeXBlXTtcblxuZXhwb3J0IGNsYXNzIEF0dHJpYnV0ZSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJpYnV0ZXM6IG9ubnguSUF0dHJpYnV0ZVByb3RvW10gfCBvcnRGYnMuQXR0cmlidXRlW10gfCBudWxsIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fYXR0cmlidXRlcyA9IG5ldyBNYXAoKTtcbiAgICBpZiAoYXR0cmlidXRlcyAhPT0gbnVsbCAmJiBhdHRyaWJ1dGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZvciAoY29uc3QgYXR0ciBvZiBhdHRyaWJ1dGVzKSB7XG4gICAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICAgIHRoaXMuX2F0dHJpYnV0ZXMuc2V0KGF0dHIubmFtZSwgW0F0dHJpYnV0ZS5nZXRWYWx1ZShhdHRyKSwgQXR0cmlidXRlLmdldFR5cGUoYXR0cildKTtcbiAgICAgICAgfSBlbHNlIGlmIChhdHRyIGluc3RhbmNlb2Ygb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgICAgICAgIHRoaXMuX2F0dHJpYnV0ZXMuc2V0KGF0dHIubmFtZSgpISwgW0F0dHJpYnV0ZS5nZXRWYWx1ZShhdHRyKSwgQXR0cmlidXRlLmdldFR5cGUoYXR0cildKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX2F0dHJpYnV0ZXMuc2l6ZSA8IGF0dHJpYnV0ZXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZHVwbGljYXRlZCBhdHRyaWJ1dGUgbmFtZXMnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzZXQoa2V5OiBzdHJpbmcsIHR5cGU6IEF0dHJpYnV0ZS5EYXRhVHlwZSwgdmFsdWU6IFZhbHVlVHlwZXMpOiB2b2lkIHtcbiAgICB0aGlzLl9hdHRyaWJ1dGVzLnNldChrZXksIFt2YWx1ZSwgdHlwZV0pO1xuICB9XG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuX2F0dHJpYnV0ZXMuZGVsZXRlKGtleSk7XG4gIH1cbiAgZ2V0RmxvYXQoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnZmxvYXQnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdmbG9hdCcsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRJbnQoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnaW50J10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnaW50JywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldFN0cmluZyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydzdHJpbmcnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdzdHJpbmcnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0VGVuc29yKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3RlbnNvciddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3RlbnNvcicsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRGbG9hdHMoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnZmxvYXRzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnZmxvYXRzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldEludHMoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnaW50cyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ2ludHMnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0U3RyaW5ncyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydzdHJpbmdzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnc3RyaW5ncycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRUZW5zb3JzKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3RlbnNvcnMnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICd0ZW5zb3JzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0PFYgZXh0ZW5kcyBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbQXR0cmlidXRlLkRhdGFUeXBlXT4oXG4gICAga2V5OiBzdHJpbmcsXG4gICAgdHlwZTogQXR0cmlidXRlLkRhdGFUeXBlLFxuICAgIGRlZmF1bHRWYWx1ZT86IFYsXG4gICk6IFYge1xuICAgIGNvbnN0IHZhbHVlQW5kVHlwZSA9IHRoaXMuX2F0dHJpYnV0ZXMuZ2V0KGtleSk7XG4gICAgaWYgKHZhbHVlQW5kVHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihgcmVxdWlyZWQgYXR0cmlidXRlIG5vdCBmb3VuZDogJHtrZXl9YCk7XG4gICAgfVxuICAgIGlmICh2YWx1ZUFuZFR5cGVbMV0gIT09IHR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdHlwZSBtaXNtYXRjaDogZXhwZWN0ZWQgJHt0eXBlfSBidXQgZ290ICR7dmFsdWVBbmRUeXBlWzFdfWApO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWVBbmRUeXBlWzBdIGFzIFY7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRUeXBlKGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvIHwgb3J0RmJzLkF0dHJpYnV0ZSk6IEF0dHJpYnV0ZS5EYXRhVHlwZSB7XG4gICAgY29uc3QgdHlwZSA9IGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvID8gYXR0ci50eXBlIDogKGF0dHIgYXMgb3J0RmJzLkF0dHJpYnV0ZSkudHlwZSgpO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuRkxPQVQ6XG4gICAgICAgIHJldHVybiAnZmxvYXQnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UOlxuICAgICAgICByZXR1cm4gJ2ludCc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkc6XG4gICAgICAgIHJldHVybiAnc3RyaW5nJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUjpcbiAgICAgICAgcmV0dXJuICd0ZW5zb3InO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuRkxPQVRTOlxuICAgICAgICByZXR1cm4gJ2Zsb2F0cyc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlRTOlxuICAgICAgICByZXR1cm4gJ2ludHMnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HUzpcbiAgICAgICAgcmV0dXJuICdzdHJpbmdzJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUlM6XG4gICAgICAgIHJldHVybiAndGVuc29ycyc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGF0dHJpYnV0ZSB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQgeWV0OiAke29ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZVt0eXBlXX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRWYWx1ZShhdHRyOiBvbm54LklBdHRyaWJ1dGVQcm90byB8IG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICBjb25zdCBhdHRyVHlwZSA9IGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvID8gYXR0ci50eXBlIDogKGF0dHIgYXMgb3J0RmJzLkF0dHJpYnV0ZSkudHlwZSgpO1xuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkdSQVBIIHx8IGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEhTKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dyYXBoIGF0dHJpYnV0ZSBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRWYWx1ZU5vQ2hlY2soYXR0cik7XG5cbiAgICAvLyBjYXN0IExPTkcgdG8gbnVtYmVyXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UICYmIExvbmdVdGlsLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBMb25nVXRpbC5sb25nVG9OdW1iZXIodmFsdWUgYXMgYmlnaW50IHwgTG9uZyk7XG4gICAgfVxuXG4gICAgLy8gY2FzdCBMT05HW10gdG8gbnVtYmVyW11cbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlRTKSB7XG4gICAgICBjb25zdCBhcnIgPSB2YWx1ZSBhcyBBcnJheTxudW1iZXIgfCBMb25nIHwgYmlnaW50PjtcbiAgICAgIGNvbnN0IG51bWJlclZhbHVlOiBudW1iZXJbXSA9IG5ldyBBcnJheTxudW1iZXI+KGFyci5sZW5ndGgpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBtYXliZUxvbmcgPSBhcnJbaV07XG4gICAgICAgIG51bWJlclZhbHVlW2ldID0gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG1heWJlTG9uZyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudW1iZXJWYWx1ZTtcbiAgICB9XG5cbiAgICAvLyBjYXN0IG9ubnguVGVuc29yUHJvdG8gdG8gb25ueGpzLlRlbnNvclxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUikge1xuICAgICAgcmV0dXJuIGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgID8gVGVuc29yLmZyb21Qcm90byh2YWx1ZSBhcyBvbm54LklUZW5zb3JQcm90bylcbiAgICAgICAgOiBUZW5zb3IuZnJvbU9ydFRlbnNvcih2YWx1ZSBhcyBvcnRGYnMuVGVuc29yKTtcbiAgICB9XG5cbiAgICAvLyBjYXN0IG9ubnguVGVuc29yUHJvdG9bXSB0byBvbm54anMuVGVuc29yW11cbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1JTKSB7XG4gICAgICBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8pIHtcbiAgICAgICAgY29uc3QgdGVuc29yUHJvdG9zID0gdmFsdWUgYXMgb25ueC5JVGVuc29yUHJvdG9bXTtcbiAgICAgICAgcmV0dXJuIHRlbnNvclByb3Rvcy5tYXAoKHZhbHVlKSA9PiBUZW5zb3IuZnJvbVByb3RvKHZhbHVlKSk7XG4gICAgICB9IGVsc2UgaWYgKGF0dHIgaW5zdGFuY2VvZiBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgICAgIGNvbnN0IHRlbnNvclByb3RvcyA9IHZhbHVlIGFzIG9ydEZicy5UZW5zb3JbXTtcbiAgICAgICAgcmV0dXJuIHRlbnNvclByb3Rvcy5tYXAoKHZhbHVlKSA9PiBUZW5zb3IuZnJvbU9ydFRlbnNvcih2YWx1ZSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGNhc3QgVWludDhBcnJheSB0byBzdHJpbmdcbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkcpIHtcbiAgICAgIC8vIHN0cmluZyBpbiBvbm54IGF0dHJpYnV0ZSBpcyBvZiB1aW50OGFycmF5IHR5cGUsIHNvIHdlIG5lZWQgdG8gY29udmVydCBpdCB0byBzdHJpbmcgYmVsb3cuIFdoaWxlIGluIG9ydCBmb3JtYXQsXG4gICAgICAvLyBzdHJpbmcgYXR0cmlidXRlcyBhcmUgcmV0dXJuZWQgYXMgc3RyaW5nLCBzbyBubyBjb252ZXJzaW9uIGlzIG5lZWRlZC5cbiAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICBjb25zdCB1dGY4U3RyaW5nID0gdmFsdWUgYXMgVWludDhBcnJheTtcbiAgICAgICAgcmV0dXJuIGRlY29kZVV0ZjhTdHJpbmcodXRmOFN0cmluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2FzdCBVaW50OEFycmF5W10gdG8gc3RyaW5nW11cbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkdTKSB7XG4gICAgICAvLyBzdHJpbmdzIGluIG9ubnggYXR0cmlidXRlIGlzIHJldHVybmVkIGFzIHVpbnQ4YXJyYXlbXSwgc28gd2UgbmVlZCB0byBjb252ZXJ0IGl0IHRvIHN0cmluZ1tdIGJlbG93LiBXaGlsZSBpbiBvcnRcbiAgICAgIC8vIGZvcm1hdCBzdHJpbmdzIGF0dHJpYnV0ZXMgYXJlIHJldHVybmVkIGFzIHN0cmluZ1tdLCBzbyBubyBjb252ZXJzaW9uIGlzIG5lZWRlZC5cbiAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICBjb25zdCB1dGY4U3RyaW5ncyA9IHZhbHVlIGFzIFVpbnQ4QXJyYXlbXTtcbiAgICAgICAgcmV0dXJuIHV0ZjhTdHJpbmdzLm1hcChkZWNvZGVVdGY4U3RyaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUgYXMgVmFsdWVUeXBlcztcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlTm9DaGVjayhhdHRyOiBvbm54LklBdHRyaWJ1dGVQcm90byB8IG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICByZXR1cm4gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgID8gdGhpcy5nZXRWYWx1ZU5vQ2hlY2tGcm9tT25ueEZvcm1hdChhdHRyKVxuICAgICAgOiB0aGlzLmdldFZhbHVlTm9DaGVja0Zyb21PcnRGb3JtYXQoYXR0ciBhcyBvcnRGYnMuQXR0cmlidXRlKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlTm9DaGVja0Zyb21Pbm54Rm9ybWF0KGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvKSB7XG4gICAgc3dpdGNoIChhdHRyLnR5cGUhKSB7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZjtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVDpcbiAgICAgICAgcmV0dXJuIGF0dHIuaTtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuIGF0dHIucztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUjpcbiAgICAgICAgcmV0dXJuIGF0dHIudDtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkdSQVBIOlxuICAgICAgICByZXR1cm4gYXR0ci5nO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuRkxPQVRTOlxuICAgICAgICByZXR1cm4gYXR0ci5mbG9hdHM7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlRTOlxuICAgICAgICByZXR1cm4gYXR0ci5pbnRzO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuc3RyaW5ncztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUlM6XG4gICAgICAgIHJldHVybiBhdHRyLnRlbnNvcnM7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5HUkFQSFM6XG4gICAgICAgIHJldHVybiBhdHRyLmdyYXBocztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgYXR0cmlidXRlIHR5cGU6ICR7b25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlW2F0dHIudHlwZSFdfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlTm9DaGVja0Zyb21PcnRGb3JtYXQoYXR0cjogb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgIHN3aXRjaCAoYXR0ci50eXBlKCkpIHtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuRkxPQVQ6XG4gICAgICAgIHJldHVybiBhdHRyLmYoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuSU5UOlxuICAgICAgICByZXR1cm4gYXR0ci5pKCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuIGF0dHIucygpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5URU5TT1I6XG4gICAgICAgIHJldHVybiBhdHRyLnQoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuR1JBUEg6XG4gICAgICAgIHJldHVybiBhdHRyLmcoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuRkxPQVRTOlxuICAgICAgICByZXR1cm4gYXR0ci5mbG9hdHNBcnJheSgpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5JTlRTOiB7XG4gICAgICAgIGNvbnN0IGludHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyLmludHNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgICAgaW50cy5wdXNoKGF0dHIuaW50cyhpKSEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnRzO1xuICAgICAgfVxuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5TVFJJTkdTOiB7XG4gICAgICAgIGNvbnN0IHN0cmluZ3MgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyLnN0cmluZ3NMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgICAgc3RyaW5ncy5wdXNoKGF0dHIuc3RyaW5ncyhpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0cmluZ3M7XG4gICAgICB9XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlRFTlNPUlM6IHtcbiAgICAgICAgY29uc3QgdGVuc29ycyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIudGVuc29yc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgICB0ZW5zb3JzLnB1c2goYXR0ci50ZW5zb3JzKGkpISk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRlbnNvcnM7XG4gICAgICB9XG4gICAgICAvLyBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLkdSQVBIUzpcbiAgICAgIC8vIFRPRE86IFN1YmdyYXBoIG5vdCBzdXBwb3J0ZWQgeWV0LlxuICAgICAgLy8gY29uc3QgZ3JhcGhzID0gW107XG4gICAgICAvLyBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIuZ3JhcGhzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgLy8gICBncmFwaHMucHVzaChhdHRyLmdyYXBocyhpKSEpO1xuICAgICAgLy8gfVxuICAgICAgLy8gcmV0dXJuIGdyYXBocztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgYXR0cmlidXRlIHR5cGU6ICR7b3J0RmJzLkF0dHJpYnV0ZVR5cGVbYXR0ci50eXBlKCldfWApO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfYXR0cmlidXRlczogTWFwPHN0cmluZywgVmFsdWU+O1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGUgfSBmcm9tICcuL2F0dHJpYnV0ZSc7XG5pbXBvcnQgKiBhcyBvcnRGYnMgZnJvbSAnLi9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ydC1nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgb25ueCB9IGZyb20gJy4vb3J0LXNjaGVtYS9wcm90b2J1Zi9vbm54JztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yJztcbmltcG9ydCB7IExvbmdVdGlsLCBNQVhfQ0xJUCwgTUlOX0NMSVAsIFByb3RvVXRpbCB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBHcmFwaCB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgU2hhcGUge1xuICAgIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVmFsdWVUeXBlIHtcbiAgICByZWFkb25seSB0ZW5zb3JUeXBlOiBUZW5zb3IuRGF0YVR5cGU7XG4gICAgcmVhZG9ubHkgc2hhcGU6IFNoYXBlO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVmFsdWUge1xuICAgIC8vIHRoZSB0ZW5zb3IgZGF0YS4gZW1wdHkgZm9yIG5vbi1pbml0aWFsaXplZCBpbnB1dHNcbiAgICByZWFkb25seSB0ZW5zb3I/OiBUZW5zb3I7XG5cbiAgICAvLyBpbmRleCB0byB0aGUgTm9kZSB3aGVyZSB0aGUgdmFsdWUgY29tZXMgZnJvbS4gLTEgZm9yIGluaXRpYWxpemVyLlxuICAgIHJlYWRvbmx5IGZyb206IG51bWJlcjtcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIE5vZGVzIHdoZXJlIHRoZSB2YWx1ZXMgZ28gdG8uXG4gICAgcmVhZG9ubHkgdG86IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gdmFsdWUgdHlwZSBzcGVjaWZpY2F0aW9uLiBlbXB0eSBmb3Igbm9uLWlucHV0IHZhbHVlcy5cbiAgICByZWFkb25seSB0eXBlPzogVmFsdWVUeXBlO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgTm9kZSB7XG4gICAgLy8gbmFtZSBvZiB0aGUgbm9kZVxuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAgIC8vIHRoZSBvcGVyYXRvciB0eXBlXG4gICAgcmVhZG9ubHkgb3BUeXBlOiBzdHJpbmc7XG5cbiAgICAvLyBpbmRpY2VzIHRvIHRoZSBWYWx1ZXMgd2hlcmUgdGhlIGlucHV0cyBjb21lIGZyb20uXG4gICAgcmVhZG9ubHkgaW5wdXRzOiByZWFkb25seSBudW1iZXJbXTtcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIFZhbHVlcyB3aGVyZSB0aGUgb3V0cHVzIGdvIHRvLlxuICAgIHJlYWRvbmx5IG91dHB1dHM6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gdGhlIGF0dHJpYnV0ZXMgdGhhdCB1c2VkIGJ5IHRoZSBvcGVyYXRvclxuICAgIHJlYWRvbmx5IGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBhIFRyYW5zZm9ybWVyIGlzIGFuIGluc3RhbmNlIHRoYXQgYWxsb3dzIGFsbCBwb3NzaWJsZSB0cmFuc2Zvcm1hdGlvbiBvcGVyYXRpb25zIHRoYXQgYXBwbGllZCB0byBhIGdyYXBoXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFRyYW5zZm9ybWVyIHtcbiAgICByZW1vdmVBbGxJZGVudGl0eU5vZGVzKCk6IHZvaWQ7XG4gICAgcmVtb3ZlQWxsRHJvcG91dE5vZGVzKCk6IHZvaWQ7XG4gICAgZnVzZUNvbnZBY3RpdmF0aW9uTm9kZXMoKTogdm9pZDtcbiAgICAvLyBUT0RPOiBhZGQgZ2VuZXJpYyBmdW5jdGlvbnMgdG8gbWFuaXB1bGF0ZSB0aGUgZ3JhcGhcbiAgfVxuXG4gIC8vIGFuIGluaXRpYWxpemVyIGNhbiB1c2UgdHJhbnNmb3JtZXIgdG8gdHJhbnNmb3JtIHRoZSBncmFwaFxuICBleHBvcnQgaW50ZXJmYWNlIEluaXRpYWxpemVyIHtcbiAgICB0cmFuc2Zvcm1HcmFwaCh0cmFuc2Zvcm1lcjogVHJhbnNmb3JtZXIpOiB2b2lkO1xuICB9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlXG5leHBvcnQgaW50ZXJmYWNlIEdyYXBoIHtcbiAgZ2V0SW5wdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdO1xuICBnZXRJbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBnZXRPdXRwdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdO1xuICBnZXRPdXRwdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXTtcbiAgZ2V0VmFsdWVzKCk6IHJlYWRvbmx5IEdyYXBoLlZhbHVlW107XG4gIGdldE5vZGVzKCk6IHJlYWRvbmx5IEdyYXBoLk5vZGVbXTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiwgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZVxuZXhwb3J0IGNvbnN0IEdyYXBoID0ge1xuICAvKipcbiAgICogY29uc3RydWN0IGEgZ3JhcGggZnJvbSBhIGdyYXBoIHByb3RvYnVmIHR5cGVcbiAgICovXG4gIGZyb206IChncmFwaFByb3RvOiBvbm54LklHcmFwaFByb3RvIHwgb3J0RmJzLkdyYXBoLCBpbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKSA9PlxuICAgIG5ldyBHcmFwaEltcGwoZ3JhcGhQcm90bywgaW5pdGlhbGl6ZXIpLFxufTtcblxuY2xhc3MgVmFsdWUgaW1wbGVtZW50cyBHcmFwaC5WYWx1ZSB7XG4gIGNvbnN0cnVjdG9yKHZhbHVlSW5mbz86IG9ubnguSVZhbHVlSW5mb1Byb3RvKSB7XG4gICAgdGhpcy5fZnJvbSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl90byA9IFtdO1xuICAgIHRoaXMudGVuc29yID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudHlwZSA9IHVuZGVmaW5lZDtcblxuICAgIGlmICh2YWx1ZUluZm8pIHtcbiAgICAgIHRoaXMudHlwZSA9IFByb3RvVXRpbC50ZW5zb3JWYWx1ZVR5cGVGcm9tUHJvdG8odmFsdWVJbmZvLnR5cGUhLnRlbnNvclR5cGUhKTtcbiAgICB9XG4gIH1cblxuICBfZnJvbT86IG51bWJlcjsgLy8gLTEgcmVwcmVzZW50IGZyb20gaW5pdGlhbGl6ZXJcbiAgZ2V0IGZyb20oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Zyb20hO1xuICB9XG4gIF90bzogbnVtYmVyW107XG4gIGdldCB0bygpIHtcbiAgICByZXR1cm4gdGhpcy5fdG87XG4gIH1cbiAgdHlwZT86IEdyYXBoLlZhbHVlVHlwZTtcbiAgdGVuc29yPzogVGVuc29yO1xufVxuXG5jbGFzcyBOb2RlIGltcGxlbWVudHMgR3JhcGguTm9kZSB7XG4gIGNvbnN0cnVjdG9yKF9ub2RlUHJvdG86IG9ubnguSU5vZGVQcm90byB8IG9ydEZicy5Ob2RlLCBuYW1lPzogc3RyaW5nKSB7XG4gICAgaWYgKF9ub2RlUHJvdG8gaW5zdGFuY2VvZiBvbm54Lk5vZGVQcm90bykge1xuICAgICAgdGhpcy5uYW1lID0gX25vZGVQcm90by5uYW1lO1xuICAgICAgdGhpcy5vcFR5cGUgPSBfbm9kZVByb3RvLm9wVHlwZTtcbiAgICAgIHRoaXMuYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGUoX25vZGVQcm90by5hdHRyaWJ1dGUpO1xuICAgIH0gZWxzZSBpZiAoX25vZGVQcm90byBpbnN0YW5jZW9mIG9ydEZicy5Ob2RlKSB7XG4gICAgICB0aGlzLm5hbWUgPSBuYW1lID8/IF9ub2RlUHJvdG8ubmFtZSgpITtcbiAgICAgIHRoaXMub3BUeXBlID0gX25vZGVQcm90by5vcFR5cGUoKSE7XG4gICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlKFByb3RvVXRpbC50ZW5zb3JBdHRyaWJ1dGVzRnJvbU9SVEZvcm1hdChfbm9kZVByb3RvKSk7XG4gICAgfVxuXG4gICAgdGhpcy5pbnB1dHMgPSBbXTtcbiAgICB0aGlzLm91dHB1dHMgPSBbXTtcbiAgICB0aGlzLmV4ZWN1dGVOb2RlID0gdHJ1ZTtcbiAgfVxuXG4gIG5hbWU6IHN0cmluZztcbiAgb3BUeXBlOiBzdHJpbmc7XG4gIGlucHV0czogbnVtYmVyW107XG4gIG91dHB1dHM6IG51bWJlcltdO1xuICBhdHRyaWJ1dGVzOiBBdHRyaWJ1dGU7XG4gIGV4ZWN1dGVOb2RlOiBib29sZWFuO1xufVxuXG5jbGFzcyBHcmFwaEltcGwgaW1wbGVtZW50cyBHcmFwaCwgR3JhcGguVHJhbnNmb3JtZXIge1xuICBwcml2YXRlIF9hbGxEYXRhOiBWYWx1ZVtdO1xuXG4gIHByaXZhdGUgX2FsbElucHV0SW5kaWNlczogbnVtYmVyW107XG4gIHByaXZhdGUgX2FsbElucHV0TmFtZXM6IHN0cmluZ1tdO1xuXG4gIHByaXZhdGUgX2FsbE91dHB1dEluZGljZXM6IG51bWJlcltdO1xuICBwcml2YXRlIF9hbGxPdXRwdXROYW1lczogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSBfbm9kZXM6IE5vZGVbXTtcblxuICBjb25zdHJ1Y3RvcihncmFwaDogb25ueC5JR3JhcGhQcm90byB8IG9ydEZicy5HcmFwaCwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKSB7XG4gICAgaWYgKCFncmFwaCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZ3JhcGggaXMgZW1wdHknKTtcbiAgICB9XG5cbiAgICAvLyBidWlsZCB0aGUgZ3JhcGggLSB3aWxsIHRocm93IGV4Y2VwdGlvbnMgaWYgc29tZXRoaW5nIGZhdGFsIGlzIGRldGVjdGVkXG4gICAgdGhpcy5idWlsZEdyYXBoKGdyYXBoKTtcblxuICAgIC8vIGV4ZWN1dGUgYW55IHRyYW5zZm9ybWF0aW9uIGxvZ2ljIGZvciB0aGUgZ3JhcGggKGlmIGFwcGxpY2FibGUpXG4gICAgdGhpcy50cmFuc2Zvcm1HcmFwaChncmFwaEluaXRpYWxpemVyKTtcblxuICAgIC8vIGNoZWNrIGZvciBjeWNsZXMgYW5kIG90aGVyIGluY29uc2lzdGVuY2llcyAtIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBpZiBzb21ldGhpbmcgZmF0YWwgaXMgZGV0ZWN0ZWRcbiAgICB0aGlzLmNoZWNrSXNBY3ljbGljKCk7XG4gIH1cblxuICBnZXRJbnB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxJbnB1dEluZGljZXM7XG4gIH1cblxuICBnZXRJbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsSW5wdXROYW1lcztcbiAgfVxuXG4gIGdldE91dHB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzO1xuICB9XG5cbiAgZ2V0T3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxPdXRwdXROYW1lcztcbiAgfVxuXG4gIGdldFZhbHVlcygpOiByZWFkb25seSBHcmFwaC5WYWx1ZVtdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsRGF0YTtcbiAgfVxuXG4gIGdldE5vZGVzKCk6IHJlYWRvbmx5IEdyYXBoLk5vZGVbXSB7XG4gICAgcmV0dXJuIHRoaXMuX25vZGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEdyYXBoKGdyYXBoOiBvbm54LklHcmFwaFByb3RvIHwgb3J0RmJzLkdyYXBoKSB7XG4gICAgLy8gYnVpbGQgdGhlIGdyYXBoIC0gd2lsbCB0aHJvdyBleGNlcHRpb25zIGlmIHNvbWV0aGluZyBmYXRhbCBpcyBkZXRlY3RlZFxuICAgIGlmIChncmFwaCBpbnN0YW5jZW9mIG9ubnguR3JhcGhQcm90bykge1xuICAgICAgdGhpcy5idWlsZEdyYXBoRnJvbU9ubnhGb3JtYXQoZ3JhcGgpO1xuICAgIH0gZWxzZSBpZiAoZ3JhcGggaW5zdGFuY2VvZiBvcnRGYnMuR3JhcGgpIHtcbiAgICAgIHRoaXMuYnVpbGRHcmFwaEZyb21PcnRGb3JtYXQoZ3JhcGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdHcmFwaCB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgYnVpbGRHcmFwaEZyb21Pbm54Rm9ybWF0KGdyYXBoOiBvbm54LklHcmFwaFByb3RvKSB7XG4gICAgY29uc3QgZGF0YUluZGljZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIHRoaXMuX2FsbERhdGEgPSBbXTtcblxuICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcyA9IFtdO1xuICAgIHRoaXMuX2FsbElucHV0TmFtZXMgPSBbXTtcblxuICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXMgPSBbXTtcbiAgICB0aGlzLl9hbGxPdXRwdXROYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5fbm9kZXMgPSBbXTtcblxuICAgIGNvbnN0IG5vZGVzSW5kaWNlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG5cbiAgICAvLyBzY2FuIGFsbCBpbnB1dHNcbiAgICBpZiAoIWdyYXBoLmlucHV0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IGlucHV0Jyk7XG4gICAgfVxuICAgIGNvbnN0IGlucHV0VmFsdWVOYW1lcyA9IFtdO1xuICAgIGZvciAoY29uc3QgaSBvZiBncmFwaC5pbnB1dCkge1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhpLm5hbWUhKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgaW5wdXQgbmFtZTogJHtpLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2gobmV3IFZhbHVlKGkpKSAtIDE7XG4gICAgICBkYXRhSW5kaWNlcy5zZXQoaS5uYW1lISwgY3VycmVudEluZGV4KTtcbiAgICAgIGlucHV0VmFsdWVOYW1lcy5wdXNoKGkubmFtZSEpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gYWxsIGluaXRpYWxpemVyc1xuICAgIGlmICghZ3JhcGguaW5pdGlhbGl6ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogaW5pdGlhbGl6ZXInKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBpIG9mIGdyYXBoLmluaXRpYWxpemVyKSB7XG4gICAgICBsZXQgaW5kZXggPSBkYXRhSW5kaWNlcy5nZXQoaS5uYW1lISk7XG4gICAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBWYWx1ZSgpO1xuICAgICAgICB2YWx1ZS50eXBlID0ge1xuICAgICAgICAgIHNoYXBlOiB7IGRpbXM6IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKGkuZGltcyEpIH0sXG4gICAgICAgICAgdGVuc29yVHlwZTogUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKGkuZGF0YVR5cGUhKSxcbiAgICAgICAgfTtcbiAgICAgICAgaW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2godmFsdWUpIC0gMTtcbiAgICAgICAgZGF0YUluZGljZXMuc2V0KGkubmFtZSEsIGluZGV4KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2FsbERhdGFbaW5kZXhdLl9mcm9tID0gLTE7XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbVByb3RvKGkpO1xuICAgIH1cblxuICAgIC8vIGZpbHRlciBvdXQgaW5wdXQgaW5kaWNlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCF0aGlzLl9hbGxEYXRhW2ldLnRlbnNvcikge1xuICAgICAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMucHVzaChpKTtcbiAgICAgICAgdGhpcy5fYWxsSW5wdXROYW1lcy5wdXNoKGlucHV0VmFsdWVOYW1lc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgb3V0cHV0c1xuICAgIGlmICghZ3JhcGgub3V0cHV0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IG91dHB1dCcpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGkgb2YgZ3JhcGgub3V0cHV0KSB7XG4gICAgICBpZiAoZGF0YUluZGljZXMuaGFzKGkubmFtZSEpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBvdXRwdXQgbmFtZTogJHtpLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2gobmV3IFZhbHVlKGkpKSAtIDE7XG4gICAgICBkYXRhSW5kaWNlcy5zZXQoaS5uYW1lISwgY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXMucHVzaChjdXJyZW50SW5kZXgpO1xuICAgICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMucHVzaChpLm5hbWUhKTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBub2Rlc1xuICAgIGlmICghZ3JhcGgubm9kZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBub2RlJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgbm9kZVByb3RvIG9mIGdyYXBoLm5vZGUpIHtcbiAgICAgIGlmICghbm9kZVByb3RvLm5hbWUpIHtcbiAgICAgICAgLy8gYXNzaWduIGEgbmFtZSB0byB0aGUgbm9kZSBpZiBpdCBkb2Vzbid0IGhhdmUgb25lXG4gICAgICAgIGZvciAobGV0IHBpY2sgPSAwOyA7IHBpY2srKykge1xuICAgICAgICAgIGNvbnN0IG5hbWUgPSBgdW5uYW1lZF8ke25vZGVQcm90by5vcFR5cGV9XyR7cGlja31gO1xuICAgICAgICAgIGlmICghbm9kZXNJbmRpY2VzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgbm9kZVByb3RvLm5hbWUgPSBuYW1lO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChub2Rlc0luZGljZXMuaGFzKG5vZGVQcm90by5uYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgbm9kZSBuYW1lOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fbm9kZXMucHVzaChuZXcgTm9kZShub2RlUHJvdG8pKSAtIDE7XG4gICAgICBub2Rlc0luZGljZXMuc2V0KG5vZGVQcm90by5uYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gbm9kZSdzIG91dHB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlW2ldO1xuICAgICAgaWYgKCFub2RlUHJvdG8ub3V0cHV0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBvdXRwdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBub2RlUHJvdG8ub3V0cHV0KSB7XG4gICAgICAgIGxldCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQob3V0cHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgZGF0YUluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZSgpKSAtIDE7XG4gICAgICAgICAgZGF0YUluZGljZXMuc2V0KG91dHB1dCwgZGF0YUluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLm91dHB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbXVsdGlwbGUgbm9kZXMgb3V0cHV0IHRvIG9uZSBkYXRhIHZhbHVlOiAke2RhdGFJbmRleH1gKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSBpO1xuXG4gICAgICAgIC8vIGZvciB0aGUgJ0NvbnN0YW50JyBvcGVyYXRvciwganVzdCBjcmVhdGUgYSBuZXcgZWRnZSBpbiB0aGUgZ3JhcGggY29ycmVzcG9uZGluZyB0byB0aGUgJ291dHB1dCcgb2YgdGhlXG4gICAgICAgIC8vIG9wZXJhdG9yIGFuZCBpZ25vcmUgdGhlIG5vZGUgZnJvbSB0aGUgZ3JhcGhcbiAgICAgICAgaWYgKG5vZGVQcm90by5vcFR5cGUgPT09ICdDb25zdGFudCcpIHtcbiAgICAgICAgICBpZiAoIW5vZGVQcm90by5hdHRyaWJ1dGUgfHwgbm9kZVByb3RvLmF0dHJpYnV0ZS5sZW5ndGggIT09IDEgfHwgIW5vZGVQcm90by5hdHRyaWJ1dGVbMF0udCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGF0dHJpYnV0ZXMgb3IgbWlzc2luZyB0ZW5zb3IgdmFsdWUgaW4gYXR0cmlidXRlcyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5vZGVQcm90by5vdXRwdXQgfHwgbm9kZVByb3RvLm91dHB1dC5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBvdXRwdXQgb3IgaW5jb3JyZWN0IG51bWJlciBvZiBvdXRwdXRzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUub3V0cHV0cy5wb3AoKTtcbiAgICAgICAgICBub2RlLmV4ZWN1dGVOb2RlID0gZmFsc2U7XG5cbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSAtMTtcbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0udGVuc29yID0gVGVuc29yLmZyb21Qcm90byhub2RlUHJvdG8uYXR0cmlidXRlWzBdLnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3MgaW5wdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZVtpXTtcblxuICAgICAgaWYgKCFub2RlUHJvdG8uaW5wdXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGlucHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBpbnB1dCBvZiBub2RlUHJvdG8uaW5wdXQpIHtcbiAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGlucHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgLy8gaGFuZGxlIGV4Y2VwdGlvbiB3aGVuIG9wc2V0ID4gOSBhbmQgcm9pIC8gc2NhbGVzIG5vdCBnaXZlblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlucHV0ID09PSAnJyAmJlxuICAgICAgICAgICAgKG5vZGVQcm90by5pbnB1dC5sZW5ndGggPT09IDMgfHwgbm9kZVByb3RvLmlucHV0Lmxlbmd0aCA9PT0gNCkgJiZcbiAgICAgICAgICAgIG5vZGVQcm90by5vcFR5cGUgPT09ICdSZXNpemUnXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgaW5wdXQgJyR7aW5wdXR9JyBmb3Igbm9kZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLmlucHV0cy5wdXNoKGRhdGFJbmRleCk7XG5cbiAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl90by5wdXNoKGkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEdyYXBoRnJvbU9ydEZvcm1hdChncmFwaDogb3J0RmJzLkdyYXBoKSB7XG4gICAgY29uc3QgZGF0YUluZGljZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIHRoaXMuX2FsbERhdGEgPSBbXTtcblxuICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcyA9IFtdO1xuICAgIHRoaXMuX2FsbElucHV0TmFtZXMgPSBbXTtcblxuICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXMgPSBbXTtcbiAgICB0aGlzLl9hbGxPdXRwdXROYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5fbm9kZXMgPSBbXTtcblxuICAgIGNvbnN0IG5vZGVzSW5kaWNlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG5cbiAgICAvLyBzY2FuIGFsbCBpbnB1dHNcbiAgICBjb25zdCBpbnB1dFZhbHVlTmFtZXMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoLmlucHV0c0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IGlucHV0TmFtZSA9IGdyYXBoLmlucHV0cyhpKTtcbiAgICAgIGlmIChkYXRhSW5kaWNlcy5oYXMoaW5wdXROYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgaW5wdXQgbmFtZTogJHtpbnB1dE5hbWV9YCk7XG4gICAgICB9XG4gICAgICAvLyBGaW5kIHRoZSBpbnB1dCB0eXBlSW5mbyBmcm9tIG5vZGVhcmdzXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGdyYXBoLm5vZGVBcmdzTGVuZ3RoKCk7IGorKykge1xuICAgICAgICBpZiAoZ3JhcGgubm9kZUFyZ3Moaik/Lm5hbWUoKSA9PT0gaW5wdXROYW1lKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBuZXcgVmFsdWUoKTtcbiAgICAgICAgICBjb25zdCB2YWx1ZVR5cGUgPSBncmFwaC5ub2RlQXJncyhqKT8udHlwZSgpPy52YWx1ZVR5cGUoKTtcbiAgICAgICAgICBpZiAodmFsdWVUeXBlICE9PSBvcnRGYnMuVHlwZUluZm9WYWx1ZS50ZW5zb3JfdHlwZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHZhbHVlIHR5cGUgZm9yIHRoZSBub2RlQXJnLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB2YWx1ZUluZm8gPSBncmFwaC5ub2RlQXJncyhqKSEudHlwZSgpIS52YWx1ZShuZXcgb3J0RmJzLlRlbnNvclR5cGVBbmRTaGFwZSgpKSE7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byh2YWx1ZUluZm8uZWxlbVR5cGUoKSk7XG4gICAgICAgICAgY29uc3Qgc2hhcGUgPSB2YWx1ZUluZm8uc2hhcGUoKSE7XG4gICAgICAgICAgY29uc3QgZGltcyA9IFtdO1xuICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgc2hhcGUuZGltTGVuZ3RoKCkhOyBrKyspIHtcbiAgICAgICAgICAgIGRpbXMucHVzaChMb25nVXRpbC5sb25nVG9OdW1iZXIoc2hhcGUuZGltKGspIS52YWx1ZSgpIS5kaW1WYWx1ZSgpISkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YWx1ZS50eXBlID0geyBzaGFwZTogeyBkaW1zIH0sIHRlbnNvclR5cGU6IHR5cGUgfTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2godmFsdWUpIC0gMTtcbiAgICAgICAgICBkYXRhSW5kaWNlcy5zZXQoaW5wdXROYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgICAgICAgIGlucHV0VmFsdWVOYW1lcy5wdXNoKGlucHV0TmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY2hlY2sgaW5pdGlhbGl6ZXJzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5pbml0aWFsaXplcnNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBjb25zdCBpbml0aWFsaXplciA9IGdyYXBoLmluaXRpYWxpemVycyhpKSE7XG4gICAgICBsZXQgaW5kZXggPSBkYXRhSW5kaWNlcy5nZXQoaW5pdGlhbGl6ZXIubmFtZSgpISk7XG4gICAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBWYWx1ZSgpO1xuICAgICAgICBjb25zdCBkaW1zID0gUHJvdG9VdGlsLnRlbnNvckRpbXNGcm9tT1JURm9ybWF0KGluaXRpYWxpemVyKTtcbiAgICAgICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhpbml0aWFsaXplci5kYXRhVHlwZSgpKTtcbiAgICAgICAgdmFsdWUudHlwZSA9IHsgc2hhcGU6IHsgZGltcyB9LCB0ZW5zb3JUeXBlOiB0eXBlIH07XG4gICAgICAgIGluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKHZhbHVlKSAtIDE7XG4gICAgICAgIGRhdGFJbmRpY2VzLnNldChpbml0aWFsaXplci5uYW1lKCkhLCBpbmRleCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgdGhpcy5fYWxsRGF0YVtpbmRleF0udGVuc29yID0gVGVuc29yLmZyb21PcnRUZW5zb3IoaW5pdGlhbGl6ZXIpO1xuICAgIH1cblxuICAgIC8vIGZpbHRlciBvdXQgaW5wdXQgaW5kaWNlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCF0aGlzLl9hbGxEYXRhW2ldLnRlbnNvcikge1xuICAgICAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMucHVzaChpKTtcbiAgICAgICAgdGhpcy5fYWxsSW5wdXROYW1lcy5wdXNoKGlucHV0VmFsdWVOYW1lc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgb3V0cHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGgub3V0cHV0c0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IG91dHB1dE5hbWUgPSBncmFwaC5vdXRwdXRzKGkpO1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhvdXRwdXROYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgb3V0cHV0IG5hbWU6ICR7b3V0cHV0TmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoKSkgLSAxO1xuICAgICAgZGF0YUluZGljZXMuc2V0KG91dHB1dE5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLnB1c2goY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzLnB1c2gob3V0cHV0TmFtZSk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgbm9kZXNcbiAgICBpZiAoIWdyYXBoLm5vZGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IG5vZGUnKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5ub2Rlc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVzKGkpO1xuICAgICAgbGV0IG5hbWUgPSBub2RlUHJvdG8hLm5hbWUoKTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICAvLyBhc3NpZ24gYSBuYW1lIHRvIHRoZSBub2RlIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcbiAgICAgICAgZm9yIChsZXQgcGljayA9IDA7IDsgcGljaysrKSB7XG4gICAgICAgICAgbmFtZSA9IGB1bm5hbWVkXyR7bm9kZVByb3RvIS5vcFR5cGUoKX1fJHtwaWNrfWA7XG4gICAgICAgICAgaWYgKCFub2Rlc0luZGljZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICAvLyBhbiB1bmlxdWUgbmFtZSBpcyBmb3VuZC4gYnJlYWsuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVzSW5kaWNlcy5oYXMobmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIG5vZGUgbmFtZTogJHtuYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fbm9kZXMucHVzaChuZXcgTm9kZShub2RlUHJvdG8hLCBuYW1lKSkgLSAxO1xuICAgICAgbm9kZXNJbmRpY2VzLnNldChuYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gbm9kZSdzIG91dHB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlcyhpKTtcbiAgICAgIGlmIChub2RlUHJvdG8gPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIG5vZGUgZXhpc3RzIGF0IGluZGV4ICR7aX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlUHJvdG8/Lm91dHB1dHNMZW5ndGgoKSA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG1pc3Npbmcgb3V0cHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBub2RlUHJvdG8/Lm91dHB1dHNMZW5ndGgoKTsgaisrKSB7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IG5vZGVQcm90bz8ub3V0cHV0cyhqKTtcbiAgICAgICAgbGV0IGRhdGFJbmRleCA9IGRhdGFJbmRpY2VzLmdldChvdXRwdXQpO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBkYXRhSW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2gobmV3IFZhbHVlKCkpIC0gMTtcbiAgICAgICAgICBkYXRhSW5kaWNlcy5zZXQob3V0cHV0LCBkYXRhSW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUub3V0cHV0cy5wdXNoKGRhdGFJbmRleCk7XG5cbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtdWx0aXBsZSBub2RlcyBvdXRwdXQgdG8gb25lIGRhdGEgdmFsdWU6ICR7ZGF0YUluZGV4fWApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSA9IGk7XG5cbiAgICAgICAgLy8gZm9yIHRoZSAnQ29uc3RhbnQnIG9wZXJhdG9yLCBqdXN0IGNyZWF0ZSBhIG5ldyBlZGdlIGluIHRoZSBncmFwaCBjb3JyZXNwb25kaW5nIHRvIHRoZSAnb3V0cHV0JyBvZiB0aGVcbiAgICAgICAgLy8gb3BlcmF0b3IgYW5kIGlnbm9yZSB0aGUgbm9kZSBmcm9tIHRoZSBncmFwaFxuICAgICAgICBpZiAobm9kZVByb3RvLm9wVHlwZSgpID09PSAnQ29uc3RhbnQnKSB7XG4gICAgICAgICAgaWYgKG5vZGVQcm90by5hdHRyaWJ1dGVzTGVuZ3RoKCkgIT09IDEgfHwgIW5vZGVQcm90by5hdHRyaWJ1dGVzKDApIS50KCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBhdHRyaWJ1dGVzIG9yIG1pc3NpbmcgdGVuc29yIHZhbHVlIGluIGF0dHJpYnV0ZXMgZm9yIHRoaXMgQ29uc3RhbnQgb3BlcmF0b3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG5vZGVQcm90by5vdXRwdXRzTGVuZ3RoKCkgIT09IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBvdXRwdXQgb3IgaW5jb3JyZWN0IG51bWJlciBvZiBvdXRwdXRzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUub3V0cHV0cy5wb3AoKTtcbiAgICAgICAgICBub2RlLmV4ZWN1dGVOb2RlID0gZmFsc2U7XG5cbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSAtMTtcbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0udGVuc29yID0gVGVuc29yLmZyb21PcnRUZW5zb3Iobm9kZVByb3RvLmF0dHJpYnV0ZXMoMCkhLnQoKSEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3MgaW5wdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZXMoaSkhO1xuXG4gICAgICBpZiAobm9kZVByb3RvLmlucHV0c0xlbmd0aCgpID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBpbnB1dCBmb3Igbm9kZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbm9kZVByb3RvLmlucHV0c0xlbmd0aCgpITsgaisrKSB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gbm9kZVByb3RvLmlucHV0cyhqKSE7XG4gICAgICAgIGNvbnN0IGRhdGFJbmRleCA9IGRhdGFJbmRpY2VzLmdldChpbnB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5yZWNvZ25pemVkIGlucHV0ICcke2lucHV0fScgZm9yIG5vZGU6ICR7bm9kZVByb3RvIS5uYW1lKCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5pbnB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fdG8ucHVzaChpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrSXNBY3ljbGljKCkge1xuICAgIC8vIGdvIHRocm91Z2ggdGhlIGdyYXBoIGFuZCBjaGVjayBmb3IgY3ljbGVzIG9yIG90aGVyIGZhdGFsIGluY29uc2lzdGVuY2llc1xuICAgIGNvbnN0IHN0YXJ0ZXJzOiBTZXQ8bnVtYmVyPiA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcy5mb3JFYWNoKChpKSA9PiB7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5fYWxsRGF0YVtpXTtcbiAgICAgIGRhdGEuX3RvLmZvckVhY2goKGopID0+IHtcbiAgICAgICAgc3RhcnRlcnMuYWRkKGopO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBJdGVyYXRpdmUgREZTIHRvIGNoZWNrIGZvciBjeWNsZXNcbiAgICBjb25zdCBub2Rlc1N0YWNrID0gQXJyYXkuZnJvbShzdGFydGVycyk7XG4gICAgY29uc3Qgbm9kZXNTdGF0ZSA9IG5ldyBBcnJheTxzdHJpbmc+KHRoaXMuX25vZGVzLmxlbmd0aCkuZmlsbCgnd2hpdGUnKTtcblxuICAgIHdoaWxlIChub2Rlc1N0YWNrLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IG5vZGVJbmRleCA9IG5vZGVzU3RhY2sucG9wKCkhO1xuICAgICAgLy8gdGhpcyBub2RlIGhhcyBub3cgYmVlbiBwcm9jZXNzZWQgY29tcGxldGVseS4gTWFyayB0aGlzIG5vZGUgJ2JsYWNrJyB0byBkZW5vdGUgdGhpcy5cbiAgICAgIGlmIChub2Rlc1N0YXRlW25vZGVJbmRleF0gPT09ICdncmF5Jykge1xuICAgICAgICBub2Rlc1N0YXRlW25vZGVJbmRleF0gPSAnYmxhY2snO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdGhpcyBub2RlIGlzIHVuZGVyIHByb2Nlc3Npbmcgc3RhZ2UuIG1hcmsgdGhpcyBub2RlICdncmF5JyB0byBkZW5vdGUgdGhpcy5cbiAgICAgICAgbm9kZXNTdGFjay5wdXNoKG5vZGVJbmRleCk7XG4gICAgICAgIG5vZGVzU3RhdGVbbm9kZUluZGV4XSA9ICdncmF5JztcblxuICAgICAgICB0aGlzLl9ub2Rlc1tub2RlSW5kZXhdLm91dHB1dHMuZm9yRWFjaCgob3V0Z29pbmdFZGdlSW5kZXgpID0+IHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5fYWxsRGF0YVtvdXRnb2luZ0VkZ2VJbmRleF07XG4gICAgICAgICAgaWYgKHR5cGVvZiBkYXRhLnRlbnNvciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbm9kZSBvdXRwdXRzIHNob3VsZCBub3QgYmUgaW5pdGlhbGl6ZWQnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRhdGEuX2Zyb20gIT09IG5vZGVJbmRleCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZnJvbSBwcm9wZXJ0eSBvZiB0aGUgVmFsdWUgb2JqZWN0IGRvZXNuJ3QgbWF0Y2ggaW5kZXggb2YgTm9kZSBiZWluZyBwcm9jZXNzZWRcIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRhdGEuX3RvLmZvckVhY2goKGRvd25zdHJlYW1Ob2RlSW5kZXgpID0+IHtcbiAgICAgICAgICAgIC8vIGJhY2sgZWRnZSBmb3VuZCAtIGN5Y2xpY1xuICAgICAgICAgICAgaWYgKG5vZGVzU3RhdGVbZG93bnN0cmVhbU5vZGVJbmRleF0gPT09ICdncmF5Jykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21vZGVsIGdyYXBoIGlzIGN5Y2xpYycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdHJlZSBlZGdlIGZvdW5kIC0gY29udGludWUgcHJvY2Vzc2luZyBieSBhZGRpbmcgaXQgdG8gc3RhY2tcbiAgICAgICAgICAgIGVsc2UgaWYgKG5vZGVzU3RhdGVbZG93bnN0cmVhbU5vZGVJbmRleF0gPT09ICd3aGl0ZScpIHtcbiAgICAgICAgICAgICAgbm9kZXNTdGFjay5wdXNoKGRvd25zdHJlYW1Ob2RlSW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRyYW5zZm9ybUdyYXBoKGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcik6IHZvaWQge1xuICAgIC8vIGFwcGx5IGNvbW1vbiB0cmFuc2Zvcm1cbiAgICB0aGlzLnJlbW92ZUFsbElkZW50aXR5Tm9kZXMoKTtcbiAgICB0aGlzLnJlbW92ZUFsbERyb3BvdXROb2RlcygpO1xuICAgIHRoaXMuZnVzZUNvbnZBY3RpdmF0aW9uTm9kZXMoKTtcbiAgICAvLyBhcHBseSBpbml0aWFsaXplciBzcGVjaWZpYyB0cmFuc2Zvcm1cbiAgICBpZiAoZ3JhcGhJbml0aWFsaXplcikge1xuICAgICAgZ3JhcGhJbml0aWFsaXplci50cmFuc2Zvcm1HcmFwaCh0aGlzKTtcbiAgICB9XG5cbiAgICAvLyBmaW5hbGl6ZSBncmFwaFxuICAgIHRoaXMuZmluYWxpemVHcmFwaCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIGZpbmFsaXplIHRoZSBncmFwaC5cbiAgICpcbiAgICogdGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgY2FsbGVkIGFmdGVyIGFsbCB0aGUgdHJhbnNmb3JtYXRpb24gY29tcGxldGVkLlxuICAgKiB0aGlzIGZ1bmN0aW9uIHJlbW92ZXMgYWxsIHVubmVjZXNzYXJ5IG5vZGVzIGFuZCB2YWx1ZXMgZnJvbSB0aGUgZ3JhcGhcbiAgICovXG4gIGZpbmFsaXplR3JhcGgoKSB7XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgLy8gZGVsZXRlIGFsbCBub2RlcyB0aGF0IGFyZSBub3QgYmVpbmcgZXhlY3V0ZWRcbiAgICAvLyBUaGUgZ3JhcGggaXMgcmVwcmVzZW50ZWQgdXNpbmcgdGhlc2UgdHdvIGFycmF5c1xuICAgIC8vIHRoaXMuX25vZGVzIC0gQXJyYXkgaG9sZGluZyB0aGUga2VybmVscyB0byBleGVjdXRlIC0gZWFjaCBlbnRyeSBpcyBhIGtlcm5lbCBwb2ludGluZyB0byB0aGlzLl9hbGxEYXRhXG4gICAgLy8gdGhpcy5fYWxsRGF0YSAtIGhvbGQgMiBmaWVsZHMgLSB0byBbXSAmIGZyb20gLSB0aGVzZSBmZWlsZWRzIGhvbGQgdGhlIGdyYXBoIG1hcCBmb3IgaW5wdXRzIGFuZCBvdXRwdXRzIHBlciBub2RlXG4gICAgLy8gbmV3SW5kaWNlcyAtIHJlbWFwcGluZyB0aGUgZ3JhcGggYWZ0ZXIgcmVhZGluZyB0aGUgZmxhZyAnZXhlY3V0ZU5vZGUnXG4gICAgY29uc3QgbmV3SW5kaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KHRoaXMuX25vZGVzLmxlbmd0aCwgMCk7XG4gICAgbGV0IG5vZGVQb3NzaXRpb24gPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgLy8gZ2l2aW5nIG5ldyBpbmRleGVzIHRvIHRoZSBub2RlcyBiYXNlZCBvbiBleGVjdXRpb24gZmxhZ1xuICAgICAgbmV3SW5kaWNlc1tpXSA9IG5vZGVQb3NzaXRpb247XG4gICAgICBpZiAodGhpcy5fbm9kZXNbaV0uZXhlY3V0ZU5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGVQb3NzaXRpb24gIT09IGkpIHtcbiAgICAgICAgICB0aGlzLl9ub2Rlc1tub2RlUG9zc2l0aW9uXSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgICB9XG4gICAgICAgIG5vZGVQb3NzaXRpb24rKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGRlbGV0ZSBhbGwgb3V0cHV0IHZhbHVlc1xuICAgICAgICB0aGlzLl9ub2Rlc1tpXS5vdXRwdXRzLmZvckVhY2goKGluZCkgPT4ge1xuICAgICAgICAgIHRoaXMuX2FsbERhdGFbaW5kXS5fZnJvbSA9IC0yO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyByZW1vdmluZyB0aGUgdW51c2VkIG5vZGVzXG4gICAgdGhpcy5fbm9kZXMuc3BsaWNlKG5vZGVQb3NzaXRpb24sIHRoaXMuX25vZGVzLmxlbmd0aCAtIG5vZGVQb3NzaXRpb24pO1xuXG4gICAgLy8gVXBkYXRpbmcgdGhpcy5fYWxsRGF0YSBhY2NvcmRpbmcgdG8gdGhlIG5ldyB0aGlzLl9ub2Rlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY3VycmVudERhdGEgPSB0aGlzLl9hbGxEYXRhW2ldO1xuICAgICAgaWYgKGN1cnJlbnREYXRhLl9mcm9tICE9PSB1bmRlZmluZWQgJiYgY3VycmVudERhdGEuX2Zyb20gIT09IC0xICYmIGN1cnJlbnREYXRhLl9mcm9tICE9PSAtMikge1xuICAgICAgICBjdXJyZW50RGF0YS5fZnJvbSA9IG5ld0luZGljZXNbY3VycmVudERhdGEuX2Zyb21dO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGN1cnJlbnREYXRhLl90by5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoY3VycmVudERhdGEuX3RvW2pdID49IDApIHtcbiAgICAgICAgICBjdXJyZW50RGF0YS5fdG9bal0gPSBuZXdJbmRpY2VzW2N1cnJlbnREYXRhLl90b1tqXV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUcnlpbmcgdG8gdXBkYXRlIGEgcmVtb3ZlZCBub2RlJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBvZmZzZXQgPSAwO1xuICAgIC8vIGRlbGV0ZSBhbGwgdmFsdWVzIHRoYXQgYXJlIG5vdCBiZWluZyByZWZlcmVuY2VkXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBpZiBjdXJyZW50IHZhbHVlIGlzIG5laXRoZXIgbGlua2VkIHRvIG5leHQgbm9kZSwgbm9yIGFuIG91dHB1dCB2YWx1ZSwgcmVtb3ZlIGl0LlxuICAgICAgaWYgKHRoaXMuX2FsbERhdGFbaV0uZnJvbSA9PT0gLTIgJiYgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5pbmRleE9mKGkgKyBvZmZzZXQpID09PSAtMSkge1xuICAgICAgICBvZmZzZXQrKztcbiAgICAgICAgdGhpcy5fYWxsRGF0YS5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGktLTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAob2Zmc2V0ID4gMCkge1xuICAgICAgICBsZXQgaW5kID0gLTE7XG4gICAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgbmVpdGhlciBhbiBpbnB1dCB2YWx1ZSBub3IgYW4gaW5pdGlhbGl6ZXIsIGZpbmQgdGhlIG5vZGUgaXQnc1xuICAgICAgICAvLyBjb21pbmcgZnJvbSBhbmQgdXBkYXRlIHRoZSBjb3JyZXNwb25kaW5nIG5vZGUgb3V0cHV0XG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2ldLmZyb20gIT09IHVuZGVmaW5lZCAmJiB0aGlzLl9hbGxEYXRhW2ldLmZyb20gIT09IC0xKSB7XG4gICAgICAgICAgaW5kID0gdGhpcy5fbm9kZXNbdGhpcy5fYWxsRGF0YVtpXS5mcm9tXS5vdXRwdXRzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX25vZGVzW3RoaXMuX2FsbERhdGFbaV0uZnJvbV0ub3V0cHV0c1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gaWYgY3VycmVudCB2YWx1ZSBpcyBhbiBpbnB1dCB2YWx1ZSwgdXBkYXRlIGl0cyByZWZlcmVuY2UgaW4gaW5wdXRJbmRpY2VzXG4gICAgICAgICAgaW5kID0gdGhpcy5fYWxsSW5wdXRJbmRpY2VzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FsbElucHV0SW5kaWNlc1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaW5kIHRoZSBub2RlIHRoYXQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgbGlua2luZyB0byBhbmQgdXBkYXRlIGl0cyBpbnB1dCByZWZlcmVuY2VcbiAgICAgICAgdGhpcy5fYWxsRGF0YVtpXS50by5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgICAgICAgaW5kID0gdGhpcy5fbm9kZXNbbm9kZV0uaW5wdXRzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX25vZGVzW25vZGVdLmlucHV0c1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtpXS50by5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAvLyBpZiBjdXJyZW50IHZhbHVlIGlzIGEgZ3JhcGggb3V0cHV0LCB1cGRhdGUgaXRzIHJlZmVyZW5jZSBpbiBvdXRwdXRJbmRpY2VzXG4gICAgICAgICAgaW5kID0gdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5pbmRleE9mKGkgKyBvZmZzZXQpO1xuICAgICAgICAgIGlmIChpbmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIHNwZWNpZmllZCBub2RlLiBBc3N1bWUgdGhlIG5vZGUgaGFzIG9uZSBpbmNvbWluZyBpbnB1dCBhbmQgdGhlIGZpcnN0IG91dHB1dCBjb25uZWN0ZWQgdG8gb3RoZXIgbm9kZXMuXG4gICAqIEFuIGlucHV0IHZhbGlkYXRpb24gbXVzdCBiZSBkb25lIGJlZm9yZSBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSBub2RlSW5kZXggVGhlIGluZGV4IG9mIG5vZGUgdG8gYmUgZGVsZXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBkZWxldGVOb2RlKG5vZGVJbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW25vZGVJbmRleF07XG4gICAgaWYgKG5vZGUub3V0cHV0cy5sZW5ndGggPiAxKSB7XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG5vZGUub3V0cHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtub2RlLm91dHB1dHNbaV1dLnRvLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vZGUgZGVsZXRpb24gd2l0aCBtb3JlIHRoYW4gb25lIG91dHB1dCBjb25uZWN0ZWQgdG8gb3RoZXIgbm9kZXMgaXMgbm90IHN1cHBvcnRlZC4gJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB0aGlzIG5vZGUgd2lsIG5vdCBiZSBleGVjdXRlZFxuICAgIG5vZGUuZXhlY3V0ZU5vZGUgPSBmYWxzZTtcbiAgICBjb25zdCBpbnB1dFZhbHVlSW5kZXggPSBub2RlLmlucHV0c1swXTtcbiAgICBjb25zdCBvdXRwdXRWYWx1ZUluZGV4ID0gbm9kZS5vdXRwdXRzWzBdO1xuICAgIGNvbnN0IG5vZGVzQ29uc3VtaW5nT3V0cHV0ID0gdGhpcy5fYWxsRGF0YVtvdXRwdXRWYWx1ZUluZGV4XS50bztcblxuICAgIC8vIHJlbW92ZSB0aGlzIG5vZGUgZnJvbSB0aGUgdG8gcHJvcGVydHkgb2YgdGhlIGlucHV0IFZhbHVlXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2RlLmlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZGVsSW5kZXggPSB0aGlzLl9hbGxEYXRhW25vZGUuaW5wdXRzW2ldXS50by5pbmRleE9mKG5vZGVJbmRleCk7XG4gICAgICAvLyBzaG91bGQgbm90IGhhcHBlblxuICAgICAgaWYgKGRlbEluZGV4ID09PSAtMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgVmFsdWUgb2JqZWN0IGRvZXNuJ3QgaGF2ZSB0aGUgY3VycmVudCBOb2RlIGluIGl0J3MgJ3RvJyBwcm9wZXJ0eSBcIik7XG4gICAgICB9XG4gICAgICB0aGlzLl9hbGxEYXRhW25vZGUuaW5wdXRzW2ldXS50by5zcGxpY2UoZGVsSW5kZXgsIDEpO1xuICAgIH1cblxuICAgIC8vIGNsZWFyIG5vZGUgaW5kaWNlcyBjb25zdW1pbmcgdGhpcyBvdXRwdXQgVmFsdWVcbiAgICB0aGlzLl9hbGxEYXRhW291dHB1dFZhbHVlSW5kZXhdLl90byA9IFtdO1xuXG4gICAgLy8gaWYgdGhlIG91dHB1dCBvZiB0aGlzIG5vZGUgaXMgYSBncmFwaCBvdXRwdXQsIGFkanVzdCB0aGUgaW5kZXggYXBwcm9wcmlhdGVseVxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5pbmRleE9mKG91dHB1dFZhbHVlSW5kZXgpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXNbaW5kZXhdID0gaW5wdXRWYWx1ZUluZGV4O1xuICAgIH1cblxuICAgIC8vIG92ZXJyaWRlIHRoZSBpbnB1dHMgZm9yIG5vZGVzIGNvbnN1bWluZyB0aGlzIG5vZGUncyBvdXRwdXQgd2l0aCB0aGUgaW5wdXQgdG8gdGhpcyBub2RlXG4gICAgaWYgKG5vZGVzQ29uc3VtaW5nT3V0cHV0ICYmIG5vZGVzQ29uc3VtaW5nT3V0cHV0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3Qgbm9kZUluZGV4IG9mIG5vZGVzQ29uc3VtaW5nT3V0cHV0KSB7XG4gICAgICAgIGNvbnN0IHJlcGxhY2VJbmRleCA9IHRoaXMuX25vZGVzW25vZGVJbmRleF0uaW5wdXRzLmluZGV4T2Yob3V0cHV0VmFsdWVJbmRleCk7XG4gICAgICAgIC8vIHNob3VsZCBub3QgaGFwcGVuXG4gICAgICAgIGlmIChyZXBsYWNlSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIE5vZGUgb2JqZWN0IGRvZXNuJ3QgaGF2ZSB0aGUgb3V0cHV0IFZhbHVlIGluIGl0J3MgJ2lucHV0cycgcHJvcGVydHkgXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX25vZGVzW25vZGVJbmRleF0uaW5wdXRzW3JlcGxhY2VJbmRleF0gPSBpbnB1dFZhbHVlSW5kZXg7XG4gICAgICAgIHRoaXMuX2FsbERhdGFbaW5wdXRWYWx1ZUluZGV4XS50by5wdXNoKG5vZGVJbmRleCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlQWxsRHJvcG91dE5vZGVzKCkge1xuICAgIGxldCBub2RlSW5kZXggPSAwO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9ub2Rlcykge1xuICAgICAgLy8gd2VlZCBvdXQgJ0Ryb3BvdXQnIG5vZGVzIHNvIHRoYXQgbm8gdGltZSBpcyB3YXN0ZWQgaW4gZXhlY3V0aW9uXG4gICAgICBpZiAobm9kZS5vcFR5cGUgPT09ICdEcm9wb3V0Jykge1xuICAgICAgICAvLyB0aGUgbm9kZSBzaG91bGQgaGF2ZSBleGFjdGx5IDEgaW5wdXQgYW5kIDEgb3IgMiBvdXRwdXRzXG4gICAgICAgIGlmIChub2RlLmlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Ryb3BvdXQgbm9kZXMgc2hvdWxkIG9ubHkgY29udGFpbiBvbmUgaW5wdXQuICcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlLm91dHB1dHMubGVuZ3RoICE9PSAxICYmIG5vZGUub3V0cHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Ryb3BvdXQgbm9kZXMgc2hvdWxkIGNvbnRhaW4gZWl0aGVyIDEgb3IgMiBvdXRwdXQocyknKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGUgc2Vjb25kIG91dHB1dCBzaG91bGQgbm90IGJlIHJlZmVyZW5jZWQgYnkgYW55IG90aGVyIG5vZGVcbiAgICAgICAgaWYgKG5vZGUub3V0cHV0cy5sZW5ndGggPT09IDIgJiYgdGhpcy5fYWxsRGF0YVtub2RlLm91dHB1dHNbMV1dLl90by5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEcm9wb3V0IG5vZGVzJ3Mgc2Vjb25kIG91dHB1dCBzaG91bGQgbm90IGJlIHJlZmVyZW5jZWQgYnkgb3RoZXIgbm9kZXNcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZWxldGVOb2RlKG5vZGVJbmRleCk7XG4gICAgICB9XG4gICAgICBub2RlSW5kZXgrKztcbiAgICB9XG4gIH1cblxuICByZW1vdmVBbGxJZGVudGl0eU5vZGVzKCkge1xuICAgIGxldCBub2RlSW5kZXggPSAwO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9ub2Rlcykge1xuICAgICAgLy8gd2VlZCBvdXQgJ0lkZW50aXR5JyBub2RlcyBzbyB0aGF0IG5vIHRpbWUgaXMgd2FzdGVkIGluIGV4ZWN1dGlvblxuICAgICAgaWYgKG5vZGUub3BUeXBlID09PSAnSWRlbnRpdHknKSB7XG4gICAgICAgIHRoaXMuZGVsZXRlTm9kZShub2RlSW5kZXgpO1xuICAgICAgfVxuICAgICAgbm9kZUluZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgaXNBY3RpdmF0aW9uKG46IE5vZGUpOiBib29sZWFuIHtcbiAgICBzd2l0Y2ggKG4ub3BUeXBlKSB7XG4gICAgICAvLyBUT0RPOiBhZGQgb3RoZXIgYWN0aXZhdGlvbiBtZXRob2RzXG4gICAgICBjYXNlICdSZWx1JzpcbiAgICAgIGNhc2UgJ1NpZ21vaWQnOlxuICAgICAgY2FzZSAnQ2xpcCc6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGZ1c2VDb252QWN0aXZhdGlvbk5vZGVzKCkge1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9ub2Rlcykge1xuICAgICAgaWYgKG5vZGUub3BUeXBlID09PSAnQ29udicpIHtcbiAgICAgICAgY29uc3QgbmV4dCA9IHRoaXMuX2FsbERhdGFbbm9kZS5vdXRwdXRzWzBdXS5fdG87XG4gICAgICAgIGlmIChuZXh0Lmxlbmd0aCA9PT0gMSAmJiB0aGlzLmlzQWN0aXZhdGlvbih0aGlzLl9ub2Rlc1tuZXh0WzBdXSkpIHtcbiAgICAgICAgICBjb25zdCBjaGlsZCA9IHRoaXMuX25vZGVzW25leHRbMF1dO1xuICAgICAgICAgIGlmIChjaGlsZC5vcFR5cGUgPT09ICdDbGlwJykge1xuICAgICAgICAgICAgaWYgKGNoaWxkLmlucHV0cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuc2V0KCdhY3RpdmF0aW9uX3BhcmFtcycsICdmbG9hdHMnLCBbXG4gICAgICAgICAgICAgICAgICBjaGlsZC5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtaW4nKSxcbiAgICAgICAgICAgICAgICAgIGNoaWxkLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21heCcpLFxuICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuc2V0KCdhY3RpdmF0aW9uX3BhcmFtcycsICdmbG9hdHMnLCBbTUlOX0NMSVAsIE1BWF9DTElQXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIGNoaWxkLmlucHV0cy5sZW5ndGggPj0gMyAmJlxuICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1sxXV0udGVuc29yICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgdGhpcy5fYWxsRGF0YVtjaGlsZC5pbnB1dHNbMl1dLnRlbnNvciAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnNldCgnYWN0aXZhdGlvbl9wYXJhbXMnLCAnZmxvYXRzJywgW1xuICAgICAgICAgICAgICAgIHRoaXMuX2FsbERhdGFbY2hpbGQuaW5wdXRzWzFdXS50ZW5zb3IhLmZsb2F0RGF0YVswXSxcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1syXV0udGVuc29yIS5mbG9hdERhdGFbMF0sXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gU2tpcCBmdXNpb24gd2l0aCBjbGlwIG5vZGUgc2luY2UgY2xpcCBtaW4gYW5kIGNsaXAgbWF4IGFyZSBub3QgY29taW5nIGZyb20gaW5pdGlhbGl6ZXJcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb24nLCAnc3RyaW5nJywgY2hpbGQub3BUeXBlKTtcbiAgICAgICAgICB0aGlzLmRlbGV0ZU5vZGUobmV4dFswXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BTZXQgfSBmcm9tICcuL29wc2V0JztcbmltcG9ydCAqIGFzIG9ydEZicyBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQgeyBvbm54IH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHsgTG9uZ1V0aWwgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgY2xhc3MgTW9kZWwge1xuICAvLyBlbXB0eSBtb2RlbFxuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgbG9hZChidWY6IFVpbnQ4QXJyYXksIGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplciwgaXNPcnRGb3JtYXQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgbGV0IG9ubnhFcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCFpc09ydEZvcm1hdCkge1xuICAgICAgLy8gaXNPcnRGb3JtYXQgPT09IGZhbHNlIHx8IGlzT3J0Rm9ybWF0ID09PSB1bmRlZmluZWRcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMubG9hZEZyb21Pbm54Rm9ybWF0KGJ1ZiwgZ3JhcGhJbml0aWFsaXplcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGlzT3J0Rm9ybWF0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIG9ubnhFcnJvciA9IGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMubG9hZEZyb21PcnRGb3JtYXQoYnVmLCBncmFwaEluaXRpYWxpemVyKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoaXNPcnRGb3JtYXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgICAgLy8gVHJpZWQgYm90aCBmb3JtYXRzIGFuZCBmYWlsZWQgKHdoZW4gaXNPcnRGb3JtYXQgPT09IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvYWQgbW9kZWwgYXMgT05OWCBmb3JtYXQ6ICR7b25ueEVycm9yfVxcbmFzIE9SVCBmb3JtYXQ6ICR7ZX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvYWRGcm9tT25ueEZvcm1hdChidWY6IFVpbnQ4QXJyYXksIGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcik6IHZvaWQge1xuICAgIGNvbnN0IG1vZGVsUHJvdG8gPSBvbm54Lk1vZGVsUHJvdG8uZGVjb2RlKGJ1Zik7XG4gICAgY29uc3QgaXJWZXJzaW9uID0gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG1vZGVsUHJvdG8uaXJWZXJzaW9uKTtcbiAgICBpZiAoaXJWZXJzaW9uIDwgMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvbmx5IHN1cHBvcnQgT05OWCBtb2RlbCB3aXRoIElSX1ZFUlNJT04+PTMnKTtcbiAgICB9XG5cbiAgICB0aGlzLl9vcHNldHMgPSBtb2RlbFByb3RvLm9wc2V0SW1wb3J0Lm1hcCgoaSkgPT4gKHtcbiAgICAgIGRvbWFpbjogaS5kb21haW4gYXMgc3RyaW5nLFxuICAgICAgdmVyc2lvbjogTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKGkudmVyc2lvbiEpLFxuICAgIH0pKTtcblxuICAgIHRoaXMuX2dyYXBoID0gR3JhcGguZnJvbShtb2RlbFByb3RvLmdyYXBoISwgZ3JhcGhJbml0aWFsaXplcik7XG4gIH1cblxuICBwcml2YXRlIGxvYWRGcm9tT3J0Rm9ybWF0KGJ1ZjogVWludDhBcnJheSwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKTogdm9pZCB7XG4gICAgY29uc3QgZmIgPSBuZXcgZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcihidWYpO1xuICAgIGNvbnN0IG9ydE1vZGVsID0gb3J0RmJzLkluZmVyZW5jZVNlc3Npb24uZ2V0Um9vdEFzSW5mZXJlbmNlU2Vzc2lvbihmYikubW9kZWwoKSE7XG4gICAgY29uc3QgaXJWZXJzaW9uID0gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG9ydE1vZGVsLmlyVmVyc2lvbigpKTtcbiAgICBpZiAoaXJWZXJzaW9uIDwgMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvbmx5IHN1cHBvcnQgT05OWCBtb2RlbCB3aXRoIElSX1ZFUlNJT04+PTMnKTtcbiAgICB9XG4gICAgdGhpcy5fb3BzZXRzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcnRNb2RlbC5vcHNldEltcG9ydExlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IG9wc2V0SWQgPSBvcnRNb2RlbC5vcHNldEltcG9ydChpKSE7XG4gICAgICB0aGlzLl9vcHNldHMucHVzaCh7IGRvbWFpbjogb3BzZXRJZD8uZG9tYWluKCkgYXMgc3RyaW5nLCB2ZXJzaW9uOiBMb25nVXRpbC5sb25nVG9OdW1iZXIob3BzZXRJZC52ZXJzaW9uKCkhKSB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9ncmFwaCA9IEdyYXBoLmZyb20ob3J0TW9kZWwuZ3JhcGgoKSEsIGdyYXBoSW5pdGlhbGl6ZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ3JhcGg6IEdyYXBoO1xuICBnZXQgZ3JhcGgoKTogR3JhcGgge1xuICAgIHJldHVybiB0aGlzLl9ncmFwaDtcbiAgfVxuXG4gIHByaXZhdGUgX29wc2V0czogT3BTZXRbXTtcbiAgZ2V0IG9wc2V0cygpOiByZWFkb25seSBPcFNldFtdIHtcbiAgICByZXR1cm4gdGhpcy5fb3BzZXRzO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IHJlc29sdmVCYWNrZW5kLCBTZXNzaW9uSGFuZGxlclR5cGUgfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHsgRXhlY3V0aW9uUGxhbiB9IGZyb20gJy4vZXhlY3V0aW9uLXBsYW4nO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IFByb2ZpbGVyIH0gZnJvbSAnLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnLi9tb2RlbCc7XG5pbXBvcnQgeyBPcGVyYXRvciB9IGZyb20gJy4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFNlc3Npb24ge1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgYmFja2VuZEhpbnQ/OiBzdHJpbmc7XG4gICAgcHJvZmlsZXI/OiBQcm9maWxlci5Db25maWc7XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIENvbnRleHQge1xuICAgIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj47XG4gICAgZ3JhcGhJbnB1dFR5cGVzPzogVGVuc29yLkRhdGFUeXBlW107XG4gICAgZ3JhcGhJbnB1dERpbXM/OiBBcnJheTxyZWFkb25seSBudW1iZXJbXT47XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNlc3Npb24ge1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IFNlc3Npb24uQ29uZmlnID0ge30pIHtcbiAgICB0aGlzLl9pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHRoaXMuYmFja2VuZEhpbnQgPSBjb25maWcuYmFja2VuZEhpbnQ7XG4gICAgdGhpcy5wcm9maWxlciA9IFByb2ZpbGVyLmNyZWF0ZShjb25maWcucHJvZmlsZXIpO1xuICAgIHRoaXMuY29udGV4dCA9IHsgcHJvZmlsZXI6IHRoaXMucHJvZmlsZXIsIGdyYXBoSW5wdXRUeXBlczogW10sIGdyYXBoSW5wdXREaW1zOiBbXSB9O1xuICB9XG5cbiAgZ2V0IGlucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9tb2RlbC5ncmFwaC5nZXRJbnB1dE5hbWVzKCk7XG4gIH1cbiAgZ2V0IG91dHB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0T3V0cHV0TmFtZXMoKTtcbiAgfVxuXG4gIHN0YXJ0UHJvZmlsaW5nKCkge1xuICAgIHRoaXMucHJvZmlsZXIuc3RhcnQoKTtcbiAgfVxuXG4gIGVuZFByb2ZpbGluZygpIHtcbiAgICB0aGlzLnByb2ZpbGVyLnN0b3AoKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWRNb2RlbCh1cmk6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIGFzeW5jIGxvYWRNb2RlbChidWZmZXI6IEFycmF5QnVmZmVyLCBieXRlT2Zmc2V0PzogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+O1xuICBhc3luYyBsb2FkTW9kZWwoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPjtcbiAgYXN5bmMgbG9hZE1vZGVsKGFyZzogc3RyaW5nIHwgQXJyYXlCdWZmZXIgfCBVaW50OEFycmF5LCBieXRlT2Zmc2V0PzogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24ubG9hZE1vZGVsJywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gcmVzb2x2ZSBiYWNrZW5kIGFuZCBzZXNzaW9uIGhhbmRsZXJcbiAgICAgIGNvbnN0IGJhY2tlbmQgPSBhd2FpdCByZXNvbHZlQmFja2VuZCh0aGlzLmJhY2tlbmRIaW50KTtcbiAgICAgIHRoaXMuc2Vzc2lvbkhhbmRsZXIgPSBiYWNrZW5kLmNyZWF0ZVNlc3Npb25IYW5kbGVyKHRoaXMuY29udGV4dCk7XG5cbiAgICAgIHRoaXMuX21vZGVsID0gbmV3IE1vZGVsKCk7XG4gICAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgaXNPcnRGb3JtYXQgPSBhcmcuZW5kc1dpdGgoJy5vcnQnKTtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSkge1xuICAgICAgICAgIC8vIG5vZGVcbiAgICAgICAgICBjb25zdCB7IHJlYWRGaWxlIH0gPSByZXF1aXJlKCdub2RlOmZzL3Byb21pc2VzJyk7XG4gICAgICAgICAgY29uc3QgYnVmID0gYXdhaXQgcmVhZEZpbGUoYXJnKTtcbiAgICAgICAgICB0aGlzLmluaXRpYWxpemUoYnVmLCBpc09ydEZvcm1hdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gYnJvd3NlclxuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYXJnKTtcbiAgICAgICAgICBjb25zdCBidWYgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZShuZXcgVWludDhBcnJheShidWYpLCBpc09ydEZvcm1hdCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIUFycmF5QnVmZmVyLmlzVmlldyhhcmcpKSB7XG4gICAgICAgIC8vIGxvYWQgbW9kZWwgZnJvbSBBcnJheUJ1ZmZlclxuICAgICAgICBjb25zdCBhcnIgPSBuZXcgVWludDhBcnJheShhcmcsIGJ5dGVPZmZzZXQgfHwgMCwgbGVuZ3RoIHx8IGFyZy5ieXRlTGVuZ3RoKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKGFycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBsb2FkIG1vZGVsIGZyb20gVWludDhhcnJheVxuICAgICAgICB0aGlzLmluaXRpYWxpemUoYXJnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZShtb2RlbFByb3RvQmxvYjogVWludDhBcnJheSwgaXNPcnRGb3JtYXQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FscmVhZHkgaW5pdGlhbGl6ZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24uaW5pdGlhbGl6ZScsICgpID0+IHtcbiAgICAgIC8vIGxvYWQgZ3JhcGhcbiAgICAgIGNvbnN0IGdyYXBoSW5pdGlhbGl6ZXIgPSB0aGlzLnNlc3Npb25IYW5kbGVyLnRyYW5zZm9ybUdyYXBoXG4gICAgICAgID8gKHRoaXMuc2Vzc2lvbkhhbmRsZXIgYXMgR3JhcGguSW5pdGlhbGl6ZXIpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fbW9kZWwubG9hZChtb2RlbFByb3RvQmxvYiwgZ3JhcGhJbml0aWFsaXplciwgaXNPcnRGb3JtYXQpO1xuXG4gICAgICAvLyBncmFwaCBpcyBjb21wbGV0ZWx5IGluaXRpYWx6aWVkIGF0IHRoaXMgc3RhZ2UgLCBsZXQgdGhlIGludGVyZXN0ZWQgaGFuZGxlcnMga25vd1xuICAgICAgaWYgKHRoaXMuc2Vzc2lvbkhhbmRsZXIub25HcmFwaEluaXRpYWxpemVkKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbkhhbmRsZXIub25HcmFwaEluaXRpYWxpemVkKHRoaXMuX21vZGVsLmdyYXBoKTtcbiAgICAgIH1cbiAgICAgIC8vIGluaXRpYWxpemUgZWFjaCBvcGVyYXRvciBpbiB0aGUgZ3JhcGhcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZU9wcyh0aGlzLl9tb2RlbC5ncmFwaCk7XG5cbiAgICAgIC8vIGluc3RhbnRpYXRlIGFuIEV4ZWN1dGlvblBsYW4gb2JqZWN0IHRvIGJlIHVzZWQgYnkgdGhlIFNlc3Npb24gb2JqZWN0XG4gICAgICB0aGlzLl9leGVjdXRpb25QbGFuID0gbmV3IEV4ZWN1dGlvblBsYW4odGhpcy5fbW9kZWwuZ3JhcGgsIHRoaXMuX29wcywgdGhpcy5wcm9maWxlcik7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XG4gIH1cblxuICBhc3luYyBydW4oaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHwgVGVuc29yW10pOiBQcm9taXNlPE1hcDxzdHJpbmcsIFRlbnNvcj4+IHtcbiAgICBpZiAoIXRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Nlc3Npb24gbm90IGluaXRpYWxpemVkIHlldCcpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24ucnVuJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgaW5wdXRUZW5zb3JzID0gdGhpcy5ub3JtYWxpemVBbmRWYWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gICAgICBjb25zdCBvdXRwdXRUZW5zb3JzID0gYXdhaXQgdGhpcy5fZXhlY3V0aW9uUGxhbi5leGVjdXRlKHRoaXMuc2Vzc2lvbkhhbmRsZXIsIGlucHV0VGVuc29ycyk7XG5cbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU91dHB1dChvdXRwdXRUZW5zb3JzKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXplQW5kVmFsaWRhdGVJbnB1dHMoaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHwgVGVuc29yW10pOiBUZW5zb3JbXSB7XG4gICAgY29uc3QgbW9kZWxJbnB1dE5hbWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0SW5wdXROYW1lcygpO1xuXG4gICAgLy8gbm9ybWFsaXplIGlucHV0c1xuICAgIC8vIGlucHV0czogVGVuc29yW11cbiAgICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dHMpKSB7XG4gICAgICBpZiAoaW5wdXRzLmxlbmd0aCAhPT0gbW9kZWxJbnB1dE5hbWVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGluY29ycmVjdCBpbnB1dCBhcnJheSBsZW5ndGg6IGV4cGVjdGVkICR7bW9kZWxJbnB1dE5hbWVzLmxlbmd0aH0gYnV0IGdvdCAke2lucHV0cy5sZW5ndGh9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNvbnZlcnQgbWFwIHRvIGFycmF5XG4gICAgLy8gaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+XG4gICAgZWxzZSB7XG4gICAgICBpZiAoaW5wdXRzLnNpemUgIT09IG1vZGVsSW5wdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbmNvcnJlY3QgaW5wdXQgbWFwIHNpemU6IGV4cGVjdGVkICR7bW9kZWxJbnB1dE5hbWVzLmxlbmd0aH0gYnV0IGdvdCAke2lucHV0cy5zaXplfWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzb3J0ZWRJbnB1dHMgPSBuZXcgQXJyYXk8VGVuc29yPihpbnB1dHMuc2l6ZSk7XG4gICAgICBsZXQgc29ydGVkSW5wdXRzSW5kZXggPSAwO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RlbElucHV0TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3QgdGVuc29yID0gaW5wdXRzLmdldChtb2RlbElucHV0TmFtZXNbaV0pO1xuICAgICAgICBpZiAoIXRlbnNvcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBpbnB1dCB0ZW5zb3IgZm9yOiAnJHtuYW1lfSdgKTtcbiAgICAgICAgfVxuICAgICAgICBzb3J0ZWRJbnB1dHNbc29ydGVkSW5wdXRzSW5kZXgrK10gPSB0ZW5zb3I7XG4gICAgICB9XG5cbiAgICAgIGlucHV0cyA9IHNvcnRlZElucHV0cztcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSBkaW1zIHJlcXVpcmVtZW50c1xuICAgIC8vIEZpcnN0IHNlc3Npb24gcnVuIC0gZ3JhcGggaW5wdXQgZGF0YSBpcyBub3QgY2FjaGVkIGZvciB0aGUgc2Vzc2lvblxuICAgIGlmIChcbiAgICAgICF0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzIHx8XG4gICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzLmxlbmd0aCA9PT0gMCB8fFxuICAgICAgIXRoaXMuY29udGV4dC5ncmFwaElucHV0RGltcyB8fFxuICAgICAgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zLmxlbmd0aCA9PT0gMFxuICAgICkge1xuICAgICAgY29uc3QgbW9kZWxJbnB1dEluZGljZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRJbnB1dEluZGljZXMoKTtcbiAgICAgIGNvbnN0IG1vZGVsVmFsdWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0VmFsdWVzKCk7XG5cbiAgICAgIGNvbnN0IGdyYXBoSW5wdXREaW1zID0gbmV3IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPihtb2RlbElucHV0SW5kaWNlcy5sZW5ndGgpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1vZGVsSW5wdXRJbmRpY2VzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGNvbnN0IGdyYXBoSW5wdXQgPSBtb2RlbFZhbHVlc1ttb2RlbElucHV0SW5kaWNlc1tpXV07XG4gICAgICAgIGdyYXBoSW5wdXREaW1zW2ldID0gZ3JhcGhJbnB1dC50eXBlIS5zaGFwZS5kaW1zO1xuXG4gICAgICAgIC8vIGNhY2hlZCBmb3Igc2Vjb25kIGFuZCBzdWJzZXF1ZW50IHJ1bnMuXG4gICAgICAgIC8vIFNvbWUgcGFydHMgb2YgdGhlIGZyYW1ld29yayB3b3JrcyBvbiB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSBncmFwaCBhbmQgdHlwZXMgYW5kIHNoYXBlcyBhcmUgc3RhdGljXG4gICAgICAgIHRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMhLnB1c2goZ3JhcGhJbnB1dC50eXBlIS50ZW5zb3JUeXBlKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zIS5wdXNoKGlucHV0c1tpXS5kaW1zKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy52YWxpZGF0ZUlucHV0VGVuc29yRGltcyhncmFwaElucHV0RGltcywgaW5wdXRzLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvLyBTZWNvbmQgYW5kIHN1YnNlcXVlbnQgc2Vzc2lvbiBydW5zIC0gZ3JhcGggaW5wdXQgZGF0YSBpcyBjYWNoZWQgZm9yIHRoZSBzZXNzaW9uXG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnZhbGlkYXRlSW5wdXRUZW5zb3JEaW1zKHRoaXMuY29udGV4dC5ncmFwaElucHV0RGltcywgaW5wdXRzLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgLy8gdmFsaWRhdGUgdHlwZXMgcmVxdWlyZW1lbnRcbiAgICB0aGlzLnZhbGlkYXRlSW5wdXRUZW5zb3JUeXBlcyh0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzISwgaW5wdXRzKTtcblxuICAgIHJldHVybiBpbnB1dHM7XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlSW5wdXRUZW5zb3JUeXBlcyhncmFwaElucHV0VHlwZXM6IFRlbnNvci5EYXRhVHlwZVtdLCBnaXZlbklucHV0czogVGVuc29yW10pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdpdmVuSW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBncmFwaElucHV0VHlwZXNbaV07XG4gICAgICBjb25zdCBhY3R1YWxUeXBlID0gZ2l2ZW5JbnB1dHNbaV0udHlwZTtcbiAgICAgIGlmIChleHBlY3RlZFR5cGUgIT09IGFjdHVhbFR5cGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dCB0ZW5zb3JbJHtpfV0gY2hlY2sgZmFpbGVkOiBleHBlY3RlZCB0eXBlICcke2V4cGVjdGVkVHlwZX0nIGJ1dCBnb3QgJHthY3R1YWxUeXBlfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVJbnB1dFRlbnNvckRpbXMoXG4gICAgZ3JhcGhJbnB1dERpbXM6IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPixcbiAgICBnaXZlbklucHV0czogVGVuc29yW10sXG4gICAgbm9uZURpbVN1cHBvcnRlZDogYm9vbGVhbixcbiAgKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnaXZlbklucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZXhwZWN0ZWREaW1zID0gZ3JhcGhJbnB1dERpbXNbaV07XG4gICAgICBjb25zdCBhY3R1YWxEaW1zID0gZ2l2ZW5JbnB1dHNbaV0uZGltcztcbiAgICAgIGlmICghdGhpcy5jb21wYXJlVGVuc29yRGltcyhleHBlY3RlZERpbXMsIGFjdHVhbERpbXMsIG5vbmVEaW1TdXBwb3J0ZWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgaW5wdXQgdGVuc29yWyR7aX1dIGNoZWNrIGZhaWxlZDogZXhwZWN0ZWQgc2hhcGUgJ1ske2V4cGVjdGVkRGltcy5qb2luKCcsJyl9XScgYnV0IGdvdCBbJHthY3R1YWxEaW1zLmpvaW4oXG4gICAgICAgICAgICAnLCcsXG4gICAgICAgICAgKX1dYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbXBhcmVUZW5zb3JEaW1zKFxuICAgIGV4cGVjdGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgYWN0dWFsRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgbm9uZURpbVN1cHBvcnRlZDogYm9vbGVhbixcbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKGV4cGVjdGVkRGltcy5sZW5ndGggIT09IGFjdHVhbERpbXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBleHBlY3RlZERpbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChleHBlY3RlZERpbXNbaV0gIT09IGFjdHVhbERpbXNbaV0gJiYgKCFub25lRGltU3VwcG9ydGVkIHx8IGV4cGVjdGVkRGltc1tpXSAhPT0gMCkpIHtcbiAgICAgICAgLy8gZGF0YSBzaGFwZSBtaXNtYXRjaCBBTkQgbm90IGEgJ05vbmUnIGRpbWVuc2lvbi5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVPdXRwdXQob3V0cHV0VGVuc29yczogVGVuc29yW10pOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHtcbiAgICBjb25zdCBtb2RlbE91dHB1dE5hbWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0T3V0cHV0TmFtZXMoKTtcbiAgICBpZiAob3V0cHV0VGVuc29ycy5sZW5ndGggIT09IG1vZGVsT3V0cHV0TmFtZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIG51bWJlciBvZiBvdXRwdXRzIGRvIG5vdCBtYXRjaCBudW1iZXIgb2YgZ2VuZXJhdGVkIG91dHB1dHMnKTtcbiAgICB9XG5cbiAgICBjb25zdCBvdXRwdXQgPSBuZXcgTWFwPHN0cmluZywgVGVuc29yPigpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9kZWxPdXRwdXROYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgb3V0cHV0LnNldChtb2RlbE91dHB1dE5hbWVzW2ldLCBvdXRwdXRUZW5zb3JzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplT3BzKGdyYXBoOiBHcmFwaCk6IHZvaWQge1xuICAgIGNvbnN0IG5vZGVzID0gZ3JhcGguZ2V0Tm9kZXMoKTtcbiAgICB0aGlzLl9vcHMgPSBuZXcgQXJyYXkobm9kZXMubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuX29wc1tpXSA9IHRoaXMuc2Vzc2lvbkhhbmRsZXIucmVzb2x2ZShub2Rlc1tpXSwgdGhpcy5fbW9kZWwub3BzZXRzLCBncmFwaCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfbW9kZWw6IE1vZGVsO1xuICBwcml2YXRlIF9pbml0aWFsaXplZDogYm9vbGVhbjtcblxuICBwcml2YXRlIF9vcHM6IE9wZXJhdG9yW107XG4gIHByaXZhdGUgX2V4ZWN1dGlvblBsYW46IEV4ZWN1dGlvblBsYW47XG5cbiAgcHJpdmF0ZSBiYWNrZW5kSGludD86IHN0cmluZztcblxuICBwcml2YXRlIHNlc3Npb25IYW5kbGVyOiBTZXNzaW9uSGFuZGxlclR5cGU7XG4gIHByaXZhdGUgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0O1xuICBwcml2YXRlIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj47XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24sIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyLCBTZXNzaW9uSGFuZGxlciwgVGVuc29yIH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vc2Vzc2lvbic7XG5pbXBvcnQgeyBUZW5zb3IgYXMgT25ueGpzVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgY2xhc3MgT25ueGpzU2Vzc2lvbkhhbmRsZXIgaW1wbGVtZW50cyBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbikge1xuICAgIHRoaXMuaW5wdXROYW1lcyA9IHRoaXMuc2Vzc2lvbi5pbnB1dE5hbWVzO1xuICAgIHRoaXMub3V0cHV0TmFtZXMgPSB0aGlzLnNlc3Npb24ub3V0cHV0TmFtZXM7XG4gIH1cblxuICBnZXQgaW5wdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHZXR0aW5nIG1vZGVsIG1ldGFkYXRhIGlzIG5vdCBzdXBwb3J0ZWQgaW4gd2ViZ2wgYmFja2VuZC4nKTtcbiAgfVxuXG4gIGdldCBvdXRwdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHZXR0aW5nIG1vZGVsIG1ldGFkYXRhIGlzIG5vdCBzdXBwb3J0ZWQgaW4gd2ViZ2wgYmFja2VuZC4nKTtcbiAgfVxuXG4gIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7fVxuICBpbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgb3V0cHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBhc3luYyBydW4oXG4gICAgZmVlZHM6IFNlc3Npb25IYW5kbGVyLkZlZWRzVHlwZSxcbiAgICBfZmV0Y2hlczogU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUsXG4gICAgX29wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPiB7XG4gICAgY29uc3QgaW5wdXRNYXAgPSBuZXcgTWFwPHN0cmluZywgT25ueGpzVGVuc29yPigpO1xuICAgIGZvciAoY29uc3QgbmFtZSBpbiBmZWVkcykge1xuICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKGZlZWRzLCBuYW1lKSkge1xuICAgICAgICBjb25zdCBmZWVkID0gZmVlZHNbbmFtZV07XG4gICAgICAgIGlucHV0TWFwLnNldChcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIG5ldyBPbm54anNUZW5zb3IoXG4gICAgICAgICAgICBmZWVkLmRpbXMsXG4gICAgICAgICAgICBmZWVkLnR5cGUgYXMgT25ueGpzVGVuc29yLkRhdGFUeXBlLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgZmVlZC5kYXRhIGFzIE9ubnhqc1RlbnNvci5OdW1iZXJUeXBlLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IG91dHB1dE1hcCA9IGF3YWl0IHRoaXMuc2Vzc2lvbi5ydW4oaW5wdXRNYXApO1xuICAgIGNvbnN0IG91dHB1dDogU2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZSA9IHt9O1xuICAgIG91dHB1dE1hcC5mb3JFYWNoKCh0ZW5zb3IsIG5hbWUpID0+IHtcbiAgICAgIG91dHB1dFtuYW1lXSA9IG5ldyBUZW5zb3IodGVuc29yLnR5cGUsIHRlbnNvci5kYXRhLCB0ZW5zb3IuZGltcyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxuICBzdGFydFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLnNlc3Npb24uc3RhcnRQcm9maWxpbmcoKTtcbiAgfVxuICBlbmRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uLmVuZFByb2ZpbGluZygpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEJhY2tlbmQsIEluZmVyZW5jZVNlc3Npb24sIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyIH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vb25ueGpzL3Nlc3Npb24nO1xuaW1wb3J0IHsgT25ueGpzU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL29ubnhqcy9zZXNzaW9uLWhhbmRsZXItaW5mZXJlbmNlJztcblxuY2xhc3MgT25ueGpzQmFja2VuZCBpbXBsZW1lbnRzIEJhY2tlbmQge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gIGFzeW5jIGluaXQoKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIGFzeW5jIGNyZWF0ZUluZmVyZW5jZVNlc3Npb25IYW5kbGVyKFxuICAgIHBhdGhPckJ1ZmZlcjogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcj4ge1xuICAgIC8vIE5PVEU6IFNlc3Npb24uQ29uZmlnKGZyb20gb25ueC5qcykgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKGZyb21cbiAgICAvLyBvbm54cnVudGltZS1jb21tb24pLlxuICAgIC8vICAgICAgIEluIGZ1dHVyZSB3ZSBzaG91bGQgcmVtb3ZlIFNlc3Npb24uQ29uZmlnIGFuZCB1c2UgSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucy5cbiAgICAvLyAgICAgICBDdXJyZW50bHkgd2UgYWxsb3cgdGhpcyB0byBoYXBwZW4gdG8gbWFrZSB0ZXN0IHJ1bm5lciB3b3JrLlxuICAgIGNvbnN0IHNlc3Npb24gPSBuZXcgU2Vzc2lvbihvcHRpb25zIGFzIHVua25vd24gYXMgU2Vzc2lvbi5Db25maWcpO1xuXG4gICAgLy8gdHlwZXNjcmlwdCBjYW5ub3QgbWVyZ2UgbWV0aG9kIG92ZXJyaWRlIGNvcnJlY3RseSAoc28gZmFyIGluIDQuMi4zKS4gbmVlZCBpZi1lbHNlIHRvIGNhbGwgdGhlIG1ldGhvZC5cbiAgICBpZiAodHlwZW9mIHBhdGhPckJ1ZmZlciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGF3YWl0IHNlc3Npb24ubG9hZE1vZGVsKHBhdGhPckJ1ZmZlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHNlc3Npb24ubG9hZE1vZGVsKHBhdGhPckJ1ZmZlcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBPbm54anNTZXNzaW9uSGFuZGxlcihzZXNzaW9uKTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgb25ueGpzQmFja2VuZCA9IG5ldyBPbm54anNCYWNrZW5kKCk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMgKi9cblxuLy8gV2UgdXNlIFwicmVxdWlyZVwiIGluc3RlYWQgb2YgXCJpbXBvcnRcIiBoZXJlIGJlY2F1c2UgaW1wb3J0IHN0YXRlbWVudCBtdXN0IGJlIHB1dCBpbiB0b3AgbGV2ZWwuIE91ciBjdXJyZW50IGNvZGUgZG9lc1xuLy8gbm90IGFsbG93IGJ1bmRsZXIgdG8gdHJlZS1zaGFraW5nIGNvZGUgYXMgZXhwZWN0ZWQgYmVjYXVzZSBzb21lIGNvZGVzIGFyZSB0cmVhdGVkIGFzIGhhdmluZyBzaWRlIGVmZmVjdHMuXG4vLyBTbyB3ZSBpbXBvcnQgY29kZSBpbnNpZGUgdGhlIGlmLWNsYXVzZSB0byBhbGxvdyBidW5kbGVyIHJlbW92ZSB0aGUgY29kZSBzYWZlbHkuXG5cbmV4cG9ydCAqIGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5pbXBvcnQgKiBhcyBvcnQgZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcbmV4cG9ydCBkZWZhdWx0IG9ydDtcblxuaW1wb3J0IHsgcmVnaXN0ZXJCYWNrZW5kLCBlbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4vdmVyc2lvbic7XG5cbmlmICghQlVJTERfREVGUy5ESVNBQkxFX1dFQkdMKSB7XG4gIGNvbnN0IG9ubnhqc0JhY2tlbmQgPSByZXF1aXJlKCcuL2JhY2tlbmQtb25ueGpzJykub25ueGpzQmFja2VuZDtcbiAgcmVnaXN0ZXJCYWNrZW5kKCd3ZWJnbCcsIG9ubnhqc0JhY2tlbmQsIC0xMCk7XG59XG5cbmlmICghQlVJTERfREVGUy5ESVNBQkxFX0pTRVAgJiYgIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJHUFUpIHtcbiAgdGhyb3cgbmV3IEVycm9yKFxuICAgICdUaGUgY3VycmVudCBidWlsZCBpcyBzcGVjaWZpZWQgdG8gZW5hYmxlIGJvdGggSlNFUCBhbmQgV2ViR1BVIEVQLiBUaGlzIGlzIG5vdCBhIHZhbGlkIGNvbmZpZ3VyYXRpb24uICcgK1xuICAgICAgJ0pTRVAgYW5kIFdlYkdQVSBFUHMgY2Fubm90IGJlIGVuYWJsZWQgYXQgdGhlIHNhbWUgdGltZS4nLFxuICApO1xufVxuXG5pZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJOTiAmJiBCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUCAmJiBCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSB7XG4gIHRocm93IG5ldyBFcnJvcihcbiAgICAnVGhlIGN1cnJlbnQgYnVpbGQgaXMgc3BlY2lmaWVkIHRvIGVuYWJsZSBXZWJOTiBFUCB3aXRob3V0IEpTRVAgb3IgV2ViR1BVIEVQLiBUaGlzIGlzIG5vdCBhIHZhbGlkIGNvbmZpZ3VyYXRpb24uICcgK1xuICAgICAgJ1dlYk5OIEVQIHJlcXVpcmVzIGVpdGhlciBKU0VQIG9yIFdlYkdQVSBFUCB0byBiZSBlbmFibGVkLicsXG4gICk7XG59XG5cbmlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU00pIHtcbiAgY29uc3Qgd2FzbUJhY2tlbmQgPSByZXF1aXJlKCcuL2JhY2tlbmQtd2FzbScpLndhc21CYWNrZW5kO1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQIHx8ICFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR1BVKSB7XG4gICAgcmVnaXN0ZXJCYWNrZW5kKCd3ZWJncHUnLCB3YXNtQmFja2VuZCwgNSk7XG4gIH1cbiAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCTk4pIHtcbiAgICByZWdpc3RlckJhY2tlbmQoJ3dlYm5uJywgd2FzbUJhY2tlbmQsIDUpO1xuICB9XG4gIHJlZ2lzdGVyQmFja2VuZCgnY3B1Jywgd2FzbUJhY2tlbmQsIDEwKTtcbiAgcmVnaXN0ZXJCYWNrZW5kKCd3YXNtJywgd2FzbUJhY2tlbmQsIDEwKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGVudi52ZXJzaW9ucywgJ3dlYicsIHsgdmFsdWU6IHZlcnNpb24sIGVudW1lcmFibGU6IHRydWUgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8vIFRoaXMgZmlsZSBpcyBnZW5lcmF0ZWQgYnkgL2pzL3NjcmlwdHMvdXBkYXRlLXZlcnNpb24udHNcbi8vIERvIG5vdCBtb2RpZnkgZmlsZSBjb250ZW50IG1hbnVhbGx5LlxuXG5leHBvcnQgY29uc3QgdmVyc2lvbiA9ICcxLjMwLjAnO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLElBZ0JNLFVBQ0EsMEJBWU8saUJBd0NQLGdDQXdDTztBQTdHYjs7O0FBZ0JBLElBQU0sV0FBcUMsb0JBQUksSUFBRztBQUNsRCxJQUFNLDJCQUFxQyxDQUFBO0FBWXBDLElBQU0sa0JBQWtCLENBQUNBLE9BQWNDLFVBQWtCLGFBQTBCO0FBQ3hGLFVBQUlBLFlBQVcsT0FBT0EsU0FBUSxTQUFTLGNBQWMsT0FBT0EsU0FBUSxrQ0FBa0MsWUFBWTtBQUNoSCxjQUFNLGlCQUFpQixTQUFTLElBQUlELEtBQUk7QUFDeEMsWUFBSSxtQkFBbUIsUUFBVztBQUNoQyxtQkFBUyxJQUFJQSxPQUFNLEVBQUUsU0FBQUMsVUFBUyxTQUFRLENBQUU7UUFDMUMsV0FBVyxlQUFlLFdBQVcsVUFBVTtBQUU3QztRQUNGLFdBQVcsZUFBZSxhQUFhLFVBQVU7QUFDL0MsY0FBSSxlQUFlLFlBQVlBLFVBQVM7QUFDdEMsa0JBQU0sSUFBSSxNQUFNLDRCQUE0QkQsS0FBSSxvQkFB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QUFZO0FBQUEsUUFDckIsSUFBSSxZQUFZO0FBQUEsVUFDZCxJQUFJLFdBQVc7QUFBQTtBQUFBLFlBRWI7QUFBQSxZQUFHO0FBQUEsWUFBSTtBQUFBLFlBQUs7QUFBQTtBQUFBLFlBRVo7QUFBQSxZQUFHO0FBQUEsWUFBRztBQUFBLFlBQUc7QUFBQTtBQUFBLFlBR1Q7QUFBQSxZQUFHO0FBQUEsWUFBSTtBQUFBO0FBQUEsWUFFUDtBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBRztBQUFBO0FBQUEsWUFFVjtBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUc7QUFBQTtBQUFBLFlBRzlCO0FBQUEsWUFBRztBQUFBLFlBQUc7QUFBQTtBQUFBLFlBRU47QUFBQTtBQUFBLFlBRUE7QUFBQTtBQUFBLFlBRUE7QUFBQTtBQUFBLFlBRUE7QUFBQTtBQUFBLFlBRUE7QUFBQTtBQUFBLFlBRUE7QUFBQTtBQUFBLFlBR0E7QUFBQSxZQUFHO0FBQUEsWUFBRztBQUFBO0FBQUEsWUFFTjtBQUFBLFlBQUs7QUFBQSxZQUFHO0FBQUEsWUFBSTtBQUFBLFlBQUc7QUFBQTtBQUFBLFlBR2Y7QUFBQSxZQUFHO0FBQUEsWUFBSTtBQUFBO0FBQUEsWUFFUDtBQUFBLFlBQUc7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFHO0FBQUE7QUFBQSxZQUVyQjtBQUFBLFlBQUc7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBSztBQUFBLFlBQUc7QUFBQTtBQUFBLFlBRTlCO0FBQUEsWUFBRztBQUFBLFlBQUs7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFLO0FBQUEsWUFBRztBQUFBO0FBQUEsWUFFOUI7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFLO0FBQUEsWUFBSTtBQUFBLFlBQUs7QUFBQSxZQUFHO0FBQUE7QUFBQSxZQUU5QjtBQUFBLFlBQUc7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBSztBQUFBLFlBQUc7QUFBQTtBQUFBLFlBRTlCO0FBQUEsWUFBRztBQUFBLFlBQUs7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFLO0FBQUEsWUFBRztBQUFBO0FBQUEsWUFHN0M7QUFBQSxZQUFJO0FBQUEsWUFBSztBQUFBLFlBQUc7QUFBQTtBQUFBLFlBRVo7QUFBQSxZQUFHO0FBQUEsWUFBRztBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUE7QUFBQSxZQUViO0FBQUEsWUFBSTtBQUFBLFlBQUc7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFJO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBRztBQUFBLFlBQUs7QUFBQSxZQUNyRTtBQUFBLFlBQUc7QUFBQSxZQUFLO0FBQUEsWUFBSTtBQUFBLFlBQUk7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBRztBQUFBLFlBQUk7QUFBQSxZQUFJO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBRztBQUFBLFlBQUk7QUFBQSxZQUNuRTtBQUFBLFlBQUs7QUFBQTtBQUFBLFlBRUw7QUFBQSxZQUFJO0FBQUEsWUFBRztBQUFBLFlBQUc7QUFBQSxZQUFLO0FBQUEsWUFBSTtBQUFBLFlBQUc7QUFBQSxZQUFLO0FBQUEsWUFBSTtBQUFBLFlBQUc7QUFBQSxZQUFLO0FBQUEsWUFBSTtBQUFBLFlBQUk7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQ3JFO0FBQUEsWUFBRztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBSTtBQUFBLFlBQUs7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBSTtBQUFBLFlBQUk7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBSTtBQUFBLFlBQ25FO0FBQUEsWUFBSztBQUFBO0FBQUEsWUFFTDtBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBRztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBRztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBRztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBSTtBQUFBLFlBQUs7QUFBQSxZQUFLO0FBQUEsWUFBSTtBQUFBLFlBQUc7QUFBQSxZQUFLO0FBQUEsWUFDckU7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFJO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFLO0FBQUEsWUFBSTtBQUFBLFlBQUc7QUFBQSxZQUFJO0FBQUEsWUFBSTtBQUFBLFlBQUs7QUFBQSxZQUFLO0FBQUEsWUFBSTtBQUFBLFlBQUc7QUFBQSxZQUFJO0FBQUEsWUFDbkU7QUFBQSxZQUFLO0FBQUE7QUFBQSxZQUVMO0FBQUEsWUFBSTtBQUFBLFlBQUc7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFHO0FBQUEsWUFBSztBQUFBLFlBQUk7QUFBQSxZQUFJO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBRztBQUFBLFlBQUs7QUFBQSxZQUNyRTtBQUFBLFlBQUc7QUFBQSxZQUFLO0FBQUEsWUFBSTtBQUFBLFlBQUk7QUFBQSxZQUFLO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBRztBQUFBLFlBQUk7QUFBQSxZQUFJO0FBQUEsWUFBSztBQUFBLFlBQUs7QUFBQSxZQUFJO0FBQUEsWUFBRztBQUFBLFlBQUk7QUFBQSxZQUNuRTtBQUFBLFlBQUs7QUFBQTtBQUFBLFlBRUw7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O0FBQUEsZ0JBQUc7QUFBQTtBQUFBLGdCQUVyQjtBQUFBLGdCQUFHO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSztBQUFBLGdCQUFHO0FBQUE7QUFBQSxnQkFFOUI7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQUs7QUFBQSxnQkFBRztBQUFBO0FBQUEsZ0JBRTlCO0FBQUEsZ0JBQUc7QUFBQSxnQkFBSztBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUc7QUFBQTtBQUFBLGdCQUU5QjtBQUFBLGdCQUFHO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSztBQUFBLGdCQUFHO0FBQUE7QUFBQSxnQkFFOUI7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBRztBQUFBO0FBQUEsZ0JBRTdDO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSztBQUFBLGdCQUFHO0FBQUE7QUFBQSxnQkFFWjtBQUFBLGdCQUFHO0FBQUEsZ0JBQUc7QUFBQSxnQkFBSTtBQUFBLGdCQUFHO0FBQUE7QUFBQSxnQkFFYjtBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSTtBQUFBLGdCQUFHO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBSTtBQUFBLGdCQUFJO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUE7QUFBQSxnQkFFWjtBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSTtBQUFBLGdCQUFHO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBSTtBQUFBLGdCQUFJO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUE7QUFBQSxnQkFFWjtBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSTtBQUFBLGdCQUFHO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBSTtBQUFBLGdCQUFJO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUE7QUFBQSxnQkFFWjtBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSTtBQUFBLGdCQUFHO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBSTtBQUFBLGdCQUFJO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUE7QUFBQSxnQkFFWjtBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSTtBQUFBLGdCQUFHO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEsZ0JBQUk7QUFBQSxnQkFBSTtBQUFBLGdCQUFLO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQUc7QUFBQSxnQkFBSTtBQUFBLGdCQUFJO0FBQUEsZ0JBQUs7QUFBQSxnQkFBSztBQUFBLGdCQUFJO0FBQUEsZ0JBQ2hFO0FBQUEsZ0JBQUk7QUFBQSxnQkFBRztBQUFBLGdCQUFLO0FBQUEs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UUFDdEM7QUFFQSxlQUFPLElBQUkscUJBQXFCLE9BQU87QUFBQSxNQUN6QztBQUFBLElBQ0Y7QUFFTyxJQUFNLGdCQUFnQixJQUFJLGNBQWM7QUFBQTtBQUFBOzs7QUN4Qi9DO0FBQ0E7QUFHQTs7O0FDUE8sSUFBTUMsV0FBVTs7O0FES3ZCLElBQU8sZ0JBQVE7QUFLZixJQUFJLE1BQTJCO0FBQzdCLFFBQU1DLGlCQUFnQiw4REFBNEI7QUFDbEQsa0JBQWdCLFNBQVNBLGdCQUFlLEdBQUc7QUFDN0M7QUFFQSxJQUFJLE9BQXdEO0FBQzFELFFBQU0sSUFBSTtBQUFBLElBQ1I7QUFBQSxFQUVGO0FBQ0Y7QUFFQSxJQUFJLE9BQW1GO0FBQ3JGLFFBQU0sSUFBSTtBQUFBLElBQ1I7QUFBQSxFQUVGO0FBQ0Y7QUFFQSxJQUFJLE9BQTBCO0FBQzVCLFFBQU0sY0FBYyxLQUEwQjtBQUM5QyxNQUFnQyxPQUE0QjtBQUMxRCxvQkFBZ0IsVUFBVSxhQUFhLENBQUM7QUFBQSxFQUMxQztBQUNBLE1BQUksT0FBMkI7QUFDN0Isb0JBQWdCLFNBQVMsYUFBYSxDQUFDO0FBQUEsRUFDekM7QUFDQSxrQkFBZ0IsT0FBTyxhQUFhLEVBQUU7QUFDdEMsa0JBQWdCLFFBQVEsYUFBYSxFQUFFO0FBQ3pDO0FBRUEsT0FBTyxlQUFlQyxLQUFJLFVBQVUsT0FBTyxFQUFFLE9BQU9DLFVBQVMsWUFBWSxLQUFLLENBQUM7IiwKICAibmFtZXMiOiBbIm5hbWUiLCAiYmFja2VuZCIsICJpIiwgImVudiIsICJjcmVhdGVDYW52YXMiLCAiVGVuc29yIiwgIlRlbnNvciIsICJuYW1lIiwgImJhY2tlbmQiLCAiSW5mZXJlbmNlU2Vzc2lvbiIsICJJbmZlcmVuY2VTZXNzaW9uIiwgIlRlbnNvciIsICJlbnYiLCAibG9nIiwgImVudiIsICJuYW1lIiwgInZlcnNpb24iLCAiR3VpZCIsICJjYWNoZSIsICJkaXYiLCAibG9nMiIsICJBcmdUeXBlIiwgIkVuY29kaW5nIiwgIkJ5dGVCdWZmZXIiLCAibyIsICJmbGF0YnVmZmVycyIsICJBdHRyaWJ1dGVUeXBlIiwgIk5vZGVUeXBlIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAiRWRnZUVuZCIsICJvIiwgImZsYXRidWZmZXJzIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAibyIsICJmbGF0YnVmZmVycyIsICJvIiwgImZsYXRidWZmZXJzIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAiVGVuc29yRGF0YVR5cGUiLCAibyIsICJmbGF0YnVmZmVycyIsICJvIiwgImZsYXRidWZmZXJzIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAibyIsICJmbGF0YnVmZmVycyIsICJEaW1lbnNpb25WYWx1ZVR5cGUiLCAibyIsICJmbGF0YnVmZmVycyIsICJvIiwgImZsYXRidWZmZXJzIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAibyIsICJmbGF0YnVmZmVycyIsICJUeXBlSW5mb1ZhbHVlIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAibyIsICJmbGF0YnVmZmVycyIsICJvIiwgImZsYXRidWZmZXJzIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAibyIsICJmbGF0YnVmZmVycyIsICJvIiwgImZsYXRidWZmZXJzIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAibyIsICJmbGF0YnVmZmVycyIsICJvIiwgImZsYXRidWZmZXJzIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAibyIsICJmbGF0YnVmZmVycyIsICJvIiwgImZsYXRidWZmZXJzIiwgIm8iLCAiZmxhdGJ1ZmZlcnMiLCAibyIsICJmbGF0YnVmZmVycyIsICJvIiwgImZsYXRidWZmZXJzIiwgImltcG9ydF90ZW5zb3IiLCAicGFyYW1zIiwgIm9mZnNldCIsICJpIiwgImV4cG9ydHMiLCAic2xpY2UiLCAic2l6ZSIsICJmcm9tTnVtYmVyIiwgInRvTnVtYmVyIiwgImdsb2JhbCIsICJleHBvcnRzIiwgIndhc20iLCAiTG9uZyIsICJpc0xvbmciLCAiY3R6MzIiLCAiSU5UX0NBQ0hFIiwgIlVJTlRfQ0FDSEUiLCAiZnJvbUludCIsICJjYWNoZSIsICJmcm9tQml0cyIsICJmcm9tTnVtYmVyIiwgIlVaRVJPIiwgIlpFUk8iLCAiVFdPX1BXUl82NF9EQkwiLCAiTUFYX1VOU0lHTkVEX1ZBTFVFIiwgIlRXT19QV1JfNjNfREJMIiwgIk1JTl9WQUxVRSIsICJNQVhfVkFMVUUiLCAiVFdPX1BXUl8zMl9EQkwiLCAicG93X2RibCIsICJmcm9tU3RyaW5nIiwgImZyb21WYWx1ZSIsICJUV09fUFdSXzE2X0RCTCIsICJUV09fUFdSXzI0X0RCTCIsICJUV09fUFdSXzI0IiwgIk9ORSIsICJVT05FIiwgIk5FR19PTkUiLCAiTG9uZ1Byb3RvdHlwZSIsICJ0b0ludCIsICJ0b051bWJlciIsICJ0b1N0cmluZyIsICJkaXYiLCAiZ2V0SGlnaEJpdHMiLCAiZ2V0SGlnaEJpdHNVbnNpZ25lZCIsICJnZXRMb3dCaXRzIiwgImdldExvd0JpdHNVbnNpZ25lZCIsICJnZXROdW1CaXRzQWJzIiwgImlzU2FmZUludGVnZXIiLCAiaXNaZXJvIiwgImlzTmVnYXRpdmUiLCAiaXNQb3NpdGl2ZSIsICJpc09kZCIsICJpc0V2ZW4iLCAiZXF1YWxzIiwgIm5vdEVxdWFscyIsICJsZXNzVGhhbiIsICJsZXNzVGhhbk9yRXF1YWwiLCAiZ3JlYXRlclRoYW4iLCAiZ3JlYXRlclRoYW5PckVxdWFsIiwgImNvbXBhcmUiLCAibmVnYXRlIiwgImFkZCIsICJzdWJ0cmFjdCIsICJtdWx0aXBseSIsICJkaXZpZGUiLCAibG9nMiIsICJtb2R1bG8iLCAibm90IiwgImNvdW50TGVhZGluZ1plcm9zIiwgImNvdW50VHJhaWxpbmdaZXJvcyIsICJhbmQiLCAib3IiLCAieG9yIiwgInNoaWZ0TGVmdCIsICJzaGlmdFJpZ2h0IiwgInNoaWZ0UmlnaHRVbnNpZ25lZCIsICJyb3RhdGVMZWZ0IiwgInJvdGF0ZVJpZ2h0IiwgInRvU2lnbmVkIiwgInRvVW5zaWduZWQiLCAidG9CeXRlcyIsICJ0b0J5dGVzTEUiLCAidG9CeXRlc0JFIiwgImZyb21CeXRlcyIsICJmcm9tQnl0ZXNMRSIsICJmcm9tQnl0ZXNCRSIsICJCdWZmZXIiLCAiTG9uZyIsICJuYW1lIiwgImkiLCAiY3JlYXRlIiwgImNyZWF0ZV9hcnJheSIsICJjcmVhdGUiLCAiYnVmZmVyIiwgInNlbGYiLCAiZXJyIiwgInJlcXVpcmVfbWluaW1hbCIsICJvbm54IiwgIkRpbWVuc2lvbiIsICJUZW5zb3IiLCAiTWFwIiwgIlNwYXJzZVRlbnNvciIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAic2hhcGUiLCAic3BsaXQiLCAiaW1wb3J0X29ubngiLCAiVGVuc29yIiwgImluaXRfdGVuc29yIiwgImNhY2hlIiwgInZlcnNpb24iLCAibmFtZSIsICJzaGFwZSIsICJzaGFwZSIsICJzaGFwZSIsICJpbml0X3RlbnNvciIsICJzaGFwZSIsICJUZW5zb3IiLCAibmFtZSIsICJuYW1lIiwgIm5hbWUiLCAiYWRkIiwgImFuZCIsICJvciIsICJ4b3IiLCAiZ2xzbCIsICJzaGFkZXJTb3VyY2UiLCAidmFsaWRhdGVJbnB1dHMiLCAic2hpZnQiLCAidmFsaWRhdGVJbnB1dHMiLCAibmFtZSIsICJsb2ciLCAibm90IiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgIm5hbWUiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAic2hhcGUiLCAidmFsaWRhdGVJbnB1dHMiLCAic3VtIiwgInZhbGlkYXRlSW5wdXRzIiwgIm5hbWUiLCAiaW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgImRpbSIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAic3BsaXQiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHNWMTMiLCAiYWRkIiwgImFuZCIsICJsb2ciLCAibm90IiwgIm9yIiwgInhvciIsICJuYW1lIiwgInNoYXBlIiwgInNoYXBlIiwgIm5hbWUiLCAic291cmNlIiwgInBhY2tlZFNhbXBsZXIiLCAidGV4TnVtUiIsICJ0ZXhOdW1DIiwgInRyYW5zcG9zZSIsICJuYW1lIiwgInNoYXBlIiwgImkiLCAibmFtZSIsICJuYW1lIiwgImVudiIsICJuYW1lIiwgInRleHR1cmUiLCAiYmFja2VuZCIsICJ2ZXJzaW9uIiwgImVudiIsICJlbnYiLCAiY2FjaGUiLCAiYmFja2VuZCIsICJpbml0X2JhY2tlbmQiLCAib3V0cHV0IiwgImltcG9ydF9vbm54IiwgIkF0dHJpYnV0ZSIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAidmFsdWUiLCAiaW1wb3J0X29ubngiLCAiR3JhcGgiLCAiTm9kZSIsICJpbml0X3RlbnNvciIsICJuYW1lIiwgIkF0dHJpYnV0ZSIsICJUZW5zb3IiLCAic2hhcGUiLCAibm9kZUluZGV4IiwgImltcG9ydF9vbm54IiwgIk1vZGVsIiwgIkdyYXBoIiwgImluaXRfYmFja2VuZCIsICJiYWNrZW5kIiwgIk1vZGVsIiwgImluaXRfdGVuc29yIiwgIm5hbWUiLCAiVGVuc29yIiwgInZlcnNpb24iLCAib25ueGpzQmFja2VuZCIsICJlbnYiLCAidmVyc2lvbiJdCn0K