diff --git "a/dist/ort.all.js" "b/dist/ort.all.js" new file mode 100755--- /dev/null +++ "b/dist/ort.all.js" @@ -0,0 +1,40380 @@ +/*! + * ONNX Runtime Web v1.23.0 + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ +"use strict"; +var ort = (() => { + 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) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; + }; + var __commonJS = (cb, mod2) => function __require2() { + return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; + }; + var __export = (target, all) => { + for (var name2 in all) + __defProp(target, name2, { get: all[name2], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, + mod2 + )); + var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2); + + // web/node_modules/onnxruntime-common/dist/esm/backend-impl.js + var backends, backendsSortedByPriority, registerBackend, tryResolveAndInitializeBackend, resolveBackendAndExecutionProviders; + var init_backend_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/backend-impl.js"() { + backends = /* @__PURE__ */ new Map(); + backendsSortedByPriority = []; + registerBackend = (name2, backend2, priority) => { + if (backend2 && typeof backend2.init === "function" && typeof backend2.createInferenceSessionHandler === "function") { + const currentBackend = backends.get(name2); + if (currentBackend === void 0) { + backends.set(name2, { backend: backend2, priority }); + } else if (currentBackend.priority > priority) { + return; + } else if (currentBackend.priority === priority) { + if (currentBackend.backend !== backend2) { + throw new Error(`cannot register backend "${name2}" using priority ${priority}`); + } + } + if (priority >= 0) { + const i = backendsSortedByPriority.indexOf(name2); + if (i !== -1) { + backendsSortedByPriority.splice(i, 1); + } + for (let i2 = 0; i2 < backendsSortedByPriority.length; i2++) { + if (backends.get(backendsSortedByPriority[i2]).priority <= priority) { + backendsSortedByPriority.splice(i2, 0, name2); + return; + } + } + backendsSortedByPriority.push(name2); + } + return; + } + throw new TypeError("not a valid backend"); + }; + tryResolveAndInitializeBackend = async (backendName) => { + const backendInfo = backends.get(backendName); + if (!backendInfo) { + return "backend not found."; + } + if (backendInfo.initialized) { + return backendInfo.backend; + } else if (backendInfo.aborted) { + return backendInfo.error; + } else { + const isInitializing = !!backendInfo.initPromise; + try { + if (!isInitializing) { + backendInfo.initPromise = backendInfo.backend.init(backendName); + } + await backendInfo.initPromise; + backendInfo.initialized = true; + return backendInfo.backend; + } catch (e) { + if (!isInitializing) { + backendInfo.error = `${e}`; + backendInfo.aborted = true; + } + return backendInfo.error; + } finally { + delete backendInfo.initPromise; + } + } + }; + resolveBackendAndExecutionProviders = async (options) => { + const eps = options.executionProviders || []; + const backendHints = eps.map((i) => typeof i === "string" ? i : i.name); + const backendNames = backendHints.length === 0 ? backendsSortedByPriority : backendHints; + let backend2; + const errors = []; + const availableBackendNames = /* @__PURE__ */ new Set(); + for (const backendName of backendNames) { + const resolveResult = await tryResolveAndInitializeBackend(backendName); + if (typeof resolveResult === "string") { + errors.push({ name: backendName, err: resolveResult }); + } else { + if (!backend2) { + backend2 = resolveResult; + } + if (backend2 === resolveResult) { + availableBackendNames.add(backendName); + } + } + } + if (!backend2) { + throw new Error(`no available backend found. ERR: ${errors.map((e) => `[${e.name}] ${e.err}`).join(", ")}`); + } + for (const { name: name2, err } of errors) { + if (backendHints.includes(name2)) { + console.warn(`removing requested execution provider "${name2}" from session options because it is not available: ${err}`); + } + } + const filteredEps = eps.filter((i) => availableBackendNames.has(typeof i === "string" ? i : i.name)); + return [ + backend2, + new Proxy(options, { + get: (target, prop) => { + if (prop === "executionProviders") { + return filteredEps; + } + return Reflect.get(target, prop); + } + }) + ]; + }; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/backend.js + var init_backend = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/backend.js"() { + init_backend_impl(); + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/version.js + var version; + var init_version = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/version.js"() { + version = "1.23.0"; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/env-impl.js + var logLevelValue, env; + var init_env_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/env-impl.js"() { + init_version(); + logLevelValue = "warning"; + env = { + wasm: {}, + webgl: {}, + webgpu: {}, + versions: { common: version }, + set logLevel(value) { + if (value === void 0) { + return; + } + if (typeof value !== "string" || ["verbose", "info", "warning", "error", "fatal"].indexOf(value) === -1) { + throw new Error(`Unsupported logging level: ${value}`); + } + logLevelValue = value; + }, + get logLevel() { + return logLevelValue; + } + }; + Object.defineProperty(env, "logLevel", { enumerable: true }); + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/env.js + var env2; + var init_env = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/env.js"() { + init_env_impl(); + env2 = env; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/tensor-conversion-impl.js + var tensorToDataURL, tensorToImageData; + var init_tensor_conversion_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-conversion-impl.js"() { + tensorToDataURL = (tensor, options) => { + const canvas = typeof document !== "undefined" ? document.createElement("canvas") : new OffscreenCanvas(1, 1); + canvas.width = tensor.dims[3]; + canvas.height = tensor.dims[2]; + const pixels2DContext = canvas.getContext("2d"); + if (pixels2DContext != null) { + let width; + let height; + if (options?.tensorLayout !== void 0 && options.tensorLayout === "NHWC") { + width = tensor.dims[2]; + height = tensor.dims[3]; + } else { + width = tensor.dims[3]; + height = tensor.dims[2]; + } + const inputformat = options?.format !== void 0 ? options.format : "RGB"; + const norm = options?.norm; + let normMean; + let normBias; + if (norm === void 0 || norm.mean === void 0) { + normMean = [255, 255, 255, 255]; + } else { + if (typeof norm.mean === "number") { + normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; + } else { + normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 0]; + if (norm.mean[3] !== void 0) { + normMean[3] = norm.mean[3]; + } + } + } + if (norm === void 0 || norm.bias === void 0) { + normBias = [0, 0, 0, 0]; + } else { + if (typeof norm.bias === "number") { + normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; + } else { + normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0]; + if (norm.bias[3] !== void 0) { + normBias[3] = norm.bias[3]; + } + } + } + const stride = height * width; + let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; + if (inputformat === "RGBA") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + aTensorPointer = stride * 3; + } else if (inputformat === "RGB") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + } else if (inputformat === "RBG") { + rTensorPointer = 0; + bTensorPointer = stride; + gTensorPointer = stride * 2; + } + for (let i = 0; i < height; i++) { + for (let j = 0; j < width; j++) { + const R = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; + const G = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; + const B = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; + const A = aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; + pixels2DContext.fillStyle = "rgba(" + R + "," + G + "," + B + "," + A + ")"; + pixels2DContext.fillRect(j, i, 1, 1); + } + } + if ("toDataURL" in canvas) { + return canvas.toDataURL(); + } else { + throw new Error("toDataURL is not supported"); + } + } else { + throw new Error("Can not access image data"); + } + }; + tensorToImageData = (tensor, options) => { + const pixels2DContext = typeof document !== "undefined" ? document.createElement("canvas").getContext("2d") : new OffscreenCanvas(1, 1).getContext("2d"); + let image; + if (pixels2DContext != null) { + let width; + let height; + let channels; + if (options?.tensorLayout !== void 0 && options.tensorLayout === "NHWC") { + width = tensor.dims[2]; + height = tensor.dims[1]; + channels = tensor.dims[3]; + } else { + width = tensor.dims[3]; + height = tensor.dims[2]; + channels = tensor.dims[1]; + } + const inputformat = options !== void 0 ? options.format !== void 0 ? options.format : "RGB" : "RGB"; + const norm = options?.norm; + let normMean; + let normBias; + if (norm === void 0 || norm.mean === void 0) { + normMean = [255, 255, 255, 255]; + } else { + if (typeof norm.mean === "number") { + normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; + } else { + normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 255]; + if (norm.mean[3] !== void 0) { + normMean[3] = norm.mean[3]; + } + } + } + if (norm === void 0 || norm.bias === void 0) { + normBias = [0, 0, 0, 0]; + } else { + if (typeof norm.bias === "number") { + normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; + } else { + normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0]; + if (norm.bias[3] !== void 0) { + normBias[3] = norm.bias[3]; + } + } + } + const stride = height * width; + if (options !== void 0) { + if (options.format !== void 0 && channels === 4 && options.format !== "RGBA" || channels === 3 && options.format !== "RGB" && options.format !== "BGR") { + throw new Error("Tensor format doesn't match input tensor dims"); + } + } + const step = 4; + let rImagePointer = 0, gImagePointer = 1, bImagePointer = 2, aImagePointer = 3; + let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; + if (inputformat === "RGBA") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + aTensorPointer = stride * 3; + } else if (inputformat === "RGB") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + } else if (inputformat === "RBG") { + rTensorPointer = 0; + bTensorPointer = stride; + gTensorPointer = stride * 2; + } + image = pixels2DContext.createImageData(width, height); + for (let i = 0; i < height * width; rImagePointer += step, gImagePointer += step, bImagePointer += step, aImagePointer += step, i++) { + image.data[rImagePointer] = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; + image.data[gImagePointer] = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; + image.data[bImagePointer] = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; + image.data[aImagePointer] = aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; + } + } else { + throw new Error("Can not access image data"); + } + return image; + }; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/tensor-factory-impl.js + var bufferToTensor, tensorFromImage, tensorFromTexture, tensorFromGpuBuffer, tensorFromMLTensor, tensorFromPinnedBuffer; + var init_tensor_factory_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-factory-impl.js"() { + init_tensor_impl(); + bufferToTensor = (buffer, options) => { + if (buffer === void 0) { + throw new Error("Image buffer must be defined"); + } + if (options.height === void 0 || options.width === void 0) { + throw new Error("Image height and width must be defined"); + } + if (options.tensorLayout === "NHWC") { + throw new Error("NHWC Tensor layout is not supported yet"); + } + const { height, width } = options; + const norm = options.norm ?? { mean: 255, bias: 0 }; + let normMean; + let normBias; + if (typeof norm.mean === "number") { + normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; + } else { + normMean = [norm.mean[0], norm.mean[1], norm.mean[2], norm.mean[3] ?? 255]; + } + if (typeof norm.bias === "number") { + normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; + } else { + normBias = [norm.bias[0], norm.bias[1], norm.bias[2], norm.bias[3] ?? 0]; + } + const inputformat = options.format !== void 0 ? options.format : "RGBA"; + const outputformat = options.tensorFormat !== void 0 ? options.tensorFormat !== void 0 ? options.tensorFormat : "RGB" : "RGB"; + const stride = height * width; + const float32Data = outputformat === "RGBA" ? new Float32Array(stride * 4) : new Float32Array(stride * 3); + let step = 4, rImagePointer = 0, gImagePointer = 1, bImagePointer = 2, aImagePointer = 3; + let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; + if (inputformat === "RGB") { + step = 3; + rImagePointer = 0; + gImagePointer = 1; + bImagePointer = 2; + aImagePointer = -1; + } + if (outputformat === "RGBA") { + aTensorPointer = stride * 3; + } else if (outputformat === "RBG") { + rTensorPointer = 0; + bTensorPointer = stride; + gTensorPointer = stride * 2; + } else if (outputformat === "BGR") { + bTensorPointer = 0; + gTensorPointer = stride; + rTensorPointer = stride * 2; + } + for (let i = 0; i < stride; i++, rImagePointer += step, bImagePointer += step, gImagePointer += step, aImagePointer += step) { + float32Data[rTensorPointer++] = (buffer[rImagePointer] + normBias[0]) / normMean[0]; + float32Data[gTensorPointer++] = (buffer[gImagePointer] + normBias[1]) / normMean[1]; + float32Data[bTensorPointer++] = (buffer[bImagePointer] + normBias[2]) / normMean[2]; + if (aTensorPointer !== -1 && aImagePointer !== -1) { + float32Data[aTensorPointer++] = (buffer[aImagePointer] + normBias[3]) / normMean[3]; + } + } + const outputTensor = outputformat === "RGBA" ? new Tensor("float32", float32Data, [1, 4, height, width]) : new Tensor("float32", float32Data, [1, 3, height, width]); + return outputTensor; + }; + tensorFromImage = async (image, options) => { + const isHTMLImageEle = typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement; + const isImageDataEle = typeof ImageData !== "undefined" && image instanceof ImageData; + const isImageBitmap = typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap; + const isString = typeof image === "string"; + let data; + let bufferToTensorOptions = options ?? {}; + const createCanvas2 = () => { + if (typeof document !== "undefined") { + return document.createElement("canvas"); + } else if (typeof OffscreenCanvas !== "undefined") { + return new OffscreenCanvas(1, 1); + } else { + throw new Error("Canvas is not supported"); + } + }; + const createCanvasContext = (canvas) => { + if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) { + return canvas.getContext("2d"); + } else if (canvas instanceof OffscreenCanvas) { + return canvas.getContext("2d"); + } else { + return null; + } + }; + if (isHTMLImageEle) { + const canvas = createCanvas2(); + canvas.width = image.width; + canvas.height = image.height; + const pixels2DContext = createCanvasContext(canvas); + if (pixels2DContext != null) { + let height = image.height; + let width = image.width; + if (options !== void 0 && options.resizedHeight !== void 0 && options.resizedWidth !== void 0) { + height = options.resizedHeight; + width = options.resizedWidth; + } + if (options !== void 0) { + bufferToTensorOptions = options; + if (options.tensorFormat !== void 0) { + throw new Error("Image input config format must be RGBA for HTMLImageElement"); + } else { + bufferToTensorOptions.tensorFormat = "RGBA"; + } + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + } else { + bufferToTensorOptions.tensorFormat = "RGBA"; + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + } + pixels2DContext.drawImage(image, 0, 0); + data = pixels2DContext.getImageData(0, 0, width, height).data; + } else { + throw new Error("Can not access image data"); + } + } else if (isImageDataEle) { + let height; + let width; + if (options !== void 0 && options.resizedWidth !== void 0 && options.resizedHeight !== void 0) { + height = options.resizedHeight; + width = options.resizedWidth; + } else { + height = image.height; + width = image.width; + } + if (options !== void 0) { + bufferToTensorOptions = options; + } + bufferToTensorOptions.format = "RGBA"; + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + if (options !== void 0) { + const tempCanvas = createCanvas2(); + tempCanvas.width = width; + tempCanvas.height = height; + const pixels2DContext = createCanvasContext(tempCanvas); + if (pixels2DContext != null) { + pixels2DContext.putImageData(image, 0, 0); + data = pixels2DContext.getImageData(0, 0, width, height).data; + } else { + throw new Error("Can not access image data"); + } + } else { + data = image.data; + } + } else if (isImageBitmap) { + if (options === void 0) { + throw new Error("Please provide image config with format for Imagebitmap"); + } + const canvas = createCanvas2(); + canvas.width = image.width; + canvas.height = image.height; + const pixels2DContext = createCanvasContext(canvas); + if (pixels2DContext != null) { + const height = image.height; + const width = image.width; + pixels2DContext.drawImage(image, 0, 0, width, height); + data = pixels2DContext.getImageData(0, 0, width, height).data; + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + return bufferToTensor(data, bufferToTensorOptions); + } else { + throw new Error("Can not access image data"); + } + } else if (isString) { + return new Promise((resolve, reject) => { + const canvas = createCanvas2(); + const context = createCanvasContext(canvas); + if (!image || !context) { + return reject(); + } + const newImage = new Image(); + newImage.crossOrigin = "Anonymous"; + newImage.src = image; + newImage.onload = () => { + canvas.width = newImage.width; + canvas.height = newImage.height; + context.drawImage(newImage, 0, 0, canvas.width, canvas.height); + const img = context.getImageData(0, 0, canvas.width, canvas.height); + bufferToTensorOptions.height = canvas.height; + bufferToTensorOptions.width = canvas.width; + resolve(bufferToTensor(img.data, bufferToTensorOptions)); + }; + }); + } else { + throw new Error("Input data provided is not supported - aborted tensor creation"); + } + if (data !== void 0) { + return bufferToTensor(data, bufferToTensorOptions); + } else { + throw new Error("Input data provided is not supported - aborted tensor creation"); + } + }; + tensorFromTexture = (texture, options) => { + const { width, height, download, dispose } = options; + const dims = [1, height, width, 4]; + return new Tensor({ location: "texture", type: "float32", texture, dims, download, dispose }); + }; + tensorFromGpuBuffer = (gpuBuffer, options) => { + const { dataType, dims, download, dispose } = options; + return new Tensor({ location: "gpu-buffer", type: dataType ?? "float32", gpuBuffer, dims, download, dispose }); + }; + tensorFromMLTensor = (mlTensor, options) => { + const { dataType, dims, download, dispose } = options; + return new Tensor({ location: "ml-tensor", type: dataType ?? "float32", mlTensor, dims, download, dispose }); + }; + tensorFromPinnedBuffer = (type, buffer, dims) => new Tensor({ location: "cpu-pinned", type, data: buffer, dims: dims ?? [buffer.length] }); + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/tensor-impl-type-mapping.js + var NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP, NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP, isTypedArrayChecked, checkTypedArray; + var init_tensor_impl_type_mapping = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-impl-type-mapping.js"() { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP = /* @__PURE__ */ new Map([ + ["float32", Float32Array], + ["uint8", Uint8Array], + ["int8", Int8Array], + ["uint16", Uint16Array], + ["int16", Int16Array], + ["int32", Int32Array], + ["bool", Uint8Array], + ["float64", Float64Array], + ["uint32", Uint32Array], + ["int4", Uint8Array], + ["uint4", Uint8Array] + ]); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP = /* @__PURE__ */ new Map([ + [Float32Array, "float32"], + [Uint8Array, "uint8"], + [Int8Array, "int8"], + [Uint16Array, "uint16"], + [Int16Array, "int16"], + [Int32Array, "int32"], + [Float64Array, "float64"], + [Uint32Array, "uint32"] + ]); + isTypedArrayChecked = false; + checkTypedArray = () => { + if (!isTypedArrayChecked) { + isTypedArrayChecked = true; + const isBigInt64ArrayAvailable = typeof BigInt64Array !== "undefined" && BigInt64Array.from; + const isBigUint64ArrayAvailable = typeof BigUint64Array !== "undefined" && BigUint64Array.from; + const Float16Array2 = globalThis.Float16Array; + const isFloat16ArrayAvailable = typeof Float16Array2 !== "undefined" && Float16Array2.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", Float16Array2); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(Float16Array2, "float16"); + } else { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("float16", Uint16Array); + } + } + }; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/tensor-utils-impl.js + var calculateSize, tensorReshape; + var init_tensor_utils_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-utils-impl.js"() { + init_tensor_impl(); + calculateSize = (dims) => { + let size = 1; + for (let i = 0; i < dims.length; i++) { + const dim = dims[i]; + if (typeof dim !== "number" || !Number.isSafeInteger(dim)) { + throw new TypeError(`dims[${i}] must be an integer, got: ${dim}`); + } + if (dim < 0) { + throw new RangeError(`dims[${i}] must be a non-negative integer, got: ${dim}`); + } + size *= dim; + } + return size; + }; + tensorReshape = (tensor, dims) => { + switch (tensor.location) { + case "cpu": + return new Tensor(tensor.type, tensor.data, dims); + case "cpu-pinned": + return new Tensor({ + location: "cpu-pinned", + data: tensor.data, + type: tensor.type, + dims + }); + case "texture": + return new Tensor({ + location: "texture", + texture: tensor.texture, + type: tensor.type, + dims + }); + case "gpu-buffer": + return new Tensor({ + location: "gpu-buffer", + gpuBuffer: tensor.gpuBuffer, + type: tensor.type, + dims + }); + case "ml-tensor": + return new Tensor({ + location: "ml-tensor", + mlTensor: tensor.mlTensor, + type: tensor.type, + dims + }); + default: + throw new Error(`tensorReshape: tensor location ${tensor.location} is not supported`); + } + }; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/tensor-impl.js + var Tensor; + var init_tensor_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-impl.js"() { + init_tensor_conversion_impl(); + init_tensor_factory_impl(); + init_tensor_impl_type_mapping(); + init_tensor_utils_impl(); + Tensor = class { + /** + * implementation. + */ + constructor(arg0, arg1, arg2) { + checkTypedArray(); + let type; + let dims; + if (typeof arg0 === "object" && "location" in arg0) { + this.dataLocation = arg0.location; + type = arg0.type; + dims = arg0.dims; + switch (arg0.location) { + case "cpu-pinned": { + const expectedTypedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(type); + if (!expectedTypedArrayConstructor) { + throw new TypeError(`unsupported type "${type}" to create tensor from pinned buffer`); + } + if (!(arg0.data instanceof expectedTypedArrayConstructor)) { + throw new TypeError(`buffer should be of type ${expectedTypedArrayConstructor.name}`); + } + this.cpuData = arg0.data; + break; + } + case "texture": { + if (type !== "float32") { + throw new TypeError(`unsupported type "${type}" to create tensor from texture`); + } + this.gpuTextureData = arg0.texture; + this.downloader = arg0.download; + this.disposer = arg0.dispose; + break; + } + case "gpu-buffer": { + if (type !== "float32" && type !== "float16" && type !== "int32" && type !== "int64" && type !== "uint32" && type !== "uint8" && type !== "bool" && type !== "uint4" && type !== "int4") { + throw new TypeError(`unsupported type "${type}" to create tensor from gpu buffer`); + } + this.gpuBufferData = arg0.gpuBuffer; + this.downloader = arg0.download; + this.disposer = arg0.dispose; + break; + } + case "ml-tensor": { + if (type !== "float32" && type !== "float16" && type !== "int32" && type !== "int64" && type !== "uint32" && type !== "uint64" && type !== "int8" && type !== "uint8" && type !== "bool" && type !== "uint4" && type !== "int4") { + throw new TypeError(`unsupported type "${type}" to create tensor from MLTensor`); + } + this.mlTensorData = arg0.mlTensor; + this.downloader = arg0.download; + this.disposer = arg0.dispose; + break; + } + default: + throw new Error(`Tensor constructor: unsupported location '${this.dataLocation}'`); + } + } else { + let data; + let maybeDims; + if (typeof arg0 === "string") { + type = arg0; + maybeDims = arg2; + if (arg0 === "string") { + if (!Array.isArray(arg1)) { + throw new TypeError("A string tensor's data must be a string array."); + } + data = arg1; + } else { + const typedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(arg0); + if (typedArrayConstructor === void 0) { + throw new TypeError(`Unsupported tensor type: ${arg0}.`); + } + if (Array.isArray(arg1)) { + if (arg0 === "float16" && typedArrayConstructor === Uint16Array || arg0 === "uint4" || arg0 === "int4") { + throw new TypeError(`Creating a ${arg0} tensor from number array is not supported. Please use ${typedArrayConstructor.name} as data.`); + } else if (arg0 === "uint64" || arg0 === "int64") { + data = typedArrayConstructor.from(arg1, BigInt); + } else { + data = typedArrayConstructor.from(arg1); + } + } else if (arg1 instanceof typedArrayConstructor) { + data = arg1; + } else if (arg1 instanceof Uint8ClampedArray) { + if (arg0 === "uint8") { + data = Uint8Array.from(arg1); + } else { + throw new TypeError(`A Uint8ClampedArray tensor's data must be type of uint8`); + } + } else if (arg0 === "float16" && arg1 instanceof Uint16Array && typedArrayConstructor !== Uint16Array) { + data = new globalThis.Float16Array(arg1.buffer, arg1.byteOffset, arg1.length); + } else { + throw new TypeError(`A ${type} tensor's data must be type of ${typedArrayConstructor}`); + } + } + } else { + maybeDims = arg1; + if (Array.isArray(arg0)) { + if (arg0.length === 0) { + throw new TypeError("Tensor type cannot be inferred from an empty array."); + } + const firstElementType = typeof arg0[0]; + if (firstElementType === "string") { + type = "string"; + data = arg0; + } else if (firstElementType === "boolean") { + type = "bool"; + data = Uint8Array.from(arg0); + } else { + throw new TypeError(`Invalid element type of data array: ${firstElementType}.`); + } + } else if (arg0 instanceof Uint8ClampedArray) { + type = "uint8"; + data = Uint8Array.from(arg0); + } else { + const mappedType = NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.get(arg0.constructor); + if (mappedType === void 0) { + throw new TypeError(`Unsupported type for tensor data: ${arg0.constructor}.`); + } + type = mappedType; + data = arg0; + } + } + if (maybeDims === void 0) { + maybeDims = [data.length]; + } else if (!Array.isArray(maybeDims)) { + throw new TypeError("A tensor's dims must be a number array"); + } + dims = maybeDims; + this.cpuData = data; + this.dataLocation = "cpu"; + } + const size = calculateSize(dims); + if (this.cpuData && size !== this.cpuData.length) { + if ((type === "uint4" || type === "int4") && Math.ceil(size / 2) === this.cpuData.length) { + } else { + throw new Error(`Tensor's size(${size}) does not match data length(${this.cpuData.length}).`); + } + } + this.type = type; + this.dims = dims; + this.size = size; + } + // #endregion + // #region factory + static async fromImage(image, options) { + return tensorFromImage(image, options); + } + static fromTexture(texture, options) { + return tensorFromTexture(texture, options); + } + static fromGpuBuffer(gpuBuffer, options) { + return tensorFromGpuBuffer(gpuBuffer, options); + } + static fromMLTensor(mlTensor, options) { + return tensorFromMLTensor(mlTensor, options); + } + static fromPinnedBuffer(type, buffer, dims) { + return tensorFromPinnedBuffer(type, buffer, dims); + } + // #endregion + // #region conversions + toDataURL(options) { + return tensorToDataURL(this, options); + } + toImageData(options) { + return tensorToImageData(this, options); + } + // #endregion + // #region properties + get data() { + this.ensureValid(); + if (!this.cpuData) { + throw new Error("The data is not on CPU. Use `getData()` to download GPU data to CPU, or use `texture` or `gpuBuffer` property to access the GPU data directly."); + } + return this.cpuData; + } + get location() { + return this.dataLocation; + } + get texture() { + this.ensureValid(); + if (!this.gpuTextureData) { + throw new Error("The data is not stored as a WebGL texture."); + } + return this.gpuTextureData; + } + get gpuBuffer() { + this.ensureValid(); + if (!this.gpuBufferData) { + throw new Error("The data is not stored as a WebGPU buffer."); + } + return this.gpuBufferData; + } + get mlTensor() { + this.ensureValid(); + if (!this.mlTensorData) { + throw new Error("The data is not stored as a WebNN MLTensor."); + } + return this.mlTensorData; + } + // #endregion + // #region methods + async getData(releaseData) { + this.ensureValid(); + switch (this.dataLocation) { + case "cpu": + case "cpu-pinned": + return this.data; + case "texture": + case "gpu-buffer": + case "ml-tensor": { + if (!this.downloader) { + throw new Error("The current tensor is not created with a specified data downloader."); + } + if (this.isDownloading) { + throw new Error("The current tensor is being downloaded."); + } + try { + this.isDownloading = true; + const data = await this.downloader(); + this.downloader = void 0; + this.dataLocation = "cpu"; + this.cpuData = data; + if (releaseData && this.disposer) { + this.disposer(); + this.disposer = void 0; + } + return data; + } finally { + this.isDownloading = false; + } + } + default: + throw new Error(`cannot get data from location: ${this.dataLocation}`); + } + } + dispose() { + if (this.isDownloading) { + throw new Error("The current tensor is being downloaded."); + } + if (this.disposer) { + this.disposer(); + this.disposer = void 0; + } + this.cpuData = void 0; + this.gpuTextureData = void 0; + this.gpuBufferData = void 0; + this.mlTensorData = void 0; + this.downloader = void 0; + this.isDownloading = void 0; + this.dataLocation = "none"; + } + // #endregion + // #region tensor utilities + ensureValid() { + if (this.dataLocation === "none") { + throw new Error("The tensor is disposed."); + } + } + reshape(dims) { + this.ensureValid(); + if (this.downloader || this.disposer) { + throw new Error("Cannot reshape a tensor that owns GPU resource."); + } + return tensorReshape(this, dims); + } + }; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/tensor.js + var Tensor2; + var init_tensor = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor.js"() { + init_tensor_impl(); + Tensor2 = Tensor; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/trace.js + var TRACE, TRACE_FUNC, TRACE_FUNC_BEGIN, TRACE_FUNC_END; + var init_trace = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/trace.js"() { + init_env_impl(); + TRACE = (deviceType, label) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + console.timeStamp(`${deviceType}::ORT::${label}`); + }; + TRACE_FUNC = (msg, extraMsg) => { + const stack = new Error().stack?.split(/\r\n|\r|\n/g) || []; + let hasTraceFunc = false; + for (let i = 0; i < stack.length; i++) { + if (hasTraceFunc && !stack[i].includes("TRACE_FUNC")) { + let label = `FUNC_${msg}::${stack[i].trim().split(" ")[1]}`; + if (extraMsg) { + label += `::${extraMsg}`; + } + TRACE("CPU", label); + return; + } + if (stack[i].includes("TRACE_FUNC")) { + hasTraceFunc = true; + } + } + }; + TRACE_FUNC_BEGIN = (extraMsg) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + TRACE_FUNC("BEGIN", extraMsg); + }; + TRACE_FUNC_END = (extraMsg) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + TRACE_FUNC("END", extraMsg); + }; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/inference-session-impl.js + var InferenceSession; + var init_inference_session_impl = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/inference-session-impl.js"() { + init_backend_impl(); + init_tensor(); + init_trace(); + InferenceSession = class _InferenceSession { + constructor(handler) { + this.handler = handler; + } + async run(feeds, arg1, arg2) { + TRACE_FUNC_BEGIN(); + const fetches = {}; + let options = {}; + if (typeof feeds !== "object" || feeds === null || feeds instanceof Tensor2 || Array.isArray(feeds)) { + throw new TypeError("'feeds' must be an object that use input names as keys and OnnxValue as corresponding values."); + } + let isFetchesEmpty = true; + if (typeof arg1 === "object") { + if (arg1 === null) { + throw new TypeError("Unexpected argument[1]: cannot be null."); + } + if (arg1 instanceof Tensor2) { + throw new TypeError("'fetches' cannot be a Tensor"); + } + if (Array.isArray(arg1)) { + if (arg1.length === 0) { + throw new TypeError("'fetches' cannot be an empty array."); + } + isFetchesEmpty = false; + for (const name2 of arg1) { + if (typeof name2 !== "string") { + throw new TypeError("'fetches' must be a string array or an object."); + } + if (this.outputNames.indexOf(name2) === -1) { + throw new RangeError(`'fetches' contains invalid output name: ${name2}.`); + } + fetches[name2] = null; + } + if (typeof arg2 === "object" && arg2 !== null) { + options = arg2; + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else { + let isFetches = false; + const arg1Keys = Object.getOwnPropertyNames(arg1); + for (const name2 of this.outputNames) { + if (arg1Keys.indexOf(name2) !== -1) { + const v = arg1[name2]; + if (v === null || v instanceof Tensor2) { + isFetches = true; + isFetchesEmpty = false; + fetches[name2] = v; + } + } + } + if (isFetches) { + if (typeof arg2 === "object" && arg2 !== null) { + options = arg2; + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else { + options = arg1; + } + } + } else if (typeof arg1 !== "undefined") { + throw new TypeError("Unexpected argument[1]: must be 'fetches' or 'options'."); + } + for (const name2 of this.inputNames) { + if (typeof feeds[name2] === "undefined") { + throw new Error(`input '${name2}' is missing in 'feeds'.`); + } + } + if (isFetchesEmpty) { + for (const name2 of this.outputNames) { + fetches[name2] = null; + } + } + const results = await this.handler.run(feeds, fetches, options); + const returnValue = {}; + for (const key in results) { + if (Object.hasOwnProperty.call(results, key)) { + const result = results[key]; + if (result instanceof Tensor2) { + returnValue[key] = result; + } else { + returnValue[key] = new Tensor2(result.type, result.data, result.dims); + } + } + } + TRACE_FUNC_END(); + return returnValue; + } + async release() { + return this.handler.dispose(); + } + static async create(arg0, arg1, arg2, arg3) { + TRACE_FUNC_BEGIN(); + let filePathOrUint8Array; + let options = {}; + if (typeof arg0 === "string") { + filePathOrUint8Array = arg0; + if (typeof arg1 === "object" && arg1 !== null) { + options = arg1; + } else if (typeof arg1 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else if (arg0 instanceof Uint8Array) { + filePathOrUint8Array = arg0; + if (typeof arg1 === "object" && arg1 !== null) { + options = arg1; + } else if (typeof arg1 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else if (arg0 instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && arg0 instanceof SharedArrayBuffer) { + const buffer = arg0; + let byteOffset = 0; + let byteLength = arg0.byteLength; + if (typeof arg1 === "object" && arg1 !== null) { + options = arg1; + } else if (typeof arg1 === "number") { + byteOffset = arg1; + if (!Number.isSafeInteger(byteOffset)) { + throw new RangeError("'byteOffset' must be an integer."); + } + if (byteOffset < 0 || byteOffset >= buffer.byteLength) { + throw new RangeError(`'byteOffset' is out of range [0, ${buffer.byteLength}).`); + } + byteLength = arg0.byteLength - byteOffset; + if (typeof arg2 === "number") { + byteLength = arg2; + if (!Number.isSafeInteger(byteLength)) { + throw new RangeError("'byteLength' must be an integer."); + } + if (byteLength <= 0 || byteOffset + byteLength > buffer.byteLength) { + throw new RangeError(`'byteLength' is out of range (0, ${buffer.byteLength - byteOffset}].`); + } + if (typeof arg3 === "object" && arg3 !== null) { + options = arg3; + } else if (typeof arg3 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'byteLength' must be a number."); + } + } else if (typeof arg1 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + filePathOrUint8Array = new Uint8Array(buffer, byteOffset, byteLength); + } else { + throw new TypeError("Unexpected argument[0]: must be 'path' or 'buffer'."); + } + const [backend2, optionsWithValidatedEPs] = await resolveBackendAndExecutionProviders(options); + const handler = await backend2.createInferenceSessionHandler(filePathOrUint8Array, optionsWithValidatedEPs); + TRACE_FUNC_END(); + return new _InferenceSession(handler); + } + startProfiling() { + this.handler.startProfiling(); + } + endProfiling() { + this.handler.endProfiling(); + } + get inputNames() { + return this.handler.inputNames; + } + get outputNames() { + return this.handler.outputNames; + } + get inputMetadata() { + return this.handler.inputMetadata; + } + get outputMetadata() { + return this.handler.outputMetadata; + } + }; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/inference-session.js + var InferenceSession2; + var init_inference_session = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/inference-session.js"() { + init_inference_session_impl(); + InferenceSession2 = InferenceSession; + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/tensor-conversion.js + var init_tensor_conversion = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-conversion.js"() { + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/tensor-factory.js + var init_tensor_factory = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/tensor-factory.js"() { + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/onnx-model.js + var init_onnx_model = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/onnx-model.js"() { + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/onnx-value.js + var init_onnx_value = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/onnx-value.js"() { + } + }); + + // web/node_modules/onnxruntime-common/dist/esm/index.js + var esm_exports = {}; + __export(esm_exports, { + InferenceSession: () => InferenceSession2, + TRACE: () => TRACE, + TRACE_FUNC_BEGIN: () => TRACE_FUNC_BEGIN, + TRACE_FUNC_END: () => TRACE_FUNC_END, + Tensor: () => Tensor2, + env: () => env2, + registerBackend: () => registerBackend + }); + var init_esm = __esm({ + "web/node_modules/onnxruntime-common/dist/esm/index.js"() { + init_backend(); + init_env(); + init_inference_session(); + init_tensor(); + init_tensor_conversion(); + init_tensor_factory(); + init_trace(); + init_onnx_model(); + init_onnx_value(); + } + }); + + // web/lib/onnxjs/instrument.ts + function log(arg0, arg1, arg2, arg3) { + if (arg1 === void 0) { + return createCategorizedLogger(arg0); + } else if (arg2 === void 0) { + logInternal(arg0, arg1, 1); + } else if (typeof arg2 === "number" && arg3 === void 0) { + logInternal(arg0, arg1, arg2); + } else if (typeof arg2 === "string" && arg3 === void 0) { + logInternal(arg0, arg2, 1, arg1); + } else if (typeof arg2 === "string" && typeof arg3 === "number") { + logInternal(arg0, arg2, arg3, arg1); + } else { + throw new TypeError("input is valid"); + } + } + function createCategorizedLogger(category) { + return { + verbose: log.verbose.bind(null, category), + info: log.info.bind(null, category), + warning: log.warning.bind(null, category), + error: log.error.bind(null, category), + fatal: log.fatal.bind(null, category) + }; + } + function logInternal(severity, content, _stack, category) { + const config = LOGGER_CONFIG_MAP[category || ""] || LOGGER_CONFIG_MAP[""]; + if (SEVERITY_VALUE[severity] < SEVERITY_VALUE[config.minimalSeverity]) { + return; + } + if (config.logDateTime) { + content = `${(/* @__PURE__ */ new Date()).toISOString()}|${content}`; + } + if (config.logSourceLocation) { + } + LOGGER_PROVIDER_MAP[config.provider].log(severity, content, category); + } + var NoOpLoggerProvider, ConsoleLoggerProvider, SEVERITY_VALUE, LOGGER_PROVIDER_MAP, LOGGER_DEFAULT_CONFIG, LOGGER_CONFIG_MAP, Logger, Event, EventRecord, Profiler, now; + var init_instrument = __esm({ + "web/lib/onnxjs/instrument.ts"() { + "use strict"; + NoOpLoggerProvider = class { + log(_severity, _content, _category) { + } + }; + ConsoleLoggerProvider = class { + log(severity, content, category) { + console.log(`${this.color(severity)} ${category ? "\x1B[35m" + category + "\x1B[0m " : ""}${content}`); + } + color(severity) { + switch (severity) { + case "verbose": + return "\x1B[34;40mv\x1B[0m"; + case "info": + return "\x1B[32mi\x1B[0m"; + case "warning": + return "\x1B[30;43mw\x1B[0m"; + case "error": + return "\x1B[31;40me\x1B[0m"; + case "fatal": + return "\x1B[101mf\x1B[0m"; + default: + throw new Error(`unsupported severity: ${severity}`); + } + } + }; + SEVERITY_VALUE = { + verbose: 1e3, + info: 2e3, + warning: 4e3, + error: 5e3, + fatal: 6e3 + }; + LOGGER_PROVIDER_MAP = { + ["none"]: new NoOpLoggerProvider(), + ["console"]: new ConsoleLoggerProvider() + }; + LOGGER_DEFAULT_CONFIG = { + provider: "console", + minimalSeverity: "warning", + logDateTime: true, + logSourceLocation: false + }; + LOGGER_CONFIG_MAP = { + [""]: LOGGER_DEFAULT_CONFIG + }; + ((log4) => { + function verbose(arg0, arg1) { + log4("verbose", arg0, arg1); + } + log4.verbose = verbose; + function info(arg0, arg1) { + log4("info", arg0, arg1); + } + log4.info = info; + function warning(arg0, arg1) { + log4("warning", arg0, arg1); + } + log4.warning = warning; + function error(arg0, arg1) { + log4("error", arg0, arg1); + } + log4.error = error; + function fatal(arg0, arg1) { + log4("fatal", arg0, arg1); + } + log4.fatal = fatal; + function reset(config) { + LOGGER_CONFIG_MAP = {}; + set("", config || {}); + } + log4.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 + }; + } + } + log4.set = set; + function setWithEnv(env3) { + const config = {}; + if (env3.logLevel) { + config.minimalSeverity = env3.logLevel; + } + set("", config); + } + log4.setWithEnv = setWithEnv; + })(log || (log = {})); + Logger = log; + Event = class { + constructor(category, name2, startTime, endCallback, timer, ctx) { + this.category = category; + this.name = name2; + this.startTime = startTime; + this.endCallback = endCallback; + this.timer = timer; + this.ctx = ctx; + } + async end() { + return this.endCallback(this); + } + async checkTimer() { + if (this.ctx === void 0 || this.timer === void 0) { + throw new Error("No webgl timer found"); + } else { + this.ctx.endTimer(); + return this.ctx.waitForQueryAndGetTime(this.timer); + } + } + }; + EventRecord = class { + constructor(category, name2, startTime, endTime) { + this.category = category; + this.name = name2; + this.startTime = startTime; + this.endTime = endTime; + } + }; + Profiler = class { + constructor(maxNumberEvents, flushBatchSize, flushIntervalInMilliseconds) { + this._started = false; + this._flushPointer = 0; + this._started = false; + this._maxNumberEvents = maxNumberEvents === void 0 ? 1e4 : maxNumberEvents; + this._flushBatchSize = flushBatchSize === void 0 ? 10 : flushBatchSize; + this._flushIntervalInMilliseconds = flushIntervalInMilliseconds === void 0 ? 5e3 : flushIntervalInMilliseconds; + } + static create(config) { + if (config === void 0) { + return new this(); + } + return new this(config.maxNumberEvents, config.flushBatchSize, config.flushIntervalInMilliseconds); + } + // start profiling + start() { + this._started = true; + this._timingEvents = []; + this._flushTime = now(); + this._flushPointer = 0; + } + // stop profiling + stop() { + this._started = false; + for (; this._flushPointer < this._timingEvents.length; this._flushPointer++) { + this.logOneEvent(this._timingEvents[this._flushPointer]); + } + } + event(category, name2, func, ctx) { + const event = this._started ? this.begin(category, name2, ctx) : void 0; + let isPromise = false; + const res = func(); + if (res && typeof res.then === "function") { + isPromise = true; + return new Promise((resolve, reject) => { + res.then( + async (value) => { + if (event) { + await event.end(); + } + resolve(value); + }, + async (reason) => { + if (event) { + await event.end(); + } + reject(reason); + } + ); + }); + } + if (!isPromise && event) { + const eventRes = event.end(); + if (eventRes && typeof eventRes.then === "function") { + return new Promise((resolve, reject) => { + eventRes.then( + () => { + resolve(res); + }, + (reason) => { + reject(reason); + } + ); + }); + } + } + return res; + } + // begin an event + begin(category, name2, ctx) { + if (!this._started) { + throw new Error("profiler is not started yet"); + } + if (ctx === void 0) { + const startTime = now(); + this.flush(startTime); + return new Event(category, name2, startTime, (e) => this.endSync(e)); + } else { + const timer = ctx.beginTimer(); + return new Event(category, name2, 0, async (e) => this.end(e), timer, ctx); + } + } + // end the specific event + async end(event) { + const endTime = await event.checkTimer(); + if (this._timingEvents.length < this._maxNumberEvents) { + this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime)); + this.flush(endTime); + } + } + endSync(event) { + const endTime = now(); + if (this._timingEvents.length < this._maxNumberEvents) { + this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime)); + this.flush(endTime); + } + } + logOneEvent(event) { + Logger.verbose( + `Profiler.${event.category}`, + `${(event.endTime - event.startTime).toFixed(2)}ms on event '${event.name}' at ${event.endTime.toFixed(2)}` + ); + } + flush(currentTime) { + if (this._timingEvents.length - this._flushPointer >= this._flushBatchSize || currentTime - this._flushTime >= this._flushIntervalInMilliseconds) { + for (const previousPointer = this._flushPointer; this._flushPointer < previousPointer + this._flushBatchSize && this._flushPointer < this._timingEvents.length; this._flushPointer++) { + this.logOneEvent(this._timingEvents[this._flushPointer]); + } + this._flushTime = now(); + } + } + get started() { + return this._started; + } + }; + now = typeof performance !== "undefined" && performance.now ? () => performance.now() : Date.now; + } + }); + + // web/lib/onnxjs/opset.ts + function resolveOperator(node, opsets, rules) { + for (const rule of rules) { + const opType = rule[0]; + const domain = rule[1]; + const versionSelector = rule[2]; + const opImpl = rule[3]; + const opInit = rule[4]; + if (node.opType === opType) { + for (const opset of opsets) { + if (opset.domain === domain || opset.domain === "ai.onnx" && domain === "") { + if (matchSelector(opset.version, versionSelector)) { + return { opImpl, opInit }; + } + } + } + } + } + throw new TypeError( + `cannot resolve operator '${node.opType}' with opsets: ${opsets.map((set) => `${set.domain || "ai.onnx"} v${set.version}`).join(", ")}` + ); + } + function matchSelector(version3, selector) { + if (selector.endsWith("+")) { + const rangeStart = Number.parseInt(selector.substring(0, selector.length - 1), 10); + return !isNaN(rangeStart) && rangeStart <= version3; + } else if (selector.split("-").length === 2) { + const pair = selector.split("-"); + const rangeStart = Number.parseInt(pair[0], 10); + const rangeEnd = Number.parseInt(pair[1], 10); + return !isNaN(rangeStart) && !isNaN(rangeEnd) && rangeStart <= version3 && version3 <= rangeEnd; + } else { + return Number.parseInt(selector, 10) === version3; + } + } + var init_opset = __esm({ + "web/lib/onnxjs/opset.ts"() { + "use strict"; + } + }); + + // web/node_modules/guid-typescript/dist/guid.js + var require_guid = __commonJS({ + "web/node_modules/guid-typescript/dist/guid.js"(exports2) { + "use strict"; + exports2.__esModule = true; + var Guid2 = ( + /** @class */ + function() { + function Guid3(guid2) { + if (!guid2) { + throw new TypeError("Invalid argument; `value` has no value."); + } + this.value = Guid3.EMPTY; + if (guid2 && Guid3.isGuid(guid2)) { + this.value = guid2; + } + } + Guid3.isGuid = function(guid2) { + var value = guid2.toString(); + return guid2 && (guid2 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(guid2) { + return new Guid3(guid2); + }; + Guid3.raw = function() { + return [Guid3.gen(2), Guid3.gen(1), Guid3.gen(1), Guid3.gen(1), Guid3.gen(3)].join("-"); + }; + Guid3.gen = function(count) { + var out = ""; + for (var i = 0; i < count; i++) { + out += ((1 + Math.random()) * 65536 | 0).toString(16).substring(1); + } + return out; + }; + Guid3.prototype.equals = function(other) { + return Guid3.isGuid(other) && this.value === other.toString(); + }; + Guid3.prototype.isEmpty = function() { + return this.value === Guid3.EMPTY; + }; + Guid3.prototype.toString = function() { + return this.value; + }; + Guid3.prototype.toJSON = function() { + return { + value: this.value + }; + }; + Guid3.validator = new RegExp("^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$", "i"); + Guid3.EMPTY = "00000000-0000-0000-0000-000000000000"; + return Guid3; + }() + ); + exports2.Guid = Guid2; + } + }); + + // web/node_modules/long/index.js + function Long(low, high, unsigned) { + this.low = low | 0; + this.high = high | 0; + this.unsigned = !!unsigned; + } + function isLong(obj) { + return (obj && obj["__isLong__"]) === true; + } + function ctz32(value) { + var c = Math.clz32(value & -value); + return value ? 31 - c : c; + } + function fromInt(value, unsigned) { + var obj, cachedObj, cache2; + if (unsigned) { + value >>>= 0; + if (cache2 = 0 <= value && value < 256) { + cachedObj = UINT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = fromBits(value, 0, true); + if (cache2) + UINT_CACHE[value] = obj; + return obj; + } else { + value |= 0; + if (cache2 = -128 <= value && value < 128) { + cachedObj = INT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = fromBits(value, value < 0 ? -1 : 0, false); + if (cache2) + INT_CACHE[value] = obj; + return obj; + } + } + function fromNumber(value, unsigned) { + if (isNaN(value)) + return unsigned ? UZERO : ZERO; + if (unsigned) { + if (value < 0) + return UZERO; + if (value >= TWO_PWR_64_DBL) + return MAX_UNSIGNED_VALUE; + } else { + if (value <= -TWO_PWR_63_DBL) + return MIN_VALUE; + if (value + 1 >= TWO_PWR_63_DBL) + return MAX_VALUE; + } + if (value < 0) + return fromNumber(-value, unsigned).neg(); + return fromBits(value % TWO_PWR_32_DBL | 0, value / TWO_PWR_32_DBL | 0, unsigned); + } + function fromBits(lowBits, highBits, unsigned) { + return new Long(lowBits, highBits, unsigned); + } + function fromString(str, unsigned, radix) { + if (str.length === 0) + throw Error("empty string"); + if (typeof unsigned === "number") { + radix = unsigned; + unsigned = false; + } else { + unsigned = !!unsigned; + } + if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") + return unsigned ? UZERO : ZERO; + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw RangeError("radix"); + var p; + if ((p = str.indexOf("-")) > 0) + throw Error("interior hyphen"); + else if (p === 0) { + return fromString(str.substring(1), unsigned, radix).neg(); + } + var radixToPower = fromNumber(pow_dbl(radix, 8)); + var result = ZERO; + for (var i = 0; i < str.length; i += 8) { + var size = Math.min(8, str.length - i), value = parseInt(str.substring(i, i + size), radix); + if (size < 8) { + var power = fromNumber(pow_dbl(radix, size)); + result = result.mul(power).add(fromNumber(value)); + } else { + result = result.mul(radixToPower); + result = result.add(fromNumber(value)); + } + } + result.unsigned = unsigned; + return result; + } + function fromValue(val, unsigned) { + if (typeof val === "number") + return fromNumber(val, unsigned); + if (typeof val === "string") + return fromString(val, unsigned); + return fromBits(val.low, val.high, typeof unsigned === "boolean" ? unsigned : val.unsigned); + } + var wasm, INT_CACHE, UINT_CACHE, pow_dbl, TWO_PWR_16_DBL, TWO_PWR_24_DBL, TWO_PWR_32_DBL, TWO_PWR_64_DBL, TWO_PWR_63_DBL, TWO_PWR_24, ZERO, UZERO, ONE, UONE, NEG_ONE, MAX_VALUE, MAX_UNSIGNED_VALUE, MIN_VALUE, LongPrototype, long_default; + var init_long = __esm({ + "web/node_modules/long/index.js"() { + wasm = null; + try { + wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([ + 0, + 97, + 115, + 109, + 1, + 0, + 0, + 0, + 1, + 13, + 2, + 96, + 0, + 1, + 127, + 96, + 4, + 127, + 127, + 127, + 127, + 1, + 127, + 3, + 7, + 6, + 0, + 1, + 1, + 1, + 1, + 1, + 6, + 6, + 1, + 127, + 1, + 65, + 0, + 11, + 7, + 50, + 6, + 3, + 109, + 117, + 108, + 0, + 1, + 5, + 100, + 105, + 118, + 95, + 115, + 0, + 2, + 5, + 100, + 105, + 118, + 95, + 117, + 0, + 3, + 5, + 114, + 101, + 109, + 95, + 115, + 0, + 4, + 5, + 114, + 101, + 109, + 95, + 117, + 0, + 5, + 8, + 103, + 101, + 116, + 95, + 104, + 105, + 103, + 104, + 0, + 0, + 10, + 191, + 1, + 6, + 4, + 0, + 35, + 0, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 126, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 127, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 128, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 129, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 130, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11 + ])), {}).exports; + } catch (e) { + } + Long.prototype.__isLong__; + Object.defineProperty(Long.prototype, "__isLong__", { value: true }); + Long.isLong = isLong; + INT_CACHE = {}; + UINT_CACHE = {}; + Long.fromInt = fromInt; + Long.fromNumber = fromNumber; + Long.fromBits = fromBits; + pow_dbl = Math.pow; + Long.fromString = fromString; + Long.fromValue = fromValue; + TWO_PWR_16_DBL = 1 << 16; + TWO_PWR_24_DBL = 1 << 24; + TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; + TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; + TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; + TWO_PWR_24 = fromInt(TWO_PWR_24_DBL); + ZERO = fromInt(0); + Long.ZERO = ZERO; + UZERO = fromInt(0, true); + Long.UZERO = UZERO; + ONE = fromInt(1); + Long.ONE = ONE; + UONE = fromInt(1, true); + Long.UONE = UONE; + NEG_ONE = fromInt(-1); + Long.NEG_ONE = NEG_ONE; + MAX_VALUE = fromBits(4294967295 | 0, 2147483647 | 0, false); + Long.MAX_VALUE = MAX_VALUE; + MAX_UNSIGNED_VALUE = fromBits(4294967295 | 0, 4294967295 | 0, true); + Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE; + MIN_VALUE = fromBits(0, 2147483648 | 0, false); + Long.MIN_VALUE = MIN_VALUE; + LongPrototype = Long.prototype; + LongPrototype.toInt = function toInt() { + return this.unsigned ? this.low >>> 0 : this.low; + }; + LongPrototype.toNumber = function toNumber() { + if (this.unsigned) + return (this.high >>> 0) * TWO_PWR_32_DBL + (this.low >>> 0); + return this.high * TWO_PWR_32_DBL + (this.low >>> 0); + }; + LongPrototype.toString = function toString(radix) { + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw RangeError("radix"); + if (this.isZero()) + return "0"; + if (this.isNegative()) { + if (this.eq(MIN_VALUE)) { + var radixLong = fromNumber(radix), div3 = this.div(radixLong), rem1 = div3.mul(radixLong).sub(this); + return div3.toString(radix) + rem1.toInt().toString(radix); + } else + return "-" + this.neg().toString(radix); + } + var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned), rem = this; + var result = ""; + while (true) { + var remDiv = rem.div(radixToPower), intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0, digits = intval.toString(radix); + rem = remDiv; + if (rem.isZero()) + return digits + result; + else { + while (digits.length < 6) + digits = "0" + digits; + result = "" + digits + result; + } + } + }; + LongPrototype.getHighBits = function getHighBits() { + return this.high; + }; + LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() { + return this.high >>> 0; + }; + LongPrototype.getLowBits = function getLowBits() { + return this.low; + }; + LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() { + return this.low >>> 0; + }; + LongPrototype.getNumBitsAbs = function getNumBitsAbs() { + if (this.isNegative()) + return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs(); + var val = this.high != 0 ? this.high : this.low; + for (var bit = 31; bit > 0; bit--) + if ((val & 1 << bit) != 0) + break; + return this.high != 0 ? bit + 33 : bit + 1; + }; + LongPrototype.isZero = function isZero() { + return this.high === 0 && this.low === 0; + }; + LongPrototype.eqz = LongPrototype.isZero; + LongPrototype.isNegative = function isNegative() { + return !this.unsigned && this.high < 0; + }; + LongPrototype.isPositive = function isPositive() { + return this.unsigned || this.high >= 0; + }; + LongPrototype.isOdd = function isOdd() { + return (this.low & 1) === 1; + }; + LongPrototype.isEven = function isEven() { + return (this.low & 1) === 0; + }; + LongPrototype.equals = function equals(other) { + if (!isLong(other)) + other = fromValue(other); + if (this.unsigned !== other.unsigned && this.high >>> 31 === 1 && other.high >>> 31 === 1) + return false; + return this.high === other.high && this.low === other.low; + }; + LongPrototype.eq = LongPrototype.equals; + LongPrototype.notEquals = function notEquals(other) { + return !this.eq( + /* validates */ + other + ); + }; + LongPrototype.neq = LongPrototype.notEquals; + LongPrototype.ne = LongPrototype.notEquals; + LongPrototype.lessThan = function lessThan(other) { + return this.comp( + /* validates */ + other + ) < 0; + }; + LongPrototype.lt = LongPrototype.lessThan; + LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) { + return this.comp( + /* validates */ + other + ) <= 0; + }; + LongPrototype.lte = LongPrototype.lessThanOrEqual; + LongPrototype.le = LongPrototype.lessThanOrEqual; + LongPrototype.greaterThan = function greaterThan(other) { + return this.comp( + /* validates */ + other + ) > 0; + }; + LongPrototype.gt = LongPrototype.greaterThan; + LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) { + return this.comp( + /* validates */ + other + ) >= 0; + }; + LongPrototype.gte = LongPrototype.greaterThanOrEqual; + LongPrototype.ge = LongPrototype.greaterThanOrEqual; + LongPrototype.compare = function compare(other) { + if (!isLong(other)) + other = fromValue(other); + if (this.eq(other)) + return 0; + var thisNeg = this.isNegative(), otherNeg = other.isNegative(); + if (thisNeg && !otherNeg) + return -1; + if (!thisNeg && otherNeg) + return 1; + if (!this.unsigned) + return this.sub(other).isNegative() ? -1 : 1; + return other.high >>> 0 > this.high >>> 0 || other.high === this.high && other.low >>> 0 > this.low >>> 0 ? -1 : 1; + }; + LongPrototype.comp = LongPrototype.compare; + LongPrototype.negate = function negate() { + if (!this.unsigned && this.eq(MIN_VALUE)) + return MIN_VALUE; + return this.not().add(ONE); + }; + LongPrototype.neg = LongPrototype.negate; + LongPrototype.add = function add(addend) { + if (!isLong(addend)) + addend = fromValue(addend); + var a48 = this.high >>> 16; + var a32 = this.high & 65535; + var a16 = this.low >>> 16; + var a00 = this.low & 65535; + var b48 = addend.high >>> 16; + var b32 = addend.high & 65535; + var b16 = addend.low >>> 16; + var b00 = addend.low & 65535; + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 + b00; + c16 += c00 >>> 16; + c00 &= 65535; + c16 += a16 + b16; + c32 += c16 >>> 16; + c16 &= 65535; + c32 += a32 + b32; + c48 += c32 >>> 16; + c32 &= 65535; + c48 += a48 + b48; + c48 &= 65535; + return fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); + }; + LongPrototype.subtract = function subtract(subtrahend) { + if (!isLong(subtrahend)) + subtrahend = fromValue(subtrahend); + return this.add(subtrahend.neg()); + }; + LongPrototype.sub = LongPrototype.subtract; + LongPrototype.multiply = function multiply(multiplier) { + if (this.isZero()) + return this; + if (!isLong(multiplier)) + multiplier = fromValue(multiplier); + if (wasm) { + var low = wasm["mul"]( + this.low, + this.high, + multiplier.low, + multiplier.high + ); + return fromBits(low, wasm["get_high"](), this.unsigned); + } + if (multiplier.isZero()) + return this.unsigned ? UZERO : ZERO; + if (this.eq(MIN_VALUE)) + return multiplier.isOdd() ? MIN_VALUE : ZERO; + if (multiplier.eq(MIN_VALUE)) + return this.isOdd() ? MIN_VALUE : ZERO; + if (this.isNegative()) { + if (multiplier.isNegative()) + return this.neg().mul(multiplier.neg()); + else + return this.neg().mul(multiplier).neg(); + } else if (multiplier.isNegative()) + return this.mul(multiplier.neg()).neg(); + if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24)) + return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned); + var a48 = this.high >>> 16; + var a32 = this.high & 65535; + var a16 = this.low >>> 16; + var a00 = this.low & 65535; + var b48 = multiplier.high >>> 16; + var b32 = multiplier.high & 65535; + var b16 = multiplier.low >>> 16; + var b00 = multiplier.low & 65535; + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 * b00; + c16 += c00 >>> 16; + c00 &= 65535; + c16 += a16 * b00; + c32 += c16 >>> 16; + c16 &= 65535; + c16 += a00 * b16; + c32 += c16 >>> 16; + c16 &= 65535; + c32 += a32 * b00; + c48 += c32 >>> 16; + c32 &= 65535; + c32 += a16 * b16; + c48 += c32 >>> 16; + c32 &= 65535; + c32 += a00 * b32; + c48 += c32 >>> 16; + c32 &= 65535; + c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; + c48 &= 65535; + return fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); + }; + LongPrototype.mul = LongPrototype.multiply; + LongPrototype.divide = function divide(divisor) { + if (!isLong(divisor)) + divisor = fromValue(divisor); + if (divisor.isZero()) + throw Error("division by zero"); + if (wasm) { + if (!this.unsigned && this.high === -2147483648 && divisor.low === -1 && divisor.high === -1) { + return this; + } + var low = (this.unsigned ? wasm["div_u"] : wasm["div_s"])( + this.low, + this.high, + divisor.low, + divisor.high + ); + return fromBits(low, wasm["get_high"](), this.unsigned); + } + if (this.isZero()) + return this.unsigned ? UZERO : ZERO; + var approx, rem, res; + if (!this.unsigned) { + if (this.eq(MIN_VALUE)) { + if (divisor.eq(ONE) || divisor.eq(NEG_ONE)) + return MIN_VALUE; + else if (divisor.eq(MIN_VALUE)) + return ONE; + else { + var halfThis = this.shr(1); + approx = halfThis.div(divisor).shl(1); + if (approx.eq(ZERO)) { + return divisor.isNegative() ? ONE : NEG_ONE; + } else { + rem = this.sub(divisor.mul(approx)); + res = approx.add(rem.div(divisor)); + return res; + } + } + } else if (divisor.eq(MIN_VALUE)) + return this.unsigned ? UZERO : ZERO; + if (this.isNegative()) { + if (divisor.isNegative()) + return this.neg().div(divisor.neg()); + return this.neg().div(divisor).neg(); + } else if (divisor.isNegative()) + return this.div(divisor.neg()).neg(); + res = ZERO; + } else { + if (!divisor.unsigned) + divisor = divisor.toUnsigned(); + if (divisor.gt(this)) + return UZERO; + if (divisor.gt(this.shru(1))) + return UONE; + res = UZERO; + } + rem = this; + while (rem.gte(divisor)) { + approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber())); + var log22 = Math.ceil(Math.log(approx) / Math.LN2), delta = log22 <= 48 ? 1 : pow_dbl(2, log22 - 48), approxRes = fromNumber(approx), approxRem = approxRes.mul(divisor); + while (approxRem.isNegative() || approxRem.gt(rem)) { + approx -= delta; + approxRes = fromNumber(approx, this.unsigned); + approxRem = approxRes.mul(divisor); + } + if (approxRes.isZero()) + approxRes = ONE; + res = res.add(approxRes); + rem = rem.sub(approxRem); + } + return res; + }; + LongPrototype.div = LongPrototype.divide; + LongPrototype.modulo = function modulo(divisor) { + if (!isLong(divisor)) + divisor = fromValue(divisor); + if (wasm) { + var low = (this.unsigned ? wasm["rem_u"] : wasm["rem_s"])( + this.low, + this.high, + divisor.low, + divisor.high + ); + return fromBits(low, wasm["get_high"](), this.unsigned); + } + return this.sub(this.div(divisor).mul(divisor)); + }; + LongPrototype.mod = LongPrototype.modulo; + LongPrototype.rem = LongPrototype.modulo; + LongPrototype.not = function not() { + return fromBits(~this.low, ~this.high, this.unsigned); + }; + LongPrototype.countLeadingZeros = function countLeadingZeros() { + return this.high ? Math.clz32(this.high) : Math.clz32(this.low) + 32; + }; + LongPrototype.clz = LongPrototype.countLeadingZeros; + LongPrototype.countTrailingZeros = function countTrailingZeros() { + return this.low ? ctz32(this.low) : ctz32(this.high) + 32; + }; + LongPrototype.ctz = LongPrototype.countTrailingZeros; + LongPrototype.and = function and(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low & other.low, this.high & other.high, this.unsigned); + }; + LongPrototype.or = function or(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low | other.low, this.high | other.high, this.unsigned); + }; + LongPrototype.xor = function xor(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned); + }; + LongPrototype.shiftLeft = function shiftLeft(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return fromBits(this.low << numBits, this.high << numBits | this.low >>> 32 - numBits, this.unsigned); + else + return fromBits(0, this.low << numBits - 32, this.unsigned); + }; + LongPrototype.shl = LongPrototype.shiftLeft; + LongPrototype.shiftRight = function shiftRight(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return fromBits(this.low >>> numBits | this.high << 32 - numBits, this.high >> numBits, this.unsigned); + else + return fromBits(this.high >> numBits - 32, this.high >= 0 ? 0 : -1, this.unsigned); + }; + LongPrototype.shr = LongPrototype.shiftRight; + LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) { + if (isLong(numBits)) numBits = numBits.toInt(); + if ((numBits &= 63) === 0) return this; + if (numBits < 32) return fromBits(this.low >>> numBits | this.high << 32 - numBits, this.high >>> numBits, this.unsigned); + if (numBits === 32) return fromBits(this.high, 0, this.unsigned); + return fromBits(this.high >>> numBits - 32, 0, this.unsigned); + }; + LongPrototype.shru = LongPrototype.shiftRightUnsigned; + LongPrototype.shr_u = LongPrototype.shiftRightUnsigned; + LongPrototype.rotateLeft = function rotateLeft(numBits) { + var b; + if (isLong(numBits)) numBits = numBits.toInt(); + if ((numBits &= 63) === 0) return this; + if (numBits === 32) return fromBits(this.high, this.low, this.unsigned); + if (numBits < 32) { + b = 32 - numBits; + return fromBits(this.low << numBits | this.high >>> b, this.high << numBits | this.low >>> b, this.unsigned); + } + numBits -= 32; + b = 32 - numBits; + return fromBits(this.high << numBits | this.low >>> b, this.low << numBits | this.high >>> b, this.unsigned); + }; + LongPrototype.rotl = LongPrototype.rotateLeft; + LongPrototype.rotateRight = function rotateRight(numBits) { + var b; + if (isLong(numBits)) numBits = numBits.toInt(); + if ((numBits &= 63) === 0) return this; + if (numBits === 32) return fromBits(this.high, this.low, this.unsigned); + if (numBits < 32) { + b = 32 - numBits; + return fromBits(this.high << b | this.low >>> numBits, this.low << b | this.high >>> numBits, this.unsigned); + } + numBits -= 32; + b = 32 - numBits; + return fromBits(this.low << b | this.high >>> numBits, this.high << b | this.low >>> numBits, this.unsigned); + }; + LongPrototype.rotr = LongPrototype.rotateRight; + LongPrototype.toSigned = function toSigned() { + if (!this.unsigned) + return this; + return fromBits(this.low, this.high, false); + }; + LongPrototype.toUnsigned = function toUnsigned() { + if (this.unsigned) + return this; + return fromBits(this.low, this.high, true); + }; + LongPrototype.toBytes = function toBytes(le) { + return le ? this.toBytesLE() : this.toBytesBE(); + }; + LongPrototype.toBytesLE = function toBytesLE() { + var hi = this.high, lo = this.low; + return [ + lo & 255, + lo >>> 8 & 255, + lo >>> 16 & 255, + lo >>> 24, + hi & 255, + hi >>> 8 & 255, + hi >>> 16 & 255, + hi >>> 24 + ]; + }; + LongPrototype.toBytesBE = function toBytesBE() { + var hi = this.high, lo = this.low; + return [ + hi >>> 24, + hi >>> 16 & 255, + hi >>> 8 & 255, + hi & 255, + lo >>> 24, + lo >>> 16 & 255, + lo >>> 8 & 255, + lo & 255 + ]; + }; + Long.fromBytes = function fromBytes(bytes, unsigned, le) { + return le ? Long.fromBytesLE(bytes, unsigned) : Long.fromBytesBE(bytes, unsigned); + }; + Long.fromBytesLE = function fromBytesLE(bytes, unsigned) { + return new Long( + bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24, + bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24, + unsigned + ); + }; + Long.fromBytesBE = function fromBytesBE(bytes, unsigned) { + return new Long( + bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7], + bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], + unsigned + ); + }; + long_default = Long; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type.js + var require_arg_type = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ArgType = void 0; + var ArgType2; + (function(ArgType3) { + ArgType3[ArgType3["INPUT"] = 0] = "INPUT"; + ArgType3[ArgType3["OUTPUT"] = 1] = "OUTPUT"; + })(ArgType2 || (exports2.ArgType = ArgType2 = {})); + } + }); + + // web/node_modules/flatbuffers/js/constants.js + var require_constants = __commonJS({ + "web/node_modules/flatbuffers/js/constants.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SIZE_PREFIX_LENGTH = exports2.FILE_IDENTIFIER_LENGTH = exports2.SIZEOF_INT = exports2.SIZEOF_SHORT = void 0; + exports2.SIZEOF_SHORT = 2; + exports2.SIZEOF_INT = 4; + exports2.FILE_IDENTIFIER_LENGTH = 4; + exports2.SIZE_PREFIX_LENGTH = 4; + } + }); + + // web/node_modules/flatbuffers/js/utils.js + var require_utils = __commonJS({ + "web/node_modules/flatbuffers/js/utils.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.isLittleEndian = exports2.float64 = exports2.float32 = exports2.int32 = void 0; + exports2.int32 = new Int32Array(2); + exports2.float32 = new Float32Array(exports2.int32.buffer); + exports2.float64 = new Float64Array(exports2.int32.buffer); + exports2.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1; + } + }); + + // web/node_modules/flatbuffers/js/encoding.js + var require_encoding = __commonJS({ + "web/node_modules/flatbuffers/js/encoding.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Encoding = void 0; + var Encoding; + (function(Encoding2) { + Encoding2[Encoding2["UTF8_BYTES"] = 1] = "UTF8_BYTES"; + Encoding2[Encoding2["UTF16_STRING"] = 2] = "UTF16_STRING"; + })(Encoding || (exports2.Encoding = Encoding = {})); + } + }); + + // web/node_modules/flatbuffers/js/byte-buffer.js + var require_byte_buffer = __commonJS({ + "web/node_modules/flatbuffers/js/byte-buffer.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ByteBuffer = void 0; + var constants_js_1 = require_constants(); + var utils_js_1 = require_utils(); + var encoding_js_1 = require_encoding(); + var ByteBuffer2 = class _ByteBuffer { + /** + * Create a new ByteBuffer with a given array of bytes (`Uint8Array`) + */ + constructor(bytes_) { + this.bytes_ = bytes_; + this.position_ = 0; + this.text_decoder_ = new TextDecoder(); + } + /** + * Create and allocate a new ByteBuffer with a given size. + */ + static allocate(byte_size) { + return new _ByteBuffer(new Uint8Array(byte_size)); + } + clear() { + this.position_ = 0; + } + /** + * Get the underlying `Uint8Array`. + */ + bytes() { + return this.bytes_; + } + /** + * Get the buffer's position. + */ + position() { + return this.position_; + } + /** + * Set the buffer's position. + */ + setPosition(position) { + this.position_ = position; + } + /** + * Get the buffer's capacity. + */ + capacity() { + return this.bytes_.length; + } + readInt8(offset) { + return this.readUint8(offset) << 24 >> 24; + } + readUint8(offset) { + return this.bytes_[offset]; + } + readInt16(offset) { + return this.readUint16(offset) << 16 >> 16; + } + readUint16(offset) { + return this.bytes_[offset] | this.bytes_[offset + 1] << 8; + } + readInt32(offset) { + return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24; + } + readUint32(offset) { + return this.readInt32(offset) >>> 0; + } + readInt64(offset) { + return BigInt.asIntN(64, BigInt(this.readUint32(offset)) + (BigInt(this.readUint32(offset + 4)) << BigInt(32))); + } + readUint64(offset) { + return BigInt.asUintN(64, BigInt(this.readUint32(offset)) + (BigInt(this.readUint32(offset + 4)) << BigInt(32))); + } + readFloat32(offset) { + utils_js_1.int32[0] = this.readInt32(offset); + return utils_js_1.float32[0]; + } + readFloat64(offset) { + utils_js_1.int32[utils_js_1.isLittleEndian ? 0 : 1] = this.readInt32(offset); + utils_js_1.int32[utils_js_1.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4); + return utils_js_1.float64[0]; + } + writeInt8(offset, value) { + this.bytes_[offset] = value; + } + writeUint8(offset, value) { + this.bytes_[offset] = value; + } + writeInt16(offset, value) { + this.bytes_[offset] = value; + this.bytes_[offset + 1] = value >> 8; + } + writeUint16(offset, value) { + this.bytes_[offset] = value; + this.bytes_[offset + 1] = value >> 8; + } + writeInt32(offset, value) { + this.bytes_[offset] = value; + this.bytes_[offset + 1] = value >> 8; + this.bytes_[offset + 2] = value >> 16; + this.bytes_[offset + 3] = value >> 24; + } + writeUint32(offset, value) { + this.bytes_[offset] = value; + this.bytes_[offset + 1] = value >> 8; + this.bytes_[offset + 2] = value >> 16; + this.bytes_[offset + 3] = value >> 24; + } + writeInt64(offset, value) { + this.writeInt32(offset, Number(BigInt.asIntN(32, value))); + this.writeInt32(offset + 4, Number(BigInt.asIntN(32, value >> BigInt(32)))); + } + writeUint64(offset, value) { + this.writeUint32(offset, Number(BigInt.asUintN(32, value))); + this.writeUint32(offset + 4, Number(BigInt.asUintN(32, value >> BigInt(32)))); + } + writeFloat32(offset, value) { + utils_js_1.float32[0] = value; + this.writeInt32(offset, utils_js_1.int32[0]); + } + writeFloat64(offset, value) { + utils_js_1.float64[0] = value; + this.writeInt32(offset, utils_js_1.int32[utils_js_1.isLittleEndian ? 0 : 1]); + this.writeInt32(offset + 4, utils_js_1.int32[utils_js_1.isLittleEndian ? 1 : 0]); + } + /** + * Return the file identifier. Behavior is undefined for FlatBuffers whose + * schema does not include a file_identifier (likely points at padding or the + * start of a the root vtable). + */ + getBufferIdentifier() { + if (this.bytes_.length < this.position_ + constants_js_1.SIZEOF_INT + constants_js_1.FILE_IDENTIFIER_LENGTH) { + throw new Error("FlatBuffers: ByteBuffer is too short to contain an identifier."); + } + let result = ""; + for (let i = 0; i < constants_js_1.FILE_IDENTIFIER_LENGTH; i++) { + result += String.fromCharCode(this.readInt8(this.position_ + constants_js_1.SIZEOF_INT + i)); + } + return result; + } + /** + * Look up a field in the vtable, return an offset into the object, or 0 if the + * field is not present. + */ + __offset(bb_pos, vtable_offset) { + const vtable = bb_pos - this.readInt32(bb_pos); + return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0; + } + /** + * Initialize any Table-derived type to point to the union at the given offset. + */ + __union(t, offset) { + t.bb_pos = offset + this.readInt32(offset); + t.bb = this; + return t; + } + /** + * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer. + * This allocates a new string and converts to wide chars upon each access. + * + * To avoid the conversion to string, pass Encoding.UTF8_BYTES as the + * "optionalEncoding" argument. This is useful for avoiding conversion when + * the data will just be packaged back up in another FlatBuffer later on. + * + * @param offset + * @param opt_encoding Defaults to UTF16_STRING + */ + __string(offset, opt_encoding) { + offset += this.readInt32(offset); + const length = this.readInt32(offset); + offset += constants_js_1.SIZEOF_INT; + const utf8bytes = this.bytes_.subarray(offset, offset + length); + if (opt_encoding === encoding_js_1.Encoding.UTF8_BYTES) + return utf8bytes; + else + return this.text_decoder_.decode(utf8bytes); + } + /** + * Handle unions that can contain string as its member, if a Table-derived type then initialize it, + * if a string then return a new one + * + * WARNING: strings are immutable in JS so we can't change the string that the user gave us, this + * makes the behaviour of __union_with_string different compared to __union + */ + __union_with_string(o, offset) { + if (typeof o === "string") { + return this.__string(offset); + } + return this.__union(o, offset); + } + /** + * Retrieve the relative offset stored at "offset" + */ + __indirect(offset) { + return offset + this.readInt32(offset); + } + /** + * Get the start of data of a vector whose offset is stored at "offset" in this object. + */ + __vector(offset) { + return offset + this.readInt32(offset) + constants_js_1.SIZEOF_INT; + } + /** + * Get the length of a vector whose offset is stored at "offset" in this object. + */ + __vector_len(offset) { + return this.readInt32(offset + this.readInt32(offset)); + } + __has_identifier(ident) { + if (ident.length != constants_js_1.FILE_IDENTIFIER_LENGTH) { + throw new Error("FlatBuffers: file identifier must be length " + constants_js_1.FILE_IDENTIFIER_LENGTH); + } + for (let i = 0; i < constants_js_1.FILE_IDENTIFIER_LENGTH; i++) { + if (ident.charCodeAt(i) != this.readInt8(this.position() + constants_js_1.SIZEOF_INT + i)) { + return false; + } + } + return true; + } + /** + * A helper function for generating list for obj api + */ + createScalarList(listAccessor, listLength) { + const ret = []; + for (let i = 0; i < listLength; ++i) { + const val = listAccessor(i); + if (val !== null) { + ret.push(val); + } + } + return ret; + } + /** + * A helper function for generating list for obj api + * @param listAccessor function that accepts an index and return data at that index + * @param listLength listLength + * @param res result list + */ + createObjList(listAccessor, listLength) { + const ret = []; + for (let i = 0; i < listLength; ++i) { + const val = listAccessor(i); + if (val !== null) { + ret.push(val.unpack()); + } + } + return ret; + } + }; + exports2.ByteBuffer = ByteBuffer2; + } + }); + + // web/node_modules/flatbuffers/js/builder.js + var require_builder = __commonJS({ + "web/node_modules/flatbuffers/js/builder.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Builder = void 0; + var byte_buffer_js_1 = require_byte_buffer(); + var constants_js_1 = require_constants(); + var Builder = class _Builder { + /** + * Create a FlatBufferBuilder. + */ + constructor(opt_initial_size) { + this.minalign = 1; + this.vtable = null; + this.vtable_in_use = 0; + this.isNested = false; + this.object_start = 0; + this.vtables = []; + this.vector_num_elems = 0; + this.force_defaults = false; + this.string_maps = null; + this.text_encoder = new TextEncoder(); + let initial_size; + if (!opt_initial_size) { + initial_size = 1024; + } else { + initial_size = opt_initial_size; + } + this.bb = byte_buffer_js_1.ByteBuffer.allocate(initial_size); + this.space = initial_size; + } + clear() { + this.bb.clear(); + this.space = this.bb.capacity(); + this.minalign = 1; + this.vtable = null; + this.vtable_in_use = 0; + this.isNested = false; + this.object_start = 0; + this.vtables = []; + this.vector_num_elems = 0; + this.force_defaults = false; + this.string_maps = null; + } + /** + * In order to save space, fields that are set to their default value + * don't get serialized into the buffer. Forcing defaults provides a + * way to manually disable this optimization. + * + * @param forceDefaults true always serializes default values + */ + forceDefaults(forceDefaults) { + this.force_defaults = forceDefaults; + } + /** + * Get the ByteBuffer representing the FlatBuffer. Only call this after you've + * called finish(). The actual data starts at the ByteBuffer's current position, + * not necessarily at 0. + */ + dataBuffer() { + return this.bb; + } + /** + * Get the bytes representing the FlatBuffer. Only call this after you've + * called finish(). + */ + asUint8Array() { + return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset()); + } + /** + * Prepare to write an element of `size` after `additional_bytes` have been + * written, e.g. if you write a string, you need to align such the int length + * field is aligned to 4 bytes, and the string data follows it directly. If all + * you need to do is alignment, `additional_bytes` will be 0. + * + * @param size This is the of the new element to write + * @param additional_bytes The padding size + */ + prep(size, additional_bytes) { + if (size > this.minalign) { + this.minalign = size; + } + const align_size = ~(this.bb.capacity() - this.space + additional_bytes) + 1 & size - 1; + while (this.space < align_size + size + additional_bytes) { + const old_buf_size = this.bb.capacity(); + this.bb = _Builder.growByteBuffer(this.bb); + this.space += this.bb.capacity() - old_buf_size; + } + this.pad(align_size); + } + pad(byte_size) { + for (let i = 0; i < byte_size; i++) { + this.bb.writeInt8(--this.space, 0); + } + } + writeInt8(value) { + this.bb.writeInt8(this.space -= 1, value); + } + writeInt16(value) { + this.bb.writeInt16(this.space -= 2, value); + } + writeInt32(value) { + this.bb.writeInt32(this.space -= 4, value); + } + writeInt64(value) { + this.bb.writeInt64(this.space -= 8, value); + } + writeFloat32(value) { + this.bb.writeFloat32(this.space -= 4, value); + } + writeFloat64(value) { + this.bb.writeFloat64(this.space -= 8, value); + } + /** + * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary). + * @param value The `int8` to add the buffer. + */ + addInt8(value) { + this.prep(1, 0); + this.writeInt8(value); + } + /** + * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary). + * @param value The `int16` to add the buffer. + */ + addInt16(value) { + this.prep(2, 0); + this.writeInt16(value); + } + /** + * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary). + * @param value The `int32` to add the buffer. + */ + addInt32(value) { + this.prep(4, 0); + this.writeInt32(value); + } + /** + * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary). + * @param value The `int64` to add the buffer. + */ + addInt64(value) { + this.prep(8, 0); + this.writeInt64(value); + } + /** + * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary). + * @param value The `float32` to add the buffer. + */ + addFloat32(value) { + this.prep(4, 0); + this.writeFloat32(value); + } + /** + * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary). + * @param value The `float64` to add the buffer. + */ + addFloat64(value) { + this.prep(8, 0); + this.writeFloat64(value); + } + addFieldInt8(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addInt8(value); + this.slot(voffset); + } + } + addFieldInt16(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addInt16(value); + this.slot(voffset); + } + } + addFieldInt32(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addInt32(value); + this.slot(voffset); + } + } + addFieldInt64(voffset, value, defaultValue) { + if (this.force_defaults || value !== defaultValue) { + this.addInt64(value); + this.slot(voffset); + } + } + addFieldFloat32(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addFloat32(value); + this.slot(voffset); + } + } + addFieldFloat64(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addFloat64(value); + this.slot(voffset); + } + } + addFieldOffset(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addOffset(value); + this.slot(voffset); + } + } + /** + * Structs are stored inline, so nothing additional is being added. `d` is always 0. + */ + addFieldStruct(voffset, value, defaultValue) { + if (value != defaultValue) { + this.nested(value); + this.slot(voffset); + } + } + /** + * Structures are always stored inline, they need to be created right + * where they're used. You'll get this assertion failure if you + * created it elsewhere. + */ + nested(obj) { + if (obj != this.offset()) { + throw new TypeError("FlatBuffers: struct must be serialized inline."); + } + } + /** + * Should not be creating any other object, string or vector + * while an object is being constructed + */ + notNested() { + if (this.isNested) { + throw new TypeError("FlatBuffers: object serialization must not be nested."); + } + } + /** + * Set the current vtable at `voffset` to the current location in the buffer. + */ + slot(voffset) { + if (this.vtable !== null) + this.vtable[voffset] = this.offset(); + } + /** + * @returns Offset relative to the end of the buffer. + */ + offset() { + return this.bb.capacity() - this.space; + } + /** + * Doubles the size of the backing ByteBuffer and copies the old data towards + * the end of the new buffer (since we build the buffer backwards). + * + * @param bb The current buffer with the existing data + * @returns A new byte buffer with the old data copied + * to it. The data is located at the end of the buffer. + * + * uint8Array.set() formally takes {Array|ArrayBufferView}, so to pass + * it a uint8Array we need to suppress the type check: + * @suppress {checkTypes} + */ + static growByteBuffer(bb) { + const old_buf_size = bb.capacity(); + if (old_buf_size & 3221225472) { + throw new Error("FlatBuffers: cannot grow buffer beyond 2 gigabytes."); + } + const new_buf_size = old_buf_size << 1; + const nbb = byte_buffer_js_1.ByteBuffer.allocate(new_buf_size); + nbb.setPosition(new_buf_size - old_buf_size); + nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size); + return nbb; + } + /** + * Adds on offset, relative to where it will be written. + * + * @param offset The offset to add. + */ + addOffset(offset) { + this.prep(constants_js_1.SIZEOF_INT, 0); + this.writeInt32(this.offset() - offset + constants_js_1.SIZEOF_INT); + } + /** + * Start encoding a new object in the buffer. Users will not usually need to + * call this directly. The FlatBuffers compiler will generate helper methods + * that call this method internally. + */ + startObject(numfields) { + this.notNested(); + if (this.vtable == null) { + this.vtable = []; + } + this.vtable_in_use = numfields; + for (let i = 0; i < numfields; i++) { + this.vtable[i] = 0; + } + this.isNested = true; + this.object_start = this.offset(); + } + /** + * Finish off writing the object that is under construction. + * + * @returns The offset to the object inside `dataBuffer` + */ + endObject() { + if (this.vtable == null || !this.isNested) { + throw new Error("FlatBuffers: endObject called without startObject"); + } + this.addInt32(0); + const vtableloc = this.offset(); + let i = this.vtable_in_use - 1; + for (; i >= 0 && this.vtable[i] == 0; i--) { + } + const trimmed_size = i + 1; + for (; i >= 0; i--) { + this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0); + } + const standard_fields = 2; + this.addInt16(vtableloc - this.object_start); + const len = (trimmed_size + standard_fields) * constants_js_1.SIZEOF_SHORT; + this.addInt16(len); + let existing_vtable = 0; + const vt1 = this.space; + outer_loop: for (i = 0; i < this.vtables.length; i++) { + const vt2 = this.bb.capacity() - this.vtables[i]; + if (len == this.bb.readInt16(vt2)) { + for (let j = constants_js_1.SIZEOF_SHORT; j < len; j += constants_js_1.SIZEOF_SHORT) { + if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) { + continue outer_loop; + } + } + existing_vtable = this.vtables[i]; + break; + } + } + if (existing_vtable) { + this.space = this.bb.capacity() - vtableloc; + this.bb.writeInt32(this.space, existing_vtable - vtableloc); + } else { + this.vtables.push(this.offset()); + this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc); + } + this.isNested = false; + return vtableloc; + } + /** + * Finalize a buffer, poiting to the given `root_table`. + */ + finish(root_table, opt_file_identifier, opt_size_prefix) { + const size_prefix = opt_size_prefix ? constants_js_1.SIZE_PREFIX_LENGTH : 0; + if (opt_file_identifier) { + const file_identifier = opt_file_identifier; + this.prep(this.minalign, constants_js_1.SIZEOF_INT + constants_js_1.FILE_IDENTIFIER_LENGTH + size_prefix); + if (file_identifier.length != constants_js_1.FILE_IDENTIFIER_LENGTH) { + throw new TypeError("FlatBuffers: file identifier must be length " + constants_js_1.FILE_IDENTIFIER_LENGTH); + } + for (let i = constants_js_1.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) { + this.writeInt8(file_identifier.charCodeAt(i)); + } + } + this.prep(this.minalign, constants_js_1.SIZEOF_INT + size_prefix); + this.addOffset(root_table); + if (size_prefix) { + this.addInt32(this.bb.capacity() - this.space); + } + this.bb.setPosition(this.space); + } + /** + * Finalize a size prefixed buffer, pointing to the given `root_table`. + */ + finishSizePrefixed(root_table, opt_file_identifier) { + this.finish(root_table, opt_file_identifier, true); + } + /** + * This checks a required field has been set in a given table that has + * just been constructed. + */ + requiredField(table, field) { + const table_start = this.bb.capacity() - table; + const vtable_start = table_start - this.bb.readInt32(table_start); + const ok = field < this.bb.readInt16(vtable_start) && this.bb.readInt16(vtable_start + field) != 0; + if (!ok) { + throw new TypeError("FlatBuffers: field " + field + " must be set"); + } + } + /** + * Start a new array/vector of objects. Users usually will not call + * this directly. The FlatBuffers compiler will create a start/end + * method for vector types in generated code. + * + * @param elem_size The size of each element in the array + * @param num_elems The number of elements in the array + * @param alignment The alignment of the array + */ + startVector(elem_size, num_elems, alignment) { + this.notNested(); + this.vector_num_elems = num_elems; + this.prep(constants_js_1.SIZEOF_INT, elem_size * num_elems); + this.prep(alignment, elem_size * num_elems); + } + /** + * Finish off the creation of an array and all its elements. The array must be + * created with `startVector`. + * + * @returns The offset at which the newly created array + * starts. + */ + endVector() { + this.writeInt32(this.vector_num_elems); + return this.offset(); + } + /** + * Encode the string `s` in the buffer using UTF-8. If the string passed has + * already been seen, we return the offset of the already written string + * + * @param s The string to encode + * @return The offset in the buffer where the encoded string starts + */ + createSharedString(s) { + if (!s) { + return 0; + } + if (!this.string_maps) { + this.string_maps = /* @__PURE__ */ new Map(); + } + if (this.string_maps.has(s)) { + return this.string_maps.get(s); + } + const offset = this.createString(s); + this.string_maps.set(s, offset); + return offset; + } + /** + * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed + * instead of a string, it is assumed to contain valid UTF-8 encoded data. + * + * @param s The string to encode + * @return The offset in the buffer where the encoded string starts + */ + createString(s) { + if (s === null || s === void 0) { + return 0; + } + let utf8; + if (s instanceof Uint8Array) { + utf8 = s; + } else { + utf8 = this.text_encoder.encode(s); + } + this.addInt8(0); + this.startVector(1, utf8.length, 1); + this.bb.setPosition(this.space -= utf8.length); + this.bb.bytes().set(utf8, this.space); + return this.endVector(); + } + /** + * Create a byte vector. + * + * @param v The bytes to add + * @returns The offset in the buffer where the byte vector starts + */ + createByteVector(v) { + if (v === null || v === void 0) { + return 0; + } + this.startVector(1, v.length, 1); + this.bb.setPosition(this.space -= v.length); + this.bb.bytes().set(v, this.space); + return this.endVector(); + } + /** + * A helper function to pack an object + * + * @returns offset of obj + */ + createObjectOffset(obj) { + if (obj === null) { + return 0; + } + if (typeof obj === "string") { + return this.createString(obj); + } else { + return obj.pack(this); + } + } + /** + * A helper function to pack a list of object + * + * @returns list of offsets of each non null object + */ + createObjectOffsetList(list) { + const ret = []; + for (let i = 0; i < list.length; ++i) { + const val = list[i]; + if (val !== null) { + ret.push(this.createObjectOffset(val)); + } else { + throw new TypeError("FlatBuffers: Argument for createObjectOffsetList cannot contain null."); + } + } + return ret; + } + createStructOffsetList(list, startFunc) { + startFunc(this, list.length); + this.createObjectOffsetList(list.slice().reverse()); + return this.endVector(); + } + }; + exports2.Builder = Builder; + } + }); + + // web/node_modules/flatbuffers/js/flatbuffers.js + var require_flatbuffers = __commonJS({ + "web/node_modules/flatbuffers/js/flatbuffers.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ByteBuffer = exports2.Builder = exports2.Encoding = exports2.isLittleEndian = exports2.float64 = exports2.float32 = exports2.int32 = exports2.SIZE_PREFIX_LENGTH = exports2.FILE_IDENTIFIER_LENGTH = exports2.SIZEOF_INT = exports2.SIZEOF_SHORT = void 0; + var constants_js_1 = require_constants(); + Object.defineProperty(exports2, "SIZEOF_SHORT", { enumerable: true, get: function() { + return constants_js_1.SIZEOF_SHORT; + } }); + var constants_js_2 = require_constants(); + Object.defineProperty(exports2, "SIZEOF_INT", { enumerable: true, get: function() { + return constants_js_2.SIZEOF_INT; + } }); + var constants_js_3 = require_constants(); + Object.defineProperty(exports2, "FILE_IDENTIFIER_LENGTH", { enumerable: true, get: function() { + return constants_js_3.FILE_IDENTIFIER_LENGTH; + } }); + var constants_js_4 = require_constants(); + Object.defineProperty(exports2, "SIZE_PREFIX_LENGTH", { enumerable: true, get: function() { + return constants_js_4.SIZE_PREFIX_LENGTH; + } }); + var utils_js_1 = require_utils(); + Object.defineProperty(exports2, "int32", { enumerable: true, get: function() { + return utils_js_1.int32; + } }); + Object.defineProperty(exports2, "float32", { enumerable: true, get: function() { + return utils_js_1.float32; + } }); + Object.defineProperty(exports2, "float64", { enumerable: true, get: function() { + return utils_js_1.float64; + } }); + Object.defineProperty(exports2, "isLittleEndian", { enumerable: true, get: function() { + return utils_js_1.isLittleEndian; + } }); + var encoding_js_1 = require_encoding(); + Object.defineProperty(exports2, "Encoding", { enumerable: true, get: function() { + return encoding_js_1.Encoding; + } }); + var builder_js_1 = require_builder(); + Object.defineProperty(exports2, "Builder", { enumerable: true, get: function() { + return builder_js_1.Builder; + } }); + var byte_buffer_js_1 = require_byte_buffer(); + Object.defineProperty(exports2, "ByteBuffer", { enumerable: true, get: function() { + return byte_buffer_js_1.ByteBuffer; + } }); + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type-and-index.js + var require_arg_type_and_index = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/arg-type-and-index.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ArgTypeAndIndex = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var arg_type_js_1 = require_arg_type(); + var ArgTypeAndIndex2 = class _ArgTypeAndIndex { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsArgTypeAndIndex(bb, obj) { + return (obj || new _ArgTypeAndIndex()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsArgTypeAndIndex(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _ArgTypeAndIndex()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + argType() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readInt8(this.bb_pos + offset) : arg_type_js_1.ArgType.INPUT; + } + index() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + static startArgTypeAndIndex(builder) { + builder.startObject(2); + } + static addArgType(builder, argType) { + builder.addFieldInt8(0, argType, arg_type_js_1.ArgType.INPUT); + } + static addIndex(builder, index) { + builder.addFieldInt32(1, index, 0); + } + static endArgTypeAndIndex(builder) { + const offset = builder.endObject(); + return offset; + } + static createArgTypeAndIndex(builder, argType, index) { + _ArgTypeAndIndex.startArgTypeAndIndex(builder); + _ArgTypeAndIndex.addArgType(builder, argType); + _ArgTypeAndIndex.addIndex(builder, index); + return _ArgTypeAndIndex.endArgTypeAndIndex(builder); + } + }; + exports2.ArgTypeAndIndex = ArgTypeAndIndex2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute-type.js + var require_attribute_type = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute-type.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.AttributeType = void 0; + var AttributeType2; + (function(AttributeType3) { + AttributeType3[AttributeType3["UNDEFINED"] = 0] = "UNDEFINED"; + AttributeType3[AttributeType3["FLOAT"] = 1] = "FLOAT"; + AttributeType3[AttributeType3["INT"] = 2] = "INT"; + AttributeType3[AttributeType3["STRING"] = 3] = "STRING"; + AttributeType3[AttributeType3["TENSOR"] = 4] = "TENSOR"; + AttributeType3[AttributeType3["GRAPH"] = 5] = "GRAPH"; + AttributeType3[AttributeType3["FLOATS"] = 6] = "FLOATS"; + AttributeType3[AttributeType3["INTS"] = 7] = "INTS"; + AttributeType3[AttributeType3["STRINGS"] = 8] = "STRINGS"; + AttributeType3[AttributeType3["TENSORS"] = 9] = "TENSORS"; + AttributeType3[AttributeType3["GRAPHS"] = 10] = "GRAPHS"; + AttributeType3[AttributeType3["SPARSE_TENSOR"] = 11] = "SPARSE_TENSOR"; + AttributeType3[AttributeType3["SPARSE_TENSORS"] = 12] = "SPARSE_TENSORS"; + })(AttributeType2 || (exports2.AttributeType = AttributeType2 = {})); + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-type.js + var require_node_type = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-type.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.NodeType = void 0; + var NodeType2; + (function(NodeType3) { + NodeType3[NodeType3["Primitive"] = 0] = "Primitive"; + NodeType3[NodeType3["Fused"] = 1] = "Fused"; + })(NodeType2 || (exports2.NodeType = NodeType2 = {})); + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node.js + var require_node = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Node = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var attribute_js_1 = require_attribute(); + var node_type_js_1 = require_node_type(); + var Node3 = class _Node { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsNode(bb, obj) { + return (obj || new _Node()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsNode(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _Node()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + name(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + docString(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + domain(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + sinceVersion() { + const offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.readInt32(this.bb_pos + offset) : 0; + } + index() { + const offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + opType(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + type() { + const offset = this.bb.__offset(this.bb_pos, 16); + return offset ? this.bb.readInt32(this.bb_pos + offset) : node_type_js_1.NodeType.Primitive; + } + executionProviderType(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 18); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + inputs(index, optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + inputsLength() { + const offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + outputs(index, optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 22); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + outputsLength() { + const offset = this.bb.__offset(this.bb_pos, 22); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + attributes(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 24); + return offset ? (obj || new attribute_js_1.Attribute()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + attributesLength() { + const offset = this.bb.__offset(this.bb_pos, 24); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + inputArgCounts(index) { + const offset = this.bb.__offset(this.bb_pos, 26); + return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; + } + inputArgCountsLength() { + const offset = this.bb.__offset(this.bb_pos, 26); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + inputArgCountsArray() { + const offset = this.bb.__offset(this.bb_pos, 26); + return offset ? new Int32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null; + } + implicitInputs(index, optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 28); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + implicitInputsLength() { + const offset = this.bb.__offset(this.bb_pos, 28); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startNode(builder) { + builder.startObject(13); + } + static addName(builder, nameOffset) { + builder.addFieldOffset(0, nameOffset, 0); + } + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(1, docStringOffset, 0); + } + static addDomain(builder, domainOffset) { + builder.addFieldOffset(2, domainOffset, 0); + } + static addSinceVersion(builder, sinceVersion) { + builder.addFieldInt32(3, sinceVersion, 0); + } + static addIndex(builder, index) { + builder.addFieldInt32(4, index, 0); + } + static addOpType(builder, opTypeOffset) { + builder.addFieldOffset(5, opTypeOffset, 0); + } + static addType(builder, type) { + builder.addFieldInt32(6, type, node_type_js_1.NodeType.Primitive); + } + static addExecutionProviderType(builder, executionProviderTypeOffset) { + builder.addFieldOffset(7, executionProviderTypeOffset, 0); + } + static addInputs(builder, inputsOffset) { + builder.addFieldOffset(8, inputsOffset, 0); + } + static createInputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startInputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addOutputs(builder, outputsOffset) { + builder.addFieldOffset(9, outputsOffset, 0); + } + static createOutputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startOutputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addAttributes(builder, attributesOffset) { + builder.addFieldOffset(10, attributesOffset, 0); + } + static createAttributesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startAttributesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addInputArgCounts(builder, inputArgCountsOffset) { + builder.addFieldOffset(11, inputArgCountsOffset, 0); + } + static createInputArgCountsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); + } + static startInputArgCountsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addImplicitInputs(builder, implicitInputsOffset) { + builder.addFieldOffset(12, implicitInputsOffset, 0); + } + static createImplicitInputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startImplicitInputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endNode(builder) { + const offset = builder.endObject(); + return offset; + } + static createNode(builder, nameOffset, docStringOffset, domainOffset, sinceVersion, index, opTypeOffset, type, executionProviderTypeOffset, inputsOffset, outputsOffset, attributesOffset, inputArgCountsOffset, implicitInputsOffset) { + _Node.startNode(builder); + _Node.addName(builder, nameOffset); + _Node.addDocString(builder, docStringOffset); + _Node.addDomain(builder, domainOffset); + _Node.addSinceVersion(builder, sinceVersion); + _Node.addIndex(builder, index); + _Node.addOpType(builder, opTypeOffset); + _Node.addType(builder, type); + _Node.addExecutionProviderType(builder, executionProviderTypeOffset); + _Node.addInputs(builder, inputsOffset); + _Node.addOutputs(builder, outputsOffset); + _Node.addAttributes(builder, attributesOffset); + _Node.addInputArgCounts(builder, inputArgCountsOffset); + _Node.addImplicitInputs(builder, implicitInputsOffset); + return _Node.endNode(builder); + } + }; + exports2.Node = Node3; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/edge-end.js + var require_edge_end = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/edge-end.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.EdgeEnd = void 0; + var EdgeEnd2 = class { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + nodeIndex() { + return this.bb.readUint32(this.bb_pos); + } + srcArgIndex() { + return this.bb.readInt32(this.bb_pos + 4); + } + dstArgIndex() { + return this.bb.readInt32(this.bb_pos + 8); + } + static sizeOf() { + return 12; + } + static createEdgeEnd(builder, node_index, src_arg_index, dst_arg_index) { + builder.prep(4, 12); + builder.writeInt32(dst_arg_index); + builder.writeInt32(src_arg_index); + builder.writeInt32(node_index); + return builder.offset(); + } + }; + exports2.EdgeEnd = EdgeEnd2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-edge.js + var require_node_edge = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/node-edge.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.NodeEdge = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var edge_end_js_1 = require_edge_end(); + var NodeEdge2 = class _NodeEdge { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsNodeEdge(bb, obj) { + return (obj || new _NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsNodeEdge(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + nodeIndex() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + inputEdges(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new edge_end_js_1.EdgeEnd()).__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) : null; + } + inputEdgesLength() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + outputEdges(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? (obj || new edge_end_js_1.EdgeEnd()).__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) : null; + } + outputEdgesLength() { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startNodeEdge(builder) { + builder.startObject(3); + } + static addNodeIndex(builder, nodeIndex) { + builder.addFieldInt32(0, nodeIndex, 0); + } + static addInputEdges(builder, inputEdgesOffset) { + builder.addFieldOffset(1, inputEdgesOffset, 0); + } + static startInputEdgesVector(builder, numElems) { + builder.startVector(12, numElems, 4); + } + static addOutputEdges(builder, outputEdgesOffset) { + builder.addFieldOffset(2, outputEdgesOffset, 0); + } + static startOutputEdgesVector(builder, numElems) { + builder.startVector(12, numElems, 4); + } + static endNodeEdge(builder) { + const offset = builder.endObject(); + return offset; + } + static createNodeEdge(builder, nodeIndex, inputEdgesOffset, outputEdgesOffset) { + _NodeEdge.startNodeEdge(builder); + _NodeEdge.addNodeIndex(builder, nodeIndex); + _NodeEdge.addInputEdges(builder, inputEdgesOffset); + _NodeEdge.addOutputEdges(builder, outputEdgesOffset); + return _NodeEdge.endNodeEdge(builder); + } + }; + exports2.NodeEdge = NodeEdge2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/nodes-to-optimize-indices.js + var require_nodes_to_optimize_indices = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/nodes-to-optimize-indices.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.NodesToOptimizeIndices = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var NodesToOptimizeIndices2 = class _NodesToOptimizeIndices { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsNodesToOptimizeIndices(bb, obj) { + return (obj || new _NodesToOptimizeIndices()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsNodesToOptimizeIndices(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _NodesToOptimizeIndices()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + nodeIndices(index) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readUint32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; + } + nodeIndicesLength() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + nodeIndicesArray() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? new Uint32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null; + } + numInputs() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + numOutputs() { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + hasVariadicInput() { + const offset = this.bb.__offset(this.bb_pos, 10); + return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; + } + hasVariadicOutput() { + const offset = this.bb.__offset(this.bb_pos, 12); + return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; + } + numVariadicInputs() { + const offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + numVariadicOutputs() { + const offset = this.bb.__offset(this.bb_pos, 16); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + static startNodesToOptimizeIndices(builder) { + builder.startObject(7); + } + static addNodeIndices(builder, nodeIndicesOffset) { + builder.addFieldOffset(0, nodeIndicesOffset, 0); + } + static createNodeIndicesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); + } + static startNodeIndicesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addNumInputs(builder, numInputs) { + builder.addFieldInt32(1, numInputs, 0); + } + static addNumOutputs(builder, numOutputs) { + builder.addFieldInt32(2, numOutputs, 0); + } + static addHasVariadicInput(builder, hasVariadicInput) { + builder.addFieldInt8(3, +hasVariadicInput, 0); + } + static addHasVariadicOutput(builder, hasVariadicOutput) { + builder.addFieldInt8(4, +hasVariadicOutput, 0); + } + static addNumVariadicInputs(builder, numVariadicInputs) { + builder.addFieldInt32(5, numVariadicInputs, 0); + } + static addNumVariadicOutputs(builder, numVariadicOutputs) { + builder.addFieldInt32(6, numVariadicOutputs, 0); + } + static endNodesToOptimizeIndices(builder) { + const offset = builder.endObject(); + return offset; + } + static createNodesToOptimizeIndices(builder, nodeIndicesOffset, numInputs, numOutputs, hasVariadicInput, hasVariadicOutput, numVariadicInputs, numVariadicOutputs) { + _NodesToOptimizeIndices.startNodesToOptimizeIndices(builder); + _NodesToOptimizeIndices.addNodeIndices(builder, nodeIndicesOffset); + _NodesToOptimizeIndices.addNumInputs(builder, numInputs); + _NodesToOptimizeIndices.addNumOutputs(builder, numOutputs); + _NodesToOptimizeIndices.addHasVariadicInput(builder, hasVariadicInput); + _NodesToOptimizeIndices.addHasVariadicOutput(builder, hasVariadicOutput); + _NodesToOptimizeIndices.addNumVariadicInputs(builder, numVariadicInputs); + _NodesToOptimizeIndices.addNumVariadicOutputs(builder, numVariadicOutputs); + return _NodesToOptimizeIndices.endNodesToOptimizeIndices(builder); + } + }; + exports2.NodesToOptimizeIndices = NodesToOptimizeIndices2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record.js + var require_runtime_optimization_record = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.RuntimeOptimizationRecord = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var nodes_to_optimize_indices_js_1 = require_nodes_to_optimize_indices(); + var RuntimeOptimizationRecord2 = class _RuntimeOptimizationRecord { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsRuntimeOptimizationRecord(bb, obj) { + return (obj || new _RuntimeOptimizationRecord()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsRuntimeOptimizationRecord(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _RuntimeOptimizationRecord()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + actionId(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + nodesToOptimizeIndices(obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new nodes_to_optimize_indices_js_1.NodesToOptimizeIndices()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + producedOpIds(index, optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + producedOpIdsLength() { + const offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startRuntimeOptimizationRecord(builder) { + builder.startObject(4); + } + static addActionId(builder, actionIdOffset) { + builder.addFieldOffset(0, actionIdOffset, 0); + } + static addNodesToOptimizeIndices(builder, nodesToOptimizeIndicesOffset) { + builder.addFieldOffset(1, nodesToOptimizeIndicesOffset, 0); + } + static addProducedOpIds(builder, producedOpIdsOffset) { + builder.addFieldOffset(3, producedOpIdsOffset, 0); + } + static createProducedOpIdsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startProducedOpIdsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endRuntimeOptimizationRecord(builder) { + const offset = builder.endObject(); + return offset; + } + }; + exports2.RuntimeOptimizationRecord = RuntimeOptimizationRecord2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record-container-entry.js + var require_runtime_optimization_record_container_entry = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimization-record-container-entry.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.RuntimeOptimizationRecordContainerEntry = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var runtime_optimization_record_js_1 = require_runtime_optimization_record(); + var RuntimeOptimizationRecordContainerEntry2 = class _RuntimeOptimizationRecordContainerEntry { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsRuntimeOptimizationRecordContainerEntry(bb, obj) { + return (obj || new _RuntimeOptimizationRecordContainerEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsRuntimeOptimizationRecordContainerEntry(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _RuntimeOptimizationRecordContainerEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + optimizerName(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + runtimeOptimizationRecords(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new runtime_optimization_record_js_1.RuntimeOptimizationRecord()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + runtimeOptimizationRecordsLength() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startRuntimeOptimizationRecordContainerEntry(builder) { + builder.startObject(2); + } + static addOptimizerName(builder, optimizerNameOffset) { + builder.addFieldOffset(0, optimizerNameOffset, 0); + } + static addRuntimeOptimizationRecords(builder, runtimeOptimizationRecordsOffset) { + builder.addFieldOffset(1, runtimeOptimizationRecordsOffset, 0); + } + static createRuntimeOptimizationRecordsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startRuntimeOptimizationRecordsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endRuntimeOptimizationRecordContainerEntry(builder) { + const offset = builder.endObject(); + builder.requiredField(offset, 4); + return offset; + } + static createRuntimeOptimizationRecordContainerEntry(builder, optimizerNameOffset, runtimeOptimizationRecordsOffset) { + _RuntimeOptimizationRecordContainerEntry.startRuntimeOptimizationRecordContainerEntry(builder); + _RuntimeOptimizationRecordContainerEntry.addOptimizerName(builder, optimizerNameOffset); + _RuntimeOptimizationRecordContainerEntry.addRuntimeOptimizationRecords(builder, runtimeOptimizationRecordsOffset); + return _RuntimeOptimizationRecordContainerEntry.endRuntimeOptimizationRecordContainerEntry(builder); + } + }; + exports2.RuntimeOptimizationRecordContainerEntry = RuntimeOptimizationRecordContainerEntry2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimizations.js + var require_runtime_optimizations = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/runtime-optimizations.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.RuntimeOptimizations = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var runtime_optimization_record_container_entry_js_1 = require_runtime_optimization_record_container_entry(); + var RuntimeOptimizations2 = class _RuntimeOptimizations { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsRuntimeOptimizations(bb, obj) { + return (obj || new _RuntimeOptimizations()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsRuntimeOptimizations(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _RuntimeOptimizations()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * mapping from optimizer name to [RuntimeOptimizationRecord] + */ + records(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new runtime_optimization_record_container_entry_js_1.RuntimeOptimizationRecordContainerEntry()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + recordsLength() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startRuntimeOptimizations(builder) { + builder.startObject(1); + } + static addRecords(builder, recordsOffset) { + builder.addFieldOffset(0, recordsOffset, 0); + } + static createRecordsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startRecordsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endRuntimeOptimizations(builder) { + const offset = builder.endObject(); + return offset; + } + static createRuntimeOptimizations(builder, recordsOffset) { + _RuntimeOptimizations.startRuntimeOptimizations(builder); + _RuntimeOptimizations.addRecords(builder, recordsOffset); + return _RuntimeOptimizations.endRuntimeOptimizations(builder); + } + }; + exports2.RuntimeOptimizations = RuntimeOptimizations2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-data-type.js + var require_tensor_data_type = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-data-type.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TensorDataType = void 0; + var TensorDataType2; + (function(TensorDataType3) { + TensorDataType3[TensorDataType3["UNDEFINED"] = 0] = "UNDEFINED"; + TensorDataType3[TensorDataType3["FLOAT"] = 1] = "FLOAT"; + TensorDataType3[TensorDataType3["UINT8"] = 2] = "UINT8"; + TensorDataType3[TensorDataType3["INT8"] = 3] = "INT8"; + TensorDataType3[TensorDataType3["UINT16"] = 4] = "UINT16"; + TensorDataType3[TensorDataType3["INT16"] = 5] = "INT16"; + TensorDataType3[TensorDataType3["INT32"] = 6] = "INT32"; + TensorDataType3[TensorDataType3["INT64"] = 7] = "INT64"; + TensorDataType3[TensorDataType3["STRING"] = 8] = "STRING"; + TensorDataType3[TensorDataType3["BOOL"] = 9] = "BOOL"; + TensorDataType3[TensorDataType3["FLOAT16"] = 10] = "FLOAT16"; + TensorDataType3[TensorDataType3["DOUBLE"] = 11] = "DOUBLE"; + TensorDataType3[TensorDataType3["UINT32"] = 12] = "UINT32"; + TensorDataType3[TensorDataType3["UINT64"] = 13] = "UINT64"; + TensorDataType3[TensorDataType3["COMPLEX64"] = 14] = "COMPLEX64"; + TensorDataType3[TensorDataType3["COMPLEX128"] = 15] = "COMPLEX128"; + TensorDataType3[TensorDataType3["BFLOAT16"] = 16] = "BFLOAT16"; + TensorDataType3[TensorDataType3["FLOAT8E4M3FN"] = 17] = "FLOAT8E4M3FN"; + TensorDataType3[TensorDataType3["FLOAT8E4M3FNUZ"] = 18] = "FLOAT8E4M3FNUZ"; + TensorDataType3[TensorDataType3["FLOAT8E5M2"] = 19] = "FLOAT8E5M2"; + TensorDataType3[TensorDataType3["FLOAT8E5M2FNUZ"] = 20] = "FLOAT8E5M2FNUZ"; + })(TensorDataType2 || (exports2.TensorDataType = TensorDataType2 = {})); + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor.js + var require_tensor = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Tensor = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var tensor_data_type_js_1 = require_tensor_data_type(); + var Tensor6 = class _Tensor { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsTensor(bb, obj) { + return (obj || new _Tensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsTensor(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _Tensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + name(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + docString(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + dims(index) { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); + } + dimsLength() { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + dataType() { + const offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.readInt32(this.bb_pos + offset) : tensor_data_type_js_1.TensorDataType.UNDEFINED; + } + rawData(index) { + const offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0; + } + rawDataLength() { + const offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + rawDataArray() { + const offset = this.bb.__offset(this.bb_pos, 12); + return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null; + } + stringData(index, optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + stringDataLength() { + const offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + externalDataOffset() { + const offset = this.bb.__offset(this.bb_pos, 16); + return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("-1"); + } + static startTensor(builder) { + builder.startObject(7); + } + static addName(builder, nameOffset) { + builder.addFieldOffset(0, nameOffset, 0); + } + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(1, docStringOffset, 0); + } + static addDims(builder, dimsOffset) { + builder.addFieldOffset(2, dimsOffset, 0); + } + static createDimsVector(builder, data) { + builder.startVector(8, data.length, 8); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt64(data[i]); + } + return builder.endVector(); + } + static startDimsVector(builder, numElems) { + builder.startVector(8, numElems, 8); + } + static addDataType(builder, dataType) { + builder.addFieldInt32(3, dataType, tensor_data_type_js_1.TensorDataType.UNDEFINED); + } + static addRawData(builder, rawDataOffset) { + builder.addFieldOffset(4, rawDataOffset, 0); + } + static createRawDataVector(builder, data) { + builder.startVector(1, data.length, 1); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt8(data[i]); + } + return builder.endVector(); + } + static startRawDataVector(builder, numElems) { + builder.startVector(1, numElems, 1); + } + static addStringData(builder, stringDataOffset) { + builder.addFieldOffset(5, stringDataOffset, 0); + } + static createStringDataVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startStringDataVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addExternalDataOffset(builder, externalDataOffset) { + builder.addFieldInt64(6, externalDataOffset, BigInt("-1")); + } + static endTensor(builder) { + const offset = builder.endObject(); + return offset; + } + static createTensor(builder, nameOffset, docStringOffset, dimsOffset, dataType, rawDataOffset, stringDataOffset, externalDataOffset) { + _Tensor.startTensor(builder); + _Tensor.addName(builder, nameOffset); + _Tensor.addDocString(builder, docStringOffset); + _Tensor.addDims(builder, dimsOffset); + _Tensor.addDataType(builder, dataType); + _Tensor.addRawData(builder, rawDataOffset); + _Tensor.addStringData(builder, stringDataOffset); + _Tensor.addExternalDataOffset(builder, externalDataOffset); + return _Tensor.endTensor(builder); + } + }; + exports2.Tensor = Tensor6; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sparse-tensor.js + var require_sparse_tensor = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sparse-tensor.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SparseTensor = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var tensor_js_1 = require_tensor(); + var SparseTensor2 = class _SparseTensor { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsSparseTensor(bb, obj) { + return (obj || new _SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsSparseTensor(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + values(obj) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + indices(obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + dims(index) { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); + } + dimsLength() { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startSparseTensor(builder) { + builder.startObject(3); + } + static addValues(builder, valuesOffset) { + builder.addFieldOffset(0, valuesOffset, 0); + } + static addIndices(builder, indicesOffset) { + builder.addFieldOffset(1, indicesOffset, 0); + } + static addDims(builder, dimsOffset) { + builder.addFieldOffset(2, dimsOffset, 0); + } + static createDimsVector(builder, data) { + builder.startVector(8, data.length, 8); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt64(data[i]); + } + return builder.endVector(); + } + static startDimsVector(builder, numElems) { + builder.startVector(8, numElems, 8); + } + static endSparseTensor(builder) { + const offset = builder.endObject(); + return offset; + } + }; + exports2.SparseTensor = SparseTensor2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/map-type.js + var require_map_type = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/map-type.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.MapType = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var tensor_data_type_js_1 = require_tensor_data_type(); + var type_info_js_1 = require_type_info(); + var MapType2 = class _MapType { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsMapType(bb, obj) { + return (obj || new _MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsMapType(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + keyType() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readInt32(this.bb_pos + offset) : tensor_data_type_js_1.TensorDataType.UNDEFINED; + } + valueType(obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new type_info_js_1.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + static startMapType(builder) { + builder.startObject(2); + } + static addKeyType(builder, keyType) { + builder.addFieldInt32(0, keyType, tensor_data_type_js_1.TensorDataType.UNDEFINED); + } + static addValueType(builder, valueTypeOffset) { + builder.addFieldOffset(1, valueTypeOffset, 0); + } + static endMapType(builder) { + const offset = builder.endObject(); + return offset; + } + }; + exports2.MapType = MapType2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sequence-type.js + var require_sequence_type = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/sequence-type.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.SequenceType = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var type_info_js_1 = require_type_info(); + var SequenceType2 = class _SequenceType { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsSequenceType(bb, obj) { + return (obj || new _SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsSequenceType(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + elemType(obj) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new type_info_js_1.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + static startSequenceType(builder) { + builder.startObject(1); + } + static addElemType(builder, elemTypeOffset) { + builder.addFieldOffset(0, elemTypeOffset, 0); + } + static endSequenceType(builder) { + const offset = builder.endObject(); + return offset; + } + static createSequenceType(builder, elemTypeOffset) { + _SequenceType.startSequenceType(builder); + _SequenceType.addElemType(builder, elemTypeOffset); + return _SequenceType.endSequenceType(builder); + } + }; + exports2.SequenceType = SequenceType2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value-type.js + var require_dimension_value_type = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value-type.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DimensionValueType = void 0; + var DimensionValueType2; + (function(DimensionValueType3) { + DimensionValueType3[DimensionValueType3["UNKNOWN"] = 0] = "UNKNOWN"; + DimensionValueType3[DimensionValueType3["VALUE"] = 1] = "VALUE"; + DimensionValueType3[DimensionValueType3["PARAM"] = 2] = "PARAM"; + })(DimensionValueType2 || (exports2.DimensionValueType = DimensionValueType2 = {})); + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value.js + var require_dimension_value = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension-value.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DimensionValue = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var dimension_value_type_js_1 = require_dimension_value_type(); + var DimensionValue2 = class _DimensionValue { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsDimensionValue(bb, obj) { + return (obj || new _DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsDimensionValue(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + dimType() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readInt8(this.bb_pos + offset) : dimension_value_type_js_1.DimensionValueType.UNKNOWN; + } + dimValue() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); + } + dimParam(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + static startDimensionValue(builder) { + builder.startObject(3); + } + static addDimType(builder, dimType) { + builder.addFieldInt8(0, dimType, dimension_value_type_js_1.DimensionValueType.UNKNOWN); + } + static addDimValue(builder, dimValue) { + builder.addFieldInt64(1, dimValue, BigInt("0")); + } + static addDimParam(builder, dimParamOffset) { + builder.addFieldOffset(2, dimParamOffset, 0); + } + static endDimensionValue(builder) { + const offset = builder.endObject(); + return offset; + } + static createDimensionValue(builder, dimType, dimValue, dimParamOffset) { + _DimensionValue.startDimensionValue(builder); + _DimensionValue.addDimType(builder, dimType); + _DimensionValue.addDimValue(builder, dimValue); + _DimensionValue.addDimParam(builder, dimParamOffset); + return _DimensionValue.endDimensionValue(builder); + } + }; + exports2.DimensionValue = DimensionValue2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension.js + var require_dimension = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/dimension.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Dimension = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var dimension_value_js_1 = require_dimension_value(); + var Dimension2 = class _Dimension { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsDimension(bb, obj) { + return (obj || new _Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsDimension(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + value(obj) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new dimension_value_js_1.DimensionValue()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + denotation(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + static startDimension(builder) { + builder.startObject(2); + } + static addValue(builder, valueOffset) { + builder.addFieldOffset(0, valueOffset, 0); + } + static addDenotation(builder, denotationOffset) { + builder.addFieldOffset(1, denotationOffset, 0); + } + static endDimension(builder) { + const offset = builder.endObject(); + return offset; + } + static createDimension(builder, valueOffset, denotationOffset) { + _Dimension.startDimension(builder); + _Dimension.addValue(builder, valueOffset); + _Dimension.addDenotation(builder, denotationOffset); + return _Dimension.endDimension(builder); + } + }; + exports2.Dimension = Dimension2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/shape.js + var require_shape = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/shape.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Shape = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var dimension_js_1 = require_dimension(); + var Shape2 = class _Shape { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsShape(bb, obj) { + return (obj || new _Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsShape(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + dim(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new dimension_js_1.Dimension()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + dimLength() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startShape(builder) { + builder.startObject(1); + } + static addDim(builder, dimOffset) { + builder.addFieldOffset(0, dimOffset, 0); + } + static createDimVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startDimVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endShape(builder) { + const offset = builder.endObject(); + return offset; + } + static createShape(builder, dimOffset) { + _Shape.startShape(builder); + _Shape.addDim(builder, dimOffset); + return _Shape.endShape(builder); + } + }; + exports2.Shape = Shape2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-type-and-shape.js + var require_tensor_type_and_shape = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/tensor-type-and-shape.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TensorTypeAndShape = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var shape_js_1 = require_shape(); + var tensor_data_type_js_1 = require_tensor_data_type(); + var TensorTypeAndShape2 = class _TensorTypeAndShape { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsTensorTypeAndShape(bb, obj) { + return (obj || new _TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsTensorTypeAndShape(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + elemType() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readInt32(this.bb_pos + offset) : tensor_data_type_js_1.TensorDataType.UNDEFINED; + } + shape(obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new shape_js_1.Shape()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + static startTensorTypeAndShape(builder) { + builder.startObject(2); + } + static addElemType(builder, elemType) { + builder.addFieldInt32(0, elemType, tensor_data_type_js_1.TensorDataType.UNDEFINED); + } + static addShape(builder, shapeOffset) { + builder.addFieldOffset(1, shapeOffset, 0); + } + static endTensorTypeAndShape(builder) { + const offset = builder.endObject(); + return offset; + } + }; + exports2.TensorTypeAndShape = TensorTypeAndShape2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info-value.js + var require_type_info_value = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info-value.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.unionListToTypeInfoValue = exports2.unionToTypeInfoValue = exports2.TypeInfoValue = void 0; + var map_type_js_1 = require_map_type(); + var sequence_type_js_1 = require_sequence_type(); + var tensor_type_and_shape_js_1 = require_tensor_type_and_shape(); + var TypeInfoValue2; + (function(TypeInfoValue3) { + TypeInfoValue3[TypeInfoValue3["NONE"] = 0] = "NONE"; + TypeInfoValue3[TypeInfoValue3["tensor_type"] = 1] = "tensor_type"; + TypeInfoValue3[TypeInfoValue3["sequence_type"] = 2] = "sequence_type"; + TypeInfoValue3[TypeInfoValue3["map_type"] = 3] = "map_type"; + })(TypeInfoValue2 || (exports2.TypeInfoValue = TypeInfoValue2 = {})); + function unionToTypeInfoValue(type, accessor) { + switch (TypeInfoValue2[type]) { + case "NONE": + return null; + case "tensor_type": + return accessor(new tensor_type_and_shape_js_1.TensorTypeAndShape()); + case "sequence_type": + return accessor(new sequence_type_js_1.SequenceType()); + case "map_type": + return accessor(new map_type_js_1.MapType()); + default: + return null; + } + } + exports2.unionToTypeInfoValue = unionToTypeInfoValue; + function unionListToTypeInfoValue(type, accessor, index) { + switch (TypeInfoValue2[type]) { + case "NONE": + return null; + case "tensor_type": + return accessor(index, new tensor_type_and_shape_js_1.TensorTypeAndShape()); + case "sequence_type": + return accessor(index, new sequence_type_js_1.SequenceType()); + case "map_type": + return accessor(index, new map_type_js_1.MapType()); + default: + return null; + } + } + exports2.unionListToTypeInfoValue = unionListToTypeInfoValue; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info.js + var require_type_info = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/type-info.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.TypeInfo = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var type_info_value_js_1 = require_type_info_value(); + var TypeInfo2 = class _TypeInfo { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsTypeInfo(bb, obj) { + return (obj || new _TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsTypeInfo(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + denotation(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + valueType() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readUint8(this.bb_pos + offset) : type_info_value_js_1.TypeInfoValue.NONE; + } + value(obj) { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__union(obj, this.bb_pos + offset) : null; + } + static startTypeInfo(builder) { + builder.startObject(3); + } + static addDenotation(builder, denotationOffset) { + builder.addFieldOffset(0, denotationOffset, 0); + } + static addValueType(builder, valueType) { + builder.addFieldInt8(1, valueType, type_info_value_js_1.TypeInfoValue.NONE); + } + static addValue(builder, valueOffset) { + builder.addFieldOffset(2, valueOffset, 0); + } + static endTypeInfo(builder) { + const offset = builder.endObject(); + return offset; + } + static createTypeInfo(builder, denotationOffset, valueType, valueOffset) { + _TypeInfo.startTypeInfo(builder); + _TypeInfo.addDenotation(builder, denotationOffset); + _TypeInfo.addValueType(builder, valueType); + _TypeInfo.addValue(builder, valueOffset); + return _TypeInfo.endTypeInfo(builder); + } + }; + exports2.TypeInfo = TypeInfo2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/value-info.js + var require_value_info = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/value-info.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.ValueInfo = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var type_info_js_1 = require_type_info(); + var ValueInfo2 = class _ValueInfo { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsValueInfo(bb, obj) { + return (obj || new _ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsValueInfo(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + name(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + docString(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + type(obj) { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? (obj || new type_info_js_1.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + static startValueInfo(builder) { + builder.startObject(3); + } + static addName(builder, nameOffset) { + builder.addFieldOffset(0, nameOffset, 0); + } + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(1, docStringOffset, 0); + } + static addType(builder, typeOffset) { + builder.addFieldOffset(2, typeOffset, 0); + } + static endValueInfo(builder) { + const offset = builder.endObject(); + return offset; + } + }; + exports2.ValueInfo = ValueInfo2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/graph.js + var require_graph = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/graph.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Graph = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var node_js_1 = require_node(); + var node_edge_js_1 = require_node_edge(); + var runtime_optimizations_js_1 = require_runtime_optimizations(); + var sparse_tensor_js_1 = require_sparse_tensor(); + var tensor_js_1 = require_tensor(); + var value_info_js_1 = require_value_info(); + var Graph3 = class _Graph { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsGraph(bb, obj) { + return (obj || new _Graph()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsGraph(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _Graph()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + initializers(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + initializersLength() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + nodeArgs(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new value_info_js_1.ValueInfo()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + nodeArgsLength() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + nodes(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? (obj || new node_js_1.Node()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + nodesLength() { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + maxNodeIndex() { + const offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + nodeEdges(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 12); + return offset ? (obj || new node_edge_js_1.NodeEdge()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + nodeEdgesLength() { + const offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + inputs(index, optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + inputsLength() { + const offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + outputs(index, optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 16); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + outputsLength() { + const offset = this.bb.__offset(this.bb_pos, 16); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + sparseInitializers(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 18); + return offset ? (obj || new sparse_tensor_js_1.SparseTensor()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + sparseInitializersLength() { + const offset = this.bb.__offset(this.bb_pos, 18); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + runtimeOptimizations(obj) { + const offset = this.bb.__offset(this.bb_pos, 20); + return offset ? (obj || new runtime_optimizations_js_1.RuntimeOptimizations()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + static startGraph(builder) { + builder.startObject(9); + } + static addInitializers(builder, initializersOffset) { + builder.addFieldOffset(0, initializersOffset, 0); + } + static createInitializersVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startInitializersVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addNodeArgs(builder, nodeArgsOffset) { + builder.addFieldOffset(1, nodeArgsOffset, 0); + } + static createNodeArgsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startNodeArgsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addNodes(builder, nodesOffset) { + builder.addFieldOffset(2, nodesOffset, 0); + } + static createNodesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startNodesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addMaxNodeIndex(builder, maxNodeIndex) { + builder.addFieldInt32(3, maxNodeIndex, 0); + } + static addNodeEdges(builder, nodeEdgesOffset) { + builder.addFieldOffset(4, nodeEdgesOffset, 0); + } + static createNodeEdgesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startNodeEdgesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addInputs(builder, inputsOffset) { + builder.addFieldOffset(5, inputsOffset, 0); + } + static createInputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startInputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addOutputs(builder, outputsOffset) { + builder.addFieldOffset(6, outputsOffset, 0); + } + static createOutputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startOutputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addSparseInitializers(builder, sparseInitializersOffset) { + builder.addFieldOffset(7, sparseInitializersOffset, 0); + } + static createSparseInitializersVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startSparseInitializersVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addRuntimeOptimizations(builder, runtimeOptimizationsOffset) { + builder.addFieldOffset(8, runtimeOptimizationsOffset, 0); + } + static endGraph(builder) { + const offset = builder.endObject(); + return offset; + } + }; + exports2.Graph = Graph3; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute.js + var require_attribute = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/attribute.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Attribute = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var attribute_type_js_1 = require_attribute_type(); + var graph_js_1 = require_graph(); + var tensor_js_1 = require_tensor(); + var Attribute3 = class _Attribute { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsAttribute(bb, obj) { + return (obj || new _Attribute()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsAttribute(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _Attribute()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + name(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + docString(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + type() { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.readInt32(this.bb_pos + offset) : attribute_type_js_1.AttributeType.UNDEFINED; + } + f() { + const offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0; + } + i() { + const offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); + } + s(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + t(obj) { + const offset = this.bb.__offset(this.bb_pos, 16); + return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + g(obj) { + const offset = this.bb.__offset(this.bb_pos, 18); + return offset ? (obj || new graph_js_1.Graph()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + floats(index) { + const offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.readFloat32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; + } + floatsLength() { + const offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + floatsArray() { + const offset = this.bb.__offset(this.bb_pos, 20); + return offset ? new Float32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null; + } + ints(index) { + const offset = this.bb.__offset(this.bb_pos, 22); + return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); + } + intsLength() { + const offset = this.bb.__offset(this.bb_pos, 22); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + strings(index, optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 24); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + stringsLength() { + const offset = this.bb.__offset(this.bb_pos, 24); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + tensors(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 26); + return offset ? (obj || new tensor_js_1.Tensor()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + tensorsLength() { + const offset = this.bb.__offset(this.bb_pos, 26); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + graphs(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 28); + return offset ? (obj || new graph_js_1.Graph()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + graphsLength() { + const offset = this.bb.__offset(this.bb_pos, 28); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startAttribute(builder) { + builder.startObject(13); + } + static addName(builder, nameOffset) { + builder.addFieldOffset(0, nameOffset, 0); + } + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(1, docStringOffset, 0); + } + static addType(builder, type) { + builder.addFieldInt32(2, type, attribute_type_js_1.AttributeType.UNDEFINED); + } + static addF(builder, f) { + builder.addFieldFloat32(3, f, 0); + } + static addI(builder, i) { + builder.addFieldInt64(4, i, BigInt("0")); + } + static addS(builder, sOffset) { + builder.addFieldOffset(5, sOffset, 0); + } + static addT(builder, tOffset) { + builder.addFieldOffset(6, tOffset, 0); + } + static addG(builder, gOffset) { + builder.addFieldOffset(7, gOffset, 0); + } + static addFloats(builder, floatsOffset) { + builder.addFieldOffset(8, floatsOffset, 0); + } + static createFloatsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addFloat32(data[i]); + } + return builder.endVector(); + } + static startFloatsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addInts(builder, intsOffset) { + builder.addFieldOffset(9, intsOffset, 0); + } + static createIntsVector(builder, data) { + builder.startVector(8, data.length, 8); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt64(data[i]); + } + return builder.endVector(); + } + static startIntsVector(builder, numElems) { + builder.startVector(8, numElems, 8); + } + static addStrings(builder, stringsOffset) { + builder.addFieldOffset(10, stringsOffset, 0); + } + static createStringsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startStringsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addTensors(builder, tensorsOffset) { + builder.addFieldOffset(11, tensorsOffset, 0); + } + static createTensorsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startTensorsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addGraphs(builder, graphsOffset) { + builder.addFieldOffset(12, graphsOffset, 0); + } + static createGraphsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startGraphsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endAttribute(builder) { + const offset = builder.endObject(); + return offset; + } + }; + exports2.Attribute = Attribute3; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-kernel-create-infos.js + var require_deprecated_kernel_create_infos = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-kernel-create-infos.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DeprecatedKernelCreateInfos = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var DeprecatedKernelCreateInfos2 = class _DeprecatedKernelCreateInfos { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsDeprecatedKernelCreateInfos(bb, obj) { + return (obj || new _DeprecatedKernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsDeprecatedKernelCreateInfos(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _DeprecatedKernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + nodeIndices(index) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readUint32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; + } + nodeIndicesLength() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + nodeIndicesArray() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? new Uint32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null; + } + kernelDefHashes(index) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : BigInt(0); + } + kernelDefHashesLength() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startDeprecatedKernelCreateInfos(builder) { + builder.startObject(2); + } + static addNodeIndices(builder, nodeIndicesOffset) { + builder.addFieldOffset(0, nodeIndicesOffset, 0); + } + static createNodeIndicesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); + } + static startNodeIndicesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addKernelDefHashes(builder, kernelDefHashesOffset) { + builder.addFieldOffset(1, kernelDefHashesOffset, 0); + } + static createKernelDefHashesVector(builder, data) { + builder.startVector(8, data.length, 8); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt64(data[i]); + } + return builder.endVector(); + } + static startKernelDefHashesVector(builder, numElems) { + builder.startVector(8, numElems, 8); + } + static endDeprecatedKernelCreateInfos(builder) { + const offset = builder.endObject(); + return offset; + } + static createDeprecatedKernelCreateInfos(builder, nodeIndicesOffset, kernelDefHashesOffset) { + _DeprecatedKernelCreateInfos.startDeprecatedKernelCreateInfos(builder); + _DeprecatedKernelCreateInfos.addNodeIndices(builder, nodeIndicesOffset); + _DeprecatedKernelCreateInfos.addKernelDefHashes(builder, kernelDefHashesOffset); + return _DeprecatedKernelCreateInfos.endDeprecatedKernelCreateInfos(builder); + } + }; + exports2.DeprecatedKernelCreateInfos = DeprecatedKernelCreateInfos2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-node-index-and-kernel-def-hash.js + var require_deprecated_node_index_and_kernel_def_hash = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-node-index-and-kernel-def-hash.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DeprecatedNodeIndexAndKernelDefHash = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var DeprecatedNodeIndexAndKernelDefHash2 = class _DeprecatedNodeIndexAndKernelDefHash { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsDeprecatedNodeIndexAndKernelDefHash(bb, obj) { + return (obj || new _DeprecatedNodeIndexAndKernelDefHash()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsDeprecatedNodeIndexAndKernelDefHash(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _DeprecatedNodeIndexAndKernelDefHash()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + nodeIndex() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + kernelDefHash() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readUint64(this.bb_pos + offset) : BigInt("0"); + } + static startDeprecatedNodeIndexAndKernelDefHash(builder) { + builder.startObject(2); + } + static addNodeIndex(builder, nodeIndex) { + builder.addFieldInt32(0, nodeIndex, 0); + } + static addKernelDefHash(builder, kernelDefHash) { + builder.addFieldInt64(1, kernelDefHash, BigInt("0")); + } + static endDeprecatedNodeIndexAndKernelDefHash(builder) { + const offset = builder.endObject(); + return offset; + } + static createDeprecatedNodeIndexAndKernelDefHash(builder, nodeIndex, kernelDefHash) { + _DeprecatedNodeIndexAndKernelDefHash.startDeprecatedNodeIndexAndKernelDefHash(builder); + _DeprecatedNodeIndexAndKernelDefHash.addNodeIndex(builder, nodeIndex); + _DeprecatedNodeIndexAndKernelDefHash.addKernelDefHash(builder, kernelDefHash); + return _DeprecatedNodeIndexAndKernelDefHash.endDeprecatedNodeIndexAndKernelDefHash(builder); + } + }; + exports2.DeprecatedNodeIndexAndKernelDefHash = DeprecatedNodeIndexAndKernelDefHash2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-sub-graph-session-state.js + var require_deprecated_sub_graph_session_state = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-sub-graph-session-state.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DeprecatedSubGraphSessionState = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var deprecated_session_state_js_1 = require_deprecated_session_state(); + var DeprecatedSubGraphSessionState2 = class _DeprecatedSubGraphSessionState { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsDeprecatedSubGraphSessionState(bb, obj) { + return (obj || new _DeprecatedSubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsDeprecatedSubGraphSessionState(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _DeprecatedSubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + graphId(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + sessionState(obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new deprecated_session_state_js_1.DeprecatedSessionState()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + static startDeprecatedSubGraphSessionState(builder) { + builder.startObject(2); + } + static addGraphId(builder, graphIdOffset) { + builder.addFieldOffset(0, graphIdOffset, 0); + } + static addSessionState(builder, sessionStateOffset) { + builder.addFieldOffset(1, sessionStateOffset, 0); + } + static endDeprecatedSubGraphSessionState(builder) { + const offset = builder.endObject(); + builder.requiredField(offset, 4); + return offset; + } + }; + exports2.DeprecatedSubGraphSessionState = DeprecatedSubGraphSessionState2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-session-state.js + var require_deprecated_session_state = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/deprecated-session-state.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.DeprecatedSessionState = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var deprecated_kernel_create_infos_js_1 = require_deprecated_kernel_create_infos(); + var deprecated_sub_graph_session_state_js_1 = require_deprecated_sub_graph_session_state(); + var DeprecatedSessionState2 = class _DeprecatedSessionState { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsDeprecatedSessionState(bb, obj) { + return (obj || new _DeprecatedSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsDeprecatedSessionState(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _DeprecatedSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + kernels(obj) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new deprecated_kernel_create_infos_js_1.DeprecatedKernelCreateInfos()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + subGraphSessionStates(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new deprecated_sub_graph_session_state_js_1.DeprecatedSubGraphSessionState()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + subGraphSessionStatesLength() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startDeprecatedSessionState(builder) { + builder.startObject(2); + } + static addKernels(builder, kernelsOffset) { + builder.addFieldOffset(0, kernelsOffset, 0); + } + static addSubGraphSessionStates(builder, subGraphSessionStatesOffset) { + builder.addFieldOffset(1, subGraphSessionStatesOffset, 0); + } + static createSubGraphSessionStatesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startSubGraphSessionStatesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endDeprecatedSessionState(builder) { + const offset = builder.endObject(); + return offset; + } + static createDeprecatedSessionState(builder, kernelsOffset, subGraphSessionStatesOffset) { + _DeprecatedSessionState.startDeprecatedSessionState(builder); + _DeprecatedSessionState.addKernels(builder, kernelsOffset); + _DeprecatedSessionState.addSubGraphSessionStates(builder, subGraphSessionStatesOffset); + return _DeprecatedSessionState.endDeprecatedSessionState(builder); + } + }; + exports2.DeprecatedSessionState = DeprecatedSessionState2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-args-entry.js + var require_kernel_type_str_args_entry = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-args-entry.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.KernelTypeStrArgsEntry = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var arg_type_and_index_js_1 = require_arg_type_and_index(); + var KernelTypeStrArgsEntry2 = class _KernelTypeStrArgsEntry { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsKernelTypeStrArgsEntry(bb, obj) { + return (obj || new _KernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsKernelTypeStrArgsEntry(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _KernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + kernelTypeStr(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + args(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new arg_type_and_index_js_1.ArgTypeAndIndex()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + argsLength() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startKernelTypeStrArgsEntry(builder) { + builder.startObject(2); + } + static addKernelTypeStr(builder, kernelTypeStrOffset) { + builder.addFieldOffset(0, kernelTypeStrOffset, 0); + } + static addArgs(builder, argsOffset) { + builder.addFieldOffset(1, argsOffset, 0); + } + static createArgsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startArgsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endKernelTypeStrArgsEntry(builder) { + const offset = builder.endObject(); + builder.requiredField(offset, 4); + return offset; + } + static createKernelTypeStrArgsEntry(builder, kernelTypeStrOffset, argsOffset) { + _KernelTypeStrArgsEntry.startKernelTypeStrArgsEntry(builder); + _KernelTypeStrArgsEntry.addKernelTypeStr(builder, kernelTypeStrOffset); + _KernelTypeStrArgsEntry.addArgs(builder, argsOffset); + return _KernelTypeStrArgsEntry.endKernelTypeStrArgsEntry(builder); + } + }; + exports2.KernelTypeStrArgsEntry = KernelTypeStrArgsEntry2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/op-id-kernel-type-str-args-entry.js + var require_op_id_kernel_type_str_args_entry = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/op-id-kernel-type-str-args-entry.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.OpIdKernelTypeStrArgsEntry = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var kernel_type_str_args_entry_js_1 = require_kernel_type_str_args_entry(); + var OpIdKernelTypeStrArgsEntry2 = class _OpIdKernelTypeStrArgsEntry { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsOpIdKernelTypeStrArgsEntry(bb, obj) { + return (obj || new _OpIdKernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsOpIdKernelTypeStrArgsEntry(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _OpIdKernelTypeStrArgsEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + opId(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + kernelTypeStrArgs(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new kernel_type_str_args_entry_js_1.KernelTypeStrArgsEntry()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + kernelTypeStrArgsLength() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startOpIdKernelTypeStrArgsEntry(builder) { + builder.startObject(2); + } + static addOpId(builder, opIdOffset) { + builder.addFieldOffset(0, opIdOffset, 0); + } + static addKernelTypeStrArgs(builder, kernelTypeStrArgsOffset) { + builder.addFieldOffset(1, kernelTypeStrArgsOffset, 0); + } + static createKernelTypeStrArgsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startKernelTypeStrArgsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endOpIdKernelTypeStrArgsEntry(builder) { + const offset = builder.endObject(); + builder.requiredField(offset, 4); + return offset; + } + static createOpIdKernelTypeStrArgsEntry(builder, opIdOffset, kernelTypeStrArgsOffset) { + _OpIdKernelTypeStrArgsEntry.startOpIdKernelTypeStrArgsEntry(builder); + _OpIdKernelTypeStrArgsEntry.addOpId(builder, opIdOffset); + _OpIdKernelTypeStrArgsEntry.addKernelTypeStrArgs(builder, kernelTypeStrArgsOffset); + return _OpIdKernelTypeStrArgsEntry.endOpIdKernelTypeStrArgsEntry(builder); + } + }; + exports2.OpIdKernelTypeStrArgsEntry = OpIdKernelTypeStrArgsEntry2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-resolver.js + var require_kernel_type_str_resolver = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/kernel-type-str-resolver.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.KernelTypeStrResolver = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var op_id_kernel_type_str_args_entry_js_1 = require_op_id_kernel_type_str_args_entry(); + var KernelTypeStrResolver2 = class _KernelTypeStrResolver { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsKernelTypeStrResolver(bb, obj) { + return (obj || new _KernelTypeStrResolver()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsKernelTypeStrResolver(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _KernelTypeStrResolver()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + opKernelTypeStrArgs(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new op_id_kernel_type_str_args_entry_js_1.OpIdKernelTypeStrArgsEntry()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + opKernelTypeStrArgsLength() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startKernelTypeStrResolver(builder) { + builder.startObject(1); + } + static addOpKernelTypeStrArgs(builder, opKernelTypeStrArgsOffset) { + builder.addFieldOffset(0, opKernelTypeStrArgsOffset, 0); + } + static createOpKernelTypeStrArgsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startOpKernelTypeStrArgsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endKernelTypeStrResolver(builder) { + const offset = builder.endObject(); + return offset; + } + static createKernelTypeStrResolver(builder, opKernelTypeStrArgsOffset) { + _KernelTypeStrResolver.startKernelTypeStrResolver(builder); + _KernelTypeStrResolver.addOpKernelTypeStrArgs(builder, opKernelTypeStrArgsOffset); + return _KernelTypeStrResolver.endKernelTypeStrResolver(builder); + } + }; + exports2.KernelTypeStrResolver = KernelTypeStrResolver2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/operator-set-id.js + var require_operator_set_id = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/operator-set-id.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.OperatorSetId = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var OperatorSetId2 = class _OperatorSetId { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsOperatorSetId(bb, obj) { + return (obj || new _OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsOperatorSetId(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + domain(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + version() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); + } + static startOperatorSetId(builder) { + builder.startObject(2); + } + static addDomain(builder, domainOffset) { + builder.addFieldOffset(0, domainOffset, 0); + } + static addVersion(builder, version3) { + builder.addFieldInt64(1, version3, BigInt("0")); + } + static endOperatorSetId(builder) { + const offset = builder.endObject(); + return offset; + } + static createOperatorSetId(builder, domainOffset, version3) { + _OperatorSetId.startOperatorSetId(builder); + _OperatorSetId.addDomain(builder, domainOffset); + _OperatorSetId.addVersion(builder, version3); + return _OperatorSetId.endOperatorSetId(builder); + } + }; + exports2.OperatorSetId = OperatorSetId2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/string-string-entry.js + var require_string_string_entry = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/string-string-entry.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.StringStringEntry = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var StringStringEntry2 = class _StringStringEntry { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsStringStringEntry(bb, obj) { + return (obj || new _StringStringEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsStringStringEntry(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _StringStringEntry()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + key(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + value(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + static startStringStringEntry(builder) { + builder.startObject(2); + } + static addKey(builder, keyOffset) { + builder.addFieldOffset(0, keyOffset, 0); + } + static addValue(builder, valueOffset) { + builder.addFieldOffset(1, valueOffset, 0); + } + static endStringStringEntry(builder) { + const offset = builder.endObject(); + return offset; + } + static createStringStringEntry(builder, keyOffset, valueOffset) { + _StringStringEntry.startStringStringEntry(builder); + _StringStringEntry.addKey(builder, keyOffset); + _StringStringEntry.addValue(builder, valueOffset); + return _StringStringEntry.endStringStringEntry(builder); + } + }; + exports2.StringStringEntry = StringStringEntry2; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/model.js + var require_model = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/model.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.Model = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var graph_js_1 = require_graph(); + var operator_set_id_js_1 = require_operator_set_id(); + var string_string_entry_js_1 = require_string_string_entry(); + var Model3 = class _Model { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsModel(bb, obj) { + return (obj || new _Model()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsModel(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _Model()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + irVersion() { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); + } + opsetImport(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new operator_set_id_js_1.OperatorSetId()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + opsetImportLength() { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + producerName(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + producerVersion(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + domain(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + modelVersion() { + const offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.readInt64(this.bb_pos + offset) : BigInt("0"); + } + docString(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 16); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + graph(obj) { + const offset = this.bb.__offset(this.bb_pos, 18); + return offset ? (obj || new graph_js_1.Graph()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + graphDocString(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + metadataProps(index, obj) { + const offset = this.bb.__offset(this.bb_pos, 22); + return offset ? (obj || new string_string_entry_js_1.StringStringEntry()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + metadataPropsLength() { + const offset = this.bb.__offset(this.bb_pos, 22); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + static startModel(builder) { + builder.startObject(10); + } + static addIrVersion(builder, irVersion) { + builder.addFieldInt64(0, irVersion, BigInt("0")); + } + static addOpsetImport(builder, opsetImportOffset) { + builder.addFieldOffset(1, opsetImportOffset, 0); + } + static createOpsetImportVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startOpsetImportVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static addProducerName(builder, producerNameOffset) { + builder.addFieldOffset(2, producerNameOffset, 0); + } + static addProducerVersion(builder, producerVersionOffset) { + builder.addFieldOffset(3, producerVersionOffset, 0); + } + static addDomain(builder, domainOffset) { + builder.addFieldOffset(4, domainOffset, 0); + } + static addModelVersion(builder, modelVersion) { + builder.addFieldInt64(5, modelVersion, BigInt("0")); + } + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(6, docStringOffset, 0); + } + static addGraph(builder, graphOffset) { + builder.addFieldOffset(7, graphOffset, 0); + } + static addGraphDocString(builder, graphDocStringOffset) { + builder.addFieldOffset(8, graphDocStringOffset, 0); + } + static addMetadataProps(builder, metadataPropsOffset) { + builder.addFieldOffset(9, metadataPropsOffset, 0); + } + static createMetadataPropsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + static startMetadataPropsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + static endModel(builder) { + const offset = builder.endObject(); + return offset; + } + }; + exports2.Model = Model3; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/inference-session.js + var require_inference_session = __commonJS({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs/inference-session.js"(exports2) { + "use strict"; + var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + }); + var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }); + var __importStar = exports2 && exports2.__importStar || function(mod2) { + if (mod2 && mod2.__esModule) return mod2; + var result = {}; + if (mod2 != null) { + for (var k in mod2) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod2, k)) __createBinding(result, mod2, k); + } + __setModuleDefault(result, mod2); + return result; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.InferenceSession = void 0; + var flatbuffers2 = __importStar(require_flatbuffers()); + var kernel_type_str_resolver_js_1 = require_kernel_type_str_resolver(); + var model_js_1 = require_model(); + var InferenceSession8 = class _InferenceSession { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + static getRootAsInferenceSession(bb, obj) { + return (obj || new _InferenceSession()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static getSizePrefixedRootAsInferenceSession(bb, obj) { + bb.setPosition(bb.position() + flatbuffers2.SIZE_PREFIX_LENGTH); + return (obj || new _InferenceSession()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + static bufferHasIdentifier(bb) { + return bb.__has_identifier("ORTM"); + } + ortVersion(optionalEncoding) { + const offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + model(obj) { + const offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new model_js_1.Model()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + kernelTypeStrResolver(obj) { + const offset = this.bb.__offset(this.bb_pos, 10); + return offset ? (obj || new kernel_type_str_resolver_js_1.KernelTypeStrResolver()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + static startInferenceSession(builder) { + builder.startObject(4); + } + static addOrtVersion(builder, ortVersionOffset) { + builder.addFieldOffset(0, ortVersionOffset, 0); + } + static addModel(builder, modelOffset) { + builder.addFieldOffset(1, modelOffset, 0); + } + static addKernelTypeStrResolver(builder, kernelTypeStrResolverOffset) { + builder.addFieldOffset(3, kernelTypeStrResolverOffset, 0); + } + static endInferenceSession(builder) { + const offset = builder.endObject(); + return offset; + } + static finishInferenceSessionBuffer(builder, offset) { + builder.finish(offset, "ORTM"); + } + static finishSizePrefixedInferenceSessionBuffer(builder, offset) { + builder.finish(offset, "ORTM", true); + } + }; + exports2.InferenceSession = InferenceSession8; + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs.ts + var import_arg_type, import_arg_type_and_index, import_attribute, import_attribute_type, import_deprecated_kernel_create_infos, import_deprecated_node_index_and_kernel_def_hash, import_deprecated_session_state, import_deprecated_sub_graph_session_state, import_dimension, import_dimension_value, import_dimension_value_type, import_edge_end, import_graph, import_inference_session, import_kernel_type_str_args_entry, import_kernel_type_str_resolver, import_map_type, import_model, import_node, import_node_edge, import_node_type, import_nodes_to_optimize_indices, import_op_id_kernel_type_str_args_entry, import_operator_set_id, import_runtime_optimization_record, import_runtime_optimization_record_container_entry, import_runtime_optimizations, import_sequence_type, import_shape, import_sparse_tensor, import_string_string_entry, import_tensor2, import_tensor_data_type, import_tensor_type_and_shape, import_type_info, import_type_info_value, import_value_info; + var init_fbs = __esm({ + "web/lib/onnxjs/ort-schema/flatbuffers/onnxruntime/fbs.ts"() { + "use strict"; + import_arg_type = __toESM(require_arg_type()); + import_arg_type_and_index = __toESM(require_arg_type_and_index()); + import_attribute = __toESM(require_attribute()); + import_attribute_type = __toESM(require_attribute_type()); + import_deprecated_kernel_create_infos = __toESM(require_deprecated_kernel_create_infos()); + import_deprecated_node_index_and_kernel_def_hash = __toESM(require_deprecated_node_index_and_kernel_def_hash()); + import_deprecated_session_state = __toESM(require_deprecated_session_state()); + import_deprecated_sub_graph_session_state = __toESM(require_deprecated_sub_graph_session_state()); + import_dimension = __toESM(require_dimension()); + import_dimension_value = __toESM(require_dimension_value()); + import_dimension_value_type = __toESM(require_dimension_value_type()); + import_edge_end = __toESM(require_edge_end()); + import_graph = __toESM(require_graph()); + import_inference_session = __toESM(require_inference_session()); + import_kernel_type_str_args_entry = __toESM(require_kernel_type_str_args_entry()); + import_kernel_type_str_resolver = __toESM(require_kernel_type_str_resolver()); + import_map_type = __toESM(require_map_type()); + import_model = __toESM(require_model()); + import_node = __toESM(require_node()); + import_node_edge = __toESM(require_node_edge()); + import_node_type = __toESM(require_node_type()); + import_nodes_to_optimize_indices = __toESM(require_nodes_to_optimize_indices()); + import_op_id_kernel_type_str_args_entry = __toESM(require_op_id_kernel_type_str_args_entry()); + import_operator_set_id = __toESM(require_operator_set_id()); + import_runtime_optimization_record = __toESM(require_runtime_optimization_record()); + import_runtime_optimization_record_container_entry = __toESM(require_runtime_optimization_record_container_entry()); + import_runtime_optimizations = __toESM(require_runtime_optimizations()); + import_sequence_type = __toESM(require_sequence_type()); + import_shape = __toESM(require_shape()); + import_sparse_tensor = __toESM(require_sparse_tensor()); + import_string_string_entry = __toESM(require_string_string_entry()); + import_tensor2 = __toESM(require_tensor()); + import_tensor_data_type = __toESM(require_tensor_data_type()); + import_tensor_type_and_shape = __toESM(require_tensor_type_and_shape()); + import_type_info = __toESM(require_type_info()); + import_type_info_value = __toESM(require_type_info_value()); + import_value_info = __toESM(require_value_info()); + } + }); + + // web/lib/onnxjs/ort-schema/flatbuffers/ort-generated.ts + var init_ort_generated = __esm({ + "web/lib/onnxjs/ort-schema/flatbuffers/ort-generated.ts"() { + "use strict"; + init_fbs(); + } + }); + + // web/node_modules/@protobufjs/aspromise/index.js + var require_aspromise = __commonJS({ + "web/node_modules/@protobufjs/aspromise/index.js"(exports2, module2) { + "use strict"; + module2.exports = asPromise; + function asPromise(fn, ctx) { + var params = new Array(arguments.length - 1), offset = 0, index = 2, pending = true; + while (index < arguments.length) + params[offset++] = arguments[index++]; + return new Promise(function executor(resolve, reject) { + params[offset] = function callback(err) { + if (pending) { + pending = false; + if (err) + reject(err); + else { + var params2 = new Array(arguments.length - 1), offset2 = 0; + while (offset2 < params2.length) + params2[offset2++] = arguments[offset2]; + resolve.apply(null, params2); + } + } + }; + try { + fn.apply(ctx || null, params); + } catch (err) { + if (pending) { + pending = false; + reject(err); + } + } + }); + } + } + }); + + // web/node_modules/@protobufjs/base64/index.js + var require_base64 = __commonJS({ + "web/node_modules/@protobufjs/base64/index.js"(exports2) { + "use strict"; + var base64 = exports2; + base64.length = function length(string) { + var p = string.length; + if (!p) + return 0; + var n = 0; + while (--p % 4 > 1 && string.charAt(p) === "=") + ++n; + return Math.ceil(string.length * 3) / 4 - n; + }; + var b64 = new Array(64); + var s64 = new Array(123); + for (i = 0; i < 64; ) + s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++; + var i; + base64.encode = function encode(buffer, start, end) { + var parts = null, chunk = []; + var i2 = 0, j = 0, t; + while (start < end) { + var b = buffer[start++]; + switch (j) { + case 0: + chunk[i2++] = b64[b >> 2]; + t = (b & 3) << 4; + j = 1; + break; + case 1: + chunk[i2++] = b64[t | b >> 4]; + t = (b & 15) << 2; + j = 2; + break; + case 2: + chunk[i2++] = b64[t | b >> 6]; + chunk[i2++] = b64[b & 63]; + j = 0; + break; + } + if (i2 > 8191) { + (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); + i2 = 0; + } + } + if (j) { + chunk[i2++] = b64[t]; + chunk[i2++] = 61; + if (j === 1) + chunk[i2++] = 61; + } + if (parts) { + if (i2) + parts.push(String.fromCharCode.apply(String, chunk.slice(0, i2))); + return parts.join(""); + } + return String.fromCharCode.apply(String, chunk.slice(0, i2)); + }; + var invalidEncoding = "invalid encoding"; + base64.decode = function decode(string, buffer, offset) { + var start = offset; + var j = 0, t; + for (var i2 = 0; i2 < string.length; ) { + var c = string.charCodeAt(i2++); + if (c === 61 && j > 1) + break; + if ((c = s64[c]) === void 0) + throw Error(invalidEncoding); + switch (j) { + case 0: + t = c; + j = 1; + break; + case 1: + buffer[offset++] = t << 2 | (c & 48) >> 4; + t = c; + j = 2; + break; + case 2: + buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2; + t = c; + j = 3; + break; + case 3: + buffer[offset++] = (t & 3) << 6 | c; + j = 0; + break; + } + } + if (j === 1) + throw Error(invalidEncoding); + return offset - start; + }; + base64.test = function test(string) { + return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string); + }; + } + }); + + // web/node_modules/@protobufjs/eventemitter/index.js + var require_eventemitter = __commonJS({ + "web/node_modules/@protobufjs/eventemitter/index.js"(exports2, module2) { + "use strict"; + module2.exports = EventEmitter; + function EventEmitter() { + this._listeners = {}; + } + EventEmitter.prototype.on = function on(evt, fn, ctx) { + (this._listeners[evt] || (this._listeners[evt] = [])).push({ + fn, + ctx: ctx || this + }); + return this; + }; + EventEmitter.prototype.off = function off(evt, fn) { + if (evt === void 0) + this._listeners = {}; + else { + if (fn === void 0) + this._listeners[evt] = []; + else { + var listeners = this._listeners[evt]; + for (var i = 0; i < listeners.length; ) + if (listeners[i].fn === fn) + listeners.splice(i, 1); + else + ++i; + } + } + return this; + }; + EventEmitter.prototype.emit = function emit(evt) { + var listeners = this._listeners[evt]; + if (listeners) { + var args = [], i = 1; + for (; i < arguments.length; ) + args.push(arguments[i++]); + for (i = 0; i < listeners.length; ) + listeners[i].fn.apply(listeners[i++].ctx, args); + } + return this; + }; + } + }); + + // web/node_modules/@protobufjs/float/index.js + var require_float = __commonJS({ + "web/node_modules/@protobufjs/float/index.js"(exports2, module2) { + "use strict"; + module2.exports = factory(factory); + function factory(exports3) { + if (typeof Float32Array !== "undefined") (function() { + var f32 = new Float32Array([-0]), f8b = new Uint8Array(f32.buffer), le = f8b[3] === 128; + function writeFloat_f32_cpy(val, buf, pos) { + f32[0] = val; + buf[pos] = f8b[0]; + buf[pos + 1] = f8b[1]; + buf[pos + 2] = f8b[2]; + buf[pos + 3] = f8b[3]; + } + function writeFloat_f32_rev(val, buf, pos) { + f32[0] = val; + buf[pos] = f8b[3]; + buf[pos + 1] = f8b[2]; + buf[pos + 2] = f8b[1]; + buf[pos + 3] = f8b[0]; + } + exports3.writeFloatLE = le ? writeFloat_f32_cpy : writeFloat_f32_rev; + exports3.writeFloatBE = le ? writeFloat_f32_rev : writeFloat_f32_cpy; + function readFloat_f32_cpy(buf, pos) { + f8b[0] = buf[pos]; + f8b[1] = buf[pos + 1]; + f8b[2] = buf[pos + 2]; + f8b[3] = buf[pos + 3]; + return f32[0]; + } + function readFloat_f32_rev(buf, pos) { + f8b[3] = buf[pos]; + f8b[2] = buf[pos + 1]; + f8b[1] = buf[pos + 2]; + f8b[0] = buf[pos + 3]; + return f32[0]; + } + exports3.readFloatLE = le ? readFloat_f32_cpy : readFloat_f32_rev; + exports3.readFloatBE = le ? readFloat_f32_rev : readFloat_f32_cpy; + })(); + else (function() { + function writeFloat_ieee754(writeUint, val, buf, pos) { + var sign = val < 0 ? 1 : 0; + if (sign) + val = -val; + if (val === 0) + writeUint(1 / val > 0 ? ( + /* positive */ + 0 + ) : ( + /* negative 0 */ + 2147483648 + ), buf, pos); + else if (isNaN(val)) + writeUint(2143289344, buf, pos); + else if (val > 34028234663852886e22) + writeUint((sign << 31 | 2139095040) >>> 0, buf, pos); + else if (val < 11754943508222875e-54) + writeUint((sign << 31 | Math.round(val / 1401298464324817e-60)) >>> 0, buf, pos); + else { + var exponent = Math.floor(Math.log(val) / Math.LN2), mantissa = Math.round(val * Math.pow(2, -exponent) * 8388608) & 8388607; + writeUint((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos); + } + } + exports3.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE); + exports3.writeFloatBE = writeFloat_ieee754.bind(null, writeUintBE); + function readFloat_ieee754(readUint, buf, pos) { + var uint = readUint(buf, pos), sign = (uint >> 31) * 2 + 1, exponent = uint >>> 23 & 255, mantissa = uint & 8388607; + return exponent === 255 ? mantissa ? NaN : sign * Infinity : exponent === 0 ? sign * 1401298464324817e-60 * mantissa : sign * Math.pow(2, exponent - 150) * (mantissa + 8388608); + } + exports3.readFloatLE = readFloat_ieee754.bind(null, readUintLE); + exports3.readFloatBE = readFloat_ieee754.bind(null, readUintBE); + })(); + if (typeof Float64Array !== "undefined") (function() { + var f64 = new Float64Array([-0]), f8b = new Uint8Array(f64.buffer), le = f8b[7] === 128; + function writeDouble_f64_cpy(val, buf, pos) { + f64[0] = val; + buf[pos] = f8b[0]; + buf[pos + 1] = f8b[1]; + buf[pos + 2] = f8b[2]; + buf[pos + 3] = f8b[3]; + buf[pos + 4] = f8b[4]; + buf[pos + 5] = f8b[5]; + buf[pos + 6] = f8b[6]; + buf[pos + 7] = f8b[7]; + } + function writeDouble_f64_rev(val, buf, pos) { + f64[0] = val; + buf[pos] = f8b[7]; + buf[pos + 1] = f8b[6]; + buf[pos + 2] = f8b[5]; + buf[pos + 3] = f8b[4]; + buf[pos + 4] = f8b[3]; + buf[pos + 5] = f8b[2]; + buf[pos + 6] = f8b[1]; + buf[pos + 7] = f8b[0]; + } + exports3.writeDoubleLE = le ? writeDouble_f64_cpy : writeDouble_f64_rev; + exports3.writeDoubleBE = le ? writeDouble_f64_rev : writeDouble_f64_cpy; + function readDouble_f64_cpy(buf, pos) { + f8b[0] = buf[pos]; + f8b[1] = buf[pos + 1]; + f8b[2] = buf[pos + 2]; + f8b[3] = buf[pos + 3]; + f8b[4] = buf[pos + 4]; + f8b[5] = buf[pos + 5]; + f8b[6] = buf[pos + 6]; + f8b[7] = buf[pos + 7]; + return f64[0]; + } + function readDouble_f64_rev(buf, pos) { + f8b[7] = buf[pos]; + f8b[6] = buf[pos + 1]; + f8b[5] = buf[pos + 2]; + f8b[4] = buf[pos + 3]; + f8b[3] = buf[pos + 4]; + f8b[2] = buf[pos + 5]; + f8b[1] = buf[pos + 6]; + f8b[0] = buf[pos + 7]; + return f64[0]; + } + exports3.readDoubleLE = le ? readDouble_f64_cpy : readDouble_f64_rev; + exports3.readDoubleBE = le ? readDouble_f64_rev : readDouble_f64_cpy; + })(); + else (function() { + function writeDouble_ieee754(writeUint, off0, off1, val, buf, pos) { + var sign = val < 0 ? 1 : 0; + if (sign) + val = -val; + if (val === 0) { + writeUint(0, buf, pos + off0); + writeUint(1 / val > 0 ? ( + /* positive */ + 0 + ) : ( + /* negative 0 */ + 2147483648 + ), buf, pos + off1); + } else if (isNaN(val)) { + writeUint(0, buf, pos + off0); + writeUint(2146959360, buf, pos + off1); + } else if (val > 17976931348623157e292) { + writeUint(0, buf, pos + off0); + writeUint((sign << 31 | 2146435072) >>> 0, buf, pos + off1); + } else { + var mantissa; + if (val < 22250738585072014e-324) { + mantissa = val / 5e-324; + writeUint(mantissa >>> 0, buf, pos + off0); + writeUint((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + off1); + } else { + var exponent = Math.floor(Math.log(val) / Math.LN2); + if (exponent === 1024) + exponent = 1023; + mantissa = val * Math.pow(2, -exponent); + writeUint(mantissa * 4503599627370496 >>> 0, buf, pos + off0); + writeUint((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + off1); + } + } + } + exports3.writeDoubleLE = writeDouble_ieee754.bind(null, writeUintLE, 0, 4); + exports3.writeDoubleBE = writeDouble_ieee754.bind(null, writeUintBE, 4, 0); + function readDouble_ieee754(readUint, off0, off1, buf, pos) { + var lo = readUint(buf, pos + off0), hi = readUint(buf, pos + off1); + var sign = (hi >> 31) * 2 + 1, exponent = hi >>> 20 & 2047, mantissa = 4294967296 * (hi & 1048575) + lo; + return exponent === 2047 ? mantissa ? NaN : sign * Infinity : exponent === 0 ? sign * 5e-324 * mantissa : sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496); + } + exports3.readDoubleLE = readDouble_ieee754.bind(null, readUintLE, 0, 4); + exports3.readDoubleBE = readDouble_ieee754.bind(null, readUintBE, 4, 0); + })(); + return exports3; + } + function writeUintLE(val, buf, pos) { + buf[pos] = val & 255; + buf[pos + 1] = val >>> 8 & 255; + buf[pos + 2] = val >>> 16 & 255; + buf[pos + 3] = val >>> 24; + } + function writeUintBE(val, buf, pos) { + buf[pos] = val >>> 24; + buf[pos + 1] = val >>> 16 & 255; + buf[pos + 2] = val >>> 8 & 255; + buf[pos + 3] = val & 255; + } + function readUintLE(buf, pos) { + return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24) >>> 0; + } + function readUintBE(buf, pos) { + return (buf[pos] << 24 | buf[pos + 1] << 16 | buf[pos + 2] << 8 | buf[pos + 3]) >>> 0; + } + } + }); + + // web/node_modules/@protobufjs/inquire/index.js + var require_inquire = __commonJS({ + "web/node_modules/@protobufjs/inquire/index.js"(exports, module) { + "use strict"; + module.exports = inquire; + function inquire(moduleName) { + try { + var mod = eval("quire".replace(/^/, "re"))(moduleName); + if (mod && (mod.length || Object.keys(mod).length)) + return mod; + } catch (e) { + } + return null; + } + } + }); + + // web/node_modules/@protobufjs/utf8/index.js + var require_utf8 = __commonJS({ + "web/node_modules/@protobufjs/utf8/index.js"(exports2) { + "use strict"; + var utf8 = exports2; + utf8.length = function utf8_length(string) { + var len = 0, c = 0; + for (var i = 0; i < string.length; ++i) { + c = string.charCodeAt(i); + if (c < 128) + len += 1; + else if (c < 2048) + len += 2; + else if ((c & 64512) === 55296 && (string.charCodeAt(i + 1) & 64512) === 56320) { + ++i; + len += 4; + } else + len += 3; + } + return len; + }; + utf8.read = function utf8_read(buffer, start, end) { + var len = end - start; + if (len < 1) + return ""; + var parts = null, chunk = [], i = 0, t; + while (start < end) { + t = buffer[start++]; + if (t < 128) + chunk[i++] = t; + else if (t > 191 && t < 224) + chunk[i++] = (t & 31) << 6 | buffer[start++] & 63; + else if (t > 239 && t < 365) { + t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 65536; + chunk[i++] = 55296 + (t >> 10); + chunk[i++] = 56320 + (t & 1023); + } else + chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63; + if (i > 8191) { + (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); + i = 0; + } + } + if (parts) { + if (i) + parts.push(String.fromCharCode.apply(String, chunk.slice(0, i))); + return parts.join(""); + } + return String.fromCharCode.apply(String, chunk.slice(0, i)); + }; + utf8.write = function utf8_write(string, buffer, offset) { + var start = offset, c1, c2; + for (var i = 0; i < string.length; ++i) { + c1 = string.charCodeAt(i); + if (c1 < 128) { + buffer[offset++] = c1; + } else if (c1 < 2048) { + buffer[offset++] = c1 >> 6 | 192; + buffer[offset++] = c1 & 63 | 128; + } else if ((c1 & 64512) === 55296 && ((c2 = string.charCodeAt(i + 1)) & 64512) === 56320) { + c1 = 65536 + ((c1 & 1023) << 10) + (c2 & 1023); + ++i; + buffer[offset++] = c1 >> 18 | 240; + buffer[offset++] = c1 >> 12 & 63 | 128; + buffer[offset++] = c1 >> 6 & 63 | 128; + buffer[offset++] = c1 & 63 | 128; + } else { + buffer[offset++] = c1 >> 12 | 224; + buffer[offset++] = c1 >> 6 & 63 | 128; + buffer[offset++] = c1 & 63 | 128; + } + } + return offset - start; + }; + } + }); + + // web/node_modules/@protobufjs/pool/index.js + var require_pool = __commonJS({ + "web/node_modules/@protobufjs/pool/index.js"(exports2, module2) { + "use strict"; + module2.exports = pool; + function pool(alloc, slice3, 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 = slice3.call(slab, offset, offset += size2); + if (offset & 7) + offset = (offset | 7) + 1; + return buf; + }; + } + } + }); + + // web/node_modules/protobufjs/src/util/longbits.js + var require_longbits = __commonJS({ + "web/node_modules/protobufjs/src/util/longbits.js"(exports2, module2) { + "use strict"; + module2.exports = LongBits; + var util = require_minimal(); + function LongBits(lo, hi) { + this.lo = lo >>> 0; + this.hi = hi >>> 0; + } + var zero = LongBits.zero = new LongBits(0, 0); + zero.toNumber = function() { + return 0; + }; + zero.zzEncode = zero.zzDecode = function() { + return this; + }; + zero.length = function() { + return 1; + }; + var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0"; + LongBits.fromNumber = function fromNumber2(value) { + if (value === 0) + return zero; + var sign = value < 0; + if (sign) + value = -value; + var lo = value >>> 0, hi = (value - lo) / 4294967296 >>> 0; + if (sign) { + hi = ~hi >>> 0; + lo = ~lo >>> 0; + if (++lo > 4294967295) { + lo = 0; + if (++hi > 4294967295) + hi = 0; + } + } + return new LongBits(lo, hi); + }; + LongBits.from = function from(value) { + if (typeof value === "number") + return LongBits.fromNumber(value); + if (util.isString(value)) { + if (util.Long) + value = util.Long.fromString(value); + else + return LongBits.fromNumber(parseInt(value, 10)); + } + return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero; + }; + LongBits.prototype.toNumber = function toNumber2(unsigned) { + if (!unsigned && this.hi >>> 31) { + var lo = ~this.lo + 1 >>> 0, hi = ~this.hi >>> 0; + if (!lo) + hi = hi + 1 >>> 0; + return -(lo + hi * 4294967296); + } + return this.lo + this.hi * 4294967296; + }; + LongBits.prototype.toLong = function toLong(unsigned) { + return util.Long ? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned)) : { low: this.lo | 0, high: this.hi | 0, unsigned: Boolean(unsigned) }; + }; + var charCodeAt = String.prototype.charCodeAt; + LongBits.fromHash = function fromHash(hash) { + if (hash === zeroHash) + return zero; + return new LongBits( + (charCodeAt.call(hash, 0) | charCodeAt.call(hash, 1) << 8 | charCodeAt.call(hash, 2) << 16 | charCodeAt.call(hash, 3) << 24) >>> 0, + (charCodeAt.call(hash, 4) | charCodeAt.call(hash, 5) << 8 | charCodeAt.call(hash, 6) << 16 | charCodeAt.call(hash, 7) << 24) >>> 0 + ); + }; + LongBits.prototype.toHash = function toHash() { + return String.fromCharCode( + this.lo & 255, + this.lo >>> 8 & 255, + this.lo >>> 16 & 255, + this.lo >>> 24, + this.hi & 255, + this.hi >>> 8 & 255, + this.hi >>> 16 & 255, + this.hi >>> 24 + ); + }; + LongBits.prototype.zzEncode = function zzEncode() { + var mask = this.hi >> 31; + this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0; + this.lo = (this.lo << 1 ^ mask) >>> 0; + return this; + }; + LongBits.prototype.zzDecode = function zzDecode() { + var mask = -(this.lo & 1); + this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0; + this.hi = (this.hi >>> 1 ^ mask) >>> 0; + return this; + }; + LongBits.prototype.length = function length() { + var part0 = this.lo, part1 = (this.lo >>> 28 | this.hi << 4) >>> 0, part2 = this.hi >>> 24; + return part2 === 0 ? part1 === 0 ? part0 < 16384 ? part0 < 128 ? 1 : 2 : part0 < 2097152 ? 3 : 4 : part1 < 16384 ? part1 < 128 ? 5 : 6 : part1 < 2097152 ? 7 : 8 : part2 < 128 ? 9 : 10; + }; + } + }); + + // web/node_modules/protobufjs/src/util/minimal.js + var require_minimal = __commonJS({ + "web/node_modules/protobufjs/src/util/minimal.js"(exports2) { + "use strict"; + var util = exports2; + util.asPromise = require_aspromise(); + util.base64 = require_base64(); + util.EventEmitter = require_eventemitter(); + util.float = require_float(); + util.inquire = require_inquire(); + util.utf8 = require_utf8(); + util.pool = require_pool(); + util.LongBits = require_longbits(); + util.isNode = Boolean(typeof global !== "undefined" && global && global.process && global.process.versions && global.process.versions.node); + util.global = util.isNode && global || typeof window !== "undefined" && window || typeof self !== "undefined" && self || exports2; + util.emptyArray = Object.freeze ? Object.freeze([]) : ( + /* istanbul ignore next */ + [] + ); + util.emptyObject = Object.freeze ? Object.freeze({}) : ( + /* istanbul ignore next */ + {} + ); + util.isInteger = Number.isInteger || /* istanbul ignore next */ + function isInteger(value) { + return typeof value === "number" && isFinite(value) && Math.floor(value) === value; + }; + util.isString = function isString(value) { + return typeof value === "string" || value instanceof String; + }; + util.isObject = function isObject(value) { + return value && typeof value === "object"; + }; + util.isset = /** + * Checks if a property on a message is considered to be present. + * @param {Object} obj Plain object or message instance + * @param {string} prop Property name + * @returns {boolean} `true` if considered to be present, otherwise `false` + */ + util.isSet = function isSet(obj, prop) { + var value = obj[prop]; + if (value != null && obj.hasOwnProperty(prop)) + return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0; + return false; + }; + util.Buffer = function() { + try { + var Buffer2 = util.inquire("buffer").Buffer; + return Buffer2.prototype.utf8Write ? Buffer2 : ( + /* istanbul ignore next */ + null + ); + } catch (e) { + return null; + } + }(); + util._Buffer_from = null; + util._Buffer_allocUnsafe = null; + util.newBuffer = function newBuffer(sizeOrArray) { + return typeof sizeOrArray === "number" ? util.Buffer ? util._Buffer_allocUnsafe(sizeOrArray) : new util.Array(sizeOrArray) : util.Buffer ? util._Buffer_from(sizeOrArray) : typeof Uint8Array === "undefined" ? sizeOrArray : new Uint8Array(sizeOrArray); + }; + util.Array = typeof Uint8Array !== "undefined" ? Uint8Array : Array; + util.Long = /* istanbul ignore next */ + util.global.dcodeIO && /* istanbul ignore next */ + util.global.dcodeIO.Long || /* istanbul ignore next */ + util.global.Long || util.inquire("long"); + util.key2Re = /^true|false|0|1$/; + util.key32Re = /^-?(?:0|[1-9][0-9]*)$/; + util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/; + util.longToHash = function longToHash(value) { + return value ? util.LongBits.from(value).toHash() : util.LongBits.zeroHash; + }; + util.longFromHash = function longFromHash(hash, unsigned) { + var bits = util.LongBits.fromHash(hash); + if (util.Long) + return util.Long.fromBits(bits.lo, bits.hi, unsigned); + return bits.toNumber(Boolean(unsigned)); + }; + function merge(dst, src, ifNotSet) { + for (var keys = Object.keys(src), i = 0; i < keys.length; ++i) + if (dst[keys[i]] === void 0 || !ifNotSet) + dst[keys[i]] = src[keys[i]]; + return dst; + } + util.merge = merge; + util.lcFirst = function lcFirst(str) { + return str.charAt(0).toLowerCase() + str.substring(1); + }; + function newError(name2) { + function CustomError(message, properties) { + if (!(this instanceof CustomError)) + return new CustomError(message, properties); + Object.defineProperty(this, "message", { get: function() { + return message; + } }); + if (Error.captureStackTrace) + Error.captureStackTrace(this, CustomError); + else + Object.defineProperty(this, "stack", { value: new Error().stack || "" }); + if (properties) + merge(this, properties); + } + CustomError.prototype = Object.create(Error.prototype, { + constructor: { + value: CustomError, + writable: true, + enumerable: false, + configurable: true + }, + name: { + get: function get() { + return name2; + }, + set: void 0, + enumerable: false, + // configurable: false would accurately preserve the behavior of + // the original, but I'm guessing that was not intentional. + // For an actual error subclass, this property would + // be configurable. + configurable: true + }, + toString: { + value: function value() { + return this.name + ": " + this.message; + }, + writable: true, + enumerable: false, + configurable: true + } + }); + return CustomError; + } + util.newError = newError; + util.ProtocolError = newError("ProtocolError"); + util.oneOfGetter = function getOneOf(fieldNames) { + var fieldMap = {}; + for (var i = 0; i < fieldNames.length; ++i) + fieldMap[fieldNames[i]] = 1; + return function() { + for (var keys = Object.keys(this), i2 = keys.length - 1; i2 > -1; --i2) + if (fieldMap[keys[i2]] === 1 && this[keys[i2]] !== void 0 && this[keys[i2]] !== null) + return keys[i2]; + }; + }; + util.oneOfSetter = function setOneOf(fieldNames) { + return function(name2) { + for (var i = 0; i < fieldNames.length; ++i) + if (fieldNames[i] !== name2) + delete this[fieldNames[i]]; + }; + }; + util.toJSONOptions = { + longs: String, + enums: String, + bytes: String, + json: true + }; + util._configure = function() { + var Buffer2 = util.Buffer; + if (!Buffer2) { + util._Buffer_from = util._Buffer_allocUnsafe = null; + return; + } + util._Buffer_from = Buffer2.from !== Uint8Array.from && Buffer2.from || /* istanbul ignore next */ + function Buffer_from(value, encoding) { + return new Buffer2(value, encoding); + }; + util._Buffer_allocUnsafe = Buffer2.allocUnsafe || /* istanbul ignore next */ + function Buffer_allocUnsafe(size) { + return new Buffer2(size); + }; + }; + } + }); + + // web/node_modules/protobufjs/src/writer.js + var require_writer = __commonJS({ + "web/node_modules/protobufjs/src/writer.js"(exports2, module2) { + "use strict"; + module2.exports = Writer; + var util = require_minimal(); + var BufferWriter; + var LongBits = util.LongBits; + var base64 = util.base64; + var utf8 = util.utf8; + function Op(fn, len, val) { + this.fn = fn; + this.len = len; + this.next = void 0; + this.val = val; + } + function noop() { + } + function State(writer) { + this.head = writer.head; + this.tail = writer.tail; + this.len = writer.len; + this.next = writer.states; + } + function Writer() { + this.len = 0; + this.head = new Op(noop, 0, 0); + this.tail = this.head; + this.states = null; + } + var create = function create2() { + return util.Buffer ? function create_buffer_setup() { + return (Writer.create = function create_buffer() { + return new BufferWriter(); + })(); + } : function create_array() { + return new Writer(); + }; + }; + Writer.create = create(); + Writer.alloc = function alloc(size) { + return new util.Array(size); + }; + if (util.Array !== Array) + Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray); + Writer.prototype._push = function push(fn, len, val) { + this.tail = this.tail.next = new Op(fn, len, val); + this.len += len; + return this; + }; + function writeByte(val, buf, pos) { + buf[pos] = val & 255; + } + function writeVarint32(val, buf, pos) { + while (val > 127) { + buf[pos++] = val & 127 | 128; + val >>>= 7; + } + buf[pos] = val; + } + function VarintOp(len, val) { + this.len = len; + this.next = void 0; + this.val = val; + } + VarintOp.prototype = Object.create(Op.prototype); + VarintOp.prototype.fn = writeVarint32; + Writer.prototype.uint32 = function write_uint32(value) { + this.len += (this.tail = this.tail.next = new VarintOp( + (value = value >>> 0) < 128 ? 1 : value < 16384 ? 2 : value < 2097152 ? 3 : value < 268435456 ? 4 : 5, + value + )).len; + return this; + }; + Writer.prototype.int32 = function write_int32(value) { + return value < 0 ? this._push(writeVarint64, 10, LongBits.fromNumber(value)) : this.uint32(value); + }; + Writer.prototype.sint32 = function write_sint32(value) { + return this.uint32((value << 1 ^ value >> 31) >>> 0); + }; + function writeVarint64(val, buf, pos) { + while (val.hi) { + buf[pos++] = val.lo & 127 | 128; + val.lo = (val.lo >>> 7 | val.hi << 25) >>> 0; + val.hi >>>= 7; + } + while (val.lo > 127) { + buf[pos++] = val.lo & 127 | 128; + val.lo = val.lo >>> 7; + } + buf[pos++] = val.lo; + } + Writer.prototype.uint64 = function write_uint64(value) { + var bits = LongBits.from(value); + return this._push(writeVarint64, bits.length(), bits); + }; + Writer.prototype.int64 = Writer.prototype.uint64; + Writer.prototype.sint64 = function write_sint64(value) { + var bits = LongBits.from(value).zzEncode(); + return this._push(writeVarint64, bits.length(), bits); + }; + Writer.prototype.bool = function write_bool(value) { + return this._push(writeByte, 1, value ? 1 : 0); + }; + function writeFixed32(val, buf, pos) { + buf[pos] = val & 255; + buf[pos + 1] = val >>> 8 & 255; + buf[pos + 2] = val >>> 16 & 255; + buf[pos + 3] = val >>> 24; + } + Writer.prototype.fixed32 = function write_fixed32(value) { + return this._push(writeFixed32, 4, value >>> 0); + }; + Writer.prototype.sfixed32 = Writer.prototype.fixed32; + Writer.prototype.fixed64 = function write_fixed64(value) { + var bits = LongBits.from(value); + return this._push(writeFixed32, 4, bits.lo)._push(writeFixed32, 4, bits.hi); + }; + Writer.prototype.sfixed64 = Writer.prototype.fixed64; + Writer.prototype.float = function write_float(value) { + return this._push(util.float.writeFloatLE, 4, value); + }; + Writer.prototype.double = function write_double(value) { + return this._push(util.float.writeDoubleLE, 8, value); + }; + var writeBytes = util.Array.prototype.set ? function writeBytes_set(val, buf, pos) { + buf.set(val, pos); + } : function writeBytes_for(val, buf, pos) { + for (var i = 0; i < val.length; ++i) + buf[pos + i] = val[i]; + }; + Writer.prototype.bytes = function write_bytes(value) { + var len = value.length >>> 0; + if (!len) + return this._push(writeByte, 1, 0); + if (util.isString(value)) { + var buf = Writer.alloc(len = base64.length(value)); + base64.decode(value, buf, 0); + value = buf; + } + return this.uint32(len)._push(writeBytes, len, value); + }; + Writer.prototype.string = function write_string(value) { + var len = utf8.length(value); + return len ? this.uint32(len)._push(utf8.write, len, value) : this._push(writeByte, 1, 0); + }; + Writer.prototype.fork = function fork() { + this.states = new State(this); + this.head = this.tail = new Op(noop, 0, 0); + this.len = 0; + return this; + }; + Writer.prototype.reset = function reset() { + if (this.states) { + this.head = this.states.head; + this.tail = this.states.tail; + this.len = this.states.len; + this.states = this.states.next; + } else { + this.head = this.tail = new Op(noop, 0, 0); + this.len = 0; + } + return this; + }; + Writer.prototype.ldelim = function ldelim() { + var head = this.head, tail = this.tail, len = this.len; + this.reset().uint32(len); + if (len) { + this.tail.next = head.next; + this.tail = tail; + this.len += len; + } + return this; + }; + Writer.prototype.finish = function finish() { + var head = this.head.next, buf = this.constructor.alloc(this.len), pos = 0; + while (head) { + head.fn(head.val, buf, pos); + pos += head.len; + head = head.next; + } + return buf; + }; + Writer._configure = function(BufferWriter_) { + BufferWriter = BufferWriter_; + Writer.create = create(); + BufferWriter._configure(); + }; + } + }); + + // web/node_modules/protobufjs/src/writer_buffer.js + var require_writer_buffer = __commonJS({ + "web/node_modules/protobufjs/src/writer_buffer.js"(exports2, module2) { + "use strict"; + module2.exports = BufferWriter; + var Writer = require_writer(); + (BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter; + var util = require_minimal(); + function BufferWriter() { + Writer.call(this); + } + BufferWriter._configure = function() { + BufferWriter.alloc = util._Buffer_allocUnsafe; + BufferWriter.writeBytesBuffer = util.Buffer && util.Buffer.prototype instanceof Uint8Array && util.Buffer.prototype.set.name === "set" ? function writeBytesBuffer_set(val, buf, pos) { + buf.set(val, pos); + } : function writeBytesBuffer_copy(val, buf, pos) { + if (val.copy) + val.copy(buf, pos, 0, val.length); + else for (var i = 0; i < val.length; ) + buf[pos++] = val[i++]; + }; + }; + BufferWriter.prototype.bytes = function write_bytes_buffer(value) { + if (util.isString(value)) + value = util._Buffer_from(value, "base64"); + var len = value.length >>> 0; + this.uint32(len); + if (len) + this._push(BufferWriter.writeBytesBuffer, len, value); + return this; + }; + function writeStringBuffer(val, buf, pos) { + if (val.length < 40) + util.utf8.write(val, buf, pos); + else if (buf.utf8Write) + buf.utf8Write(val, pos); + else + buf.write(val, pos); + } + BufferWriter.prototype.string = function write_string_buffer(value) { + var len = util.Buffer.byteLength(value); + this.uint32(len); + if (len) + this._push(writeStringBuffer, len, value); + return this; + }; + BufferWriter._configure(); + } + }); + + // web/node_modules/protobufjs/src/reader.js + var require_reader = __commonJS({ + "web/node_modules/protobufjs/src/reader.js"(exports2, module2) { + "use strict"; + module2.exports = Reader; + var util = require_minimal(); + var BufferReader; + var LongBits = util.LongBits; + var utf8 = util.utf8; + function indexOutOfRange(reader, writeLength) { + return RangeError("index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len); + } + function Reader(buffer) { + this.buf = buffer; + this.pos = 0; + this.len = buffer.length; + } + var create_array = typeof Uint8Array !== "undefined" ? function create_typed_array(buffer) { + if (buffer instanceof Uint8Array || Array.isArray(buffer)) + return new Reader(buffer); + throw Error("illegal buffer"); + } : function create_array2(buffer) { + if (Array.isArray(buffer)) + return new Reader(buffer); + throw Error("illegal buffer"); + }; + var create = function create2() { + return util.Buffer ? function create_buffer_setup(buffer) { + return (Reader.create = function create_buffer(buffer2) { + return util.Buffer.isBuffer(buffer2) ? new BufferReader(buffer2) : create_array(buffer2); + })(buffer); + } : create_array; + }; + Reader.create = create(); + Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */ + util.Array.prototype.slice; + Reader.prototype.uint32 = /* @__PURE__ */ function read_uint32_setup() { + var value = 4294967295; + return function read_uint32() { + value = (this.buf[this.pos] & 127) >>> 0; + if (this.buf[this.pos++] < 128) return value; + value = (value | (this.buf[this.pos] & 127) << 7) >>> 0; + if (this.buf[this.pos++] < 128) return value; + value = (value | (this.buf[this.pos] & 127) << 14) >>> 0; + if (this.buf[this.pos++] < 128) return value; + value = (value | (this.buf[this.pos] & 127) << 21) >>> 0; + if (this.buf[this.pos++] < 128) return value; + value = (value | (this.buf[this.pos] & 15) << 28) >>> 0; + if (this.buf[this.pos++] < 128) return value; + if ((this.pos += 5) > this.len) { + this.pos = this.len; + throw indexOutOfRange(this, 10); + } + return value; + }; + }(); + Reader.prototype.int32 = function read_int32() { + return this.uint32() | 0; + }; + Reader.prototype.sint32 = function read_sint32() { + var value = this.uint32(); + return value >>> 1 ^ -(value & 1) | 0; + }; + function readLongVarint() { + var bits = new LongBits(0, 0); + var i = 0; + if (this.len - this.pos > 4) { + for (; i < 4; ++i) { + bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + bits.lo = (bits.lo | (this.buf[this.pos] & 127) << 28) >>> 0; + bits.hi = (bits.hi | (this.buf[this.pos] & 127) >> 4) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + i = 0; + } else { + for (; i < 3; ++i) { + if (this.pos >= this.len) + throw indexOutOfRange(this); + bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + bits.lo = (bits.lo | (this.buf[this.pos++] & 127) << i * 7) >>> 0; + return bits; + } + if (this.len - this.pos > 4) { + for (; i < 5; ++i) { + bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + } else { + for (; i < 5; ++i) { + if (this.pos >= this.len) + throw indexOutOfRange(this); + bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + } + throw Error("invalid varint encoding"); + } + Reader.prototype.bool = function read_bool() { + return this.uint32() !== 0; + }; + function readFixed32_end(buf, end) { + return (buf[end - 4] | buf[end - 3] << 8 | buf[end - 2] << 16 | buf[end - 1] << 24) >>> 0; + } + Reader.prototype.fixed32 = function read_fixed32() { + if (this.pos + 4 > this.len) + throw indexOutOfRange(this, 4); + return readFixed32_end(this.buf, this.pos += 4); + }; + Reader.prototype.sfixed32 = function read_sfixed32() { + if (this.pos + 4 > this.len) + throw indexOutOfRange(this, 4); + return readFixed32_end(this.buf, this.pos += 4) | 0; + }; + function readFixed64() { + if (this.pos + 8 > this.len) + throw indexOutOfRange(this, 8); + return new LongBits(readFixed32_end(this.buf, this.pos += 4), readFixed32_end(this.buf, this.pos += 4)); + } + Reader.prototype.float = function read_float() { + if (this.pos + 4 > this.len) + throw indexOutOfRange(this, 4); + var value = util.float.readFloatLE(this.buf, this.pos); + this.pos += 4; + return value; + }; + Reader.prototype.double = function read_double() { + if (this.pos + 8 > this.len) + throw indexOutOfRange(this, 4); + var value = util.float.readDoubleLE(this.buf, this.pos); + this.pos += 8; + return value; + }; + Reader.prototype.bytes = function read_bytes() { + var length = this.uint32(), start = this.pos, end = this.pos + length; + if (end > this.len) + throw indexOutOfRange(this, length); + this.pos += length; + if (Array.isArray(this.buf)) + return this.buf.slice(start, end); + if (start === end) { + var nativeBuffer = util.Buffer; + return nativeBuffer ? nativeBuffer.alloc(0) : new this.buf.constructor(0); + } + return this._slice.call(this.buf, start, end); + }; + Reader.prototype.string = function read_string() { + var bytes = this.bytes(); + return utf8.read(bytes, 0, bytes.length); + }; + Reader.prototype.skip = function skip(length) { + if (typeof length === "number") { + if (this.pos + length > this.len) + throw indexOutOfRange(this, length); + this.pos += length; + } else { + do { + if (this.pos >= this.len) + throw indexOutOfRange(this); + } while (this.buf[this.pos++] & 128); + } + return this; + }; + Reader.prototype.skipType = function(wireType) { + switch (wireType) { + case 0: + this.skip(); + break; + case 1: + this.skip(8); + break; + case 2: + this.skip(this.uint32()); + break; + case 3: + while ((wireType = this.uint32() & 7) !== 4) { + this.skipType(wireType); + } + break; + case 5: + this.skip(4); + break; + /* istanbul ignore next */ + default: + throw Error("invalid wire type " + wireType + " at offset " + this.pos); + } + return this; + }; + Reader._configure = function(BufferReader_) { + BufferReader = BufferReader_; + Reader.create = create(); + BufferReader._configure(); + var fn = util.Long ? "toLong" : ( + /* istanbul ignore next */ + "toNumber" + ); + util.merge(Reader.prototype, { + int64: function read_int64() { + return readLongVarint.call(this)[fn](false); + }, + uint64: function read_uint64() { + return readLongVarint.call(this)[fn](true); + }, + sint64: function read_sint64() { + return readLongVarint.call(this).zzDecode()[fn](false); + }, + fixed64: function read_fixed64() { + return readFixed64.call(this)[fn](true); + }, + sfixed64: function read_sfixed64() { + return readFixed64.call(this)[fn](false); + } + }); + }; + } + }); + + // web/node_modules/protobufjs/src/reader_buffer.js + var require_reader_buffer = __commonJS({ + "web/node_modules/protobufjs/src/reader_buffer.js"(exports2, module2) { + "use strict"; + module2.exports = BufferReader; + var Reader = require_reader(); + (BufferReader.prototype = Object.create(Reader.prototype)).constructor = BufferReader; + var util = require_minimal(); + function BufferReader(buffer) { + Reader.call(this, buffer); + } + BufferReader._configure = function() { + if (util.Buffer) + BufferReader.prototype._slice = util.Buffer.prototype.slice; + }; + BufferReader.prototype.string = function read_string_buffer() { + var len = this.uint32(); + return this.buf.utf8Slice ? this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + len, this.len)) : this.buf.toString("utf-8", this.pos, this.pos = Math.min(this.pos + len, this.len)); + }; + BufferReader._configure(); + } + }); + + // web/node_modules/protobufjs/src/rpc/service.js + var require_service = __commonJS({ + "web/node_modules/protobufjs/src/rpc/service.js"(exports2, module2) { + "use strict"; + module2.exports = Service; + var util = require_minimal(); + (Service.prototype = Object.create(util.EventEmitter.prototype)).constructor = Service; + function Service(rpcImpl, requestDelimited, responseDelimited) { + if (typeof rpcImpl !== "function") + throw TypeError("rpcImpl must be a function"); + util.EventEmitter.call(this); + this.rpcImpl = rpcImpl; + this.requestDelimited = Boolean(requestDelimited); + this.responseDelimited = Boolean(responseDelimited); + } + Service.prototype.rpcCall = function rpcCall(method, requestCtor, responseCtor, request, callback) { + if (!request) + throw TypeError("request must be specified"); + var self2 = this; + if (!callback) + return util.asPromise(rpcCall, self2, method, requestCtor, responseCtor, request); + if (!self2.rpcImpl) { + setTimeout(function() { + callback(Error("already ended")); + }, 0); + return void 0; + } + try { + return self2.rpcImpl( + method, + requestCtor[self2.requestDelimited ? "encodeDelimited" : "encode"](request).finish(), + function rpcCallback(err, response) { + if (err) { + self2.emit("error", err, method); + return callback(err); + } + if (response === null) { + self2.end( + /* endedByRPC */ + true + ); + return void 0; + } + if (!(response instanceof responseCtor)) { + try { + response = responseCtor[self2.responseDelimited ? "decodeDelimited" : "decode"](response); + } catch (err2) { + self2.emit("error", err2, method); + return callback(err2); + } + } + self2.emit("data", response, method); + return callback(null, response); + } + ); + } catch (err) { + self2.emit("error", err, method); + setTimeout(function() { + callback(err); + }, 0); + return void 0; + } + }; + Service.prototype.end = function end(endedByRPC) { + if (this.rpcImpl) { + if (!endedByRPC) + this.rpcImpl(null, null, null); + this.rpcImpl = null; + this.emit("end").off(); + } + return this; + }; + } + }); + + // web/node_modules/protobufjs/src/rpc.js + var require_rpc = __commonJS({ + "web/node_modules/protobufjs/src/rpc.js"(exports2) { + "use strict"; + var rpc = exports2; + rpc.Service = require_service(); + } + }); + + // web/node_modules/protobufjs/src/roots.js + var require_roots = __commonJS({ + "web/node_modules/protobufjs/src/roots.js"(exports2, module2) { + "use strict"; + module2.exports = {}; + } + }); + + // web/node_modules/protobufjs/src/index-minimal.js + var require_index_minimal = __commonJS({ + "web/node_modules/protobufjs/src/index-minimal.js"(exports2) { + "use strict"; + var protobuf = exports2; + protobuf.build = "minimal"; + protobuf.Writer = require_writer(); + protobuf.BufferWriter = require_writer_buffer(); + protobuf.Reader = require_reader(); + protobuf.BufferReader = require_reader_buffer(); + protobuf.util = require_minimal(); + protobuf.rpc = require_rpc(); + protobuf.roots = require_roots(); + protobuf.configure = configure; + function configure() { + protobuf.util._configure(); + protobuf.Writer._configure(protobuf.BufferWriter); + protobuf.Reader._configure(protobuf.BufferReader); + } + configure(); + } + }); + + // web/node_modules/protobufjs/minimal.js + var require_minimal2 = __commonJS({ + "web/node_modules/protobufjs/minimal.js"(exports2, module2) { + "use strict"; + module2.exports = require_index_minimal(); + } + }); + + // web/lib/onnxjs/ort-schema/protobuf/onnx.js + var require_onnx = __commonJS({ + "web/lib/onnxjs/ort-schema/protobuf/onnx.js"(exports2, module2) { + "use strict"; + var $protobuf = require_minimal2(); + var $Reader = $protobuf.Reader; + var $Writer = $protobuf.Writer; + var $util = $protobuf.util; + var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); + $root.onnx = function() { + var onnx6 = {}; + onnx6.Version = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "_START_VERSION"] = 0; + values[valuesById[1] = "IR_VERSION_2017_10_10"] = 1; + values[valuesById[2] = "IR_VERSION_2017_10_30"] = 2; + values[valuesById[3] = "IR_VERSION_2017_11_3"] = 3; + values[valuesById[4] = "IR_VERSION_2019_1_22"] = 4; + values[valuesById[5] = "IR_VERSION_2019_3_18"] = 5; + values[valuesById[6] = "IR_VERSION_2019_9_19"] = 6; + values[valuesById[7] = "IR_VERSION_2020_5_8"] = 7; + values[valuesById[8] = "IR_VERSION_2021_7_30"] = 8; + values[valuesById[9] = "IR_VERSION"] = 9; + return values; + }(); + onnx6.AttributeProto = function() { + function AttributeProto(properties) { + this.floats = []; + this.ints = []; + this.strings = []; + this.tensors = []; + this.graphs = []; + this.sparseTensors = []; + this.typeProtos = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + AttributeProto.prototype.name = ""; + AttributeProto.prototype.refAttrName = ""; + AttributeProto.prototype.docString = ""; + AttributeProto.prototype.type = 0; + AttributeProto.prototype.f = 0; + AttributeProto.prototype.i = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + AttributeProto.prototype.s = $util.newBuffer([]); + AttributeProto.prototype.t = null; + AttributeProto.prototype.g = null; + AttributeProto.prototype.sparseTensor = null; + AttributeProto.prototype.tp = null; + AttributeProto.prototype.floats = $util.emptyArray; + AttributeProto.prototype.ints = $util.emptyArray; + AttributeProto.prototype.strings = $util.emptyArray; + AttributeProto.prototype.tensors = $util.emptyArray; + AttributeProto.prototype.graphs = $util.emptyArray; + AttributeProto.prototype.sparseTensors = $util.emptyArray; + AttributeProto.prototype.typeProtos = $util.emptyArray; + AttributeProto.create = function create(properties) { + return new AttributeProto(properties); + }; + AttributeProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.name); + if (message.f != null && Object.hasOwnProperty.call(message, "f")) + writer.uint32( + /* id 2, wireType 5 =*/ + 21 + ).float(message.f); + if (message.i != null && Object.hasOwnProperty.call(message, "i")) + writer.uint32( + /* id 3, wireType 0 =*/ + 24 + ).int64(message.i); + if (message.s != null && Object.hasOwnProperty.call(message, "s")) + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).bytes(message.s); + if (message.t != null && Object.hasOwnProperty.call(message, "t")) + $root.onnx.TensorProto.encode(message.t, writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork()).ldelim(); + if (message.g != null && Object.hasOwnProperty.call(message, "g")) + $root.onnx.GraphProto.encode(message.g, writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).fork()).ldelim(); + if (message.floats != null && message.floats.length) { + writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).fork(); + for (var i = 0; i < message.floats.length; ++i) writer.float(message.floats[i]); + writer.ldelim(); + } + if (message.ints != null && message.ints.length) { + writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).fork(); + for (var i = 0; i < message.ints.length; ++i) writer.int64(message.ints[i]); + writer.ldelim(); + } + if (message.strings != null && message.strings.length) + for (var i = 0; i < message.strings.length; ++i) + writer.uint32( + /* id 9, wireType 2 =*/ + 74 + ).bytes(message.strings[i]); + if (message.tensors != null && message.tensors.length) + for (var i = 0; i < message.tensors.length; ++i) + $root.onnx.TensorProto.encode(message.tensors[i], writer.uint32( + /* id 10, wireType 2 =*/ + 82 + ).fork()).ldelim(); + if (message.graphs != null && message.graphs.length) + for (var i = 0; i < message.graphs.length; ++i) + $root.onnx.GraphProto.encode(message.graphs[i], writer.uint32( + /* id 11, wireType 2 =*/ + 90 + ).fork()).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 13, wireType 2 =*/ + 106 + ).string(message.docString); + if (message.tp != null && Object.hasOwnProperty.call(message, "tp")) + $root.onnx.TypeProto.encode(message.tp, writer.uint32( + /* id 14, wireType 2 =*/ + 114 + ).fork()).ldelim(); + if (message.typeProtos != null && message.typeProtos.length) + for (var i = 0; i < message.typeProtos.length; ++i) + $root.onnx.TypeProto.encode( + message.typeProtos[i], + writer.uint32( + /* id 15, wireType 2 =*/ + 122 + ).fork() + ).ldelim(); + if (message.type != null && Object.hasOwnProperty.call(message, "type")) + writer.uint32( + /* id 20, wireType 0 =*/ + 160 + ).int32(message.type); + if (message.refAttrName != null && Object.hasOwnProperty.call(message, "refAttrName")) + writer.uint32( + /* id 21, wireType 2 =*/ + 170 + ).string(message.refAttrName); + if (message.sparseTensor != null && Object.hasOwnProperty.call(message, "sparseTensor")) + $root.onnx.SparseTensorProto.encode( + message.sparseTensor, + writer.uint32( + /* id 22, wireType 2 =*/ + 178 + ).fork() + ).ldelim(); + if (message.sparseTensors != null && message.sparseTensors.length) + for (var i = 0; i < message.sparseTensors.length; ++i) + $root.onnx.SparseTensorProto.encode( + message.sparseTensors[i], + writer.uint32( + /* id 23, wireType 2 =*/ + 186 + ).fork() + ).ldelim(); + return writer; + }; + AttributeProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + AttributeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.AttributeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.name = reader.string(); + break; + } + case 21: { + message.refAttrName = reader.string(); + break; + } + case 13: { + message.docString = reader.string(); + break; + } + case 20: { + message.type = reader.int32(); + break; + } + case 2: { + message.f = reader.float(); + break; + } + case 3: { + message.i = reader.int64(); + break; + } + case 4: { + message.s = reader.bytes(); + break; + } + case 5: { + message.t = $root.onnx.TensorProto.decode(reader, reader.uint32()); + break; + } + case 6: { + message.g = $root.onnx.GraphProto.decode(reader, reader.uint32()); + break; + } + case 22: { + message.sparseTensor = $root.onnx.SparseTensorProto.decode(reader, reader.uint32()); + break; + } + case 14: { + message.tp = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + case 7: { + if (!(message.floats && message.floats.length)) message.floats = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) message.floats.push(reader.float()); + } else message.floats.push(reader.float()); + break; + } + case 8: { + if (!(message.ints && message.ints.length)) message.ints = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) message.ints.push(reader.int64()); + } else message.ints.push(reader.int64()); + break; + } + case 9: { + if (!(message.strings && message.strings.length)) message.strings = []; + message.strings.push(reader.bytes()); + break; + } + case 10: { + if (!(message.tensors && message.tensors.length)) message.tensors = []; + message.tensors.push($root.onnx.TensorProto.decode(reader, reader.uint32())); + break; + } + case 11: { + if (!(message.graphs && message.graphs.length)) message.graphs = []; + message.graphs.push($root.onnx.GraphProto.decode(reader, reader.uint32())); + break; + } + case 23: { + if (!(message.sparseTensors && message.sparseTensors.length)) message.sparseTensors = []; + message.sparseTensors.push($root.onnx.SparseTensorProto.decode(reader, reader.uint32())); + break; + } + case 15: { + if (!(message.typeProtos && message.typeProtos.length)) message.typeProtos = []; + message.typeProtos.push($root.onnx.TypeProto.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + AttributeProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + AttributeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) return "name: string expected"; + } + if (message.refAttrName != null && message.hasOwnProperty("refAttrName")) { + if (!$util.isString(message.refAttrName)) return "refAttrName: string expected"; + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) return "docString: string expected"; + } + if (message.type != null && message.hasOwnProperty("type")) + switch (message.type) { + default: + return "type: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 11: + case 13: + case 6: + case 7: + case 8: + case 9: + case 10: + case 12: + case 14: + break; + } + if (message.f != null && message.hasOwnProperty("f")) { + if (typeof message.f !== "number") return "f: number expected"; + } + if (message.i != null && message.hasOwnProperty("i")) { + if (!$util.isInteger(message.i) && !(message.i && $util.isInteger(message.i.low) && $util.isInteger(message.i.high))) + return "i: integer|Long expected"; + } + if (message.s != null && message.hasOwnProperty("s")) { + if (!(message.s && typeof message.s.length === "number" || $util.isString(message.s))) + return "s: buffer expected"; + } + if (message.t != null && message.hasOwnProperty("t")) { + var error = $root.onnx.TensorProto.verify(message.t); + if (error) return "t." + error; + } + if (message.g != null && message.hasOwnProperty("g")) { + var error = $root.onnx.GraphProto.verify(message.g); + if (error) return "g." + error; + } + if (message.sparseTensor != null && message.hasOwnProperty("sparseTensor")) { + var error = $root.onnx.SparseTensorProto.verify(message.sparseTensor); + if (error) return "sparseTensor." + error; + } + if (message.tp != null && message.hasOwnProperty("tp")) { + var error = $root.onnx.TypeProto.verify(message.tp); + if (error) return "tp." + error; + } + if (message.floats != null && message.hasOwnProperty("floats")) { + if (!Array.isArray(message.floats)) return "floats: array expected"; + for (var i = 0; i < message.floats.length; ++i) + if (typeof message.floats[i] !== "number") return "floats: number[] expected"; + } + if (message.ints != null && message.hasOwnProperty("ints")) { + if (!Array.isArray(message.ints)) return "ints: array expected"; + for (var i = 0; i < message.ints.length; ++i) + if (!$util.isInteger(message.ints[i]) && !(message.ints[i] && $util.isInteger(message.ints[i].low) && $util.isInteger(message.ints[i].high))) + return "ints: integer|Long[] expected"; + } + if (message.strings != null && message.hasOwnProperty("strings")) { + if (!Array.isArray(message.strings)) return "strings: array expected"; + for (var i = 0; i < message.strings.length; ++i) + if (!(message.strings[i] && typeof message.strings[i].length === "number" || $util.isString(message.strings[i]))) + return "strings: buffer[] expected"; + } + if (message.tensors != null && message.hasOwnProperty("tensors")) { + if (!Array.isArray(message.tensors)) return "tensors: array expected"; + for (var i = 0; i < message.tensors.length; ++i) { + var error = $root.onnx.TensorProto.verify(message.tensors[i]); + if (error) return "tensors." + error; + } + } + if (message.graphs != null && message.hasOwnProperty("graphs")) { + if (!Array.isArray(message.graphs)) return "graphs: array expected"; + for (var i = 0; i < message.graphs.length; ++i) { + var error = $root.onnx.GraphProto.verify(message.graphs[i]); + if (error) return "graphs." + error; + } + } + if (message.sparseTensors != null && message.hasOwnProperty("sparseTensors")) { + if (!Array.isArray(message.sparseTensors)) return "sparseTensors: array expected"; + for (var i = 0; i < message.sparseTensors.length; ++i) { + var error = $root.onnx.SparseTensorProto.verify(message.sparseTensors[i]); + if (error) return "sparseTensors." + error; + } + } + if (message.typeProtos != null && message.hasOwnProperty("typeProtos")) { + if (!Array.isArray(message.typeProtos)) return "typeProtos: array expected"; + for (var i = 0; i < message.typeProtos.length; ++i) { + var error = $root.onnx.TypeProto.verify(message.typeProtos[i]); + if (error) return "typeProtos." + error; + } + } + return null; + }; + AttributeProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.AttributeProto) return object; + var message = new $root.onnx.AttributeProto(); + if (object.name != null) message.name = String(object.name); + if (object.refAttrName != null) message.refAttrName = String(object.refAttrName); + if (object.docString != null) message.docString = String(object.docString); + switch (object.type) { + default: + if (typeof object.type === "number") { + message.type = object.type; + break; + } + break; + case "UNDEFINED": + case 0: + message.type = 0; + break; + case "FLOAT": + case 1: + message.type = 1; + break; + case "INT": + case 2: + message.type = 2; + break; + case "STRING": + case 3: + message.type = 3; + break; + case "TENSOR": + case 4: + message.type = 4; + break; + case "GRAPH": + case 5: + message.type = 5; + break; + case "SPARSE_TENSOR": + case 11: + message.type = 11; + break; + case "TYPE_PROTO": + case 13: + message.type = 13; + break; + case "FLOATS": + case 6: + message.type = 6; + break; + case "INTS": + case 7: + message.type = 7; + break; + case "STRINGS": + case 8: + message.type = 8; + break; + case "TENSORS": + case 9: + message.type = 9; + break; + case "GRAPHS": + case 10: + message.type = 10; + break; + case "SPARSE_TENSORS": + case 12: + message.type = 12; + break; + case "TYPE_PROTOS": + case 14: + message.type = 14; + break; + } + if (object.f != null) message.f = Number(object.f); + if (object.i != null) { + if ($util.Long) (message.i = $util.Long.fromValue(object.i)).unsigned = false; + else if (typeof object.i === "string") message.i = parseInt(object.i, 10); + else if (typeof object.i === "number") message.i = object.i; + else if (typeof object.i === "object") + message.i = new $util.LongBits(object.i.low >>> 0, object.i.high >>> 0).toNumber(); + } + if (object.s != null) { + if (typeof object.s === "string") + $util.base64.decode(object.s, message.s = $util.newBuffer($util.base64.length(object.s)), 0); + else if (object.s.length >= 0) message.s = object.s; + } + if (object.t != null) { + if (typeof object.t !== "object") throw TypeError(".onnx.AttributeProto.t: object expected"); + message.t = $root.onnx.TensorProto.fromObject(object.t); + } + if (object.g != null) { + if (typeof object.g !== "object") throw TypeError(".onnx.AttributeProto.g: object expected"); + message.g = $root.onnx.GraphProto.fromObject(object.g); + } + if (object.sparseTensor != null) { + if (typeof object.sparseTensor !== "object") + throw TypeError(".onnx.AttributeProto.sparseTensor: object expected"); + message.sparseTensor = $root.onnx.SparseTensorProto.fromObject(object.sparseTensor); + } + if (object.tp != null) { + if (typeof object.tp !== "object") throw TypeError(".onnx.AttributeProto.tp: object expected"); + message.tp = $root.onnx.TypeProto.fromObject(object.tp); + } + if (object.floats) { + if (!Array.isArray(object.floats)) throw TypeError(".onnx.AttributeProto.floats: array expected"); + message.floats = []; + for (var i = 0; i < object.floats.length; ++i) message.floats[i] = Number(object.floats[i]); + } + if (object.ints) { + if (!Array.isArray(object.ints)) throw TypeError(".onnx.AttributeProto.ints: array expected"); + message.ints = []; + for (var i = 0; i < object.ints.length; ++i) + if ($util.Long) (message.ints[i] = $util.Long.fromValue(object.ints[i])).unsigned = false; + else if (typeof object.ints[i] === "string") message.ints[i] = parseInt(object.ints[i], 10); + else if (typeof object.ints[i] === "number") message.ints[i] = object.ints[i]; + else if (typeof object.ints[i] === "object") + message.ints[i] = new $util.LongBits(object.ints[i].low >>> 0, object.ints[i].high >>> 0).toNumber(); + } + if (object.strings) { + if (!Array.isArray(object.strings)) throw TypeError(".onnx.AttributeProto.strings: array expected"); + message.strings = []; + for (var i = 0; i < object.strings.length; ++i) + if (typeof object.strings[i] === "string") + $util.base64.decode( + object.strings[i], + message.strings[i] = $util.newBuffer($util.base64.length(object.strings[i])), + 0 + ); + else if (object.strings[i].length >= 0) message.strings[i] = object.strings[i]; + } + if (object.tensors) { + if (!Array.isArray(object.tensors)) throw TypeError(".onnx.AttributeProto.tensors: array expected"); + message.tensors = []; + for (var i = 0; i < object.tensors.length; ++i) { + if (typeof object.tensors[i] !== "object") throw TypeError(".onnx.AttributeProto.tensors: object expected"); + message.tensors[i] = $root.onnx.TensorProto.fromObject(object.tensors[i]); + } + } + if (object.graphs) { + if (!Array.isArray(object.graphs)) throw TypeError(".onnx.AttributeProto.graphs: array expected"); + message.graphs = []; + for (var i = 0; i < object.graphs.length; ++i) { + if (typeof object.graphs[i] !== "object") throw TypeError(".onnx.AttributeProto.graphs: object expected"); + message.graphs[i] = $root.onnx.GraphProto.fromObject(object.graphs[i]); + } + } + if (object.sparseTensors) { + if (!Array.isArray(object.sparseTensors)) throw TypeError(".onnx.AttributeProto.sparseTensors: array expected"); + message.sparseTensors = []; + for (var i = 0; i < object.sparseTensors.length; ++i) { + if (typeof object.sparseTensors[i] !== "object") + throw TypeError(".onnx.AttributeProto.sparseTensors: object expected"); + message.sparseTensors[i] = $root.onnx.SparseTensorProto.fromObject(object.sparseTensors[i]); + } + } + if (object.typeProtos) { + if (!Array.isArray(object.typeProtos)) throw TypeError(".onnx.AttributeProto.typeProtos: array expected"); + message.typeProtos = []; + for (var i = 0; i < object.typeProtos.length; ++i) { + if (typeof object.typeProtos[i] !== "object") + throw TypeError(".onnx.AttributeProto.typeProtos: object expected"); + message.typeProtos[i] = $root.onnx.TypeProto.fromObject(object.typeProtos[i]); + } + } + return message; + }; + AttributeProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.floats = []; + object.ints = []; + object.strings = []; + object.tensors = []; + object.graphs = []; + object.typeProtos = []; + object.sparseTensors = []; + } + if (options.defaults) { + object.name = ""; + object.f = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.i = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else object.i = options.longs === String ? "0" : 0; + if (options.bytes === String) object.s = ""; + else { + object.s = []; + if (options.bytes !== Array) object.s = $util.newBuffer(object.s); + } + object.t = null; + object.g = null; + object.docString = ""; + object.tp = null; + object.type = options.enums === String ? "UNDEFINED" : 0; + object.refAttrName = ""; + object.sparseTensor = null; + } + if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; + if (message.f != null && message.hasOwnProperty("f")) + object.f = options.json && !isFinite(message.f) ? String(message.f) : message.f; + if (message.i != null && message.hasOwnProperty("i")) + if (typeof message.i === "number") object.i = options.longs === String ? String(message.i) : message.i; + else + object.i = options.longs === String ? $util.Long.prototype.toString.call(message.i) : options.longs === Number ? new $util.LongBits(message.i.low >>> 0, message.i.high >>> 0).toNumber() : message.i; + if (message.s != null && message.hasOwnProperty("s")) + object.s = options.bytes === String ? $util.base64.encode(message.s, 0, message.s.length) : options.bytes === Array ? Array.prototype.slice.call(message.s) : message.s; + if (message.t != null && message.hasOwnProperty("t")) + object.t = $root.onnx.TensorProto.toObject(message.t, options); + if (message.g != null && message.hasOwnProperty("g")) + object.g = $root.onnx.GraphProto.toObject(message.g, options); + if (message.floats && message.floats.length) { + object.floats = []; + for (var j = 0; j < message.floats.length; ++j) + object.floats[j] = options.json && !isFinite(message.floats[j]) ? String(message.floats[j]) : message.floats[j]; + } + if (message.ints && message.ints.length) { + object.ints = []; + for (var j = 0; j < message.ints.length; ++j) + if (typeof message.ints[j] === "number") + object.ints[j] = options.longs === String ? String(message.ints[j]) : message.ints[j]; + else + object.ints[j] = options.longs === String ? $util.Long.prototype.toString.call(message.ints[j]) : options.longs === Number ? new $util.LongBits(message.ints[j].low >>> 0, message.ints[j].high >>> 0).toNumber() : message.ints[j]; + } + if (message.strings && message.strings.length) { + object.strings = []; + for (var j = 0; j < message.strings.length; ++j) + object.strings[j] = options.bytes === String ? $util.base64.encode(message.strings[j], 0, message.strings[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.strings[j]) : message.strings[j]; + } + if (message.tensors && message.tensors.length) { + object.tensors = []; + for (var j = 0; j < message.tensors.length; ++j) + object.tensors[j] = $root.onnx.TensorProto.toObject(message.tensors[j], options); + } + if (message.graphs && message.graphs.length) { + object.graphs = []; + for (var j = 0; j < message.graphs.length; ++j) + object.graphs[j] = $root.onnx.GraphProto.toObject(message.graphs[j], options); + } + if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; + if (message.tp != null && message.hasOwnProperty("tp")) + object.tp = $root.onnx.TypeProto.toObject(message.tp, options); + if (message.typeProtos && message.typeProtos.length) { + object.typeProtos = []; + for (var j = 0; j < message.typeProtos.length; ++j) + object.typeProtos[j] = $root.onnx.TypeProto.toObject(message.typeProtos[j], options); + } + if (message.type != null && message.hasOwnProperty("type")) + object.type = options.enums === String ? $root.onnx.AttributeProto.AttributeType[message.type] === void 0 ? message.type : $root.onnx.AttributeProto.AttributeType[message.type] : message.type; + if (message.refAttrName != null && message.hasOwnProperty("refAttrName")) + object.refAttrName = message.refAttrName; + if (message.sparseTensor != null && message.hasOwnProperty("sparseTensor")) + object.sparseTensor = $root.onnx.SparseTensorProto.toObject(message.sparseTensor, options); + if (message.sparseTensors && message.sparseTensors.length) { + object.sparseTensors = []; + for (var j = 0; j < message.sparseTensors.length; ++j) + object.sparseTensors[j] = $root.onnx.SparseTensorProto.toObject(message.sparseTensors[j], options); + } + return object; + }; + AttributeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + AttributeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.AttributeProto"; + }; + AttributeProto.AttributeType = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNDEFINED"] = 0; + values[valuesById[1] = "FLOAT"] = 1; + values[valuesById[2] = "INT"] = 2; + values[valuesById[3] = "STRING"] = 3; + values[valuesById[4] = "TENSOR"] = 4; + values[valuesById[5] = "GRAPH"] = 5; + values[valuesById[11] = "SPARSE_TENSOR"] = 11; + values[valuesById[13] = "TYPE_PROTO"] = 13; + values[valuesById[6] = "FLOATS"] = 6; + values[valuesById[7] = "INTS"] = 7; + values[valuesById[8] = "STRINGS"] = 8; + values[valuesById[9] = "TENSORS"] = 9; + values[valuesById[10] = "GRAPHS"] = 10; + values[valuesById[12] = "SPARSE_TENSORS"] = 12; + values[valuesById[14] = "TYPE_PROTOS"] = 14; + return values; + }(); + return AttributeProto; + }(); + onnx6.ValueInfoProto = function() { + function ValueInfoProto(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + ValueInfoProto.prototype.name = ""; + ValueInfoProto.prototype.type = null; + ValueInfoProto.prototype.docString = ""; + ValueInfoProto.create = function create(properties) { + return new ValueInfoProto(properties); + }; + ValueInfoProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.name); + if (message.type != null && Object.hasOwnProperty.call(message, "type")) + $root.onnx.TypeProto.encode(message.type, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).string(message.docString); + return writer; + }; + ValueInfoProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + ValueInfoProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.ValueInfoProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.name = reader.string(); + break; + } + case 2: { + message.type = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + case 3: { + message.docString = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + ValueInfoProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + ValueInfoProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) return "name: string expected"; + } + if (message.type != null && message.hasOwnProperty("type")) { + var error = $root.onnx.TypeProto.verify(message.type); + if (error) return "type." + error; + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) return "docString: string expected"; + } + return null; + }; + ValueInfoProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.ValueInfoProto) return object; + var message = new $root.onnx.ValueInfoProto(); + if (object.name != null) message.name = String(object.name); + if (object.type != null) { + if (typeof object.type !== "object") throw TypeError(".onnx.ValueInfoProto.type: object expected"); + message.type = $root.onnx.TypeProto.fromObject(object.type); + } + if (object.docString != null) message.docString = String(object.docString); + return message; + }; + ValueInfoProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.name = ""; + object.type = null; + object.docString = ""; + } + if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; + if (message.type != null && message.hasOwnProperty("type")) + object.type = $root.onnx.TypeProto.toObject(message.type, options); + if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; + return object; + }; + ValueInfoProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + ValueInfoProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.ValueInfoProto"; + }; + return ValueInfoProto; + }(); + onnx6.NodeProto = function() { + function NodeProto(properties) { + this.input = []; + this.output = []; + this.attribute = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + NodeProto.prototype.input = $util.emptyArray; + NodeProto.prototype.output = $util.emptyArray; + NodeProto.prototype.name = ""; + NodeProto.prototype.opType = ""; + NodeProto.prototype.domain = ""; + NodeProto.prototype.attribute = $util.emptyArray; + NodeProto.prototype.docString = ""; + NodeProto.create = function create(properties) { + return new NodeProto(properties); + }; + NodeProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.input != null && message.input.length) + for (var i = 0; i < message.input.length; ++i) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.input[i]); + if (message.output != null && message.output.length) + for (var i = 0; i < message.output.length; ++i) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.output[i]); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).string(message.name); + if (message.opType != null && Object.hasOwnProperty.call(message, "opType")) + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).string(message.opType); + if (message.attribute != null && message.attribute.length) + for (var i = 0; i < message.attribute.length; ++i) + $root.onnx.AttributeProto.encode( + message.attribute[i], + writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork() + ).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).string(message.docString); + if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) + writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).string(message.domain); + return writer; + }; + NodeProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + NodeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.NodeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (!(message.input && message.input.length)) message.input = []; + message.input.push(reader.string()); + break; + } + case 2: { + if (!(message.output && message.output.length)) message.output = []; + message.output.push(reader.string()); + break; + } + case 3: { + message.name = reader.string(); + break; + } + case 4: { + message.opType = reader.string(); + break; + } + case 7: { + message.domain = reader.string(); + break; + } + case 5: { + if (!(message.attribute && message.attribute.length)) message.attribute = []; + message.attribute.push($root.onnx.AttributeProto.decode(reader, reader.uint32())); + break; + } + case 6: { + message.docString = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + NodeProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + NodeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.input != null && message.hasOwnProperty("input")) { + if (!Array.isArray(message.input)) return "input: array expected"; + for (var i = 0; i < message.input.length; ++i) + if (!$util.isString(message.input[i])) return "input: string[] expected"; + } + if (message.output != null && message.hasOwnProperty("output")) { + if (!Array.isArray(message.output)) return "output: array expected"; + for (var i = 0; i < message.output.length; ++i) + if (!$util.isString(message.output[i])) return "output: string[] expected"; + } + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) return "name: string expected"; + } + if (message.opType != null && message.hasOwnProperty("opType")) { + if (!$util.isString(message.opType)) return "opType: string expected"; + } + if (message.domain != null && message.hasOwnProperty("domain")) { + if (!$util.isString(message.domain)) return "domain: string expected"; + } + if (message.attribute != null && message.hasOwnProperty("attribute")) { + if (!Array.isArray(message.attribute)) return "attribute: array expected"; + for (var i = 0; i < message.attribute.length; ++i) { + var error = $root.onnx.AttributeProto.verify(message.attribute[i]); + if (error) return "attribute." + error; + } + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) return "docString: string expected"; + } + return null; + }; + NodeProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.NodeProto) return object; + var message = new $root.onnx.NodeProto(); + if (object.input) { + if (!Array.isArray(object.input)) throw TypeError(".onnx.NodeProto.input: array expected"); + message.input = []; + for (var i = 0; i < object.input.length; ++i) message.input[i] = String(object.input[i]); + } + if (object.output) { + if (!Array.isArray(object.output)) throw TypeError(".onnx.NodeProto.output: array expected"); + message.output = []; + for (var i = 0; i < object.output.length; ++i) message.output[i] = String(object.output[i]); + } + if (object.name != null) message.name = String(object.name); + if (object.opType != null) message.opType = String(object.opType); + if (object.domain != null) message.domain = String(object.domain); + if (object.attribute) { + if (!Array.isArray(object.attribute)) throw TypeError(".onnx.NodeProto.attribute: array expected"); + message.attribute = []; + for (var i = 0; i < object.attribute.length; ++i) { + if (typeof object.attribute[i] !== "object") throw TypeError(".onnx.NodeProto.attribute: object expected"); + message.attribute[i] = $root.onnx.AttributeProto.fromObject(object.attribute[i]); + } + } + if (object.docString != null) message.docString = String(object.docString); + return message; + }; + NodeProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.input = []; + object.output = []; + object.attribute = []; + } + if (options.defaults) { + object.name = ""; + object.opType = ""; + object.docString = ""; + object.domain = ""; + } + if (message.input && message.input.length) { + object.input = []; + for (var j = 0; j < message.input.length; ++j) object.input[j] = message.input[j]; + } + if (message.output && message.output.length) { + object.output = []; + for (var j = 0; j < message.output.length; ++j) object.output[j] = message.output[j]; + } + if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; + if (message.opType != null && message.hasOwnProperty("opType")) object.opType = message.opType; + if (message.attribute && message.attribute.length) { + object.attribute = []; + for (var j = 0; j < message.attribute.length; ++j) + object.attribute[j] = $root.onnx.AttributeProto.toObject(message.attribute[j], options); + } + if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; + if (message.domain != null && message.hasOwnProperty("domain")) object.domain = message.domain; + return object; + }; + NodeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + NodeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.NodeProto"; + }; + return NodeProto; + }(); + onnx6.TrainingInfoProto = function() { + function TrainingInfoProto(properties) { + this.initializationBinding = []; + this.updateBinding = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + TrainingInfoProto.prototype.initialization = null; + TrainingInfoProto.prototype.algorithm = null; + TrainingInfoProto.prototype.initializationBinding = $util.emptyArray; + TrainingInfoProto.prototype.updateBinding = $util.emptyArray; + TrainingInfoProto.create = function create(properties) { + return new TrainingInfoProto(properties); + }; + TrainingInfoProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.initialization != null && Object.hasOwnProperty.call(message, "initialization")) + $root.onnx.GraphProto.encode(message.initialization, writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + if (message.algorithm != null && Object.hasOwnProperty.call(message, "algorithm")) + $root.onnx.GraphProto.encode(message.algorithm, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + if (message.initializationBinding != null && message.initializationBinding.length) + for (var i = 0; i < message.initializationBinding.length; ++i) + $root.onnx.StringStringEntryProto.encode( + message.initializationBinding[i], + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).fork() + ).ldelim(); + if (message.updateBinding != null && message.updateBinding.length) + for (var i = 0; i < message.updateBinding.length; ++i) + $root.onnx.StringStringEntryProto.encode( + message.updateBinding[i], + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).fork() + ).ldelim(); + return writer; + }; + TrainingInfoProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TrainingInfoProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TrainingInfoProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.initialization = $root.onnx.GraphProto.decode(reader, reader.uint32()); + break; + } + case 2: { + message.algorithm = $root.onnx.GraphProto.decode(reader, reader.uint32()); + break; + } + case 3: { + if (!(message.initializationBinding && message.initializationBinding.length)) + message.initializationBinding = []; + message.initializationBinding.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + case 4: { + if (!(message.updateBinding && message.updateBinding.length)) message.updateBinding = []; + message.updateBinding.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TrainingInfoProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TrainingInfoProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.initialization != null && message.hasOwnProperty("initialization")) { + var error = $root.onnx.GraphProto.verify(message.initialization); + if (error) return "initialization." + error; + } + if (message.algorithm != null && message.hasOwnProperty("algorithm")) { + var error = $root.onnx.GraphProto.verify(message.algorithm); + if (error) return "algorithm." + error; + } + if (message.initializationBinding != null && message.hasOwnProperty("initializationBinding")) { + if (!Array.isArray(message.initializationBinding)) return "initializationBinding: array expected"; + for (var i = 0; i < message.initializationBinding.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.initializationBinding[i]); + if (error) return "initializationBinding." + error; + } + } + if (message.updateBinding != null && message.hasOwnProperty("updateBinding")) { + if (!Array.isArray(message.updateBinding)) return "updateBinding: array expected"; + for (var i = 0; i < message.updateBinding.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.updateBinding[i]); + if (error) return "updateBinding." + error; + } + } + return null; + }; + TrainingInfoProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TrainingInfoProto) return object; + var message = new $root.onnx.TrainingInfoProto(); + if (object.initialization != null) { + if (typeof object.initialization !== "object") + throw TypeError(".onnx.TrainingInfoProto.initialization: object expected"); + message.initialization = $root.onnx.GraphProto.fromObject(object.initialization); + } + if (object.algorithm != null) { + if (typeof object.algorithm !== "object") throw TypeError(".onnx.TrainingInfoProto.algorithm: object expected"); + message.algorithm = $root.onnx.GraphProto.fromObject(object.algorithm); + } + if (object.initializationBinding) { + if (!Array.isArray(object.initializationBinding)) + throw TypeError(".onnx.TrainingInfoProto.initializationBinding: array expected"); + message.initializationBinding = []; + for (var i = 0; i < object.initializationBinding.length; ++i) { + if (typeof object.initializationBinding[i] !== "object") + throw TypeError(".onnx.TrainingInfoProto.initializationBinding: object expected"); + message.initializationBinding[i] = $root.onnx.StringStringEntryProto.fromObject( + object.initializationBinding[i] + ); + } + } + if (object.updateBinding) { + if (!Array.isArray(object.updateBinding)) + throw TypeError(".onnx.TrainingInfoProto.updateBinding: array expected"); + message.updateBinding = []; + for (var i = 0; i < object.updateBinding.length; ++i) { + if (typeof object.updateBinding[i] !== "object") + throw TypeError(".onnx.TrainingInfoProto.updateBinding: object expected"); + message.updateBinding[i] = $root.onnx.StringStringEntryProto.fromObject(object.updateBinding[i]); + } + } + return message; + }; + TrainingInfoProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.initializationBinding = []; + object.updateBinding = []; + } + if (options.defaults) { + object.initialization = null; + object.algorithm = null; + } + if (message.initialization != null && message.hasOwnProperty("initialization")) + object.initialization = $root.onnx.GraphProto.toObject(message.initialization, options); + if (message.algorithm != null && message.hasOwnProperty("algorithm")) + object.algorithm = $root.onnx.GraphProto.toObject(message.algorithm, options); + if (message.initializationBinding && message.initializationBinding.length) { + object.initializationBinding = []; + for (var j = 0; j < message.initializationBinding.length; ++j) + object.initializationBinding[j] = $root.onnx.StringStringEntryProto.toObject( + message.initializationBinding[j], + options + ); + } + if (message.updateBinding && message.updateBinding.length) { + object.updateBinding = []; + for (var j = 0; j < message.updateBinding.length; ++j) + object.updateBinding[j] = $root.onnx.StringStringEntryProto.toObject(message.updateBinding[j], options); + } + return object; + }; + TrainingInfoProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TrainingInfoProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TrainingInfoProto"; + }; + return TrainingInfoProto; + }(); + onnx6.ModelProto = function() { + function ModelProto(properties) { + this.opsetImport = []; + this.metadataProps = []; + this.trainingInfo = []; + this.functions = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + ModelProto.prototype.irVersion = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + ModelProto.prototype.opsetImport = $util.emptyArray; + ModelProto.prototype.producerName = ""; + ModelProto.prototype.producerVersion = ""; + ModelProto.prototype.domain = ""; + ModelProto.prototype.modelVersion = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + ModelProto.prototype.docString = ""; + ModelProto.prototype.graph = null; + ModelProto.prototype.metadataProps = $util.emptyArray; + ModelProto.prototype.trainingInfo = $util.emptyArray; + ModelProto.prototype.functions = $util.emptyArray; + ModelProto.create = function create(properties) { + return new ModelProto(properties); + }; + ModelProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.irVersion != null && Object.hasOwnProperty.call(message, "irVersion")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int64(message.irVersion); + if (message.producerName != null && Object.hasOwnProperty.call(message, "producerName")) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.producerName); + if (message.producerVersion != null && Object.hasOwnProperty.call(message, "producerVersion")) + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).string(message.producerVersion); + if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).string(message.domain); + if (message.modelVersion != null && Object.hasOwnProperty.call(message, "modelVersion")) + writer.uint32( + /* id 5, wireType 0 =*/ + 40 + ).int64(message.modelVersion); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).string(message.docString); + if (message.graph != null && Object.hasOwnProperty.call(message, "graph")) + $root.onnx.GraphProto.encode(message.graph, writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).fork()).ldelim(); + if (message.opsetImport != null && message.opsetImport.length) + for (var i = 0; i < message.opsetImport.length; ++i) + $root.onnx.OperatorSetIdProto.encode( + message.opsetImport[i], + writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).fork() + ).ldelim(); + if (message.metadataProps != null && message.metadataProps.length) + for (var i = 0; i < message.metadataProps.length; ++i) + $root.onnx.StringStringEntryProto.encode( + message.metadataProps[i], + writer.uint32( + /* id 14, wireType 2 =*/ + 114 + ).fork() + ).ldelim(); + if (message.trainingInfo != null && message.trainingInfo.length) + for (var i = 0; i < message.trainingInfo.length; ++i) + $root.onnx.TrainingInfoProto.encode( + message.trainingInfo[i], + writer.uint32( + /* id 20, wireType 2 =*/ + 162 + ).fork() + ).ldelim(); + if (message.functions != null && message.functions.length) + for (var i = 0; i < message.functions.length; ++i) + $root.onnx.FunctionProto.encode( + message.functions[i], + writer.uint32( + /* id 25, wireType 2 =*/ + 202 + ).fork() + ).ldelim(); + return writer; + }; + ModelProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + ModelProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.ModelProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.irVersion = reader.int64(); + break; + } + case 8: { + if (!(message.opsetImport && message.opsetImport.length)) message.opsetImport = []; + message.opsetImport.push($root.onnx.OperatorSetIdProto.decode(reader, reader.uint32())); + break; + } + case 2: { + message.producerName = reader.string(); + break; + } + case 3: { + message.producerVersion = reader.string(); + break; + } + case 4: { + message.domain = reader.string(); + break; + } + case 5: { + message.modelVersion = reader.int64(); + break; + } + case 6: { + message.docString = reader.string(); + break; + } + case 7: { + message.graph = $root.onnx.GraphProto.decode(reader, reader.uint32()); + break; + } + case 14: { + if (!(message.metadataProps && message.metadataProps.length)) message.metadataProps = []; + message.metadataProps.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + case 20: { + if (!(message.trainingInfo && message.trainingInfo.length)) message.trainingInfo = []; + message.trainingInfo.push($root.onnx.TrainingInfoProto.decode(reader, reader.uint32())); + break; + } + case 25: { + if (!(message.functions && message.functions.length)) message.functions = []; + message.functions.push($root.onnx.FunctionProto.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + ModelProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + ModelProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.irVersion != null && message.hasOwnProperty("irVersion")) { + if (!$util.isInteger(message.irVersion) && !(message.irVersion && $util.isInteger(message.irVersion.low) && $util.isInteger(message.irVersion.high))) + return "irVersion: integer|Long expected"; + } + if (message.opsetImport != null && message.hasOwnProperty("opsetImport")) { + if (!Array.isArray(message.opsetImport)) return "opsetImport: array expected"; + for (var i = 0; i < message.opsetImport.length; ++i) { + var error = $root.onnx.OperatorSetIdProto.verify(message.opsetImport[i]); + if (error) return "opsetImport." + error; + } + } + if (message.producerName != null && message.hasOwnProperty("producerName")) { + if (!$util.isString(message.producerName)) return "producerName: string expected"; + } + if (message.producerVersion != null && message.hasOwnProperty("producerVersion")) { + if (!$util.isString(message.producerVersion)) return "producerVersion: string expected"; + } + if (message.domain != null && message.hasOwnProperty("domain")) { + if (!$util.isString(message.domain)) return "domain: string expected"; + } + if (message.modelVersion != null && message.hasOwnProperty("modelVersion")) { + if (!$util.isInteger(message.modelVersion) && !(message.modelVersion && $util.isInteger(message.modelVersion.low) && $util.isInteger(message.modelVersion.high))) + return "modelVersion: integer|Long expected"; + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) return "docString: string expected"; + } + if (message.graph != null && message.hasOwnProperty("graph")) { + var error = $root.onnx.GraphProto.verify(message.graph); + if (error) return "graph." + error; + } + if (message.metadataProps != null && message.hasOwnProperty("metadataProps")) { + if (!Array.isArray(message.metadataProps)) return "metadataProps: array expected"; + for (var i = 0; i < message.metadataProps.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.metadataProps[i]); + if (error) return "metadataProps." + error; + } + } + if (message.trainingInfo != null && message.hasOwnProperty("trainingInfo")) { + if (!Array.isArray(message.trainingInfo)) return "trainingInfo: array expected"; + for (var i = 0; i < message.trainingInfo.length; ++i) { + var error = $root.onnx.TrainingInfoProto.verify(message.trainingInfo[i]); + if (error) return "trainingInfo." + error; + } + } + if (message.functions != null && message.hasOwnProperty("functions")) { + if (!Array.isArray(message.functions)) return "functions: array expected"; + for (var i = 0; i < message.functions.length; ++i) { + var error = $root.onnx.FunctionProto.verify(message.functions[i]); + if (error) return "functions." + error; + } + } + return null; + }; + ModelProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.ModelProto) return object; + var message = new $root.onnx.ModelProto(); + if (object.irVersion != null) { + if ($util.Long) (message.irVersion = $util.Long.fromValue(object.irVersion)).unsigned = false; + else if (typeof object.irVersion === "string") message.irVersion = parseInt(object.irVersion, 10); + else if (typeof object.irVersion === "number") message.irVersion = object.irVersion; + else if (typeof object.irVersion === "object") + message.irVersion = new $util.LongBits(object.irVersion.low >>> 0, object.irVersion.high >>> 0).toNumber(); + } + if (object.opsetImport) { + if (!Array.isArray(object.opsetImport)) throw TypeError(".onnx.ModelProto.opsetImport: array expected"); + message.opsetImport = []; + for (var i = 0; i < object.opsetImport.length; ++i) { + if (typeof object.opsetImport[i] !== "object") + throw TypeError(".onnx.ModelProto.opsetImport: object expected"); + message.opsetImport[i] = $root.onnx.OperatorSetIdProto.fromObject(object.opsetImport[i]); + } + } + if (object.producerName != null) message.producerName = String(object.producerName); + if (object.producerVersion != null) message.producerVersion = String(object.producerVersion); + if (object.domain != null) message.domain = String(object.domain); + if (object.modelVersion != null) { + if ($util.Long) (message.modelVersion = $util.Long.fromValue(object.modelVersion)).unsigned = false; + else if (typeof object.modelVersion === "string") message.modelVersion = parseInt(object.modelVersion, 10); + else if (typeof object.modelVersion === "number") message.modelVersion = object.modelVersion; + else if (typeof object.modelVersion === "object") + message.modelVersion = new $util.LongBits( + object.modelVersion.low >>> 0, + object.modelVersion.high >>> 0 + ).toNumber(); + } + if (object.docString != null) message.docString = String(object.docString); + if (object.graph != null) { + if (typeof object.graph !== "object") throw TypeError(".onnx.ModelProto.graph: object expected"); + message.graph = $root.onnx.GraphProto.fromObject(object.graph); + } + if (object.metadataProps) { + if (!Array.isArray(object.metadataProps)) throw TypeError(".onnx.ModelProto.metadataProps: array expected"); + message.metadataProps = []; + for (var i = 0; i < object.metadataProps.length; ++i) { + if (typeof object.metadataProps[i] !== "object") + throw TypeError(".onnx.ModelProto.metadataProps: object expected"); + message.metadataProps[i] = $root.onnx.StringStringEntryProto.fromObject(object.metadataProps[i]); + } + } + if (object.trainingInfo) { + if (!Array.isArray(object.trainingInfo)) throw TypeError(".onnx.ModelProto.trainingInfo: array expected"); + message.trainingInfo = []; + for (var i = 0; i < object.trainingInfo.length; ++i) { + if (typeof object.trainingInfo[i] !== "object") + throw TypeError(".onnx.ModelProto.trainingInfo: object expected"); + message.trainingInfo[i] = $root.onnx.TrainingInfoProto.fromObject(object.trainingInfo[i]); + } + } + if (object.functions) { + if (!Array.isArray(object.functions)) throw TypeError(".onnx.ModelProto.functions: array expected"); + message.functions = []; + for (var i = 0; i < object.functions.length; ++i) { + if (typeof object.functions[i] !== "object") throw TypeError(".onnx.ModelProto.functions: object expected"); + message.functions[i] = $root.onnx.FunctionProto.fromObject(object.functions[i]); + } + } + return message; + }; + ModelProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.opsetImport = []; + object.metadataProps = []; + object.trainingInfo = []; + object.functions = []; + } + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.irVersion = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else object.irVersion = options.longs === String ? "0" : 0; + object.producerName = ""; + object.producerVersion = ""; + object.domain = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.modelVersion = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else object.modelVersion = options.longs === String ? "0" : 0; + object.docString = ""; + object.graph = null; + } + if (message.irVersion != null && message.hasOwnProperty("irVersion")) + if (typeof message.irVersion === "number") + object.irVersion = options.longs === String ? String(message.irVersion) : message.irVersion; + else + object.irVersion = options.longs === String ? $util.Long.prototype.toString.call(message.irVersion) : options.longs === Number ? new $util.LongBits(message.irVersion.low >>> 0, message.irVersion.high >>> 0).toNumber() : message.irVersion; + if (message.producerName != null && message.hasOwnProperty("producerName")) + object.producerName = message.producerName; + if (message.producerVersion != null && message.hasOwnProperty("producerVersion")) + object.producerVersion = message.producerVersion; + if (message.domain != null && message.hasOwnProperty("domain")) object.domain = message.domain; + if (message.modelVersion != null && message.hasOwnProperty("modelVersion")) + if (typeof message.modelVersion === "number") + object.modelVersion = options.longs === String ? String(message.modelVersion) : message.modelVersion; + else + object.modelVersion = options.longs === String ? $util.Long.prototype.toString.call(message.modelVersion) : options.longs === Number ? new $util.LongBits(message.modelVersion.low >>> 0, message.modelVersion.high >>> 0).toNumber() : message.modelVersion; + if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; + if (message.graph != null && message.hasOwnProperty("graph")) + object.graph = $root.onnx.GraphProto.toObject(message.graph, options); + if (message.opsetImport && message.opsetImport.length) { + object.opsetImport = []; + for (var j = 0; j < message.opsetImport.length; ++j) + object.opsetImport[j] = $root.onnx.OperatorSetIdProto.toObject(message.opsetImport[j], options); + } + if (message.metadataProps && message.metadataProps.length) { + object.metadataProps = []; + for (var j = 0; j < message.metadataProps.length; ++j) + object.metadataProps[j] = $root.onnx.StringStringEntryProto.toObject(message.metadataProps[j], options); + } + if (message.trainingInfo && message.trainingInfo.length) { + object.trainingInfo = []; + for (var j = 0; j < message.trainingInfo.length; ++j) + object.trainingInfo[j] = $root.onnx.TrainingInfoProto.toObject(message.trainingInfo[j], options); + } + if (message.functions && message.functions.length) { + object.functions = []; + for (var j = 0; j < message.functions.length; ++j) + object.functions[j] = $root.onnx.FunctionProto.toObject(message.functions[j], options); + } + return object; + }; + ModelProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + ModelProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.ModelProto"; + }; + return ModelProto; + }(); + onnx6.StringStringEntryProto = function() { + function StringStringEntryProto(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + StringStringEntryProto.prototype.key = ""; + StringStringEntryProto.prototype.value = ""; + StringStringEntryProto.create = function create(properties) { + return new StringStringEntryProto(properties); + }; + StringStringEntryProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.key != null && Object.hasOwnProperty.call(message, "key")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.key); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.value); + return writer; + }; + StringStringEntryProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + StringStringEntryProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.StringStringEntryProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.key = reader.string(); + break; + } + case 2: { + message.value = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + StringStringEntryProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + StringStringEntryProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.key != null && message.hasOwnProperty("key")) { + if (!$util.isString(message.key)) return "key: string expected"; + } + if (message.value != null && message.hasOwnProperty("value")) { + if (!$util.isString(message.value)) return "value: string expected"; + } + return null; + }; + StringStringEntryProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.StringStringEntryProto) return object; + var message = new $root.onnx.StringStringEntryProto(); + if (object.key != null) message.key = String(object.key); + if (object.value != null) message.value = String(object.value); + return message; + }; + StringStringEntryProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.key = ""; + object.value = ""; + } + if (message.key != null && message.hasOwnProperty("key")) object.key = message.key; + if (message.value != null && message.hasOwnProperty("value")) object.value = message.value; + return object; + }; + StringStringEntryProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + StringStringEntryProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.StringStringEntryProto"; + }; + return StringStringEntryProto; + }(); + onnx6.TensorAnnotation = function() { + function TensorAnnotation(properties) { + this.quantParameterTensorNames = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + TensorAnnotation.prototype.tensorName = ""; + TensorAnnotation.prototype.quantParameterTensorNames = $util.emptyArray; + TensorAnnotation.create = function create(properties) { + return new TensorAnnotation(properties); + }; + TensorAnnotation.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.tensorName != null && Object.hasOwnProperty.call(message, "tensorName")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.tensorName); + if (message.quantParameterTensorNames != null && message.quantParameterTensorNames.length) + for (var i = 0; i < message.quantParameterTensorNames.length; ++i) + $root.onnx.StringStringEntryProto.encode( + message.quantParameterTensorNames[i], + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork() + ).ldelim(); + return writer; + }; + TensorAnnotation.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TensorAnnotation.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorAnnotation(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.tensorName = reader.string(); + break; + } + case 2: { + if (!(message.quantParameterTensorNames && message.quantParameterTensorNames.length)) + message.quantParameterTensorNames = []; + message.quantParameterTensorNames.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TensorAnnotation.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TensorAnnotation.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.tensorName != null && message.hasOwnProperty("tensorName")) { + if (!$util.isString(message.tensorName)) return "tensorName: string expected"; + } + if (message.quantParameterTensorNames != null && message.hasOwnProperty("quantParameterTensorNames")) { + if (!Array.isArray(message.quantParameterTensorNames)) return "quantParameterTensorNames: array expected"; + for (var i = 0; i < message.quantParameterTensorNames.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.quantParameterTensorNames[i]); + if (error) return "quantParameterTensorNames." + error; + } + } + return null; + }; + TensorAnnotation.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorAnnotation) return object; + var message = new $root.onnx.TensorAnnotation(); + if (object.tensorName != null) message.tensorName = String(object.tensorName); + if (object.quantParameterTensorNames) { + if (!Array.isArray(object.quantParameterTensorNames)) + throw TypeError(".onnx.TensorAnnotation.quantParameterTensorNames: array expected"); + message.quantParameterTensorNames = []; + for (var i = 0; i < object.quantParameterTensorNames.length; ++i) { + if (typeof object.quantParameterTensorNames[i] !== "object") + throw TypeError(".onnx.TensorAnnotation.quantParameterTensorNames: object expected"); + message.quantParameterTensorNames[i] = $root.onnx.StringStringEntryProto.fromObject( + object.quantParameterTensorNames[i] + ); + } + } + return message; + }; + TensorAnnotation.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) object.quantParameterTensorNames = []; + if (options.defaults) object.tensorName = ""; + if (message.tensorName != null && message.hasOwnProperty("tensorName")) object.tensorName = message.tensorName; + if (message.quantParameterTensorNames && message.quantParameterTensorNames.length) { + object.quantParameterTensorNames = []; + for (var j = 0; j < message.quantParameterTensorNames.length; ++j) + object.quantParameterTensorNames[j] = $root.onnx.StringStringEntryProto.toObject( + message.quantParameterTensorNames[j], + options + ); + } + return object; + }; + TensorAnnotation.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TensorAnnotation.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorAnnotation"; + }; + return TensorAnnotation; + }(); + onnx6.GraphProto = function() { + function GraphProto(properties) { + this.node = []; + this.initializer = []; + this.sparseInitializer = []; + this.input = []; + this.output = []; + this.valueInfo = []; + this.quantizationAnnotation = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + GraphProto.prototype.node = $util.emptyArray; + GraphProto.prototype.name = ""; + GraphProto.prototype.initializer = $util.emptyArray; + GraphProto.prototype.sparseInitializer = $util.emptyArray; + GraphProto.prototype.docString = ""; + GraphProto.prototype.input = $util.emptyArray; + GraphProto.prototype.output = $util.emptyArray; + GraphProto.prototype.valueInfo = $util.emptyArray; + GraphProto.prototype.quantizationAnnotation = $util.emptyArray; + GraphProto.create = function create(properties) { + return new GraphProto(properties); + }; + GraphProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.node != null && message.node.length) + for (var i = 0; i < message.node.length; ++i) + $root.onnx.NodeProto.encode(message.node[i], writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.name); + if (message.initializer != null && message.initializer.length) + for (var i = 0; i < message.initializer.length; ++i) + $root.onnx.TensorProto.encode( + message.initializer[i], + writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork() + ).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 10, wireType 2 =*/ + 82 + ).string(message.docString); + if (message.input != null && message.input.length) + for (var i = 0; i < message.input.length; ++i) + $root.onnx.ValueInfoProto.encode( + message.input[i], + writer.uint32( + /* id 11, wireType 2 =*/ + 90 + ).fork() + ).ldelim(); + if (message.output != null && message.output.length) + for (var i = 0; i < message.output.length; ++i) + $root.onnx.ValueInfoProto.encode( + message.output[i], + writer.uint32( + /* id 12, wireType 2 =*/ + 98 + ).fork() + ).ldelim(); + if (message.valueInfo != null && message.valueInfo.length) + for (var i = 0; i < message.valueInfo.length; ++i) + $root.onnx.ValueInfoProto.encode( + message.valueInfo[i], + writer.uint32( + /* id 13, wireType 2 =*/ + 106 + ).fork() + ).ldelim(); + if (message.quantizationAnnotation != null && message.quantizationAnnotation.length) + for (var i = 0; i < message.quantizationAnnotation.length; ++i) + $root.onnx.TensorAnnotation.encode( + message.quantizationAnnotation[i], + writer.uint32( + /* id 14, wireType 2 =*/ + 114 + ).fork() + ).ldelim(); + if (message.sparseInitializer != null && message.sparseInitializer.length) + for (var i = 0; i < message.sparseInitializer.length; ++i) + $root.onnx.SparseTensorProto.encode( + message.sparseInitializer[i], + writer.uint32( + /* id 15, wireType 2 =*/ + 122 + ).fork() + ).ldelim(); + return writer; + }; + GraphProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + GraphProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.GraphProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (!(message.node && message.node.length)) message.node = []; + message.node.push($root.onnx.NodeProto.decode(reader, reader.uint32())); + break; + } + case 2: { + message.name = reader.string(); + break; + } + case 5: { + if (!(message.initializer && message.initializer.length)) message.initializer = []; + message.initializer.push($root.onnx.TensorProto.decode(reader, reader.uint32())); + break; + } + case 15: { + if (!(message.sparseInitializer && message.sparseInitializer.length)) message.sparseInitializer = []; + message.sparseInitializer.push($root.onnx.SparseTensorProto.decode(reader, reader.uint32())); + break; + } + case 10: { + message.docString = reader.string(); + break; + } + case 11: { + if (!(message.input && message.input.length)) message.input = []; + message.input.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32())); + break; + } + case 12: { + if (!(message.output && message.output.length)) message.output = []; + message.output.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32())); + break; + } + case 13: { + if (!(message.valueInfo && message.valueInfo.length)) message.valueInfo = []; + message.valueInfo.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32())); + break; + } + case 14: { + if (!(message.quantizationAnnotation && message.quantizationAnnotation.length)) + message.quantizationAnnotation = []; + message.quantizationAnnotation.push($root.onnx.TensorAnnotation.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + GraphProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + GraphProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.node != null && message.hasOwnProperty("node")) { + if (!Array.isArray(message.node)) return "node: array expected"; + for (var i = 0; i < message.node.length; ++i) { + var error = $root.onnx.NodeProto.verify(message.node[i]); + if (error) return "node." + error; + } + } + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) return "name: string expected"; + } + if (message.initializer != null && message.hasOwnProperty("initializer")) { + if (!Array.isArray(message.initializer)) return "initializer: array expected"; + for (var i = 0; i < message.initializer.length; ++i) { + var error = $root.onnx.TensorProto.verify(message.initializer[i]); + if (error) return "initializer." + error; + } + } + if (message.sparseInitializer != null && message.hasOwnProperty("sparseInitializer")) { + if (!Array.isArray(message.sparseInitializer)) return "sparseInitializer: array expected"; + for (var i = 0; i < message.sparseInitializer.length; ++i) { + var error = $root.onnx.SparseTensorProto.verify(message.sparseInitializer[i]); + if (error) return "sparseInitializer." + error; + } + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) return "docString: string expected"; + } + if (message.input != null && message.hasOwnProperty("input")) { + if (!Array.isArray(message.input)) return "input: array expected"; + for (var i = 0; i < message.input.length; ++i) { + var error = $root.onnx.ValueInfoProto.verify(message.input[i]); + if (error) return "input." + error; + } + } + if (message.output != null && message.hasOwnProperty("output")) { + if (!Array.isArray(message.output)) return "output: array expected"; + for (var i = 0; i < message.output.length; ++i) { + var error = $root.onnx.ValueInfoProto.verify(message.output[i]); + if (error) return "output." + error; + } + } + if (message.valueInfo != null && message.hasOwnProperty("valueInfo")) { + if (!Array.isArray(message.valueInfo)) return "valueInfo: array expected"; + for (var i = 0; i < message.valueInfo.length; ++i) { + var error = $root.onnx.ValueInfoProto.verify(message.valueInfo[i]); + if (error) return "valueInfo." + error; + } + } + if (message.quantizationAnnotation != null && message.hasOwnProperty("quantizationAnnotation")) { + if (!Array.isArray(message.quantizationAnnotation)) return "quantizationAnnotation: array expected"; + for (var i = 0; i < message.quantizationAnnotation.length; ++i) { + var error = $root.onnx.TensorAnnotation.verify(message.quantizationAnnotation[i]); + if (error) return "quantizationAnnotation." + error; + } + } + return null; + }; + GraphProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.GraphProto) return object; + var message = new $root.onnx.GraphProto(); + if (object.node) { + if (!Array.isArray(object.node)) throw TypeError(".onnx.GraphProto.node: array expected"); + message.node = []; + for (var i = 0; i < object.node.length; ++i) { + if (typeof object.node[i] !== "object") throw TypeError(".onnx.GraphProto.node: object expected"); + message.node[i] = $root.onnx.NodeProto.fromObject(object.node[i]); + } + } + if (object.name != null) message.name = String(object.name); + if (object.initializer) { + if (!Array.isArray(object.initializer)) throw TypeError(".onnx.GraphProto.initializer: array expected"); + message.initializer = []; + for (var i = 0; i < object.initializer.length; ++i) { + if (typeof object.initializer[i] !== "object") + throw TypeError(".onnx.GraphProto.initializer: object expected"); + message.initializer[i] = $root.onnx.TensorProto.fromObject(object.initializer[i]); + } + } + if (object.sparseInitializer) { + if (!Array.isArray(object.sparseInitializer)) + throw TypeError(".onnx.GraphProto.sparseInitializer: array expected"); + message.sparseInitializer = []; + for (var i = 0; i < object.sparseInitializer.length; ++i) { + if (typeof object.sparseInitializer[i] !== "object") + throw TypeError(".onnx.GraphProto.sparseInitializer: object expected"); + message.sparseInitializer[i] = $root.onnx.SparseTensorProto.fromObject(object.sparseInitializer[i]); + } + } + if (object.docString != null) message.docString = String(object.docString); + if (object.input) { + if (!Array.isArray(object.input)) throw TypeError(".onnx.GraphProto.input: array expected"); + message.input = []; + for (var i = 0; i < object.input.length; ++i) { + if (typeof object.input[i] !== "object") throw TypeError(".onnx.GraphProto.input: object expected"); + message.input[i] = $root.onnx.ValueInfoProto.fromObject(object.input[i]); + } + } + if (object.output) { + if (!Array.isArray(object.output)) throw TypeError(".onnx.GraphProto.output: array expected"); + message.output = []; + for (var i = 0; i < object.output.length; ++i) { + if (typeof object.output[i] !== "object") throw TypeError(".onnx.GraphProto.output: object expected"); + message.output[i] = $root.onnx.ValueInfoProto.fromObject(object.output[i]); + } + } + if (object.valueInfo) { + if (!Array.isArray(object.valueInfo)) throw TypeError(".onnx.GraphProto.valueInfo: array expected"); + message.valueInfo = []; + for (var i = 0; i < object.valueInfo.length; ++i) { + if (typeof object.valueInfo[i] !== "object") throw TypeError(".onnx.GraphProto.valueInfo: object expected"); + message.valueInfo[i] = $root.onnx.ValueInfoProto.fromObject(object.valueInfo[i]); + } + } + if (object.quantizationAnnotation) { + if (!Array.isArray(object.quantizationAnnotation)) + throw TypeError(".onnx.GraphProto.quantizationAnnotation: array expected"); + message.quantizationAnnotation = []; + for (var i = 0; i < object.quantizationAnnotation.length; ++i) { + if (typeof object.quantizationAnnotation[i] !== "object") + throw TypeError(".onnx.GraphProto.quantizationAnnotation: object expected"); + message.quantizationAnnotation[i] = $root.onnx.TensorAnnotation.fromObject(object.quantizationAnnotation[i]); + } + } + return message; + }; + GraphProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.node = []; + object.initializer = []; + object.input = []; + object.output = []; + object.valueInfo = []; + object.quantizationAnnotation = []; + object.sparseInitializer = []; + } + if (options.defaults) { + object.name = ""; + object.docString = ""; + } + if (message.node && message.node.length) { + object.node = []; + for (var j = 0; j < message.node.length; ++j) + object.node[j] = $root.onnx.NodeProto.toObject(message.node[j], options); + } + if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; + if (message.initializer && message.initializer.length) { + object.initializer = []; + for (var j = 0; j < message.initializer.length; ++j) + object.initializer[j] = $root.onnx.TensorProto.toObject(message.initializer[j], options); + } + if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; + if (message.input && message.input.length) { + object.input = []; + for (var j = 0; j < message.input.length; ++j) + object.input[j] = $root.onnx.ValueInfoProto.toObject(message.input[j], options); + } + if (message.output && message.output.length) { + object.output = []; + for (var j = 0; j < message.output.length; ++j) + object.output[j] = $root.onnx.ValueInfoProto.toObject(message.output[j], options); + } + if (message.valueInfo && message.valueInfo.length) { + object.valueInfo = []; + for (var j = 0; j < message.valueInfo.length; ++j) + object.valueInfo[j] = $root.onnx.ValueInfoProto.toObject(message.valueInfo[j], options); + } + if (message.quantizationAnnotation && message.quantizationAnnotation.length) { + object.quantizationAnnotation = []; + for (var j = 0; j < message.quantizationAnnotation.length; ++j) + object.quantizationAnnotation[j] = $root.onnx.TensorAnnotation.toObject( + message.quantizationAnnotation[j], + options + ); + } + if (message.sparseInitializer && message.sparseInitializer.length) { + object.sparseInitializer = []; + for (var j = 0; j < message.sparseInitializer.length; ++j) + object.sparseInitializer[j] = $root.onnx.SparseTensorProto.toObject(message.sparseInitializer[j], options); + } + return object; + }; + GraphProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + GraphProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.GraphProto"; + }; + return GraphProto; + }(); + onnx6.TensorProto = function() { + function TensorProto(properties) { + this.dims = []; + this.floatData = []; + this.int32Data = []; + this.stringData = []; + this.int64Data = []; + this.externalData = []; + this.doubleData = []; + this.uint64Data = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + TensorProto.prototype.dims = $util.emptyArray; + TensorProto.prototype.dataType = 0; + TensorProto.prototype.segment = null; + TensorProto.prototype.floatData = $util.emptyArray; + TensorProto.prototype.int32Data = $util.emptyArray; + TensorProto.prototype.stringData = $util.emptyArray; + TensorProto.prototype.int64Data = $util.emptyArray; + TensorProto.prototype.name = ""; + TensorProto.prototype.docString = ""; + TensorProto.prototype.rawData = $util.newBuffer([]); + TensorProto.prototype.externalData = $util.emptyArray; + TensorProto.prototype.dataLocation = 0; + TensorProto.prototype.doubleData = $util.emptyArray; + TensorProto.prototype.uint64Data = $util.emptyArray; + TensorProto.create = function create(properties) { + return new TensorProto(properties); + }; + TensorProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.dims != null && message.dims.length) { + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork(); + for (var i = 0; i < message.dims.length; ++i) writer.int64(message.dims[i]); + writer.ldelim(); + } + if (message.dataType != null && Object.hasOwnProperty.call(message, "dataType")) + writer.uint32( + /* id 2, wireType 0 =*/ + 16 + ).int32(message.dataType); + if (message.segment != null && Object.hasOwnProperty.call(message, "segment")) + $root.onnx.TensorProto.Segment.encode( + message.segment, + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).fork() + ).ldelim(); + if (message.floatData != null && message.floatData.length) { + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).fork(); + for (var i = 0; i < message.floatData.length; ++i) writer.float(message.floatData[i]); + writer.ldelim(); + } + if (message.int32Data != null && message.int32Data.length) { + writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork(); + for (var i = 0; i < message.int32Data.length; ++i) writer.int32(message.int32Data[i]); + writer.ldelim(); + } + if (message.stringData != null && message.stringData.length) + for (var i = 0; i < message.stringData.length; ++i) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).bytes(message.stringData[i]); + if (message.int64Data != null && message.int64Data.length) { + writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).fork(); + for (var i = 0; i < message.int64Data.length; ++i) writer.int64(message.int64Data[i]); + writer.ldelim(); + } + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).string(message.name); + if (message.rawData != null && Object.hasOwnProperty.call(message, "rawData")) + writer.uint32( + /* id 9, wireType 2 =*/ + 74 + ).bytes(message.rawData); + if (message.doubleData != null && message.doubleData.length) { + writer.uint32( + /* id 10, wireType 2 =*/ + 82 + ).fork(); + for (var i = 0; i < message.doubleData.length; ++i) writer.double(message.doubleData[i]); + writer.ldelim(); + } + if (message.uint64Data != null && message.uint64Data.length) { + writer.uint32( + /* id 11, wireType 2 =*/ + 90 + ).fork(); + for (var i = 0; i < message.uint64Data.length; ++i) writer.uint64(message.uint64Data[i]); + writer.ldelim(); + } + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 12, wireType 2 =*/ + 98 + ).string(message.docString); + if (message.externalData != null && message.externalData.length) + for (var i = 0; i < message.externalData.length; ++i) + $root.onnx.StringStringEntryProto.encode( + message.externalData[i], + writer.uint32( + /* id 13, wireType 2 =*/ + 106 + ).fork() + ).ldelim(); + if (message.dataLocation != null && Object.hasOwnProperty.call(message, "dataLocation")) + writer.uint32( + /* id 14, wireType 0 =*/ + 112 + ).int32(message.dataLocation); + return writer; + }; + TensorProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TensorProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (!(message.dims && message.dims.length)) message.dims = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) message.dims.push(reader.int64()); + } else message.dims.push(reader.int64()); + break; + } + case 2: { + message.dataType = reader.int32(); + break; + } + case 3: { + message.segment = $root.onnx.TensorProto.Segment.decode(reader, reader.uint32()); + break; + } + case 4: { + if (!(message.floatData && message.floatData.length)) message.floatData = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) message.floatData.push(reader.float()); + } else message.floatData.push(reader.float()); + break; + } + case 5: { + if (!(message.int32Data && message.int32Data.length)) message.int32Data = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) message.int32Data.push(reader.int32()); + } else message.int32Data.push(reader.int32()); + break; + } + case 6: { + if (!(message.stringData && message.stringData.length)) message.stringData = []; + message.stringData.push(reader.bytes()); + break; + } + case 7: { + if (!(message.int64Data && message.int64Data.length)) message.int64Data = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) message.int64Data.push(reader.int64()); + } else message.int64Data.push(reader.int64()); + break; + } + case 8: { + message.name = reader.string(); + break; + } + case 12: { + message.docString = reader.string(); + break; + } + case 9: { + message.rawData = reader.bytes(); + break; + } + case 13: { + if (!(message.externalData && message.externalData.length)) message.externalData = []; + message.externalData.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + case 14: { + message.dataLocation = reader.int32(); + break; + } + case 10: { + if (!(message.doubleData && message.doubleData.length)) message.doubleData = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) message.doubleData.push(reader.double()); + } else message.doubleData.push(reader.double()); + break; + } + case 11: { + if (!(message.uint64Data && message.uint64Data.length)) message.uint64Data = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) message.uint64Data.push(reader.uint64()); + } else message.uint64Data.push(reader.uint64()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TensorProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TensorProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.dims != null && message.hasOwnProperty("dims")) { + if (!Array.isArray(message.dims)) return "dims: array expected"; + for (var i = 0; i < message.dims.length; ++i) + if (!$util.isInteger(message.dims[i]) && !(message.dims[i] && $util.isInteger(message.dims[i].low) && $util.isInteger(message.dims[i].high))) + return "dims: integer|Long[] expected"; + } + if (message.dataType != null && message.hasOwnProperty("dataType")) { + if (!$util.isInteger(message.dataType)) return "dataType: integer expected"; + } + if (message.segment != null && message.hasOwnProperty("segment")) { + var error = $root.onnx.TensorProto.Segment.verify(message.segment); + if (error) return "segment." + error; + } + if (message.floatData != null && message.hasOwnProperty("floatData")) { + if (!Array.isArray(message.floatData)) return "floatData: array expected"; + for (var i = 0; i < message.floatData.length; ++i) + if (typeof message.floatData[i] !== "number") return "floatData: number[] expected"; + } + if (message.int32Data != null && message.hasOwnProperty("int32Data")) { + if (!Array.isArray(message.int32Data)) return "int32Data: array expected"; + for (var i = 0; i < message.int32Data.length; ++i) + if (!$util.isInteger(message.int32Data[i])) return "int32Data: integer[] expected"; + } + if (message.stringData != null && message.hasOwnProperty("stringData")) { + if (!Array.isArray(message.stringData)) return "stringData: array expected"; + for (var i = 0; i < message.stringData.length; ++i) + if (!(message.stringData[i] && typeof message.stringData[i].length === "number" || $util.isString(message.stringData[i]))) + return "stringData: buffer[] expected"; + } + if (message.int64Data != null && message.hasOwnProperty("int64Data")) { + if (!Array.isArray(message.int64Data)) return "int64Data: array expected"; + for (var i = 0; i < message.int64Data.length; ++i) + if (!$util.isInteger(message.int64Data[i]) && !(message.int64Data[i] && $util.isInteger(message.int64Data[i].low) && $util.isInteger(message.int64Data[i].high))) + return "int64Data: integer|Long[] expected"; + } + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) return "name: string expected"; + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) return "docString: string expected"; + } + if (message.rawData != null && message.hasOwnProperty("rawData")) { + if (!(message.rawData && typeof message.rawData.length === "number" || $util.isString(message.rawData))) + return "rawData: buffer expected"; + } + if (message.externalData != null && message.hasOwnProperty("externalData")) { + if (!Array.isArray(message.externalData)) return "externalData: array expected"; + for (var i = 0; i < message.externalData.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.externalData[i]); + if (error) return "externalData." + error; + } + } + if (message.dataLocation != null && message.hasOwnProperty("dataLocation")) + switch (message.dataLocation) { + default: + return "dataLocation: enum value expected"; + case 0: + case 1: + break; + } + if (message.doubleData != null && message.hasOwnProperty("doubleData")) { + if (!Array.isArray(message.doubleData)) return "doubleData: array expected"; + for (var i = 0; i < message.doubleData.length; ++i) + if (typeof message.doubleData[i] !== "number") return "doubleData: number[] expected"; + } + if (message.uint64Data != null && message.hasOwnProperty("uint64Data")) { + if (!Array.isArray(message.uint64Data)) return "uint64Data: array expected"; + for (var i = 0; i < message.uint64Data.length; ++i) + if (!$util.isInteger(message.uint64Data[i]) && !(message.uint64Data[i] && $util.isInteger(message.uint64Data[i].low) && $util.isInteger(message.uint64Data[i].high))) + return "uint64Data: integer|Long[] expected"; + } + return null; + }; + TensorProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorProto) return object; + var message = new $root.onnx.TensorProto(); + if (object.dims) { + if (!Array.isArray(object.dims)) throw TypeError(".onnx.TensorProto.dims: array expected"); + message.dims = []; + for (var i = 0; i < object.dims.length; ++i) + if ($util.Long) (message.dims[i] = $util.Long.fromValue(object.dims[i])).unsigned = false; + else if (typeof object.dims[i] === "string") message.dims[i] = parseInt(object.dims[i], 10); + else if (typeof object.dims[i] === "number") message.dims[i] = object.dims[i]; + else if (typeof object.dims[i] === "object") + message.dims[i] = new $util.LongBits(object.dims[i].low >>> 0, object.dims[i].high >>> 0).toNumber(); + } + if (object.dataType != null) message.dataType = object.dataType | 0; + if (object.segment != null) { + if (typeof object.segment !== "object") throw TypeError(".onnx.TensorProto.segment: object expected"); + message.segment = $root.onnx.TensorProto.Segment.fromObject(object.segment); + } + if (object.floatData) { + if (!Array.isArray(object.floatData)) throw TypeError(".onnx.TensorProto.floatData: array expected"); + message.floatData = []; + for (var i = 0; i < object.floatData.length; ++i) message.floatData[i] = Number(object.floatData[i]); + } + if (object.int32Data) { + if (!Array.isArray(object.int32Data)) throw TypeError(".onnx.TensorProto.int32Data: array expected"); + message.int32Data = []; + for (var i = 0; i < object.int32Data.length; ++i) message.int32Data[i] = object.int32Data[i] | 0; + } + if (object.stringData) { + if (!Array.isArray(object.stringData)) throw TypeError(".onnx.TensorProto.stringData: array expected"); + message.stringData = []; + for (var i = 0; i < object.stringData.length; ++i) + if (typeof object.stringData[i] === "string") + $util.base64.decode( + object.stringData[i], + message.stringData[i] = $util.newBuffer($util.base64.length(object.stringData[i])), + 0 + ); + else if (object.stringData[i].length >= 0) message.stringData[i] = object.stringData[i]; + } + if (object.int64Data) { + if (!Array.isArray(object.int64Data)) throw TypeError(".onnx.TensorProto.int64Data: array expected"); + message.int64Data = []; + for (var i = 0; i < object.int64Data.length; ++i) + if ($util.Long) (message.int64Data[i] = $util.Long.fromValue(object.int64Data[i])).unsigned = false; + else if (typeof object.int64Data[i] === "string") message.int64Data[i] = parseInt(object.int64Data[i], 10); + else if (typeof object.int64Data[i] === "number") message.int64Data[i] = object.int64Data[i]; + else if (typeof object.int64Data[i] === "object") + message.int64Data[i] = new $util.LongBits( + object.int64Data[i].low >>> 0, + object.int64Data[i].high >>> 0 + ).toNumber(); + } + if (object.name != null) message.name = String(object.name); + if (object.docString != null) message.docString = String(object.docString); + if (object.rawData != null) { + if (typeof object.rawData === "string") + $util.base64.decode( + object.rawData, + message.rawData = $util.newBuffer($util.base64.length(object.rawData)), + 0 + ); + else if (object.rawData.length >= 0) message.rawData = object.rawData; + } + if (object.externalData) { + if (!Array.isArray(object.externalData)) throw TypeError(".onnx.TensorProto.externalData: array expected"); + message.externalData = []; + for (var i = 0; i < object.externalData.length; ++i) { + if (typeof object.externalData[i] !== "object") + throw TypeError(".onnx.TensorProto.externalData: object expected"); + message.externalData[i] = $root.onnx.StringStringEntryProto.fromObject(object.externalData[i]); + } + } + switch (object.dataLocation) { + default: + if (typeof object.dataLocation === "number") { + message.dataLocation = object.dataLocation; + break; + } + break; + case "DEFAULT": + case 0: + message.dataLocation = 0; + break; + case "EXTERNAL": + case 1: + message.dataLocation = 1; + break; + } + if (object.doubleData) { + if (!Array.isArray(object.doubleData)) throw TypeError(".onnx.TensorProto.doubleData: array expected"); + message.doubleData = []; + for (var i = 0; i < object.doubleData.length; ++i) message.doubleData[i] = Number(object.doubleData[i]); + } + if (object.uint64Data) { + if (!Array.isArray(object.uint64Data)) throw TypeError(".onnx.TensorProto.uint64Data: array expected"); + message.uint64Data = []; + for (var i = 0; i < object.uint64Data.length; ++i) + if ($util.Long) (message.uint64Data[i] = $util.Long.fromValue(object.uint64Data[i])).unsigned = true; + else if (typeof object.uint64Data[i] === "string") message.uint64Data[i] = parseInt(object.uint64Data[i], 10); + else if (typeof object.uint64Data[i] === "number") message.uint64Data[i] = object.uint64Data[i]; + else if (typeof object.uint64Data[i] === "object") + message.uint64Data[i] = new $util.LongBits( + object.uint64Data[i].low >>> 0, + object.uint64Data[i].high >>> 0 + ).toNumber(true); + } + return message; + }; + TensorProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.dims = []; + object.floatData = []; + object.int32Data = []; + object.stringData = []; + object.int64Data = []; + object.doubleData = []; + object.uint64Data = []; + object.externalData = []; + } + if (options.defaults) { + object.dataType = 0; + object.segment = null; + object.name = ""; + if (options.bytes === String) object.rawData = ""; + else { + object.rawData = []; + if (options.bytes !== Array) object.rawData = $util.newBuffer(object.rawData); + } + object.docString = ""; + object.dataLocation = options.enums === String ? "DEFAULT" : 0; + } + if (message.dims && message.dims.length) { + object.dims = []; + for (var j = 0; j < message.dims.length; ++j) + if (typeof message.dims[j] === "number") + object.dims[j] = options.longs === String ? String(message.dims[j]) : message.dims[j]; + else + object.dims[j] = options.longs === String ? $util.Long.prototype.toString.call(message.dims[j]) : options.longs === Number ? new $util.LongBits(message.dims[j].low >>> 0, message.dims[j].high >>> 0).toNumber() : message.dims[j]; + } + if (message.dataType != null && message.hasOwnProperty("dataType")) object.dataType = message.dataType; + if (message.segment != null && message.hasOwnProperty("segment")) + object.segment = $root.onnx.TensorProto.Segment.toObject(message.segment, options); + if (message.floatData && message.floatData.length) { + object.floatData = []; + for (var j = 0; j < message.floatData.length; ++j) + object.floatData[j] = options.json && !isFinite(message.floatData[j]) ? String(message.floatData[j]) : message.floatData[j]; + } + if (message.int32Data && message.int32Data.length) { + object.int32Data = []; + for (var j = 0; j < message.int32Data.length; ++j) object.int32Data[j] = message.int32Data[j]; + } + if (message.stringData && message.stringData.length) { + object.stringData = []; + for (var j = 0; j < message.stringData.length; ++j) + object.stringData[j] = options.bytes === String ? $util.base64.encode(message.stringData[j], 0, message.stringData[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.stringData[j]) : message.stringData[j]; + } + if (message.int64Data && message.int64Data.length) { + object.int64Data = []; + for (var j = 0; j < message.int64Data.length; ++j) + if (typeof message.int64Data[j] === "number") + object.int64Data[j] = options.longs === String ? String(message.int64Data[j]) : message.int64Data[j]; + else + object.int64Data[j] = options.longs === String ? $util.Long.prototype.toString.call(message.int64Data[j]) : options.longs === Number ? new $util.LongBits(message.int64Data[j].low >>> 0, message.int64Data[j].high >>> 0).toNumber() : message.int64Data[j]; + } + if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; + if (message.rawData != null && message.hasOwnProperty("rawData")) + object.rawData = options.bytes === String ? $util.base64.encode(message.rawData, 0, message.rawData.length) : options.bytes === Array ? Array.prototype.slice.call(message.rawData) : message.rawData; + if (message.doubleData && message.doubleData.length) { + object.doubleData = []; + for (var j = 0; j < message.doubleData.length; ++j) + object.doubleData[j] = options.json && !isFinite(message.doubleData[j]) ? String(message.doubleData[j]) : message.doubleData[j]; + } + if (message.uint64Data && message.uint64Data.length) { + object.uint64Data = []; + for (var j = 0; j < message.uint64Data.length; ++j) + if (typeof message.uint64Data[j] === "number") + object.uint64Data[j] = options.longs === String ? String(message.uint64Data[j]) : message.uint64Data[j]; + else + object.uint64Data[j] = options.longs === String ? $util.Long.prototype.toString.call(message.uint64Data[j]) : options.longs === Number ? new $util.LongBits(message.uint64Data[j].low >>> 0, message.uint64Data[j].high >>> 0).toNumber(true) : message.uint64Data[j]; + } + if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; + if (message.externalData && message.externalData.length) { + object.externalData = []; + for (var j = 0; j < message.externalData.length; ++j) + object.externalData[j] = $root.onnx.StringStringEntryProto.toObject(message.externalData[j], options); + } + if (message.dataLocation != null && message.hasOwnProperty("dataLocation")) + object.dataLocation = options.enums === String ? $root.onnx.TensorProto.DataLocation[message.dataLocation] === void 0 ? message.dataLocation : $root.onnx.TensorProto.DataLocation[message.dataLocation] : message.dataLocation; + return object; + }; + TensorProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TensorProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorProto"; + }; + TensorProto.DataType = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNDEFINED"] = 0; + values[valuesById[1] = "FLOAT"] = 1; + values[valuesById[2] = "UINT8"] = 2; + values[valuesById[3] = "INT8"] = 3; + values[valuesById[4] = "UINT16"] = 4; + values[valuesById[5] = "INT16"] = 5; + values[valuesById[6] = "INT32"] = 6; + values[valuesById[7] = "INT64"] = 7; + values[valuesById[8] = "STRING"] = 8; + values[valuesById[9] = "BOOL"] = 9; + values[valuesById[10] = "FLOAT16"] = 10; + values[valuesById[11] = "DOUBLE"] = 11; + values[valuesById[12] = "UINT32"] = 12; + values[valuesById[13] = "UINT64"] = 13; + values[valuesById[14] = "COMPLEX64"] = 14; + values[valuesById[15] = "COMPLEX128"] = 15; + values[valuesById[16] = "BFLOAT16"] = 16; + values[valuesById[17] = "FLOAT8E4M3FN"] = 17; + values[valuesById[18] = "FLOAT8E4M3FNUZ"] = 18; + values[valuesById[19] = "FLOAT8E5M2"] = 19; + values[valuesById[20] = "FLOAT8E5M2FNUZ"] = 20; + return values; + }(); + TensorProto.Segment = function() { + function Segment(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + Segment.prototype.begin = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + Segment.prototype.end = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + Segment.create = function create(properties) { + return new Segment(properties); + }; + Segment.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.begin != null && Object.hasOwnProperty.call(message, "begin")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int64(message.begin); + if (message.end != null && Object.hasOwnProperty.call(message, "end")) + writer.uint32( + /* id 2, wireType 0 =*/ + 16 + ).int64(message.end); + return writer; + }; + Segment.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Segment.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorProto.Segment(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.begin = reader.int64(); + break; + } + case 2: { + message.end = reader.int64(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Segment.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Segment.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.begin != null && message.hasOwnProperty("begin")) { + if (!$util.isInteger(message.begin) && !(message.begin && $util.isInteger(message.begin.low) && $util.isInteger(message.begin.high))) + return "begin: integer|Long expected"; + } + if (message.end != null && message.hasOwnProperty("end")) { + if (!$util.isInteger(message.end) && !(message.end && $util.isInteger(message.end.low) && $util.isInteger(message.end.high))) + return "end: integer|Long expected"; + } + return null; + }; + Segment.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorProto.Segment) return object; + var message = new $root.onnx.TensorProto.Segment(); + if (object.begin != null) { + if ($util.Long) (message.begin = $util.Long.fromValue(object.begin)).unsigned = false; + else if (typeof object.begin === "string") message.begin = parseInt(object.begin, 10); + else if (typeof object.begin === "number") message.begin = object.begin; + else if (typeof object.begin === "object") + message.begin = new $util.LongBits(object.begin.low >>> 0, object.begin.high >>> 0).toNumber(); + } + if (object.end != null) { + if ($util.Long) (message.end = $util.Long.fromValue(object.end)).unsigned = false; + else if (typeof object.end === "string") message.end = parseInt(object.end, 10); + else if (typeof object.end === "number") message.end = object.end; + else if (typeof object.end === "object") + message.end = new $util.LongBits(object.end.low >>> 0, object.end.high >>> 0).toNumber(); + } + return message; + }; + Segment.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.begin = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else object.begin = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.end = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else object.end = options.longs === String ? "0" : 0; + } + if (message.begin != null && message.hasOwnProperty("begin")) + if (typeof message.begin === "number") + object.begin = options.longs === String ? String(message.begin) : message.begin; + else + object.begin = options.longs === String ? $util.Long.prototype.toString.call(message.begin) : options.longs === Number ? new $util.LongBits(message.begin.low >>> 0, message.begin.high >>> 0).toNumber() : message.begin; + if (message.end != null && message.hasOwnProperty("end")) + if (typeof message.end === "number") + object.end = options.longs === String ? String(message.end) : message.end; + else + object.end = options.longs === String ? $util.Long.prototype.toString.call(message.end) : options.longs === Number ? new $util.LongBits(message.end.low >>> 0, message.end.high >>> 0).toNumber() : message.end; + return object; + }; + Segment.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Segment.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorProto.Segment"; + }; + return Segment; + }(); + TensorProto.DataLocation = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "DEFAULT"] = 0; + values[valuesById[1] = "EXTERNAL"] = 1; + return values; + }(); + return TensorProto; + }(); + onnx6.SparseTensorProto = function() { + function SparseTensorProto(properties) { + this.dims = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + SparseTensorProto.prototype.values = null; + SparseTensorProto.prototype.indices = null; + SparseTensorProto.prototype.dims = $util.emptyArray; + SparseTensorProto.create = function create(properties) { + return new SparseTensorProto(properties); + }; + SparseTensorProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.values != null && Object.hasOwnProperty.call(message, "values")) + $root.onnx.TensorProto.encode(message.values, writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + if (message.indices != null && Object.hasOwnProperty.call(message, "indices")) + $root.onnx.TensorProto.encode(message.indices, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + if (message.dims != null && message.dims.length) { + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).fork(); + for (var i = 0; i < message.dims.length; ++i) writer.int64(message.dims[i]); + writer.ldelim(); + } + return writer; + }; + SparseTensorProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + SparseTensorProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.SparseTensorProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.values = $root.onnx.TensorProto.decode(reader, reader.uint32()); + break; + } + case 2: { + message.indices = $root.onnx.TensorProto.decode(reader, reader.uint32()); + break; + } + case 3: { + if (!(message.dims && message.dims.length)) message.dims = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) message.dims.push(reader.int64()); + } else message.dims.push(reader.int64()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + SparseTensorProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + SparseTensorProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.values != null && message.hasOwnProperty("values")) { + var error = $root.onnx.TensorProto.verify(message.values); + if (error) return "values." + error; + } + if (message.indices != null && message.hasOwnProperty("indices")) { + var error = $root.onnx.TensorProto.verify(message.indices); + if (error) return "indices." + error; + } + if (message.dims != null && message.hasOwnProperty("dims")) { + if (!Array.isArray(message.dims)) return "dims: array expected"; + for (var i = 0; i < message.dims.length; ++i) + if (!$util.isInteger(message.dims[i]) && !(message.dims[i] && $util.isInteger(message.dims[i].low) && $util.isInteger(message.dims[i].high))) + return "dims: integer|Long[] expected"; + } + return null; + }; + SparseTensorProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.SparseTensorProto) return object; + var message = new $root.onnx.SparseTensorProto(); + if (object.values != null) { + if (typeof object.values !== "object") throw TypeError(".onnx.SparseTensorProto.values: object expected"); + message.values = $root.onnx.TensorProto.fromObject(object.values); + } + if (object.indices != null) { + if (typeof object.indices !== "object") throw TypeError(".onnx.SparseTensorProto.indices: object expected"); + message.indices = $root.onnx.TensorProto.fromObject(object.indices); + } + if (object.dims) { + if (!Array.isArray(object.dims)) throw TypeError(".onnx.SparseTensorProto.dims: array expected"); + message.dims = []; + for (var i = 0; i < object.dims.length; ++i) + if ($util.Long) (message.dims[i] = $util.Long.fromValue(object.dims[i])).unsigned = false; + else if (typeof object.dims[i] === "string") message.dims[i] = parseInt(object.dims[i], 10); + else if (typeof object.dims[i] === "number") message.dims[i] = object.dims[i]; + else if (typeof object.dims[i] === "object") + message.dims[i] = new $util.LongBits(object.dims[i].low >>> 0, object.dims[i].high >>> 0).toNumber(); + } + return message; + }; + SparseTensorProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) object.dims = []; + if (options.defaults) { + object.values = null; + object.indices = null; + } + if (message.values != null && message.hasOwnProperty("values")) + object.values = $root.onnx.TensorProto.toObject(message.values, options); + if (message.indices != null && message.hasOwnProperty("indices")) + object.indices = $root.onnx.TensorProto.toObject(message.indices, options); + if (message.dims && message.dims.length) { + object.dims = []; + for (var j = 0; j < message.dims.length; ++j) + if (typeof message.dims[j] === "number") + object.dims[j] = options.longs === String ? String(message.dims[j]) : message.dims[j]; + else + object.dims[j] = options.longs === String ? $util.Long.prototype.toString.call(message.dims[j]) : options.longs === Number ? new $util.LongBits(message.dims[j].low >>> 0, message.dims[j].high >>> 0).toNumber() : message.dims[j]; + } + return object; + }; + SparseTensorProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + SparseTensorProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.SparseTensorProto"; + }; + return SparseTensorProto; + }(); + onnx6.TensorShapeProto = function() { + function TensorShapeProto(properties) { + this.dim = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + TensorShapeProto.prototype.dim = $util.emptyArray; + TensorShapeProto.create = function create(properties) { + return new TensorShapeProto(properties); + }; + TensorShapeProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.dim != null && message.dim.length) + for (var i = 0; i < message.dim.length; ++i) + $root.onnx.TensorShapeProto.Dimension.encode( + message.dim[i], + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork() + ).ldelim(); + return writer; + }; + TensorShapeProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TensorShapeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorShapeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (!(message.dim && message.dim.length)) message.dim = []; + message.dim.push($root.onnx.TensorShapeProto.Dimension.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TensorShapeProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TensorShapeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.dim != null && message.hasOwnProperty("dim")) { + if (!Array.isArray(message.dim)) return "dim: array expected"; + for (var i = 0; i < message.dim.length; ++i) { + var error = $root.onnx.TensorShapeProto.Dimension.verify(message.dim[i]); + if (error) return "dim." + error; + } + } + return null; + }; + TensorShapeProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorShapeProto) return object; + var message = new $root.onnx.TensorShapeProto(); + if (object.dim) { + if (!Array.isArray(object.dim)) throw TypeError(".onnx.TensorShapeProto.dim: array expected"); + message.dim = []; + for (var i = 0; i < object.dim.length; ++i) { + if (typeof object.dim[i] !== "object") throw TypeError(".onnx.TensorShapeProto.dim: object expected"); + message.dim[i] = $root.onnx.TensorShapeProto.Dimension.fromObject(object.dim[i]); + } + } + return message; + }; + TensorShapeProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) object.dim = []; + if (message.dim && message.dim.length) { + object.dim = []; + for (var j = 0; j < message.dim.length; ++j) + object.dim[j] = $root.onnx.TensorShapeProto.Dimension.toObject(message.dim[j], options); + } + return object; + }; + TensorShapeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TensorShapeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorShapeProto"; + }; + TensorShapeProto.Dimension = function() { + function Dimension2(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + Dimension2.prototype.dimValue = null; + Dimension2.prototype.dimParam = null; + Dimension2.prototype.denotation = ""; + var $oneOfFields; + Object.defineProperty(Dimension2.prototype, "value", { + get: $util.oneOfGetter($oneOfFields = ["dimValue", "dimParam"]), + set: $util.oneOfSetter($oneOfFields) + }); + Dimension2.create = function create(properties) { + return new Dimension2(properties); + }; + Dimension2.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.dimValue != null && Object.hasOwnProperty.call(message, "dimValue")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int64(message.dimValue); + if (message.dimParam != null && Object.hasOwnProperty.call(message, "dimParam")) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.dimParam); + if (message.denotation != null && Object.hasOwnProperty.call(message, "denotation")) + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).string(message.denotation); + return writer; + }; + Dimension2.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Dimension2.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorShapeProto.Dimension(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.dimValue = reader.int64(); + break; + } + case 2: { + message.dimParam = reader.string(); + break; + } + case 3: { + message.denotation = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Dimension2.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Dimension2.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + var properties = {}; + if (message.dimValue != null && message.hasOwnProperty("dimValue")) { + properties.value = 1; + if (!$util.isInteger(message.dimValue) && !(message.dimValue && $util.isInteger(message.dimValue.low) && $util.isInteger(message.dimValue.high))) + return "dimValue: integer|Long expected"; + } + if (message.dimParam != null && message.hasOwnProperty("dimParam")) { + if (properties.value === 1) return "value: multiple values"; + properties.value = 1; + if (!$util.isString(message.dimParam)) return "dimParam: string expected"; + } + if (message.denotation != null && message.hasOwnProperty("denotation")) { + if (!$util.isString(message.denotation)) return "denotation: string expected"; + } + return null; + }; + Dimension2.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorShapeProto.Dimension) return object; + var message = new $root.onnx.TensorShapeProto.Dimension(); + if (object.dimValue != null) { + if ($util.Long) (message.dimValue = $util.Long.fromValue(object.dimValue)).unsigned = false; + else if (typeof object.dimValue === "string") message.dimValue = parseInt(object.dimValue, 10); + else if (typeof object.dimValue === "number") message.dimValue = object.dimValue; + else if (typeof object.dimValue === "object") + message.dimValue = new $util.LongBits(object.dimValue.low >>> 0, object.dimValue.high >>> 0).toNumber(); + } + if (object.dimParam != null) message.dimParam = String(object.dimParam); + if (object.denotation != null) message.denotation = String(object.denotation); + return message; + }; + Dimension2.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) object.denotation = ""; + if (message.dimValue != null && message.hasOwnProperty("dimValue")) { + if (typeof message.dimValue === "number") + object.dimValue = options.longs === String ? String(message.dimValue) : message.dimValue; + else + object.dimValue = options.longs === String ? $util.Long.prototype.toString.call(message.dimValue) : options.longs === Number ? new $util.LongBits(message.dimValue.low >>> 0, message.dimValue.high >>> 0).toNumber() : message.dimValue; + if (options.oneofs) object.value = "dimValue"; + } + if (message.dimParam != null && message.hasOwnProperty("dimParam")) { + object.dimParam = message.dimParam; + if (options.oneofs) object.value = "dimParam"; + } + if (message.denotation != null && message.hasOwnProperty("denotation")) object.denotation = message.denotation; + return object; + }; + Dimension2.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Dimension2.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorShapeProto.Dimension"; + }; + return Dimension2; + }(); + return TensorShapeProto; + }(); + onnx6.TypeProto = function() { + function TypeProto(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + TypeProto.prototype.tensorType = null; + TypeProto.prototype.sequenceType = null; + TypeProto.prototype.mapType = null; + TypeProto.prototype.optionalType = null; + TypeProto.prototype.sparseTensorType = null; + TypeProto.prototype.denotation = ""; + var $oneOfFields; + Object.defineProperty(TypeProto.prototype, "value", { + get: $util.oneOfGetter( + $oneOfFields = ["tensorType", "sequenceType", "mapType", "optionalType", "sparseTensorType"] + ), + set: $util.oneOfSetter($oneOfFields) + }); + TypeProto.create = function create(properties) { + return new TypeProto(properties); + }; + TypeProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.tensorType != null && Object.hasOwnProperty.call(message, "tensorType")) + $root.onnx.TypeProto.Tensor.encode( + message.tensorType, + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork() + ).ldelim(); + if (message.sequenceType != null && Object.hasOwnProperty.call(message, "sequenceType")) + $root.onnx.TypeProto.Sequence.encode( + message.sequenceType, + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).fork() + ).ldelim(); + if (message.mapType != null && Object.hasOwnProperty.call(message, "mapType")) + $root.onnx.TypeProto.Map.encode(message.mapType, writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork()).ldelim(); + if (message.denotation != null && Object.hasOwnProperty.call(message, "denotation")) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).string(message.denotation); + if (message.sparseTensorType != null && Object.hasOwnProperty.call(message, "sparseTensorType")) + $root.onnx.TypeProto.SparseTensor.encode( + message.sparseTensorType, + writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).fork() + ).ldelim(); + if (message.optionalType != null && Object.hasOwnProperty.call(message, "optionalType")) + $root.onnx.TypeProto.Optional.encode( + message.optionalType, + writer.uint32( + /* id 9, wireType 2 =*/ + 74 + ).fork() + ).ldelim(); + return writer; + }; + TypeProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TypeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.tensorType = $root.onnx.TypeProto.Tensor.decode(reader, reader.uint32()); + break; + } + case 4: { + message.sequenceType = $root.onnx.TypeProto.Sequence.decode(reader, reader.uint32()); + break; + } + case 5: { + message.mapType = $root.onnx.TypeProto.Map.decode(reader, reader.uint32()); + break; + } + case 9: { + message.optionalType = $root.onnx.TypeProto.Optional.decode(reader, reader.uint32()); + break; + } + case 8: { + message.sparseTensorType = $root.onnx.TypeProto.SparseTensor.decode(reader, reader.uint32()); + break; + } + case 6: { + message.denotation = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TypeProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TypeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + var properties = {}; + if (message.tensorType != null && message.hasOwnProperty("tensorType")) { + properties.value = 1; + { + var error = $root.onnx.TypeProto.Tensor.verify(message.tensorType); + if (error) return "tensorType." + error; + } + } + if (message.sequenceType != null && message.hasOwnProperty("sequenceType")) { + if (properties.value === 1) return "value: multiple values"; + properties.value = 1; + { + var error = $root.onnx.TypeProto.Sequence.verify(message.sequenceType); + if (error) return "sequenceType." + error; + } + } + if (message.mapType != null && message.hasOwnProperty("mapType")) { + if (properties.value === 1) return "value: multiple values"; + properties.value = 1; + { + var error = $root.onnx.TypeProto.Map.verify(message.mapType); + if (error) return "mapType." + error; + } + } + if (message.optionalType != null && message.hasOwnProperty("optionalType")) { + if (properties.value === 1) return "value: multiple values"; + properties.value = 1; + { + var error = $root.onnx.TypeProto.Optional.verify(message.optionalType); + if (error) return "optionalType." + error; + } + } + if (message.sparseTensorType != null && message.hasOwnProperty("sparseTensorType")) { + if (properties.value === 1) return "value: multiple values"; + properties.value = 1; + { + var error = $root.onnx.TypeProto.SparseTensor.verify(message.sparseTensorType); + if (error) return "sparseTensorType." + error; + } + } + if (message.denotation != null && message.hasOwnProperty("denotation")) { + if (!$util.isString(message.denotation)) return "denotation: string expected"; + } + return null; + }; + TypeProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto) return object; + var message = new $root.onnx.TypeProto(); + if (object.tensorType != null) { + if (typeof object.tensorType !== "object") throw TypeError(".onnx.TypeProto.tensorType: object expected"); + message.tensorType = $root.onnx.TypeProto.Tensor.fromObject(object.tensorType); + } + if (object.sequenceType != null) { + if (typeof object.sequenceType !== "object") throw TypeError(".onnx.TypeProto.sequenceType: object expected"); + message.sequenceType = $root.onnx.TypeProto.Sequence.fromObject(object.sequenceType); + } + if (object.mapType != null) { + if (typeof object.mapType !== "object") throw TypeError(".onnx.TypeProto.mapType: object expected"); + message.mapType = $root.onnx.TypeProto.Map.fromObject(object.mapType); + } + if (object.optionalType != null) { + if (typeof object.optionalType !== "object") throw TypeError(".onnx.TypeProto.optionalType: object expected"); + message.optionalType = $root.onnx.TypeProto.Optional.fromObject(object.optionalType); + } + if (object.sparseTensorType != null) { + if (typeof object.sparseTensorType !== "object") + throw TypeError(".onnx.TypeProto.sparseTensorType: object expected"); + message.sparseTensorType = $root.onnx.TypeProto.SparseTensor.fromObject(object.sparseTensorType); + } + if (object.denotation != null) message.denotation = String(object.denotation); + return message; + }; + TypeProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) object.denotation = ""; + if (message.tensorType != null && message.hasOwnProperty("tensorType")) { + object.tensorType = $root.onnx.TypeProto.Tensor.toObject(message.tensorType, options); + if (options.oneofs) object.value = "tensorType"; + } + if (message.sequenceType != null && message.hasOwnProperty("sequenceType")) { + object.sequenceType = $root.onnx.TypeProto.Sequence.toObject(message.sequenceType, options); + if (options.oneofs) object.value = "sequenceType"; + } + if (message.mapType != null && message.hasOwnProperty("mapType")) { + object.mapType = $root.onnx.TypeProto.Map.toObject(message.mapType, options); + if (options.oneofs) object.value = "mapType"; + } + if (message.denotation != null && message.hasOwnProperty("denotation")) object.denotation = message.denotation; + if (message.sparseTensorType != null && message.hasOwnProperty("sparseTensorType")) { + object.sparseTensorType = $root.onnx.TypeProto.SparseTensor.toObject(message.sparseTensorType, options); + if (options.oneofs) object.value = "sparseTensorType"; + } + if (message.optionalType != null && message.hasOwnProperty("optionalType")) { + object.optionalType = $root.onnx.TypeProto.Optional.toObject(message.optionalType, options); + if (options.oneofs) object.value = "optionalType"; + } + return object; + }; + TypeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TypeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto"; + }; + TypeProto.Tensor = function() { + function Tensor6(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]]; + } + } + Tensor6.prototype.elemType = 0; + Tensor6.prototype.shape = null; + Tensor6.create = function create(properties) { + return new Tensor6(properties); + }; + Tensor6.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; + }; + Tensor6.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Tensor6.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; + }; + Tensor6.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Tensor6.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; + }; + Tensor6.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; + }; + Tensor6.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; + }; + Tensor6.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Tensor6.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.Tensor"; + }; + return Tensor6; + }(); + TypeProto.Sequence = function() { + function Sequence(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + Sequence.prototype.elemType = null; + Sequence.create = function create(properties) { + return new Sequence(properties); + }; + Sequence.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) + $root.onnx.TypeProto.encode(message.elemType, writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + return writer; + }; + Sequence.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Sequence.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Sequence(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.elemType = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Sequence.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Sequence.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.elemType != null && message.hasOwnProperty("elemType")) { + var error = $root.onnx.TypeProto.verify(message.elemType); + if (error) return "elemType." + error; + } + return null; + }; + Sequence.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto.Sequence) return object; + var message = new $root.onnx.TypeProto.Sequence(); + if (object.elemType != null) { + if (typeof object.elemType !== "object") + throw TypeError(".onnx.TypeProto.Sequence.elemType: object expected"); + message.elemType = $root.onnx.TypeProto.fromObject(object.elemType); + } + return message; + }; + Sequence.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) object.elemType = null; + if (message.elemType != null && message.hasOwnProperty("elemType")) + object.elemType = $root.onnx.TypeProto.toObject(message.elemType, options); + return object; + }; + Sequence.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Sequence.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.Sequence"; + }; + return Sequence; + }(); + TypeProto.Map = function() { + function Map2(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + Map2.prototype.keyType = 0; + Map2.prototype.valueType = null; + Map2.create = function create(properties) { + return new Map2(properties); + }; + Map2.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.keyType != null && Object.hasOwnProperty.call(message, "keyType")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int32(message.keyType); + if (message.valueType != null && Object.hasOwnProperty.call(message, "valueType")) + $root.onnx.TypeProto.encode(message.valueType, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + return writer; + }; + Map2.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Map2.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Map(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.keyType = reader.int32(); + break; + } + case 2: { + message.valueType = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Map2.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Map2.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.keyType != null && message.hasOwnProperty("keyType")) { + if (!$util.isInteger(message.keyType)) return "keyType: integer expected"; + } + if (message.valueType != null && message.hasOwnProperty("valueType")) { + var error = $root.onnx.TypeProto.verify(message.valueType); + if (error) return "valueType." + error; + } + return null; + }; + Map2.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto.Map) return object; + var message = new $root.onnx.TypeProto.Map(); + if (object.keyType != null) message.keyType = object.keyType | 0; + if (object.valueType != null) { + if (typeof object.valueType !== "object") throw TypeError(".onnx.TypeProto.Map.valueType: object expected"); + message.valueType = $root.onnx.TypeProto.fromObject(object.valueType); + } + return message; + }; + Map2.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.keyType = 0; + object.valueType = null; + } + if (message.keyType != null && message.hasOwnProperty("keyType")) object.keyType = message.keyType; + if (message.valueType != null && message.hasOwnProperty("valueType")) + object.valueType = $root.onnx.TypeProto.toObject(message.valueType, options); + return object; + }; + Map2.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Map2.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.Map"; + }; + return Map2; + }(); + TypeProto.Optional = function() { + function Optional(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + Optional.prototype.elemType = null; + Optional.create = function create(properties) { + return new Optional(properties); + }; + Optional.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) + $root.onnx.TypeProto.encode(message.elemType, writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + return writer; + }; + Optional.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Optional.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Optional(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.elemType = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Optional.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Optional.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.elemType != null && message.hasOwnProperty("elemType")) { + var error = $root.onnx.TypeProto.verify(message.elemType); + if (error) return "elemType." + error; + } + return null; + }; + Optional.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto.Optional) return object; + var message = new $root.onnx.TypeProto.Optional(); + if (object.elemType != null) { + if (typeof object.elemType !== "object") + throw TypeError(".onnx.TypeProto.Optional.elemType: object expected"); + message.elemType = $root.onnx.TypeProto.fromObject(object.elemType); + } + return message; + }; + Optional.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) object.elemType = null; + if (message.elemType != null && message.hasOwnProperty("elemType")) + object.elemType = $root.onnx.TypeProto.toObject(message.elemType, options); + return object; + }; + Optional.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Optional.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.Optional"; + }; + return Optional; + }(); + TypeProto.SparseTensor = function() { + function SparseTensor2(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + SparseTensor2.prototype.elemType = 0; + SparseTensor2.prototype.shape = null; + SparseTensor2.create = function create(properties) { + return new SparseTensor2(properties); + }; + SparseTensor2.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int32(message.elemType); + if (message.shape != null && Object.hasOwnProperty.call(message, "shape")) + $root.onnx.TensorShapeProto.encode(message.shape, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + return writer; + }; + SparseTensor2.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + SparseTensor2.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.SparseTensor(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.elemType = reader.int32(); + break; + } + case 2: { + message.shape = $root.onnx.TensorShapeProto.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + SparseTensor2.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + SparseTensor2.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.elemType != null && message.hasOwnProperty("elemType")) { + if (!$util.isInteger(message.elemType)) return "elemType: integer expected"; + } + if (message.shape != null && message.hasOwnProperty("shape")) { + var error = $root.onnx.TensorShapeProto.verify(message.shape); + if (error) return "shape." + error; + } + return null; + }; + SparseTensor2.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto.SparseTensor) return object; + var message = new $root.onnx.TypeProto.SparseTensor(); + if (object.elemType != null) message.elemType = object.elemType | 0; + if (object.shape != null) { + if (typeof object.shape !== "object") throw TypeError(".onnx.TypeProto.SparseTensor.shape: object expected"); + message.shape = $root.onnx.TensorShapeProto.fromObject(object.shape); + } + return message; + }; + SparseTensor2.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.elemType = 0; + object.shape = null; + } + if (message.elemType != null && message.hasOwnProperty("elemType")) object.elemType = message.elemType; + if (message.shape != null && message.hasOwnProperty("shape")) + object.shape = $root.onnx.TensorShapeProto.toObject(message.shape, options); + return object; + }; + SparseTensor2.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + SparseTensor2.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.SparseTensor"; + }; + return SparseTensor2; + }(); + return TypeProto; + }(); + onnx6.OperatorSetIdProto = function() { + function OperatorSetIdProto(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + OperatorSetIdProto.prototype.domain = ""; + OperatorSetIdProto.prototype.version = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + OperatorSetIdProto.create = function create(properties) { + return new OperatorSetIdProto(properties); + }; + OperatorSetIdProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.domain); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + writer.uint32( + /* id 2, wireType 0 =*/ + 16 + ).int64(message.version); + return writer; + }; + OperatorSetIdProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + OperatorSetIdProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.OperatorSetIdProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.domain = reader.string(); + break; + } + case 2: { + message.version = reader.int64(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + OperatorSetIdProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + OperatorSetIdProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.domain != null && message.hasOwnProperty("domain")) { + if (!$util.isString(message.domain)) return "domain: string expected"; + } + if (message.version != null && message.hasOwnProperty("version")) { + if (!$util.isInteger(message.version) && !(message.version && $util.isInteger(message.version.low) && $util.isInteger(message.version.high))) + return "version: integer|Long expected"; + } + return null; + }; + OperatorSetIdProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.OperatorSetIdProto) return object; + var message = new $root.onnx.OperatorSetIdProto(); + if (object.domain != null) message.domain = String(object.domain); + if (object.version != null) { + if ($util.Long) (message.version = $util.Long.fromValue(object.version)).unsigned = false; + else if (typeof object.version === "string") message.version = parseInt(object.version, 10); + else if (typeof object.version === "number") message.version = object.version; + else if (typeof object.version === "object") + message.version = new $util.LongBits(object.version.low >>> 0, object.version.high >>> 0).toNumber(); + } + return message; + }; + OperatorSetIdProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.domain = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.version = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else object.version = options.longs === String ? "0" : 0; + } + if (message.domain != null && message.hasOwnProperty("domain")) object.domain = message.domain; + if (message.version != null && message.hasOwnProperty("version")) + if (typeof message.version === "number") + object.version = options.longs === String ? String(message.version) : message.version; + else + object.version = options.longs === String ? $util.Long.prototype.toString.call(message.version) : options.longs === Number ? new $util.LongBits(message.version.low >>> 0, message.version.high >>> 0).toNumber() : message.version; + return object; + }; + OperatorSetIdProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + OperatorSetIdProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.OperatorSetIdProto"; + }; + return OperatorSetIdProto; + }(); + onnx6.OperatorStatus = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "EXPERIMENTAL"] = 0; + values[valuesById[1] = "STABLE"] = 1; + return values; + }(); + onnx6.FunctionProto = function() { + function FunctionProto(properties) { + this.input = []; + this.output = []; + this.attribute = []; + this.attributeProto = []; + this.node = []; + this.opsetImport = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + } + FunctionProto.prototype.name = ""; + FunctionProto.prototype.input = $util.emptyArray; + FunctionProto.prototype.output = $util.emptyArray; + FunctionProto.prototype.attribute = $util.emptyArray; + FunctionProto.prototype.attributeProto = $util.emptyArray; + FunctionProto.prototype.node = $util.emptyArray; + FunctionProto.prototype.docString = ""; + FunctionProto.prototype.opsetImport = $util.emptyArray; + FunctionProto.prototype.domain = ""; + FunctionProto.create = function create(properties) { + return new FunctionProto(properties); + }; + FunctionProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.name); + if (message.input != null && message.input.length) + for (var i = 0; i < message.input.length; ++i) + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).string(message.input[i]); + if (message.output != null && message.output.length) + for (var i = 0; i < message.output.length; ++i) + writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).string(message.output[i]); + if (message.attribute != null && message.attribute.length) + for (var i = 0; i < message.attribute.length; ++i) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).string(message.attribute[i]); + if (message.node != null && message.node.length) + for (var i = 0; i < message.node.length; ++i) + $root.onnx.NodeProto.encode(message.node[i], writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).fork()).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).string(message.docString); + if (message.opsetImport != null && message.opsetImport.length) + for (var i = 0; i < message.opsetImport.length; ++i) + $root.onnx.OperatorSetIdProto.encode( + message.opsetImport[i], + writer.uint32( + /* id 9, wireType 2 =*/ + 74 + ).fork() + ).ldelim(); + if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) + writer.uint32( + /* id 10, wireType 2 =*/ + 82 + ).string(message.domain); + if (message.attributeProto != null && message.attributeProto.length) + for (var i = 0; i < message.attributeProto.length; ++i) + $root.onnx.AttributeProto.encode( + message.attributeProto[i], + writer.uint32( + /* id 11, wireType 2 =*/ + 90 + ).fork() + ).ldelim(); + return writer; + }; + FunctionProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + FunctionProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.FunctionProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.name = reader.string(); + break; + } + case 4: { + if (!(message.input && message.input.length)) message.input = []; + message.input.push(reader.string()); + break; + } + case 5: { + if (!(message.output && message.output.length)) message.output = []; + message.output.push(reader.string()); + break; + } + case 6: { + if (!(message.attribute && message.attribute.length)) message.attribute = []; + message.attribute.push(reader.string()); + break; + } + case 11: { + if (!(message.attributeProto && message.attributeProto.length)) message.attributeProto = []; + message.attributeProto.push($root.onnx.AttributeProto.decode(reader, reader.uint32())); + break; + } + case 7: { + if (!(message.node && message.node.length)) message.node = []; + message.node.push($root.onnx.NodeProto.decode(reader, reader.uint32())); + break; + } + case 8: { + message.docString = reader.string(); + break; + } + case 9: { + if (!(message.opsetImport && message.opsetImport.length)) message.opsetImport = []; + message.opsetImport.push($root.onnx.OperatorSetIdProto.decode(reader, reader.uint32())); + break; + } + case 10: { + message.domain = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + FunctionProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + FunctionProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) return "name: string expected"; + } + if (message.input != null && message.hasOwnProperty("input")) { + if (!Array.isArray(message.input)) return "input: array expected"; + for (var i = 0; i < message.input.length; ++i) + if (!$util.isString(message.input[i])) return "input: string[] expected"; + } + if (message.output != null && message.hasOwnProperty("output")) { + if (!Array.isArray(message.output)) return "output: array expected"; + for (var i = 0; i < message.output.length; ++i) + if (!$util.isString(message.output[i])) return "output: string[] expected"; + } + if (message.attribute != null && message.hasOwnProperty("attribute")) { + if (!Array.isArray(message.attribute)) return "attribute: array expected"; + for (var i = 0; i < message.attribute.length; ++i) + if (!$util.isString(message.attribute[i])) return "attribute: string[] expected"; + } + if (message.attributeProto != null && message.hasOwnProperty("attributeProto")) { + if (!Array.isArray(message.attributeProto)) return "attributeProto: array expected"; + for (var i = 0; i < message.attributeProto.length; ++i) { + var error = $root.onnx.AttributeProto.verify(message.attributeProto[i]); + if (error) return "attributeProto." + error; + } + } + if (message.node != null && message.hasOwnProperty("node")) { + if (!Array.isArray(message.node)) return "node: array expected"; + for (var i = 0; i < message.node.length; ++i) { + var error = $root.onnx.NodeProto.verify(message.node[i]); + if (error) return "node." + error; + } + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) return "docString: string expected"; + } + if (message.opsetImport != null && message.hasOwnProperty("opsetImport")) { + if (!Array.isArray(message.opsetImport)) return "opsetImport: array expected"; + for (var i = 0; i < message.opsetImport.length; ++i) { + var error = $root.onnx.OperatorSetIdProto.verify(message.opsetImport[i]); + if (error) return "opsetImport." + error; + } + } + if (message.domain != null && message.hasOwnProperty("domain")) { + if (!$util.isString(message.domain)) return "domain: string expected"; + } + return null; + }; + FunctionProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.FunctionProto) return object; + var message = new $root.onnx.FunctionProto(); + if (object.name != null) message.name = String(object.name); + if (object.input) { + if (!Array.isArray(object.input)) throw TypeError(".onnx.FunctionProto.input: array expected"); + message.input = []; + for (var i = 0; i < object.input.length; ++i) message.input[i] = String(object.input[i]); + } + if (object.output) { + if (!Array.isArray(object.output)) throw TypeError(".onnx.FunctionProto.output: array expected"); + message.output = []; + for (var i = 0; i < object.output.length; ++i) message.output[i] = String(object.output[i]); + } + if (object.attribute) { + if (!Array.isArray(object.attribute)) throw TypeError(".onnx.FunctionProto.attribute: array expected"); + message.attribute = []; + for (var i = 0; i < object.attribute.length; ++i) message.attribute[i] = String(object.attribute[i]); + } + if (object.attributeProto) { + if (!Array.isArray(object.attributeProto)) + throw TypeError(".onnx.FunctionProto.attributeProto: array expected"); + message.attributeProto = []; + for (var i = 0; i < object.attributeProto.length; ++i) { + if (typeof object.attributeProto[i] !== "object") + throw TypeError(".onnx.FunctionProto.attributeProto: object expected"); + message.attributeProto[i] = $root.onnx.AttributeProto.fromObject(object.attributeProto[i]); + } + } + if (object.node) { + if (!Array.isArray(object.node)) throw TypeError(".onnx.FunctionProto.node: array expected"); + message.node = []; + for (var i = 0; i < object.node.length; ++i) { + if (typeof object.node[i] !== "object") throw TypeError(".onnx.FunctionProto.node: object expected"); + message.node[i] = $root.onnx.NodeProto.fromObject(object.node[i]); + } + } + if (object.docString != null) message.docString = String(object.docString); + if (object.opsetImport) { + if (!Array.isArray(object.opsetImport)) throw TypeError(".onnx.FunctionProto.opsetImport: array expected"); + message.opsetImport = []; + for (var i = 0; i < object.opsetImport.length; ++i) { + if (typeof object.opsetImport[i] !== "object") + throw TypeError(".onnx.FunctionProto.opsetImport: object expected"); + message.opsetImport[i] = $root.onnx.OperatorSetIdProto.fromObject(object.opsetImport[i]); + } + } + if (object.domain != null) message.domain = String(object.domain); + return message; + }; + FunctionProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.input = []; + object.output = []; + object.attribute = []; + object.node = []; + object.opsetImport = []; + object.attributeProto = []; + } + if (options.defaults) { + object.name = ""; + object.docString = ""; + object.domain = ""; + } + if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; + if (message.input && message.input.length) { + object.input = []; + for (var j = 0; j < message.input.length; ++j) object.input[j] = message.input[j]; + } + if (message.output && message.output.length) { + object.output = []; + for (var j = 0; j < message.output.length; ++j) object.output[j] = message.output[j]; + } + if (message.attribute && message.attribute.length) { + object.attribute = []; + for (var j = 0; j < message.attribute.length; ++j) object.attribute[j] = message.attribute[j]; + } + if (message.node && message.node.length) { + object.node = []; + for (var j = 0; j < message.node.length; ++j) + object.node[j] = $root.onnx.NodeProto.toObject(message.node[j], options); + } + if (message.docString != null && message.hasOwnProperty("docString")) object.docString = message.docString; + if (message.opsetImport && message.opsetImport.length) { + object.opsetImport = []; + for (var j = 0; j < message.opsetImport.length; ++j) + object.opsetImport[j] = $root.onnx.OperatorSetIdProto.toObject(message.opsetImport[j], options); + } + if (message.domain != null && message.hasOwnProperty("domain")) object.domain = message.domain; + if (message.attributeProto && message.attributeProto.length) { + object.attributeProto = []; + for (var j = 0; j < message.attributeProto.length; ++j) + object.attributeProto[j] = $root.onnx.AttributeProto.toObject(message.attributeProto[j], options); + } + return object; + }; + FunctionProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + FunctionProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.FunctionProto"; + }; + return FunctionProto; + }(); + return onnx6; + }(); + module2.exports = $root; + } + }); + + // web/lib/onnxjs/util.ts + function assert(expr, msg) { + if (!expr) { + throw new Error(typeof msg === "string" ? msg : msg()); + } + } + function decodeUtf8String(buffer) { + return new TextDecoder().decode(buffer); + } + var import_onnx, ArrayUtil, MatMulUtil, BroadcastUtil, GemmUtil, ProtoUtil, LongUtil, ShapeUtil, SplitUtil, PoolConvUtil, MIN_CLIP, MAX_CLIP; + var init_util = __esm({ + "web/lib/onnxjs/util.ts"() { + "use strict"; + init_long(); + import_onnx = __toESM(require_onnx()); + init_tensor2(); + ArrayUtil = class { + /** + * Verifies if 2 input arrays contain the same elements. + * @param n1 Array 1 + * @param n2 Array 2 + * @returns Whether these 2 are equal + */ + static arraysEqual(n1, n2) { + if (n1.length !== n2.length) { + return false; + } + for (let i = 0; i < n1.length; i++) { + if (n1[i] !== n2[i]) { + return false; + } + } + return true; + } + }; + MatMulUtil = class { + /** + * Fix the input shapes for MatMul operation if they need fixing + * @param dimsA The shape of tensor A. Should be an array of positive integers + * @param dimsB The shape of tensor B. Should be an array of positive integers + * @returns A tuple containing the preprocessed input shapes as required by ONNX specifications + */ + static preprocessInputShapes(dimsA, dimsB) { + const a = dimsA.length === 1 ? [1, dimsA[0]] : dimsA; + const b = dimsB.length === 1 ? [dimsB[0], 1] : dimsB; + return [a, b]; + } + /** + * Fix the output shape computed for MatMul operation if it needs fixing + * @param outputShape The computed outputShape. Should be an array (atleast of length 2) of positive integers. + * This will be mutated. + * @param aRank The rank of tensor A. + * @param bRank The rank of tensor B. + */ + static postprocessOutputShape(outputShape, aRank, bRank) { + if (aRank === 1) { + outputShape.splice(outputShape.length - 2, 1); + } + if (bRank === 1) { + outputShape.pop(); + } + } + /** + * Calculate the expected shape when matrix multiplication + * @param a The shape of tensor A. Should be a tuple of 2 positive integers + * @param b The shape of tensor B. Should be a tuple of 2 positive integers + * @returns The expected shape of the result, or undefined if N/A + */ + static calcMatMulShape(a, b) { + return a[1] !== b[0] ? void 0 : [a[0], b[1]]; + } + }; + BroadcastUtil = class _BroadcastUtil { + /** + * Calculate the expected shape when broadcasting 2 tensors + * @param a The shape of tensor A. Should be an array of positive integers + * @param b The shape of tensor B. Should be an array of positive integers + * @param isMatMul Whether the operation is MatMul + * @returns The expected shape of the result, or undefined if N/A + */ + static calcShape(adims, bdims, isMatMul = false) { + const arank = adims.length; + const brank = bdims.length; + if (arank === 0) { + return bdims; + } + if (brank === 0) { + return adims; + } + const crank = Math.max(adims.length, bdims.length); + const cdims = new Array(crank); + if (isMatMul) { + if (arank < 2 || brank < 2) { + return void 0; + } + const cShapeMatMul = MatMulUtil.calcMatMulShape( + [adims[arank - 2], adims[arank - 1]], + [bdims[brank - 2], bdims[brank - 1]] + ); + if (cShapeMatMul === void 0) { + return void 0; + } + [cdims[crank - 2], cdims[crank - 1]] = cShapeMatMul; + } + for (let i = isMatMul ? 3 : 1; i <= crank; i++) { + const aLen = arank - i < 0 ? 1 : adims[arank - i]; + const bLen = brank - i < 0 ? 1 : bdims[brank - i]; + if (aLen !== bLen && aLen > 1 && bLen > 1) { + return void 0; + } + cdims[crank - i] = Math.max(aLen, bLen); + } + return cdims; + } + /** + * Given the indices of a broadcasted tensor, calculate the original indices + * @param broadcastedIndices The given indices of the broadcasted tensor. + * @param originalShape The original shape of the tensor before broadcas + * @returns The calculated indices that maps to the original tensor. + */ + static index(broadcastedIndices, originalShape) { + const originalIndices = new Array(originalShape.length); + _BroadcastUtil.fillIndex(broadcastedIndices, originalShape, originalIndices); + return originalIndices; + } + /** + * Given the indices of a broadcasted tensor, calculate the original indices + * @param broadcastedIndices The given indices of the broadcasted tensor. + * @param originalShape The original shape of the tensor before broadcast + * @param originalIndices The mapping of broadcastedIndices to the originalIndices (output parameter - will be + * mutated). + */ + static fillIndex(broadcastedIndices, originalShape, originalIndices) { + const dimOffset = broadcastedIndices.length - originalShape.length; + for (let i = 0; i < originalShape.length; i++) { + originalIndices[i] = broadcastedIndices[dimOffset + i] % originalShape[i]; + } + } + /** + * Perform the broadcasting operation on the specific operator + * @param a The input tensor A + * @param b The input tensor B + * @param op The operator lambda function + * @param inplace Whether to write the result back to A. + * @returns The result tensor, or undefined if input not broadcastable. + */ + static calc(a, b, op, inplace, resultType) { + const outputShape = _BroadcastUtil.calcShape(a.dims, b.dims); + if (outputShape) { + if (inplace && !ShapeUtil.areEqual(outputShape, a.dims)) { + return void 0; + } + const size = ShapeUtil.size(outputShape); + const c = inplace ? a : new Tensor4(outputShape, resultType || a.type); + if (outputShape.length === 0) { + c.set([], op(a.get([]), b.get([]))); + } else { + const outputIndices = new Array(outputShape.length); + const originalIndicesA = new Array(a.dims.length); + const originalIndicesB = new Array(b.dims.length); + let valA = 0; + let valB = 0; + let isAScalar = false; + let isBScalar = false; + if (a.dims.length === 0) { + valA = a.get([]); + isAScalar = true; + } + if (b.dims.length === 0) { + valB = b.get([]); + isBScalar = true; + } + let rest; + for (let i = 0; i < size; i++) { + rest = i; + for (let j = outputShape.length - 1; j >= 0; j--) { + outputIndices[j] = rest % outputShape[j]; + rest = Math.floor(rest / outputShape[j]); + } + if (!isAScalar) { + _BroadcastUtil.fillIndex(outputIndices, a.dims, originalIndicesA); + valA = a.get(originalIndicesA); + } + if (!isBScalar) { + _BroadcastUtil.fillIndex(outputIndices, b.dims, originalIndicesB); + valB = b.get(originalIndicesB); + } + c.set(outputIndices, op(valA, valB)); + } + } + return c; + } + return void 0; + } + /** + * Determine if a shape is unidirectional broadcastable to another shape + * @param shape The input shape + * @param finalShape The desired shape after broadcasting + */ + static isValidBroadcast(shape2, finalShape) { + const inputRank = shape2.length; + const finalRank = finalShape.length; + if (inputRank > finalRank) { + return false; + } + for (let i = 1; i <= inputRank; i++) { + if (shape2[inputRank - i] !== 1 && shape2[inputRank - i] !== finalShape[finalRank - i]) { + return false; + } + } + return true; + } + /** + * Determine the broadcasted dims in input shape based on the given output shape. + * Note that this function only returns the broadcasted dims. + * @param inputShape The input shape + * @param outputShape The output shape + * @returns The broadcasted dims in input shape. + */ + static getBroadcastDims(inputShape, outputShape) { + const inRank = inputShape.length; + const dims = []; + for (let i = 0; i < inRank; i++) { + const dim = inRank - 1 - i; + const a = inputShape[dim] || 1; + const b = outputShape[outputShape.length - 1 - i] || 1; + if (b > 1 && a === 1) { + dims.unshift(dim); + } + } + return dims; + } + }; + GemmUtil = class { + // will make sure input shapes are compatible for this op + // and return back the shape of the output in the form of a tuple + // will throw exception if the input shapes are not compatible + static getShapeOfGemmResult(leftShape, transLeft, rightShape, transRight, biasShape) { + if (leftShape.length !== 2 || rightShape.length !== 2) { + throw new Error("shape need to be of size 2"); + } + let M; + let K; + let N; + if (transLeft) { + M = leftShape[1]; + K = leftShape[0]; + } else { + M = leftShape[0]; + K = leftShape[1]; + } + let kDim = -1; + if (transRight) { + N = rightShape[0]; + kDim = 1; + } else { + N = rightShape[1]; + kDim = 0; + } + if (rightShape[kDim] !== K) { + throw new Error("dimension mismatch"); + } + if (M <= 0 || N <= 0 || K <= 0) { + throw new Error("invalid shape specified"); + } + if (biasShape && !BroadcastUtil.isValidBroadcast(biasShape, [M, N])) { + throw new Error("gemm: invalid bias shape for broadcast"); + } + return [M, N, K]; + } + }; + ProtoUtil = class _ProtoUtil { + static tensorDataTypeFromProto(typeProto) { + switch (typeProto) { + case import_onnx.onnx.TensorProto.DataType.INT8: + return "int8"; + case import_onnx.onnx.TensorProto.DataType.UINT8: + return "uint8"; + case import_onnx.onnx.TensorProto.DataType.BOOL: + return "bool"; + case import_onnx.onnx.TensorProto.DataType.INT16: + return "int16"; + case import_onnx.onnx.TensorProto.DataType.UINT16: + return "uint16"; + case import_onnx.onnx.TensorProto.DataType.INT32: + return "int32"; + case import_onnx.onnx.TensorProto.DataType.UINT32: + return "uint32"; + case import_onnx.onnx.TensorProto.DataType.FLOAT: + return "float32"; + case import_onnx.onnx.TensorProto.DataType.DOUBLE: + return "float64"; + case import_onnx.onnx.TensorProto.DataType.STRING: + return "string"; + // For INT64/UINT64, reduce their value to 32-bits. + // Should throw exception when overflow + case import_onnx.onnx.TensorProto.DataType.INT64: + return "int32"; + case import_onnx.onnx.TensorProto.DataType.UINT64: + return "uint32"; + default: + throw new Error(`unsupported data type: ${import_onnx.onnx.TensorProto.DataType[typeProto]}`); + } + } + static tensorDataTypeStringToEnum(type) { + switch (type) { + case "int8": + return import_onnx.onnx.TensorProto.DataType.INT8; + case "uint8": + return import_onnx.onnx.TensorProto.DataType.UINT8; + case "bool": + return import_onnx.onnx.TensorProto.DataType.BOOL; + case "int16": + return import_onnx.onnx.TensorProto.DataType.INT16; + case "uint16": + return import_onnx.onnx.TensorProto.DataType.UINT16; + case "int32": + return import_onnx.onnx.TensorProto.DataType.INT32; + case "uint32": + return import_onnx.onnx.TensorProto.DataType.UINT32; + case "float32": + return import_onnx.onnx.TensorProto.DataType.FLOAT; + case "float64": + return import_onnx.onnx.TensorProto.DataType.DOUBLE; + case "string": + return import_onnx.onnx.TensorProto.DataType.STRING; + case "int64": + return import_onnx.onnx.TensorProto.DataType.INT64; + case "uint64": + return import_onnx.onnx.TensorProto.DataType.UINT64; + default: + throw new Error(`unsupported data type: ${type}`); + } + } + static tensorDimsFromProto(dims) { + return dims.map((d) => long_default.isLong(d) ? d.toNumber() : d); + } + static tensorValueTypeFromProto(valueType) { + return { + tensorType: _ProtoUtil.tensorDataTypeFromProto(valueType.elemType), + shape: { dims: _ProtoUtil.tensorDimsFromProto(valueType.shape.dim.map((d) => d.dimValue)) } + }; + } + static tensorDimsFromORTFormat(tensor) { + const dims = []; + for (let i = 0; i < tensor.dimsLength(); i++) { + dims.push(LongUtil.longToNumber(tensor.dims(i))); + } + return dims; + } + static tensorAttributesFromORTFormat(node) { + const attributes = []; + for (let i = 0; i < node.attributesLength(); i++) { + attributes.push(node.attributes(i)); + } + return attributes; + } + }; + LongUtil = class { + // This function is called to get a number from long type of data for attribute, dim, and ir version, + // which values are signed integers. + // To make it more generic, add an optional parameter to convert to a unsigned number. + static longToNumber(n) { + if (long_default.isLong(n)) { + return n.toNumber(); + } else if (typeof n === "bigint") { + return Number(n); + } + return n; + } + static isLong(n) { + return long_default.isLong(n) || typeof n === "bigint"; + } + }; + ShapeUtil = class _ShapeUtil { + static size(dims) { + return _ShapeUtil.getSizeFromDimensionRange(dims, 0, dims.length); + } + // `axis` inclusive + static sizeFromDimension(dims, axis) { + if (axis < 0 || axis > dims.length) { + throw new Error(`invalid dimension of ${axis} for sizeFromDimension as Tensor has ${dims.length} dimensions.`); + } + return _ShapeUtil.getSizeFromDimensionRange(dims, axis, dims.length); + } + // `axis` exclusive + static sizeToDimension(dims, axis) { + if (axis < 0 || axis > dims.length) { + throw new Error(`invalid dimension of ${axis} for sizeToDimension as Tensor has ${dims.length} dimensions.`); + } + return _ShapeUtil.getSizeFromDimensionRange(dims, 0, axis); + } + static getSizeFromDimensionRange(dims, start, end) { + let size = 1; + for (let i = start; i < end; i++) { + if (dims[i] <= 0) { + throw new Error( + // eslint-disable-next-line max-len + "cannot get valid size from specified dimension range. Most likely the range contains 0 or negative values in them." + ); + } + size *= dims[i]; + } + return size; + } + static computeStrides(dims) { + const rank = dims.length; + if (rank === 0) { + return []; + } else if (rank === 1) { + return [1]; + } + const strides = new Array(rank); + strides[rank - 1] = 1; + strides[rank - 2] = dims[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * dims[i + 1]; + } + return strides; + } + static transpose(dims) { + const copy = dims.slice(); + return copy.reverse(); + } + static indicesToOffset(indices, strides, axis) { + if (axis === void 0) { + axis = indices.length; + } + let offset = 0; + for (let i = 0; i < axis; ++i) { + offset += strides[i] * indices[i]; + } + return offset; + } + static offsetToIndices(offset, strides) { + const rank = strides.length; + if (rank === 0) { + return []; + } else if (rank === 1) { + return [offset * strides[0]]; + } + const indices = new Array(strides.length); + for (let i = 0; i < indices.length - 1; ++i) { + indices[i] = Math.floor(offset / strides[i]); + offset -= indices[i] * strides[i]; + } + indices[indices.length - 1] = offset; + return indices; + } + /** + * normailze axis of range [-r, r) into [0, r). + */ + static normalizeAxis(axis, tensorRank) { + if (axis < -tensorRank && axis >= tensorRank) { + throw new Error("unsupported axis for this operation."); + } + return axis < 0 ? axis + tensorRank : axis; + } + static normalizeAxes(axes, tensorRank) { + return axes.map((x) => this.normalizeAxis(x, tensorRank)); + } + // Increment an index into a tensor (in lexicographic + // ordering), wrapping around the specified upper_bound. + /** + * Increment an index into a tensor (in lexicographic ordering), wrapping around the specified upper_bound. + * @param index Given index to increment (Will be mutated) + * @param dims The dimensions of the tensor for which the given index corresponds to + * @param axisToIncrementOn The 1-indexed axis to increment on. If undefined, axisToIncrementOn == rank + */ + static incrementIndex(index, dims, axisToIncrementOn) { + if (dims.length === 0 || index.length === 0) { + throw new Error("Index incrementing unsupported for scalar Tensor"); + } + if (axisToIncrementOn === void 0) { + axisToIncrementOn = dims.length; + } else { + if (axisToIncrementOn <= 0 || axisToIncrementOn > dims.length) { + throw new Error("Incorrect axis to increment on"); + } + } + for (let k = axisToIncrementOn - 1; k >= 0; --k) { + index[k]++; + if (index[k] < dims[k]) { + break; + } + index[k] = 0; + } + } + /** + * Produces a new dimensions array based on the values in the 'originalDimensions' and 'shape' array + * Used in Reshape + * @param originalDims Original Shape array + * @param shapeHints array containing values to compute the new dimensions + * For example: + * originalDims = [2,2] and shapeHints = [0,-1] will return [2,2] + * originalDims = [2,2] and shapeHints = [4] will return [4] + * originalDims = [2,2] and shapeHints = [5] will throw an exception + * https://github.com/onnx/onnx/blob/main/docs/Operators.md#Reshape + */ + static calculateReshapedDims(originalDims, shapeHints) { + if (shapeHints.length === 0) { + if (originalDims.length === 0 || _ShapeUtil.size(originalDims) === 1) { + return []; + } else { + throw new Error("cannot reshape to a scalar Tensor"); + } + } + const nDims = shapeHints.length; + const reshapedDims = new Array(nDims); + let unknownDimension = -1; + let newTensorSize = 1; + for (let i = 0; i < nDims; i++) { + if (shapeHints[i] < -1) { + throw new Error("a dimension in shape hints cannot be less than -1"); + } + if (shapeHints[i] === -1) { + if (unknownDimension !== -1) { + throw new Error("at most one dimension in shape hints can be -1"); + } + unknownDimension = i; + } else { + if (shapeHints[i] === 0) { + if (i >= originalDims.length) { + throw new Error("the dimension with value zero exceeds the dimension size of the input tensor"); + } + reshapedDims[i] = originalDims[i]; + } else { + reshapedDims[i] = shapeHints[i]; + } + newTensorSize *= reshapedDims[i]; + } + } + const oldTensorSize = _ShapeUtil.size(originalDims); + if (unknownDimension !== -1) { + if (oldTensorSize % newTensorSize !== 0) { + throw new Error( + `the input tensor cannot be reshaped to the requested shape. Input shape: [${originalDims}] Output shape: [${shapeHints}]` + ); + } + reshapedDims[unknownDimension] = oldTensorSize / newTensorSize; + } else { + if (newTensorSize !== oldTensorSize) { + throw new Error("reshapedDims and originalDims don't have matching sizes"); + } + } + return reshapedDims; + } + /** + * Sorts a given array based on the indices in the Perm array + * Used in Transpose + * @param a Array to be sorted such as dims or strides + * @param perm Perm given; if null a will be reversed + */ + static sortBasedOnPerm(a, perm) { + if (perm) { + return perm.map((v) => a[v]); + } else { + return a.slice().reverse(); + } + } + /** + * Pads a given shape according to the padding values + * @param dims shape of the Tensor to be padded + * @param pad pad values + */ + static padShape(dims, pad2) { + const rank = dims.length; + return dims.map((v, i) => v + pad2[i] + pad2[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, split3, numOutputs) { + if (split3.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, split3); + } + const shapes = []; + const offsets = [0]; + for (let i = 0; i < split3.length; ++i) { + if (i !== 0) { + offsets.push(offsets[i - 1] + split3[i - 1]); + } + const shape2 = dims.slice(); + shape2[axis] = split3[i]; + shapes.push(shape2); + } + return [shapes, offsets]; + } + static determineSplit(numElementsAlongAxis, numOutputs, split3) { + if (numElementsAlongAxis % numOutputs !== 0) { + throw new Error("cannot split tensor to equal sized parts"); + } + for (let i = 0; i < numOutputs; ++i) { + split3.push(numElementsAlongAxis / numOutputs); + } + } + }; + PoolConvUtil = class _PoolConvUtil { + /** + * Adjust the kernel, strides, pads to correct rank. Set to default value if not present + * @param isGlobalOperator If true, perform global pooling. + * @param inputDims The input tensor dimension. + * @param kernelShape The size of the kernel along each axis. + * @param strides Stride along each axis. + * @param dilations Dilation along each axis. + * @param pads Padding for the beginning and ending along each axis. + */ + static adjustPoolAttributes(isGlobalOperator, inputDims, kernelShape, strides, dilations, pads) { + if (!isGlobalOperator && kernelShape.length !== inputDims.length - 2) { + throw new Error("length of specified kernel shapes should be 2 less than length of input dimensions"); + } + if (isGlobalOperator) { + for (let dim = 0; dim < inputDims.length - 2; dim++) { + if (dim >= kernelShape.length) { + kernelShape.push(inputDims[dim + 2]); + } else { + kernelShape[dim] = inputDims[dim + 2]; + } + } + } + for (let dim = 0; dim < kernelShape.length; dim++) { + if (dim < strides.length) { + if (strides[dim] < 0) { + throw new Error("strides should be greater than or equal to 1"); + } + } else { + strides.push(1); + } + } + for (let dim = 0; dim < kernelShape.length; dim++) { + if (dim < dilations.length) { + if (dilations[dim] < 0) { + throw new Error("dilations should be greater than or equal to 1"); + } + } else { + dilations.push(1); + } + } + for (let dim = 0; dim < kernelShape.length * 2; dim++) { + if (dim < pads.length) { + if (pads[dim] < 0) { + throw new Error("pad should be greater than or equal to 1"); + } + } else { + pads.push(0); + } + } + for (let dim = 0; dim < kernelShape.length; dim++) { + if (kernelShape[dim] <= 0) { + throw new Error("kernel shapes need to be greater than 0"); + } + if (pads[dim] >= kernelShape[dim] || pads[dim + kernelShape.length] >= kernelShape[dim]) { + throw new Error("pads should be smaller than kernel"); + } + } + } + // adjust pad values based on 'autoPad' attribute + static adjustPadsBasedOnAutoPad(inputDims, strides, dilations, kernelShape, pads, autoPad) { + if (!autoPad) { + return; + } + if (pads.length !== 2 * (inputDims.length - 2)) { + throw new Error("length of pads should be twice the length of data dimensions"); + } + if (strides.length !== inputDims.length - 2) { + throw new Error("length of strides should be the length of data dimensions"); + } + if (kernelShape.length !== inputDims.length - 2) { + throw new Error("length of kernel shapes should be the length of data dimensions"); + } + for (let dim = 0; dim < inputDims.length - 2; dim++) { + _PoolConvUtil.adjustPadAndReturnShape( + inputDims[dim + 2], + strides[dim], + dilations[dim], + kernelShape[dim], + pads, + dim, + dim + inputDims.length - 2, + autoPad + ); + } + } + /** + * Calculate the output shape for Pool ops based on input attributes. (Should be used only for Pool ops) + * @param isGlobalOperator If true, perform global pooling. + * @param inputDims The input tensor dimension. (inputs[0].dims) + * @param strides Stride along each axis. + * @param dilations Dilation along each axis. + * @param kernelShape The size of the kernel along each axis. + * @param pads Padding for the beginning and ending along each axis. + * @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each + * dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID. + */ + static computePoolOutputShape(isGlobalOperator, inputDims, strides, dilations, kernelShape, pads, autoPad) { + if (inputDims.length <= 0) { + throw new Error("input shape must be of size greater than 0"); + } + const outputDims = [inputDims[0], inputDims[1]]; + _PoolConvUtil.computeShapeHelper( + isGlobalOperator, + inputDims, + outputDims, + strides, + dilations, + kernelShape, + pads, + autoPad + ); + return outputDims; + } + /** + * Calculate the output shape for Conv op based on input attributes. (Should be used only for Conv op) + * @param inputDims The input tensor dimension. (inputs[0].dims) + * @param filterDims The filter tensor dimension. (inputs[1].dims) + * @param strides Stride along each axis. + * @param kernelShape The size of the kernel along each axis. + * @param pads Padding for the beginning and ending along each axis. + * @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each + * dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID. + */ + static computeConvOutputShape(inputDims, filterDims, strides, dilations, kernelShape, pads, autoPad) { + if (inputDims.length <= 0 || filterDims.length <= 0) { + throw new Error("invalid input tensor dims or invalid filter tensor dims"); + } + const outputDims = [inputDims[0], filterDims[0]]; + _PoolConvUtil.computeShapeHelper(false, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad); + return outputDims; + } + // will compute output shapes for data dimensions ONLY (i.e.) no batch size and channels + // called by computePoolOutputShape() and computeConvOutputShape() + // adjust pads based on 'autoPad' attribute prior to shape computation + static computeShapeHelper(isGlobalOperator, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad) { + if (isGlobalOperator) { + for (let dim = 0; dim < inputDims.length - 2; dim++) { + outputDims.push(1); + } + } else { + for (let dim = 0; dim < inputDims.length - 2; dim++) { + outputDims.push( + _PoolConvUtil.adjustPadAndReturnShape( + inputDims[dim + 2], + strides[dim], + dilations[dim], + kernelShape[dim], + pads, + dim, + dim + inputDims.length - 2, + autoPad + ) + ); + } + } + } + // helper for computeShapeHelper() and adjustPadsBasedOnAutoPad() + // adjusts pad value for given 'autoPad' string and computes output shape along a particular dimension + static adjustPadAndReturnShape(inSize, stride, dilation, kernel, pads, padHeadIndex, padTailIndex, autoPad) { + const dkernel = dilation * (kernel - 1) + 1; + if (autoPad && autoPad !== "NOTSET") { + switch (autoPad) { + case "VALID": + pads[padHeadIndex] = 0; + pads[padTailIndex] = 0; + return Math.floor((inSize - dkernel) / stride + 1); + case "SAME_LOWER": + case "SAME_UPPER": + if (dilation !== 1) { + throw new Error("Dilation not supported for SAME_UPPER or SAME_LOWER"); + } else { + const legacyTargetSize = (inSize + stride - 1) / stride; + const padNeeded = (legacyTargetSize - 1) * stride + kernel - inSize; + pads[padHeadIndex] = autoPad === "SAME_LOWER" ? Math.floor((padNeeded + 1) / 2) : Math.floor(padNeeded / 2); + pads[padTailIndex] = padNeeded - pads[padHeadIndex]; + return Math.floor((inSize + padNeeded - kernel) / stride + 1); + } + default: + throw new Error("Unsupported AutoPad type"); + } + } else { + return Math.floor((inSize + pads[padHeadIndex] + pads[padTailIndex] - dkernel) / stride + 1); + } + } + }; + MIN_CLIP = -34028234663852886e22; + MAX_CLIP = 34028234663852886e22; + } + }); + + // web/lib/onnxjs/tensor.ts + function sizeof(type) { + switch (type) { + case "bool": + case "int8": + case "uint8": + return 1; + case "int16": + case "uint16": + return 2; + case "int32": + case "uint32": + case "float32": + return 4; + case "float64": + return 8; + default: + throw new Error(`cannot calculate sizeof() on type ${type}`); + } + } + function sizeofProto(type) { + switch (type) { + case import_onnx2.onnx.TensorProto.DataType.UINT8: + case import_onnx2.onnx.TensorProto.DataType.INT8: + case import_onnx2.onnx.TensorProto.DataType.BOOL: + return 1; + case import_onnx2.onnx.TensorProto.DataType.UINT16: + case import_onnx2.onnx.TensorProto.DataType.INT16: + return 2; + case import_onnx2.onnx.TensorProto.DataType.FLOAT: + case import_onnx2.onnx.TensorProto.DataType.INT32: + case import_onnx2.onnx.TensorProto.DataType.UINT32: + return 4; + case import_onnx2.onnx.TensorProto.DataType.INT64: + case import_onnx2.onnx.TensorProto.DataType.DOUBLE: + case import_onnx2.onnx.TensorProto.DataType.UINT64: + return 8; + default: + throw new Error(`cannot calculate sizeof() on type ${import_onnx2.onnx.TensorProto.DataType[type]}`); + } + } + function createView(dataBuffer, type) { + return new (dataviewConstructor(type))(dataBuffer); + } + function dataviewConstructor(type) { + switch (type) { + case "bool": + case "uint8": + return Uint8Array; + case "int8": + return Int8Array; + case "int16": + return Int16Array; + case "uint16": + return Uint16Array; + case "int32": + return Int32Array; + case "uint32": + return Uint32Array; + case "int64": + return BigInt64Array; + case "float32": + return Float32Array; + case "float64": + return Float64Array; + default: + throw new Error("unspecified error"); + } + } + function longToNumber(i, type) { + if (type === import_onnx2.onnx.TensorProto.DataType.INT64 || type === import_tensor_data_type.TensorDataType.INT64) { + if (i.greaterThanOrEqual(2147483648) || i.lessThan(-2147483648)) { + throw new TypeError("int64 is not supported"); + } + } else if (type === import_onnx2.onnx.TensorProto.DataType.UINT32 || type === import_tensor_data_type.TensorDataType.UINT32 || type === import_onnx2.onnx.TensorProto.DataType.UINT64 || type === import_tensor_data_type.TensorDataType.UINT64) { + if (i.greaterThanOrEqual(4294967296) || i.lessThan(0)) { + throw new TypeError("uint64 is not supported"); + } + } else { + throw new TypeError(`not a LONG type: ${import_onnx2.onnx.TensorProto.DataType[type]}`); + } + return i.toNumber(); + } + function readProto(view, type, byteOffset) { + switch (type) { + case import_onnx2.onnx.TensorProto.DataType.BOOL: + case import_onnx2.onnx.TensorProto.DataType.UINT8: + return view.getUint8(byteOffset); + case import_onnx2.onnx.TensorProto.DataType.INT8: + return view.getInt8(byteOffset); + case import_onnx2.onnx.TensorProto.DataType.UINT16: + return view.getUint16(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.INT16: + return view.getInt16(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.FLOAT: + return view.getFloat32(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.INT32: + return view.getInt32(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.UINT32: + return view.getUint32(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.INT64: + return longToNumber( + long_default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), false), + type + ); + case import_onnx2.onnx.TensorProto.DataType.DOUBLE: + return view.getFloat64(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.UINT64: + return longToNumber( + long_default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), true), + type + ); + default: + throw new Error(`cannot read from DataView for type ${import_onnx2.onnx.TensorProto.DataType[type]}`); + } + } + var import_guid_typescript, import_onnx2, Tensor4; + var init_tensor2 = __esm({ + "web/lib/onnxjs/tensor.ts"() { + "use strict"; + import_guid_typescript = __toESM(require_guid()); + init_long(); + init_ort_generated(); + import_onnx2 = __toESM(require_onnx()); + init_util(); + Tensor4 = class _Tensor { + constructor(dims, type, dataProvider, asyncDataProvider, cache2, dataId = import_guid_typescript.Guid.create()) { + this.dims = dims; + this.type = type; + this.dataProvider = dataProvider; + this.asyncDataProvider = asyncDataProvider; + this.cache = cache2; + this.dataId = dataId; + this.size = ShapeUtil.validateDimsAndCalcSize(dims); + const size = this.size; + const empty = dataProvider === void 0 && asyncDataProvider === void 0 && cache2 === void 0; + if (cache2 !== void 0) { + if (cache2.length !== size) { + throw new RangeError("Input dims doesn't match data length."); + } + } + if (type === "string") { + if (cache2 !== void 0 && (!Array.isArray(cache2) || !cache2.every((i) => typeof i === "string"))) { + throw new TypeError("cache should be a string array"); + } + if (empty) { + this.cache = new Array(size); + } + } else { + if (cache2 !== void 0) { + const constructor = dataviewConstructor(type); + if (!(cache2 instanceof constructor)) { + throw new TypeError(`cache should be type ${constructor.name}`); + } + } + if (empty) { + const buf = new ArrayBuffer(size * sizeof(type)); + this.cache = createView(buf, type); + } + } + } + /** + * get the underlying tensor data + */ + get data() { + if (this.cache === void 0) { + const data = this.dataProvider(this.dataId); + if (data.length !== this.size) { + throw new Error("Length of data provided by the Data Provider is inconsistent with the dims of this Tensor."); + } + this.cache = data; + } + return this.cache; + } + /** + * get the underlying string tensor data. Should only use when type is STRING + */ + get stringData() { + if (this.type !== "string") { + throw new TypeError("data type is not string"); + } + return this.data; + } + /** + * get the underlying integer tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16, + * INT16, INT32, UINT32, BOOL) + */ + get integerData() { + switch (this.type) { + case "uint8": + case "int8": + case "uint16": + case "int16": + case "int32": + case "uint32": + case "bool": + return this.data; + default: + throw new TypeError("data type is not integer (uint8, int8, uint16, int16, int32, uint32, bool)"); + } + } + /** + * get the underlying float tensor data. Should only use when type is one of the following: (FLOAT, DOUBLE) + */ + get floatData() { + switch (this.type) { + case "float32": + case "float64": + return this.data; + default: + throw new TypeError("data type is not float (float32, float64)"); + } + } + /** + * get the underlying number tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16, + * INT16, INT32, UINT32, BOOL, FLOAT, DOUBLE) + */ + get numberData() { + if (this.type !== "string") { + return this.data; + } + throw new TypeError("type cannot be non-number (string)"); + } + /** + * get value of an element at the given indices + */ + get(indices) { + return this.data[ShapeUtil.indicesToOffset(indices, this.strides)]; + } + /** + * set value of an element at the given indices + */ + set(indices, value) { + this.data[ShapeUtil.indicesToOffset(indices, this.strides)] = value; + } + /** + * get the underlying tensor data asynchronously + */ + async getData() { + if (this.cache === void 0) { + this.cache = await this.asyncDataProvider(this.dataId); + } + return this.cache; + } + /** + * get the strides for each dimension + */ + get strides() { + if (!this._strides) { + this._strides = ShapeUtil.computeStrides(this.dims); + } + return this._strides; + } + /** + * Construct new Tensor from a ONNX Tensor object + * @param tensorProto the ONNX Tensor + */ + static fromProto(tensorProto) { + if (!tensorProto) { + throw new Error("cannot construct Value from an empty tensor"); + } + const type = ProtoUtil.tensorDataTypeFromProto(tensorProto.dataType); + const dims = ProtoUtil.tensorDimsFromProto(tensorProto.dims); + const value = new _Tensor(dims, type); + if (type === "string") { + tensorProto.stringData.forEach((str, i) => { + value.data[i] = decodeUtf8String(str); + }); + } else if (tensorProto.rawData && typeof tensorProto.rawData.byteLength === "number" && tensorProto.rawData.byteLength > 0) { + const dataDest = value.data; + const dataSource = new DataView( + tensorProto.rawData.buffer, + tensorProto.rawData.byteOffset, + tensorProto.rawData.byteLength + ); + const elementSize = sizeofProto(tensorProto.dataType); + const length = tensorProto.rawData.byteLength / elementSize; + if (tensorProto.rawData.byteLength % elementSize !== 0) { + throw new Error("invalid buffer length"); + } + if (dataDest.length !== length) { + throw new Error("buffer length mismatch"); + } + for (let i = 0; i < length; i++) { + const n = readProto(dataSource, tensorProto.dataType, i * elementSize); + dataDest[i] = n; + } + } else { + let array; + switch (tensorProto.dataType) { + case import_onnx2.onnx.TensorProto.DataType.FLOAT: + array = tensorProto.floatData; + break; + case import_onnx2.onnx.TensorProto.DataType.INT32: + case import_onnx2.onnx.TensorProto.DataType.INT16: + case import_onnx2.onnx.TensorProto.DataType.UINT16: + case import_onnx2.onnx.TensorProto.DataType.INT8: + case import_onnx2.onnx.TensorProto.DataType.UINT8: + case import_onnx2.onnx.TensorProto.DataType.BOOL: + array = tensorProto.int32Data; + break; + case import_onnx2.onnx.TensorProto.DataType.INT64: + array = tensorProto.int64Data; + break; + case import_onnx2.onnx.TensorProto.DataType.DOUBLE: + array = tensorProto.doubleData; + break; + case import_onnx2.onnx.TensorProto.DataType.UINT32: + case import_onnx2.onnx.TensorProto.DataType.UINT64: + array = tensorProto.uint64Data; + break; + default: + throw new Error("unspecific error"); + } + if (array === null || array === void 0) { + throw new Error("failed to populate data from a tensorproto value"); + } + const data = value.data; + if (data.length !== array.length) { + throw new Error("array length mismatch"); + } + for (let i = 0; i < array.length; i++) { + const element = array[i]; + if (long_default.isLong(element)) { + data[i] = longToNumber(element, tensorProto.dataType); + } else { + data[i] = element; + } + } + } + return value; + } + /** + * Construct new Tensor from raw data + * @param data the raw data object. Should be a string array for 'string' tensor, and the corresponding typed array + * for other types of tensor. + * @param dims the dimensions of the tensor + * @param type the type of the tensor + */ + static fromData(data, dims, type) { + return new _Tensor(dims, type, void 0, void 0, data); + } + static fromOrtTensor(ortTensor) { + if (!ortTensor) { + throw new Error("cannot construct Value from an empty tensor"); + } + const dims = ProtoUtil.tensorDimsFromORTFormat(ortTensor); + const type = ProtoUtil.tensorDataTypeFromProto(ortTensor.dataType()); + const value = new _Tensor(dims, type); + if (type === "string") { + for (let i = 0; i < ortTensor.stringDataLength(); i++) { + value.data[i] = ortTensor.stringData(i); + } + } else if (ortTensor.rawDataArray() && typeof ortTensor.rawDataLength() === "number" && ortTensor.rawDataLength() > 0) { + const dataDest = value.data; + const dataSource = new DataView( + ortTensor.rawDataArray().buffer, + ortTensor.rawDataArray().byteOffset, + ortTensor.rawDataLength() + ); + const elementSize = sizeofProto(ortTensor.dataType()); + const length = ortTensor.rawDataLength() / elementSize; + if (ortTensor.rawDataLength() % elementSize !== 0) { + throw new Error("invalid buffer length"); + } + if (dataDest.length !== length) { + throw new Error("buffer length mismatch"); + } + for (let i = 0; i < length; i++) { + const n = readProto(dataSource, ortTensor.dataType(), i * elementSize); + dataDest[i] = n; + } + } + return value; + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/glsl-source.ts + function getGlsl(version3) { + return version3 === 1 ? GLSL_ES_2_0 : GLSL_ES_3_0; + } + function getVertexShaderSource(version3) { + const glsl = getGlsl(version3); + return `${glsl.version} + precision highp float; + ${glsl.attribute} vec3 position; + ${glsl.attribute} vec2 textureCoord; + + ${glsl.varyingVertex} vec2 TexCoords; + + void main() + { + gl_Position = vec4(position, 1.0); + TexCoords = textureCoord; + }`; + } + function getFragShaderPreamble(version3) { + const glsl = getGlsl(version3); + return `${glsl.version} + precision highp float; + precision highp int; + precision highp sampler2D; + ${glsl.varyingFrag} vec2 TexCoords; + ${glsl.outputDeclaration} + const vec2 halfCR = vec2(0.5, 0.5); + + // Custom vector types to handle higher dimenalities. + struct ivec5 + { + int x; + int y; + int z; + int w; + int u; + }; + + struct ivec6 + { + int x; + int y; + int z; + int w; + int u; + int v; + }; + + int imod(int x, int y) { + return x - y * (x / y); + } + + `; + } + function getDefaultFragShaderMain(version3, outputShapeLength) { + const glsl = getGlsl(version3); + return ` + void main() { + int indices[${outputShapeLength}]; + toVec(TexCoords, indices); + vec4 result = vec4(process(indices)); + ${glsl.output} = result; + } + `; + } + var GLSL_ES_2_0, GLSL_ES_3_0; + var init_glsl_source = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-source.ts"() { + "use strict"; + GLSL_ES_2_0 = { + version: "", + attribute: "attribute", + varyingVertex: "varying", + varyingFrag: "varying", + texture2D: "texture2D", + output: "gl_FragColor", + outputDeclaration: "" + }; + GLSL_ES_3_0 = { + version: "#version 300 es", + attribute: "in", + varyingVertex: "out", + varyingFrag: "in", + texture2D: "texture", + output: "outputColor", + outputDeclaration: "out vec4 outputColor;" + }; + } + }); + + // web/lib/onnxjs/backends/webgl/types.ts + var init_types = __esm({ + "web/lib/onnxjs/backends/webgl/types.ts"() { + "use strict"; + } + }); + + // web/lib/onnxjs/backends/webgl/utils.ts + async function repeatedTry(checkFn, delayFn = (_counter) => 0, maxCounter) { + return new Promise((resolve, reject) => { + let tryCount = 0; + const tryFn = () => { + if (checkFn()) { + resolve(); + return; + } + tryCount++; + const nextBackoff = delayFn(tryCount); + if (maxCounter != null && tryCount >= maxCounter) { + reject(); + return; + } + setTimeout(tryFn, nextBackoff); + }; + tryFn(); + }); + } + function generateShaderFuncNameFromInputSamplerName(samplerName) { + assert(typeof samplerName !== "undefined" && samplerName.length !== 0, () => "empty string found for sampler name"); + return "get" + samplerName.charAt(0).toUpperCase() + samplerName.slice(1); + } + function generateShaderFuncNameFromInputSamplerNameAtOutCoords(samplerName) { + assert(typeof samplerName !== "undefined" && samplerName.length !== 0, () => "empty string found for sampler name"); + return "get" + samplerName.charAt(0).toUpperCase() + samplerName.slice(1) + "AtOutCoords"; + } + function squeezeInputShape(inputShape, squeezedShape) { + let newInputShape = JSON.parse(JSON.stringify(inputShape)); + newInputShape = squeezedShape; + return newInputShape; + } + function getSqueezedParams(params, keptDims) { + return keptDims.map((d) => params[d]).join(", "); + } + function getCoordsDataType(rank) { + if (rank <= 1) { + return "int"; + } else if (rank === 2) { + return "ivec2"; + } else if (rank === 3) { + return "ivec3"; + } else if (rank === 4) { + return "ivec4"; + } else if (rank === 5) { + return "ivec5"; + } else if (rank === 6) { + return "ivec6"; + } else { + throw Error(`GPU for rank ${rank} is not yet supported`); + } + } + function getGlChannels(rank = 6) { + return ["x", "y", "z", "w", "u", "v"].slice(0, rank); + } + var init_utils = __esm({ + "web/lib/onnxjs/backends/webgl/utils.ts"() { + "use strict"; + init_util(); + } + }); + + // web/lib/onnxjs/backends/webgl/ops/packing-utils.ts + function getVecChannels(name2, rank) { + return getGlChannels(rank).map((d) => `${name2}.${d}`); + } + function getChannels(name2, rank) { + if (rank === 1) { + return [name2]; + } + return getVecChannels(name2, rank); + } + function unpackFromChannel() { + return ` + float getChannel(vec4 frag, int dim) { + int modCoord = imod(dim, 2); + return modCoord == 0 ? frag.r : frag.g; + } + + float getChannel(vec4 frag, vec2 innerDims) { + vec2 modCoord = mod(innerDims, 2.); + return modCoord.x == 0. ? + (modCoord.y == 0. ? frag.r : frag.g) : + (modCoord.y == 0. ? frag.b : frag.a); + } + `; + } + var init_packing_utils = __esm({ + "web/lib/onnxjs/backends/webgl/ops/packing-utils.ts"() { + "use strict"; + init_utils(); + } + }); + + // web/lib/onnxjs/backends/webgl/ops/pack.ts + function getOutOfBoundsCondition(rank, shape2, dims) { + if (rank === 0) { + return "false"; + } + if (rank === 1) { + return `rc > ${shape2[0]}`; + } + let cond = ""; + for (let i = rank - 2; i < rank; i++) { + cond += `${dims[i]} >= ${shape2[i - rank + 2]}`; + if (i < rank - 1) { + cond += "||"; + } + } + return cond; + } + function getOutput(shape2, dims) { + const rank = shape2.length; + if (rank === 0) { + return "getA(), 0, 0, 0"; + } + if (rank === 1) { + return `getA(rc), + rc + 1 >= ${shape2[0]} ? 0. : getA(rc + 1), + 0, 0`; + } + const coord00 = "r, c"; + const coord01 = "r, cp1"; + const coord10 = "rp1, c"; + const coord11 = "rp1, cp1"; + let D = ""; + if (rank > 2) { + for (let i = 0; i < rank - 2; ++i) { + D = D + `${dims[i]},`; + } + } + return `getA(${D}${coord00}), + rEdge ? 0. : getA(${D}${coord10}), + cEdge ? 0. : getA(${D}${coord01}), + rEdge || cEdge ? 0. : getA(${D}${coord11})`; + } + function getSetup(rank, dims, rows, cols) { + if (rank === 0 || rank === 1) { + return ""; + } else { + const setup = ` + int r = ${dims[rank - 2]}; + int c = ${dims[rank - 1]}; + int rp1 = ${dims[rank - 2]} + 1; + int cp1 = ${dims[rank - 1]} + 1; + bool rEdge = rp1 >= ${cols}; + bool cEdge = cp1 >= ${rows}; + `; + return setup; + } + } + var packProgramMetadata, createPackProgramInfo, createPackProgramInfoLoader; + var init_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/pack.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + packProgramMetadata = { + name: "pack", + inputNames: ["A"], + inputTypes: [1 /* unpackedReversed */] + }; + createPackProgramInfo = (handler, input) => { + const glsl = getGlsl(handler.session.backend.glContext.version); + const inputShape = input.dims; + const inputRank = inputShape.length; + const outputRank = input.dims.length; + const coordsDataType = getCoordsDataType(outputRank); + const channels = getChannels("rc", outputRank); + const setup = getSetup(outputRank, channels, inputShape[inputShape.length - 2], inputShape[inputShape.length - 1]); + let reversedInputWH; + if (inputRank === 0) { + reversedInputWH = [1, 1]; + } else if (inputRank === 1) { + reversedInputWH = [inputShape[0], 1]; + } else { + reversedInputWH = [inputShape[outputRank - 1], inputShape[outputRank - 2]]; + } + const outOfBoundsCondition = getOutOfBoundsCondition(outputRank, reversedInputWH, channels); + const output = getOutput(inputShape, channels); + const shaderSource = ` + void main() { + ${coordsDataType} rc = getOutputCoords(); + + if(${outOfBoundsCondition}) { + ${glsl.output} = vec4(0); + } else { + ${setup} + + ${glsl.output} = vec4(${output}); + } + } + `; + return { + ...packProgramMetadata, + hasMain: true, + output: { dims: input.dims, type: input.type, textureType: 2 /* packed */ }, + shaderSource + }; + }; + createPackProgramInfoLoader = (handler, input) => ({ + ...packProgramMetadata, + get: () => createPackProgramInfo(handler, input) + }); + } + }); + + // web/lib/onnxjs/backends/webgl/ops/reshape-packed.ts + function processDims3D(shape2) { + if (shape2.length === 0) { + return [1, 1, 1]; + } + let batch = 1; + for (let i = 0; i < shape2.length - 2; ++i) { + batch *= shape2[i]; + } + return [batch, shape2.length > 1 ? shape2[shape2.length - 2] : 1, shape2[shape2.length - 1]]; + } + function isReshapeCheap(dims, reshapedDims) { + let isCheapReshape = false; + if (dims.length === 0 || reshapedDims.length === 0) { + isCheapReshape = true; + } else if (dims.length < 2 || reshapedDims.length < 2) { + isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1]; + } else { + isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1] && dims[dims.length - 2] === reshapedDims[reshapedDims.length - 2]; + } + return isCheapReshape; + } + function getReshapedInputCoords(shape2) { + const strides = ShapeUtil.computeStrides(shape2); + const coords = ["b", "r", "c"]; + const index = "index"; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coords[i]} = ${index} / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coords[i + 1]} = ${index} - ${coords[i]} * ${stride}` : `index -= ${coords[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + return ` + ivec3 inputCoordsFromReshapedOutCoords(int index) { + ${coordsFromIndexSnippet} + return ivec3(b, r, c); + } + `; + } + function getFlattenedIndexFrom3D(shape2) { + const strides = ShapeUtil.computeStrides(shape2); + return ` + int getFlattenedIndex(ivec3 coords) { + // reverse y, z order + return coords.x * ${strides[0]} + coords.z * ${strides[1]} + coords.y; + } +`; + } + var createPackedReshape3DProgramMetadata, createPackedReshape3DProgramInfo, createPackedReshape3DProgramInfoLoader; + var init_reshape_packed = __esm({ + "web/lib/onnxjs/backends/webgl/ops/reshape-packed.ts"() { + "use strict"; + init_util(); + init_glsl_source(); + init_types(); + init_packing_utils(); + createPackedReshape3DProgramMetadata = (outputShape3D) => ({ + name: "Reshape (packed)", + inputTypes: [2 /* packed */], + inputNames: ["A"], + cacheHint: `${outputShape3D}` + }); + createPackedReshape3DProgramInfo = (handler, input3D, metadata, outputShape3D) => { + const inputShape3D = input3D.dims; + const squeezedOutputShape = outputShape3D; + let mainLoop = ""; + for (let i = 0; i < 4; i++) { + let outputCoords = ""; + switch (i) { + case 0: + outputCoords = "outputCoords = rc;"; + break; + case 1: + outputCoords = "outputCoords = ivec3(rc.x, rc.y+1, rc.z);"; + break; + case 2: + outputCoords = "outputCoords = ivec3(rc.x, rc.y, rc.z+1);"; + break; + case 3: + outputCoords = "outputCoords = ivec3(rc.x, rc.y+1, rc.z+1);"; + break; + default: + throw new Error(); + } + mainLoop += ` + ${outputCoords} + ${i > 0 ? "if(outputCoords.y < rows && outputCoords.z < cols){" : ""} + int flattenedIndex = getFlattenedIndex(outputCoords); + + ivec3 inputRC = inputCoordsFromReshapedOutCoords(flattenedIndex); + vec2 innerDims = vec2(float(inputRC.y),float(inputRC.z)); + + result[${i}] = getChannel(getA(inputRC.x, inputRC.y, inputRC.z), innerDims); + + ${i > 0 ? "}" : ""} + `; + } + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${getReshapedInputCoords(inputShape3D)} + ${getFlattenedIndexFrom3D(squeezedOutputShape)} + ${unpackFromChannel()} + + void main() { + ivec3 rc = getOutputCoords(); + + vec4 result = vec4(0.0); + + ivec3 outputCoords; + int rows = ${squeezedOutputShape[2]}; + int cols = ${squeezedOutputShape[1]}; + + ${mainLoop} + ${glsl.output} = result; + } + `; + return { + ...metadata, + output: { dims: squeezedOutputShape, type: input3D.type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedReshape3DProgramInfoLoader = (handler, input3D, outputShape3D) => { + const metadata = createPackedReshape3DProgramMetadata(outputShape3D); + return { ...metadata, get: () => createPackedReshape3DProgramInfo(handler, input3D, metadata, outputShape3D) }; + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/uint8-encode.ts + var encodeAsUint8; + var init_uint8_encode = __esm({ + "web/lib/onnxjs/backends/webgl/ops/uint8-encode.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + encodeAsUint8 = (inferenceHandler, input) => { + const outputShape = input.shape; + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` + const float FLOAT_MAX = 1.70141184e38; + const float FLOAT_MIN = 1.17549435e-38; + + bool isNaN(float val) { + return (val < 1.0 || 0.0 < val || val == 0.0) ? false : true; + } + + highp vec4 encodeAsUint8(highp float v) { + if (isNaN(v)) { + return vec4(255, 255, 255, 255); + } + + highp float av = abs(v); + + if(av < FLOAT_MIN) { + return vec4(0.0, 0.0, 0.0, 0.0); + } else if(v > FLOAT_MAX) { + return vec4(0.0, 0.0, 128.0, 127.0) / 255.0; + } else if(v < -FLOAT_MAX) { + return vec4(0.0, 0.0, 128.0, 255.0) / 255.0; + } + + highp vec4 c = vec4(0,0,0,0); + + highp float e = floor(log2(av)); + highp float m = exp2(fract(log2(av))) - 1.0; + + c[2] = floor(128.0 * m); + m -= c[2] / 128.0; + c[1] = floor(32768.0 * m); + m -= c[1] / 32768.0; + c[0] = floor(8388608.0 * m); + + highp float ebias = e + 127.0; + c[3] = floor(ebias / 2.0); + ebias -= c[3] * 2.0; + c[2] += floor(ebias) * 128.0; + + c[3] += 128.0 * step(0.0, -v); + + return c / 255.0; + } + + void main() { + float value = ${glsl.texture2D}(X,TexCoords).r; + ${glsl.output} = encodeAsUint8(value); + }`; + const programInfo = { + name: "Uint8Encode", + inputTypes: [0 /* unpacked */], + inputNames: ["X"], + output: { dims: outputShape, type: input.tensor.type, textureType: 3 /* downloadUint8AsFloat */ }, + shaderSource, + hasMain: true + }; + return inferenceHandler.executeProgram(programInfo, [input.tensor]); + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/unpack.ts + function getSourceCoords(rank, dims) { + if (rank === 1) { + return "rc"; + } + let coords = ""; + for (let i = 0; i < rank; i++) { + coords += dims[i]; + if (i < rank - 1) { + coords += ","; + } + } + return coords; + } + var unpackProgramMetadata, createUnpackProgramInfo, createUnpackProgramInfoLoader; + var init_unpack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/unpack.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + unpackProgramMetadata = { + name: "unpack", + inputNames: ["A"], + inputTypes: [2 /* packed */] + }; + createUnpackProgramInfo = (handler, input) => { + const rank = input.dims.length; + const channels = getChannels("rc", rank); + const innerDims = channels.slice(-2); + const coordsDataType = getCoordsDataType(rank); + const unpackChannel = unpackFromChannel(); + const isScalar = input.dims.length === 0; + const sourceCoords = isScalar ? "" : getSourceCoords(rank, channels); + const coords = rank <= 1 ? "rc" : `vec2(${innerDims.join(",")})`; + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${unpackChannel} + void main() { + ${coordsDataType} rc = getOutputCoords(); + + // Sample the texture with the coords to get the rgba channel value. + vec4 packedInput = getA(${sourceCoords}); + + ${glsl.output} = vec4(getChannel(packedInput, ${coords}), 0, 0, 0); + } + `; + return { + ...unpackProgramMetadata, + hasMain: true, + output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createUnpackProgramInfoLoader = (handler, input) => ({ + ...unpackProgramMetadata, + get: () => createUnpackProgramInfo(handler, input) + }); + } + }); + + // web/lib/onnxjs/backends/webgl/texture-data-encoder.ts + var RedFloat32DataEncoder, RGBAFloatDataEncoder, Uint8DataEncoder; + var init_texture_data_encoder = __esm({ + "web/lib/onnxjs/backends/webgl/texture-data-encoder.ts"() { + "use strict"; + init_instrument(); + RedFloat32DataEncoder = class { + constructor(gl, channels = 1) { + if (channels === 1) { + this.internalFormat = gl.R32F; + this.format = gl.RED; + this.textureType = gl.FLOAT; + this.channelSize = channels; + } else if (channels === 4) { + this.internalFormat = gl.RGBA32F; + this.format = gl.RGBA; + this.textureType = gl.FLOAT; + this.channelSize = channels; + } else { + throw new Error(`Invalid number of channels: ${channels}`); + } + } + encode(src, textureSize) { + let result; + let source; + if (src.constructor !== Float32Array) { + Logger.warning("Encoder", "data was not of type Float32; creating new Float32Array"); + source = new Float32Array(src); + } + if (textureSize * this.channelSize > src.length) { + Logger.warning("Encoder", "Source data too small. Allocating larger array"); + source = src; + result = this.allocate(textureSize * this.channelSize); + source.forEach((v, i) => result[i] = v); + } else { + source = src; + result = source; + } + return result; + } + allocate(size) { + return new Float32Array(size * 4); + } + decode(buffer, dataSize) { + if (this.channelSize === 1) { + const filteredData = buffer.filter((_value, index) => index % 4 === 0).subarray(0, dataSize); + return filteredData; + } + return buffer.subarray(0, dataSize); + } + }; + RGBAFloatDataEncoder = class { + constructor(gl, channels = 1, textureType) { + if (channels !== 1 && channels !== 4) { + throw new Error(`Invalid number of channels: ${channels}`); + } + this.internalFormat = gl.RGBA; + this.format = gl.RGBA; + this.channelSize = channels; + this.textureType = textureType || gl.FLOAT; + } + encode(src, textureSize) { + let dest = src; + if (this.channelSize === 1) { + Logger.verbose("Encoder", "Exploding into a larger array"); + dest = this.allocate(textureSize); + src.forEach((v, i) => dest[i * 4] = v); + } + return dest; + } + allocate(size) { + return new Float32Array(size * 4); + } + decode(buffer, dataSize) { + if (this.channelSize === 1) { + const filteredData = buffer.filter((_value, index) => index % 4 === 0).subarray(0, dataSize); + return filteredData; + } + return buffer.subarray(0, dataSize); + } + }; + Uint8DataEncoder = class { + constructor(gl, channels = 1) { + this.channelSize = 4; + if (channels === 1) { + this.internalFormat = gl.ALPHA; + this.format = gl.ALPHA; + this.textureType = gl.UNSIGNED_BYTE; + this.channelSize = channels; + } else if (channels === 4) { + this.internalFormat = gl.RGBA; + this.format = gl.RGBA; + this.textureType = gl.UNSIGNED_BYTE; + this.channelSize = channels; + } else { + throw new Error(`Invalid number of channels: ${channels}`); + } + } + encode(src, _textureSize) { + return new Uint8Array(src.buffer, src.byteOffset, src.byteLength); + } + allocate(size) { + return new Uint8Array(size * this.channelSize); + } + decode(buffer, dataSize) { + if (buffer instanceof Uint8Array) { + return buffer.subarray(0, dataSize); + } + throw new Error(`Invalid array type: ${buffer.constructor}`); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/texture-layout.ts + var createTextureLayoutFromTextureType, calculateTextureWidthAndHeight, createTextureLayoutFromShape; + var init_texture_layout = __esm({ + "web/lib/onnxjs/backends/webgl/texture-layout.ts"() { + "use strict"; + init_util(); + init_types(); + createTextureLayoutFromTextureType = (textureLayoutStrategy, shape2, textureType) => { + const channel = textureType === 0 /* unpacked */ || textureType === 1 /* unpackedReversed */ ? 1 : 4; + const isPacked = textureType === 2 /* packed */; + const reverseWH = textureType === 1 /* unpackedReversed */ || textureType === 2 /* packed */; + const breakAxis = textureType === 4 /* packedLastDimension */ ? shape2.length - 1 : void 0; + const unpackedShape = textureType === 4 /* packedLastDimension */ ? shape2.map((d, i) => i === shape2.length - 1 ? d * 4 : d) : void 0; + return createTextureLayoutFromShape(textureLayoutStrategy, shape2, channel, unpackedShape, { + isPacked, + reverseWH, + breakAxis + }); + }; + calculateTextureWidthAndHeight = (textureLayoutStrategy, shape2, textureType) => { + const layout = createTextureLayoutFromTextureType(textureLayoutStrategy, shape2, textureType); + return [layout.width, layout.height]; + }; + createTextureLayoutFromShape = (textureLayoutStrategy, shape2, channels = 1, unpackedShape, prefs) => { + const isPacked = !!(prefs && prefs.isPacked); + const [width, height] = textureLayoutStrategy.computeTextureWH(isPacked ? unpackedShape || shape2 : shape2, prefs); + const rank = shape2.length; + let inferredDims = shape2.slice(0); + if (rank === 0) { + inferredDims = [1]; + } + if (channels === 1) { + unpackedShape = shape2; + } else if (isPacked) { + if (channels !== 4) { + throw new Error("a packed texture must be 4-channel"); + } + unpackedShape = shape2; + if (rank > 0) { + inferredDims[rank - 1] = Math.ceil(inferredDims[rank - 1] / 2); + } + if (rank > 1) { + inferredDims[rank - 2] = Math.ceil(inferredDims[rank - 2] / 2); + } + } else if (!unpackedShape) { + throw new Error("Unpacked shape is needed when using channels > 1"); + } + return { + width, + height, + channels, + isPacked, + shape: inferredDims, + strides: ShapeUtil.computeStrides(inferredDims), + unpackedShape, + reversedWH: prefs && prefs.reverseWH + }; + }; + } + }); + + // web/lib/onnxjs/backends/webgl/inference-handler.ts + var getProgramInfoUniqueKey, WebGLInferenceHandler; + var init_inference_handler = __esm({ + "web/lib/onnxjs/backends/webgl/inference-handler.ts"() { + "use strict"; + init_instrument(); + init_tensor2(); + init_util(); + init_pack(); + init_reshape_packed(); + init_uint8_encode(); + init_unpack(); + init_texture_data_encoder(); + init_texture_layout(); + init_types(); + getProgramInfoUniqueKey = (programInfo, inputTextureDatas) => { + const inputs = inputTextureDatas.map((texture) => `${texture.unpackedShape.join(",")};${texture.width}x${texture.height}`).join("_"); + let key = programInfo.name; + if (programInfo.cacheHint) { + key += "[" + programInfo.cacheHint + "]"; + } + key += ":" + inputs; + return key; + }; + WebGLInferenceHandler = class { + constructor(session) { + this.session = session; + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + } + /** + * @returns [width, height] + */ + calculateTextureWidthAndHeight(shape2, textureType) { + return calculateTextureWidthAndHeight(this.session.layoutStrategy, shape2, textureType); + } + executeProgram(program, inputs) { + if (inputs.length < program.inputNames.length) { + throw new Error(`Input size mustn't be less than ${program.inputNames.length}.`); + } + if (program.inputNames.length !== program.inputTypes.length) { + throw new Error("input names size does not match input types"); + } + const inputTextureDatas = []; + for (let i = 0; i < program.inputNames.length; ++i) { + inputTextureDatas[i] = this.getOrCreateTextureData(inputs[i], program.inputTypes[i]); + } + const key = getProgramInfoUniqueKey(program, inputTextureDatas); + let artifact = this.session.programManager.getArtifact(key); + const programInfo = artifact ? artifact.programInfo : typeof program.get === "function" ? program.get() : program; + const outputTextureLayout = createTextureLayoutFromTextureType( + this.session.layoutStrategy, + programInfo.output.dims, + programInfo.output.textureType + ); + const outputTextureData = this.createTextureData(outputTextureLayout, programInfo.output.type); + if (!artifact) { + artifact = this.session.programManager.build(programInfo, inputTextureDatas, outputTextureData); + this.session.programManager.setArtifact(key, artifact); + } + this.runProgram(artifact, inputTextureDatas, outputTextureData); + return outputTextureData; + } + run(program, inputs) { + const outputTextureData = this.executeProgram(program, inputs); + return outputTextureData.tensor; + } + runProgram(artifact, inputs, output) { + for (let i = 0; i < inputs.length; ++i) { + if (!!inputs[i].isPacked !== (artifact.programInfo.inputTypes[i] === 2 /* packed */)) { + throw new Error(`input[${i}] property packed inconsistent`); + } + } + if (!!output.isPacked !== (artifact.programInfo.output.textureType === 2 /* packed */)) { + throw new Error("output property packed inconsistent"); + } + this.session.programManager.run(artifact, inputs, output); + } + /** + * Create a TextureData object from a tensor. + * Usage = EncoderUsage.UploadOnly. + * If a related texture data is found in cache, returns it; + * Otherwise: + * Creates a new texture layout if not provided; + * Creates WebGLTexture with the layout; + * Upload tensor data to the texture; + * Creates a texture data object associated with the given tensor. + * @param tensor the tensor with data to upload + */ + getOrCreateTextureData(tensor, textureType) { + let td = this.getTextureData(tensor.dataId, textureType === 2 /* packed */); + if (!td) { + td = this.getTextureData(tensor.dataId, textureType !== 2 /* packed */); + if (td) { + if (textureType === 2 /* packed */) { + return this.pack(td); + } else { + return this.unpack(td); + } + } + } + if (!td) { + const layout = createTextureLayoutFromTextureType(this.session.layoutStrategy, tensor.dims, textureType); + if (textureType === 4 /* packedLastDimension */) { + const group = 1; + const channels = 4; + const shape2 = tensor.dims; + if (shape2.length === 4) { + const adjustedKernelShape = [shape2[0], Math.ceil(shape2[1] * shape2[2] * shape2[3] / channels)]; + const adjustedLayout = createTextureLayoutFromTextureType( + this.session.layoutStrategy, + adjustedKernelShape, + textureType + ); + let buffer = tensor.numberData; + if (shape2[1] * shape2[2] * shape2[3] % channels !== 0) { + const numFeatureMaps = shape2[0]; + const oldRowSize = shape2[1] * shape2[2] * shape2[3]; + const newRowSize = Math.ceil(oldRowSize * group / channels) * channels; + const newSize = numFeatureMaps * newRowSize; + buffer = new Float32Array(newSize); + for (let f = 0; f < numFeatureMaps; ++f) { + const oldOffset = f * oldRowSize; + const newOffset = f * newRowSize + f % group * oldRowSize; + buffer.set(tensor.numberData.subarray(oldOffset, oldOffset + oldRowSize), newOffset); + } + } + return this.createTextureData(adjustedLayout, tensor.type, buffer, tensor, 1 /* UploadOnly */); + } + } + if (textureType === 2 /* packed */) { + const unpackedTextureLayout = createTextureLayoutFromShape(this.session.layoutStrategy, tensor.dims, 1, [], { + reverseWH: true + }); + const unpackedTextureData = this.createTextureData( + unpackedTextureLayout, + tensor.type, + tensor.numberData, + tensor, + 1 /* UploadOnly */ + ); + td = this.pack(unpackedTextureData); + } else { + td = this.createTextureData(layout, tensor.type, tensor.numberData, tensor, 1 /* UploadOnly */); + } + } + return td; + } + /** + * Create a TextureData object using the given data and bind to the given tensor. + * Usage = EncoderUsage.UploadOnly. + * NOTE: this function is a hack for Conv implementation. should remove this function, after rewriting Conv + * implementation by Graph.Transformer + * @param dataType the tensor data type + * @param data the actual data to upload + * @param tensor the tensor to bind. tensor's data is ignored. + */ + createTextureDataFromLayoutBindTensor(layout, dataType, data, tensor) { + return this.createTextureData(layout, dataType, data, tensor, 1 /* UploadOnly */); + } + createTextureData(layout, dataType, data, tensor, usage) { + Logger.verbose("InferenceHandler", `Creating TextureData: layout:[${JSON.stringify(layout)}]`); + const texture = this.session.textureManager.createTextureFromLayout(dataType, layout, data, usage); + return this.createTextureDataFromTexture(layout, dataType, texture, tensor); + } + reshapeUnpacked(input, reshapedDims) { + const inputTD = this.getOrCreateTextureData(input, 0 /* unpacked */); + const newTextureLayout = { + channels: inputTD.channels, + height: inputTD.height, + width: inputTD.width, + // handle reshaping into scalar Tensors + shape: reshapedDims.length !== 0 ? reshapedDims : [1], + strides: ShapeUtil.computeStrides(reshapedDims), + unpackedShape: reshapedDims + }; + const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture); + return newTextureData.tensor; + } + reshapePacked(input, reshapedDims) { + const inputTD = this.getOrCreateTextureData(input, 2 /* packed */); + if (isReshapeCheap(input.dims, reshapedDims)) { + const newTextureLayout = { + channels: inputTD.channels, + height: inputTD.height, + width: inputTD.width, + // handle reshaping into scalar Tensors + shape: reshapedDims.length !== 0 ? reshapedDims : [1], + strides: ShapeUtil.computeStrides(reshapedDims), + unpackedShape: reshapedDims, + isPacked: true + }; + const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture); + return newTextureData.tensor; + } + const squeezedInputShape = processDims3D(input.dims); + const squeezedOutputShape = processDims3D(reshapedDims); + const squeezedInputTensor = this.reshapePacked(input, squeezedInputShape); + const squeezedOutputTensor = this.run( + createPackedReshape3DProgramInfoLoader(this, squeezedInputTensor, squeezedOutputShape), + [squeezedInputTensor] + ); + const outputTensor = this.reshapePacked(squeezedOutputTensor, reshapedDims); + return outputTensor; + } + cast(input, type) { + const inputTD = this.getOrCreateTextureData(input, 0 /* unpacked */); + const newTextureData = this.createTextureDataFromTexture(inputTD, type, inputTD.texture); + return newTextureData.tensor; + } + createTextureDataFromTexture(layout, dataType, texture, tensor, tensorId) { + const textureData = { + ...layout, + tensor: tensor || new Tensor4( + layout.unpackedShape, + dataType, + (_id) => this.readTexture(textureData), + async (_id) => this.readTextureAsync(textureData), + void 0, + tensorId + ), + texture + }; + this.setTextureData(textureData.tensor.dataId, textureData, layout.isPacked); + return textureData; + } + getTextureData(tensorId, isPacked = false) { + return this.session.isInitializer(tensorId) ? this.session.getTextureData(tensorId, isPacked) : isPacked ? this.packedTextureDataCache.get(tensorId) : this.unpackedTextureDataCache.get(tensorId); + } + setTextureData(tensorId, td, isPacked = false) { + if (this.session.isInitializer(tensorId)) { + this.session.setTextureData(tensorId, td, isPacked); + } else { + (isPacked ? this.packedTextureDataCache : this.unpackedTextureDataCache).set(tensorId, td); + } + } + isTextureLayoutCached(tensor, isPacked = false) { + return !!this.getTextureData(tensor.dataId, isPacked); + } + dispose() { + this.session.textureManager.clearActiveTextures(); + this.packedTextureDataCache.forEach((td) => this.session.textureManager.releaseTexture(td)); + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache.forEach((td) => this.session.textureManager.releaseTexture(td)); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + } + readTexture(textureData) { + if (textureData.isPacked) { + return this.readTexture(this.unpack(textureData)); + } + if (!this.session.backend.glContext.isFloat32DownloadSupported) { + return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData)); + } + return this.session.textureManager.readTexture(textureData, textureData.tensor.type, textureData.channels); + } + async readTextureAsync(textureData) { + if (textureData.isPacked) { + return this.readTextureAsync(this.unpack(textureData)); + } + if (!this.session.backend.glContext.isFloat32DownloadSupported) { + return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData)); + } + return this.session.textureManager.readTextureAsync(textureData, textureData.tensor.type, textureData.channels); + } + pack(input) { + const outputTextureData = this.executeProgram(createPackProgramInfoLoader(this, input.tensor), [input.tensor]); + return outputTextureData; + } + unpack(input) { + const outputTextureData = this.executeProgram(createUnpackProgramInfoLoader(this, input.tensor), [input.tensor]); + return outputTextureData; + } + }; + } + }); + + // web/lib/onnxjs/attribute-with-cache-key.ts + var AttributeWithCacheKeyImpl, createAttributeWithCacheKey; + var init_attribute_with_cache_key = __esm({ + "web/lib/onnxjs/attribute-with-cache-key.ts"() { + "use strict"; + AttributeWithCacheKeyImpl = class { + constructor(attribute) { + Object.assign(this, attribute); + } + get cacheKey() { + if (!this.key) { + this.key = Object.getOwnPropertyNames(this).sort().map((name2) => `${this[name2]}`).join(";"); + } + return this.key; + } + }; + createAttributeWithCacheKey = (attribute) => new AttributeWithCacheKeyImpl(attribute); + } + }); + + // web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts + var batchNormalizationProgramMetadata, batchNormalization, parseBatchNormalizationAttributes, createBatchNormalizationProgramInfo, validateInputs; + var init_batch_normalization = __esm({ + "web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_glsl_source(); + init_types(); + batchNormalizationProgramMetadata = { + name: "BatchNormalization", + inputNames: ["A", "Scale", "B", "Mean", "Variance"], + inputTypes: [ + 0 /* unpacked */, + 0 /* unpacked */, + 0 /* unpacked */, + 0 /* unpacked */, + 0 /* unpacked */ + ] + }; + batchNormalization = (inferenceHandler, inputs, attributes) => { + validateInputs(inputs); + const output = inferenceHandler.run( + { + ...batchNormalizationProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createBatchNormalizationProgramInfo(inferenceHandler, inputs, attributes) + }, + inputs + ); + return [output]; + }; + parseBatchNormalizationAttributes = (node) => { + const epsilon = node.attributes.getFloat("epsilon", 1e-5); + const momentum = node.attributes.getFloat("momentum", 0.9); + const spatial = node.attributes.getInt("spatial", 1); + return createAttributeWithCacheKey({ epsilon, momentum, spatial }); + }; + createBatchNormalizationProgramInfo = (inferenceHandler, inputs, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const rank = inputs[0].dims.length; + const [scaleWidth, scaleHeight] = inferenceHandler.calculateTextureWidthAndHeight( + inputs[1].dims, + 0 /* unpacked */ + ); + const shaderSource = ` + float process(int[${rank}] indices) { + vec2 position = offsetToCoords(indices[1], ${scaleWidth}, ${scaleHeight}); + float scale = getColorAsFloat(${glsl.texture2D}(Scale, position)); + float mean = getColorAsFloat(${glsl.texture2D}(Mean, position)); + float variance = getColorAsFloat(${glsl.texture2D}(Variance, position)); + float b = getColorAsFloat(${glsl.texture2D}(B, position)); + + return scale * ( (_A(indices) - mean) / sqrt(variance + float(${attributes.epsilon})) ) + b; + }`; + return { + ...batchNormalizationProgramMetadata, + output: { dims: inputs[0].dims, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs = (inputs) => { + if (!inputs || inputs.length !== 5) { + throw new Error("BatchNormalization requires 5 inputs."); + } + const X = inputs[0]; + const scale = inputs[1]; + const B = inputs[2]; + const mean = inputs[3]; + const var_ = inputs[4]; + if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1 || mean.dims.length !== 1 || var_.dims.length !== 1) { + throw new Error("invalid input shape."); + } + if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1] || mean.dims[0] !== X.dims[1] || var_.dims[0] !== X.dims[1]) { + throw new Error("invalid input shape."); + } + if (X.type !== "float32" && X.type !== "float64" || scale.type !== "float32" && scale.type !== "float64" || B.type !== "float32" && B.type !== "float64" || mean.type !== "float32" && mean.type !== "float64" || var_.type !== "float32" && var_.type !== "float64") { + throw new Error("invalid input tensor types."); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/glsl-definitions.ts + var GlslContext, GlslLib, GlslLibRoutine, GlslLibRoutineNode, TopologicalSortGlslRoutines; + var init_glsl_definitions = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-definitions.ts"() { + "use strict"; + GlslContext = class { + constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) { + this.glContext = glContext; + this.programInfo = programInfo; + this.inputTextureLayouts = inputTextureLayouts; + this.outputTextureLayout = outputTextureLayout; + } + }; + GlslLib = class { + constructor(context) { + this.context = context; + } + }; + GlslLibRoutine = class { + constructor(routineBody, dependencies) { + this.routineBody = routineBody; + this.dependencies = dependencies; + } + }; + GlslLibRoutineNode = class { + constructor(name2, routineBody, dependencies) { + this.name = name2; + if (dependencies) { + this.dependencies = dependencies; + } else { + this.dependencies = []; + } + if (routineBody) { + this.routineBody = routineBody; + } + } + addDependency(node) { + if (node) { + this.dependencies.push(node); + } + } + }; + TopologicalSortGlslRoutines = class { + static returnOrderedNodes(nodes) { + if (!nodes || nodes.length === 0) { + return []; + } + if (nodes.length === 1) { + return nodes; + } + const cycleCheck = /* @__PURE__ */ new Set(); + const alreadyTraversed = /* @__PURE__ */ new Set(); + const result = new Array(); + this.createOrderedNodes(nodes, cycleCheck, alreadyTraversed, result); + return result; + } + static createOrderedNodes(graphNodes, cycleCheck, alreadyTraversed, result) { + for (let i = 0; i < graphNodes.length; ++i) { + this.dfsTraverse(graphNodes[i], cycleCheck, alreadyTraversed, result); + } + } + static dfsTraverse(root, cycleCheck, alreadyTraversed, result) { + if (!root || alreadyTraversed.has(root.name)) { + return; + } + if (cycleCheck.has(root.name)) { + throw new Error("Cyclic dependency detected. Can't topologically sort routines needed for shader."); + } + cycleCheck.add(root.name); + const dependencies = root.dependencies; + if (dependencies && dependencies.length > 0) { + for (let i = 0; i < dependencies.length; ++i) { + this.dfsTraverse(dependencies[i], cycleCheck, alreadyTraversed, result); + } + } + result.push(root); + alreadyTraversed.add(root.name); + cycleCheck.delete(root.name); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/binary-op.ts + function glslAdd() { + const name2 = "add_"; + const body = ` + float ${name2}(float a, float b) { + return a + b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 + v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslDiv() { + const name2 = "div_"; + const body = ` + float ${name2}(float a, float b) { + return a / b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 / v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslMul() { + const name2 = "mul_"; + const body = ` + float ${name2}(float a, float b) { + return a * b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 * v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslSub() { + const name2 = "sub_"; + const body = ` + float ${name2}(float a, float b) { + return a - b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 - v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslEqual() { + const name2 = "equal_"; + const body = ` + float ${name2}(float a, float b) { + return float(a == b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4(equal(v1, v2)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslGreater() { + const name2 = "greater_"; + const body = ` + float ${name2}(float a, float b) { + return float(a > b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4( v1.r > v2.r , + v1.g > v2.g, + v1.b > v2.b, + v1.a > v2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslLess() { + const name2 = "less_"; + const body = ` + float ${name2}(float a, float b) { + return float(a < b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4( v1.r < v2.r , + v1.g < v2.g, + v1.b < v2.b, + v1.a < v2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslAnd() { + const name2 = "and_"; + const body = ` + float ${name2}(float a, float b) { + return float( bool(a) && bool(b) ); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + bvec4 b1 = bvec4(v1); + bvec4 b2 = bvec4(v2); + return vec4( b1.r && b2.r , + b1.g && b2.g, + b1.b && b2.b, + b1.a && b2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslOr() { + const name2 = "or_"; + const body = ` + float ${name2}(float a, float b) { + return float( bool(a) || bool(b) ); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + bvec4 b1 = bvec4(v1); + bvec4 b2 = bvec4(v2); + return vec4( b1.r || b2.r , + b1.g || b2.g, + b1.b || b2.b, + b1.a || b2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslXor() { + const name2 = "xor_"; + const body = ` + float ${name2}(float a, float b) { + return float( bool(a) ^^ bool(b) ); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + bvec4 b1 = bvec4(v1); + bvec4 b2 = bvec4(v2); + return vec4( b1.r ^^ b2.r , + b1.g ^^ b2.g, + b1.b ^^ b2.b, + b1.a ^^ b2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslPow() { + return glslBuiltinBinary("pow"); + } + function glslPRelu() { + const name2 = "prelu_"; + const body = ` + float ${name2}(float a, float b) { + return a < 0.0 ? a * b: a; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4( + v1.r < 0.0 ? v1.r * v2.r: v1.r, + v1.g < 0.0 ? v1.g * v2.g: v1.g, + v1.b < 0.0 ? v1.b * v2.b: v1.b, + v1.a < 0.0 ? v1.a * v2.a: v1.a + ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslBuiltinBinary(fname) { + const name2 = `${fname}_`; + const body = ` + float ${name2}(float a, float b) { + return ${fname}(a, b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return ${fname}(v1, v2); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + var createBinaryProgramInfoLoader, createBinaryProgramInfo, add2, and2, div, equal, greater, less, mul, or2, pow, pRelu, sub, xor2; + var init_binary_op = __esm({ + "web/lib/onnxjs/backends/webgl/ops/binary-op.ts"() { + "use strict"; + init_util(); + init_glsl_definitions(); + init_glsl_source(); + init_types(); + createBinaryProgramInfoLoader = (handler, inputs, glslFunc, outputTensorType = inputs[0].type, cacheKey) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + return { + name: glslFunc.name, + inputNames: ["A", "B"], + inputTypes: [textureType, textureType], + cacheHint: cacheKey, + get: () => createBinaryProgramInfo(handler, inputs, glslFunc, outputTensorType) + }; + }; + createBinaryProgramInfo = (handler, inputs, glslFunc, outputTensorType = inputs[0].type) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims); + let outputShape = inputs[0].dims; + const usePackedTexture = handler.session.pack; + if (isBroadcast) { + const calculatedShape = BroadcastUtil.calcShape(inputs[0].dims, inputs[1].dims, false); + if (!calculatedShape) { + throw new Error("Can't perform binary op on the given tensors"); + } + outputShape = calculatedShape; + const outputRank = outputShape.length; + const aRank = inputs[0].dims.length !== 0 ? inputs[0].dims.length : 1; + const bRank = inputs[1].dims.length !== 0 ? inputs[1].dims.length : 1; + const aBcast = inputs[0].dims.length !== 0 ? "bcastIndices_A(indices, aindices);" : "aindices[0] = 0;"; + const bBcast = inputs[1].dims.length !== 0 ? "bcastIndices_B(indices, bindices);" : "bindices[0] = 0;"; + const glsl2 = getGlsl(handler.session.backend.glContext.version); + const shaderSource2 = usePackedTexture ? ` + ${glslFunc.body} + void main() { + vec4 a = getAAtOutCoords(); + vec4 b = getBAtOutCoords(); + vec4 result = ${glslFunc.name}(a, b); + ${glsl2.output} = result; + }` : ` + ${glslFunc.body} + float process(int indices[${outputRank}]) { + int aindices[${aRank}]; + int bindices[${bRank}]; + ${aBcast} + ${bBcast} + return ${glslFunc.name}(_A(aindices), _B(bindices)); + }`; + return { + name: glslFunc.name, + inputNames: ["A", "B"], + inputTypes: [textureType, textureType], + output: { dims: outputShape, type: outputTensorType, textureType }, + shaderSource: shaderSource2, + hasMain: usePackedTexture + }; + } + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${glslFunc.body} + void main() { + vec4 v1 = ${glsl.texture2D}(A, TexCoords); + vec4 v2 = ${glsl.texture2D}(B, TexCoords); + vec4 result = ${glslFunc.name}(v1, v2); + ${glsl.output} = result; + } + `; + return { + name: glslFunc.name, + inputNames: ["A", "B"], + inputTypes: [textureType, textureType], + output: { dims: inputs[0].dims, type: outputTensorType, textureType }, + shaderSource, + hasMain: true + }; + }; + add2 = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAdd()), inputs) + ]; + and2 = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAnd(), "bool"), inputs) + ]; + div = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslDiv()), inputs) + ]; + equal = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslEqual(), "bool"), inputs) + ]; + greater = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslGreater(), "bool"), inputs) + ]; + less = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslLess(), "bool"), inputs) + ]; + mul = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslMul()), inputs) + ]; + or2 = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslOr(), "bool"), inputs) + ]; + pow = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPow()), inputs) + ]; + pRelu = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPRelu()), inputs) + ]; + sub = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslSub()), inputs) + ]; + xor2 = (handler, inputs) => [ + handler.run(createBinaryProgramInfoLoader(handler, inputs, glslXor(), "bool"), inputs) + ]; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/cast.ts + var cast, parseCastAttributes, validateInputs2; + var init_cast = __esm({ + "web/lib/onnxjs/backends/webgl/ops/cast.ts"() { + "use strict"; + init_util(); + cast = (handler, inputs, to) => { + validateInputs2(inputs); + return [handler.cast(inputs[0], to)]; + }; + parseCastAttributes = (node) => ProtoUtil.tensorDataTypeFromProto(node.attributes.getInt("to")); + validateInputs2 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Cast requires 1 input."); + } + if (inputs[0].type === "string") { + throw new Error("Invalid input type."); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/concat-packed.ts + var createPackedConcatProgramMetadata, createPackedConcatProgramInfo, createPackedConcatProgramInfoLoader, getShiftedChannelsSnippet; + var init_concat_packed = __esm({ + "web/lib/onnxjs/backends/webgl/ops/concat-packed.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + createPackedConcatProgramMetadata = (inputCount, cacheHint) => ({ + name: "Concat (packed)", + inputNames: Array.from({ length: inputCount }, (_v, i) => `X${i}`), + inputTypes: Array(inputCount).fill(2 /* packed */), + cacheHint + }); + createPackedConcatProgramInfo = (handler, metadata, inputs, axis) => { + const inputShape = inputs[0].dims.slice(); + if (axis >= inputShape.length || axis < -1 * inputShape.length) { + throw new Error("axis specified for concat doesn't match input dimensionality"); + } + if (axis < 0) { + axis = inputShape.length + axis; + } + const outputShape = inputShape.slice(0); + for (let i = 1; i < inputs.length; i++) { + const dataNShape = inputs[i].dims.slice(); + for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) { + if (axisIndex === axis) { + outputShape[axis] += dataNShape[axisIndex]; + } else if (inputShape[axisIndex] !== dataNShape[axisIndex]) { + throw new Error("non concat dimensions must match"); + } + } + } + const rank = outputShape.length; + const coords = getChannels("coords", rank); + const dtype = getCoordsDataType(rank); + const unpackChannel = unpackFromChannel(); + const shapes = inputs.map((i) => i.dims); + const channels = getGlChannels(rank); + const offsets = new Array(shapes.length - 1); + offsets[0] = shapes[0][axis]; + for (let i = 1; i < offsets.length; i++) { + offsets[i] = offsets[i - 1] + shapes[i][axis]; + } + const channel = channels[axis]; + const lastChannels = channels.slice(-2); + const allChannels = channels.join(); + let getValueSnippet = `if (${channel} < ${offsets[0]}) { + return getChannel( + getX0(${allChannels}), vec2(${lastChannels.join()})); + }`; + for (let i = 1; i < offsets.length; i++) { + const shift2 = offsets[i - 1]; + getValueSnippet += ` + if (${channel} < ${offsets[i]} && ${channel} >= ${offsets[i - 1]}) { + return getChannel( + getX${i}(${getShiftedChannelsSnippet(channels, channel, shift2)}), + vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift2)})); + }`; + } + const lastIndex = offsets.length; + const shift = offsets[offsets.length - 1]; + getValueSnippet += ` + return getChannel( + getX${lastIndex}(${getShiftedChannelsSnippet(channels, channel, shift)}), + vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));`; + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${unpackChannel} + float getValue(${channels.map((x) => "int " + x)}) { + ${getValueSnippet} + } + + void main() { + ${dtype} coords = getOutputCoords(); + int lastDim = coords.${channels[rank - 1]}; + coords.${channels[rank - 1]} = coords.${channels[rank - 2]}; + coords.${channels[rank - 2]} = lastDim; + + vec4 result = vec4(getValue(${coords}), 0., 0., 0.); + + ${coords[rank - 1]} = ${coords[rank - 1]} + 1; + if (${coords[rank - 1]} < ${outputShape[rank - 1]}) { + result.g = getValue(${coords}); + } + + ${coords[rank - 2]} = ${coords[rank - 2]} + 1; + if (${coords[rank - 2]} < ${outputShape[rank - 2]}) { + result.a = getValue(${coords}); + } + + ${coords[rank - 1]} = ${coords[rank - 1]} - 1; + if (${coords[rank - 2]} < ${outputShape[rank - 2]} && + ${coords[rank - 1]} < ${outputShape[rank - 1]}) { + result.b = getValue(${coords}); + } + ${glsl.output} = result; + } + `; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedConcatProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = createPackedConcatProgramMetadata(inputs.length, attributes.cacheKey); + return { ...metadata, get: () => createPackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) }; + }; + getShiftedChannelsSnippet = (channels, channel, shift) => { + const channelIdx = channels.indexOf(channel); + const res = channels.map((c, idx) => { + if (idx === channelIdx) { + return `${c} - ${shift}`; + } else { + return c; + } + }); + return res.join(); + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/concat.ts + var concat, createUnpackedConcatProgramMetadata, createUnpackedConcatProgramInfo, createUnpackedConcatProgramInfoLoader, getTextureIndexWhereDataResidesLinearSearch, getTextureIndexWhereDataResidesBinarySearch, getFetchDataFromCorrectTextureMethod, getGetSizeInConcatAxisValueFromIndexMethod, parseConcatAttributes, validateInputs3; + var init_concat = __esm({ + "web/lib/onnxjs/backends/webgl/ops/concat.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_types(); + init_concat_packed(); + concat = (inferenceHandler, inputs, attributes) => { + validateInputs3(inputs); + if (inferenceHandler.session.pack && inputs[0].dims.length > 1) { + const output = inferenceHandler.run( + createPackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), + inputs + ); + return [output]; + } else { + const output = inferenceHandler.run( + createUnpackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), + inputs + ); + return [output]; + } + }; + createUnpackedConcatProgramMetadata = (inputCount, cacheHint) => ({ + name: "Concat", + inputNames: Array.from({ length: inputCount }, (_v, i) => `X${i}`), + inputTypes: Array(inputCount).fill(0 /* unpacked */), + cacheHint + }); + createUnpackedConcatProgramInfo = (_handler, metadata, inputs, axis) => { + const inputShape = inputs[0].dims.slice(); + if (axis >= inputShape.length || axis < -1 * inputShape.length) { + throw new Error("axis specified for concat doesn't match input dimensionality"); + } + if (axis < 0) { + axis = inputShape.length + axis; + } + const outputShape = inputShape.slice(0); + for (let i = 1; i < inputs.length; i++) { + const dataNShape = inputs[i].dims.slice(); + for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) { + if (axisIndex === axis) { + outputShape[axis] += dataNShape[axisIndex]; + } else if (inputShape[axisIndex] !== dataNShape[axisIndex]) { + throw new Error("non concat dimensions must match"); + } + } + } + const rank = outputShape.length; + const sizeInConcatAxis = new Array(inputs.length); + let previousSum = 0; + for (let i = 0; i < sizeInConcatAxis.length; ++i) { + previousSum += inputs[i].dims[axis]; + sizeInConcatAxis[i] = previousSum; + } + let getTextureIndexWhereDataResidesMethod = ""; + if (inputs.length < 5) { + getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis); + } else { + getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesBinarySearch(sizeInConcatAxis); + } + const fetchDataFromCorrectTextureMethod = getFetchDataFromCorrectTextureMethod(inputs.length, rank); + const getSizeInConcatAxisValueFromIndexMethod = getGetSizeInConcatAxisValueFromIndexMethod(sizeInConcatAxis); + const shaderSource = ` + ${fetchDataFromCorrectTextureMethod} + ${getSizeInConcatAxisValueFromIndexMethod} + ${getTextureIndexWhereDataResidesMethod} + float process(int indices[${rank}]) { + int textureIndex = getTextureWhereDataResides (indices[${axis}]); + + if(textureIndex != 0) { + indices[${axis}] = indices[${axis}] - int(getSizeInConcatAxisValueFromIndex(textureIndex-int(1))); + } + + return fetchDataFromCorrectTexture(textureIndex, indices); + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createUnpackedConcatProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = createUnpackedConcatProgramMetadata(inputs.length, attributes.cacheKey); + return { ...metadata, get: () => createUnpackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) }; + }; + getTextureIndexWhereDataResidesLinearSearch = (sizeInConcatAxis) => { + const searchAxis = sizeInConcatAxis.map( + (size, i) => `if(index<${size}) {return ${i};} +` + ); + return `int getTextureWhereDataResides(int index) { + ${searchAxis.join("")} + }`; + }; + getTextureIndexWhereDataResidesBinarySearch = (sizeInConcatAxis) => getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis); + getFetchDataFromCorrectTextureMethod = (numberOfTensors, tensorRank) => { + const codeLines = [`float fetchDataFromCorrectTexture(int textureIndex, int indices[${tensorRank}]) {`]; + for (let i = 0; i < numberOfTensors; ++i) { + if (i === 0) { + codeLines.push(` if (textureIndex == ${i}) { return _X${i}(indices); }`); + } else if (i === numberOfTensors - 1) { + codeLines.push(` else { return _X${i}(indices); }`); + } else { + codeLines.push(` else if (textureIndex == ${i}) { return _X${i}(indices); }`); + } + } + codeLines.push(" }"); + return codeLines.join("\n"); + }; + getGetSizeInConcatAxisValueFromIndexMethod = (sizeInConcatAxis) => { + const codeLines = ["int getSizeInConcatAxisValueFromIndex(int index) {"]; + for (let i = 0; i < sizeInConcatAxis.length; ++i) { + if (i === 0) { + codeLines.push(` if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`); + } else if (i === sizeInConcatAxis.length - 1) { + codeLines.push(` else { return ${sizeInConcatAxis[i]}; }`); + } else { + codeLines.push(` else if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`); + } + } + codeLines.push(" }"); + return codeLines.join("\n"); + }; + parseConcatAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis") }); + validateInputs3 = (inputs) => { + if (!inputs || inputs.length < 1) { + throw new Error("too few inputs"); + } + const inputType = inputs[0].type; + const inputDimensionality = inputs[0].dims.length; + if (inputType === "string") { + throw new Error("string tensor is not supported yet"); + } + for (const input of inputs) { + if (input.type !== inputType) { + throw new Error("input tensors should be one type"); + } + if (input.dims.length !== inputDimensionality) { + throw new Error("input tensors should have the same shape"); + } + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/unary-op.ts + function glslAbs() { + return glslBuiltinUnary("abs"); + } + function glslAcos() { + return glslBuiltinUnary("acos"); + } + function glslAsin() { + return glslBuiltinUnary("asin"); + } + function glslAtan() { + return glslBuiltinUnary("atan"); + } + function glslCeil() { + return glslBuiltinUnary("ceil"); + } + function glslCos() { + return glslBuiltinUnary("cos"); + } + function glslElu(alpha) { + const name2 = "elu"; + const body = ` + const float alpha = float(${alpha}); + + float ${name2}_(float a) { + return a >= 0.0 ? a: (exp(a) - 1.0) * alpha; + } + vec4 ${name2}_(vec4 v) { + return vec4(${name2}_(v.x), ${name2}_(v.y), ${name2}_(v.z), ${name2}_(v.w)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslExp() { + return glslBuiltinUnary("exp"); + } + function glslFloor() { + return glslBuiltinUnary("floor"); + } + function glslClip(min, max) { + const name2 = "clip"; + const body = ` + const float min = float(${min}); + const float max = float(${max}); + + float ${name2}_(float a) { + return clamp(a, min, max); + } + vec4 ${name2}_(vec4 v) { + return clamp(v, min, max); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslIdentity() { + const name2 = "indentity"; + const body = ` + float ${name2}_(float a) { + return a; + } + vec4 ${name2}_(vec4 v) { + return v; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslLeakyRelu(alpha) { + const name2 = "leakyRelu"; + const body = ` + const float alpha = float(${alpha}); + + float ${name2}_(float a) { + return a < 0.0 ? a * alpha : a; + } + vec4 ${name2}_(vec4 v) { + return vec4(${name2}_(v.x), ${name2}_(v.y), ${name2}_(v.z), ${name2}_(v.w)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslLog() { + return glslBuiltinUnary("log"); + } + function glslNeg() { + const name2 = "neg"; + const body = ` + float ${name2}_(float a) { + return -a; + } + vec4 ${name2}_(vec4 v) { + return -v; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslNot() { + const name2 = "not"; + const body = ` + float ${name2}_(float a) { + return float( ! bool(a) ); + } + bool ${name2}_(bool a) { + return !a; + } + vec4 ${name2}_(vec4 v) { + return vec4(!bool(v.x), !bool(v.y), !bool(v.z), !bool(v.w)); + } + bvec4 ${name2}_(bvec4 v) { + return bvec4(!v.x, !v.y, !v.z, !v.w); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslSin() { + return glslBuiltinUnary("sin"); + } + function glslRelu() { + const name2 = "relu"; + const body = ` + float ${name2}_(float a) { + return max( a, 0.0 ); + } + vec4 ${name2}_(vec4 v) { + return max( v, 0.0 ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslSigmoid() { + const name2 = "sigmoid"; + const body = ` + float ${name2}_(float a) { + return 1.0 / (1.0 + exp(-a)); + } + vec4 ${name2}_(vec4 v) { + return 1.0 / (1.0 + exp(-v)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslSqrt() { + return glslBuiltinUnary("sqrt"); + } + function glslTan() { + return glslBuiltinUnary("tan"); + } + function glslTanh() { + const name2 = "tanh"; + const body = ` + float ${name2}_(float a) { + a = clamp(a, -10., 10.); + a = exp(2.*a); + return (a - 1.) / (a + 1.); + } + vec4 ${name2}_(vec4 v) { + v = clamp(v, -10., 10.); + v = exp(2.*v); + return (v - 1.) / (v + 1.); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + function glslBuiltinUnary(name2) { + const body = ` + float ${name2}_(float a) { + return ${name2}(a); + } + vec4 ${name2}_(vec4 v) { + return ${name2}(v); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; + } + var createElementwiseProgramInfo, createElementwiseProgramInfoLoader, abs, acos, asin, atan, clip, parseClipAttributes, clipV11, generateClipAttributesFromInputs, ceil, cos, elu, parseEluAttributes, exp, floor, identity, leakyRelu, parseLeakyReluAttributes, log2, neg, not2, relu, sigmoid, sin, sqrt, tan, tanh; + var init_unary_op = __esm({ + "web/lib/onnxjs/backends/webgl/ops/unary-op.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_glsl_definitions(); + init_glsl_source(); + init_types(); + createElementwiseProgramInfo = (handler, metadata, input, glslFunc) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + const glsl = getGlsl(handler.session.backend.glContext.version); + return { + ...metadata, + output: { dims: input.dims, type: input.type, textureType }, + shaderSource: ` + ${glslFunc.body} + void main() { + vec4 v = ${glsl.texture2D}(A, TexCoords); + v = ${glslFunc.name}_(v); + ${glsl.output} = v; + } + `, + hasMain: true + }; + }; + createElementwiseProgramInfoLoader = (handler, input, glslFunc, cacheKey) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + const metadata = { name: glslFunc.name, inputTypes: [textureType], inputNames: ["A"], cacheHint: cacheKey }; + return { ...metadata, get: () => createElementwiseProgramInfo(handler, metadata, input, glslFunc) }; + }; + abs = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAbs()), inputs) + ]; + acos = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAcos()), inputs) + ]; + asin = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAsin()), inputs) + ]; + atan = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAtan()), inputs) + ]; + clip = (handler, inputs, attributes) => [ + handler.run( + createElementwiseProgramInfoLoader( + handler, + inputs[0], + glslClip(attributes.min, attributes.max), + attributes.cacheKey + ), + inputs + ) + ]; + parseClipAttributes = (node) => createAttributeWithCacheKey({ + min: node.attributes.getFloat("min", MIN_CLIP), + max: node.attributes.getFloat("max", MAX_CLIP) + }); + clipV11 = (handler, inputs) => { + const attributes = generateClipAttributesFromInputs(handler, inputs); + return clip(handler, [inputs[0]], attributes); + }; + generateClipAttributesFromInputs = (handler, inputs) => { + if (inputs.length >= 3 && (!handler.session.isInitializer(inputs[1].dataId) || !handler.session.isInitializer(inputs[2].dataId))) { + throw new Error("dynamic clip attributes are not allowed"); + } + const min = inputs.length >= 3 ? inputs[1].numberData[0] : MIN_CLIP; + const max = inputs.length >= 3 ? inputs[2].numberData[0] : MAX_CLIP; + return createAttributeWithCacheKey({ min, max }); + }; + ceil = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCeil()), inputs) + ]; + cos = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCos()), inputs) + ]; + elu = (handler, inputs, attributes) => [ + handler.run( + createElementwiseProgramInfoLoader(handler, inputs[0], glslElu(attributes.alpha), attributes.cacheKey), + inputs + ) + ]; + parseEluAttributes = (node) => createAttributeWithCacheKey({ alpha: node.attributes.getFloat("alpha", 1) }); + exp = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslExp()), inputs) + ]; + floor = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslFloor()), inputs) + ]; + identity = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslIdentity()), inputs) + ]; + leakyRelu = (handler, inputs, attributes) => [ + handler.run( + createElementwiseProgramInfoLoader(handler, inputs[0], glslLeakyRelu(attributes.alpha), attributes.cacheKey), + inputs + ) + ]; + parseLeakyReluAttributes = (node) => createAttributeWithCacheKey({ alpha: node.attributes.getFloat("alpha", 0.01) }); + log2 = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslLog()), inputs) + ]; + neg = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNeg()), inputs) + ]; + not2 = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNot()), inputs) + ]; + relu = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslRelu()), inputs) + ]; + sigmoid = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSigmoid()), inputs) + ]; + sin = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSin()), inputs) + ]; + sqrt = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSqrt()), inputs) + ]; + tan = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTan()), inputs) + ]; + tanh = (handler, inputs) => [ + handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTanh()), inputs) + ]; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts + function getActivationSnippet(attributes) { + let func; + switch (attributes.activation) { + case "Relu": + func = glslRelu(); + break; + case "Sigmoid": + func = glslSigmoid(); + break; + case "Clip": + func = glslClip(attributes.clipMin, attributes.clipMax); + break; + // TODO: adding other activations that can be fused. + default: + return { activationFunction: "", applyActivation: "" }; + } + const activationName = func.name; + const activationFunction = func.body; + const applyActivation = `value = ${activationName}_(value);`; + return { activationFunction, applyActivation }; + } + var parseInternalActivationAttributes; + var init_fuse_utils = __esm({ + "web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts"() { + "use strict"; + init_util(); + init_unary_op(); + parseInternalActivationAttributes = (attributes) => { + const activation = attributes.getString("activation", ""); + if (activation === "Clip") { + const [clipMin, clipMax] = attributes.getFloats("activation_params", [MIN_CLIP, MAX_CLIP]); + return { activation, clipMax, clipMin, activationCacheKey: `${activation}:${clipMin},${clipMax}` }; + } + return { activation, activationCacheKey: activation }; + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts + var createUnpackedGroupedConvProgramMetadata, createUnpackedGroupedConvProgramInfo, createUnpackedGroupedConvProgramInfoLoader; + var init_conv_grouped = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts"() { + "use strict"; + init_instrument(); + init_glsl_source(); + init_types(); + init_conv(); + init_fuse_utils(); + createUnpackedGroupedConvProgramMetadata = (hasBias, cacheHint) => ({ + name: "GroupedConv", + inputNames: hasBias ? ["X", "W", "Bias"] : ["X", "W"], + inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + cacheHint + }); + createUnpackedGroupedConvProgramInfo = (inferenceHandler, inputs, metadata, attributes) => { + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += getBias(output_channel);" : ""; + const xShape = inputs[0].dims.slice(); + const wShape = inputs[1].dims.slice(); + const outputChannelsPerGroup = wShape[0] / attributes.group; + Logger.verbose( + "GroupedConv", + `autpPad:${attributes.autoPad}, dilations:${attributes.dilations}, group:${attributes.group}, kernelShape:${attributes.kernelShape}, pads:${attributes.pads}, strides:${attributes.strides}` + ); + const outputShape = calculateOutputShape(xShape, wShape, attributes.dilations, attributes.pads, attributes.strides); + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const { activationFunction, applyActivation } = getActivationSnippet(attributes); + const shaderSource = ` + const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]}); + const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]}); + ${activationFunction} + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + int output_channel = coords.y; + ivec2 xRCCorner = coords.zw * strides - pads; + int group_id = output_channel / ${outputChannelsPerGroup}; + + float value = 0.0; + for (int wInChannel = 0; wInChannel < ${wShape[1]}; wInChannel++) { + int input_channel = group_id * ${wShape[1]} + wInChannel; + for (int wHeight = 0; wHeight < ${wShape[2]}; wHeight++) { + int xHeight = xRCCorner.x + wHeight * ${attributes.dilations[0]}; + + if (xHeight < 0 || xHeight >= ${xShape[2]}) { + continue; + } + + for (int wWidth = 0; wWidth < ${wShape[3]}; wWidth++) { + int xWidth = xRCCorner.y + wWidth * ${attributes.dilations[1]}; + if (xWidth < 0 || xWidth >= ${xShape[3]}) { + continue; + } + + float xVal = getX(batch, input_channel, xWidth, xHeight); + float wVal = getW(output_channel, wInChannel, wWidth, wHeight); + value += xVal*wVal; + } + } + } + ${processBias} + ${applyActivation} + ${glsl.output} = vec4(value, .0, .0, .0); + } +`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource, + hasMain: true + }; + }; + createUnpackedGroupedConvProgramInfoLoader = (inferenceHandler, inputs, attributes) => { + const metadata = createUnpackedGroupedConvProgramMetadata(inputs.length > 2, attributes.cacheKey); + return { + ...metadata, + get: () => createUnpackedGroupedConvProgramInfo(inferenceHandler, inputs, metadata, attributes) + }; + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts + var createPackedIm2ColProgramMetadata, createPackedIm2ColProgramInfo, createPackedIm2ColProgramInfoLoader; + var init_im2col_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_packing_utils(); + createPackedIm2ColProgramMetadata = (cacheHint) => ({ + name: "Im2Col (packed)", + inputNames: ["A"], + inputTypes: [2 /* packed */], + cacheHint + }); + createPackedIm2ColProgramInfo = (inferenceHandler, metadata, x, w, outputShape, attributes) => { + const xshape = x.dims; + const wshape = w.dims; + const rowDim = 2; + const colDim = 3; + const rank = outputShape.length; + const im2colShape = [wshape[1] * wshape[2] * wshape[3], outputShape[2] * outputShape[3]]; + const kernelSize = wshape[2] * wshape[3]; + const unpackChannel = unpackFromChannel(); + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + let unrolled = ""; + for (let row = 0; row <= 1; row++) { + for (let col = 0; col <= 1; col++) { + unrolled += ` + blockIndex = rc.x + ${col}; + pos = rc.y + ${row}; + + if(blockIndex < ${im2colShape[1]} && pos < ${im2colShape[0]}) { + offsetY = int(blockIndex / (${outputShape[rank - 1]})) * ${attributes.strides[0]} - + ${attributes.pads[0]}; + d0 = offsetY + ${attributes.dilations[0]} * (imod(pos, ${kernelSize}) / ${wshape[2]}); + + if(d0 < ${xshape[rowDim]} && d0 >= 0) { + offsetX = imod(blockIndex, ${outputShape[rank - 1]}) * ${attributes.strides[1]} - + ${attributes.pads[1]}; + d1 = offsetX + ${attributes.dilations[1]} * imod(imod(pos, ${kernelSize}), ${wshape[2]}); + + if(d1 < ${xshape[colDim]} && d1 >= 0) { + + ch = int(float(pos)/ ${kernelSize}.); + innerDims = vec2(d0, d1); + result[${row * 2 + col}] = getChannel( + getA(0, ch, int(innerDims.x), + int(innerDims.y)), innerDims); + } + } + } + + `; + } + } + const shaderSource = ` + ${unpackChannel} + + void main() { + ivec2 rc = getOutputCoords(); + vec4 result = vec4(0.0); + int blockIndex, pos, offsetY, d0, offsetX, d1, ch; + vec2 innerDims; + ${unrolled} + ${glsl.output} = result; + } + `; + return { + ...metadata, + output: { dims: im2colShape, type: x.type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => { + const metadata = createPackedIm2ColProgramMetadata(attributes.cacheKey); + return { + ...metadata, + get: () => createPackedIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) + }; + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/matmul.ts + function createMatmulProgramInfo(metadata, inputs, activationAttributes) { + const aShape = inputs[0].dims; + const bShape = inputs[1].dims; + const outputShape = BroadcastUtil.calcShape(aShape, bShape, true); + if (!outputShape) { + throw new Error("Can't use matmul on the given tensors"); + } + const coordsDataType = getCoordsDataType(outputShape.length); + const allGlChannels = getGlChannels(); + const { activationFunction, applyActivation } = getActivationSnippet(activationAttributes); + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += getBiasForMatmul();" : ""; + const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, false)}` : ""; + const rank = outputShape.length; + const arank = aShape.length; + const brank = bShape.length; + const sharedDim = aShape[aShape.length - 1]; + const shaderSource = ` + ${activationFunction} + ${getBiasForMatmulSnippet} + float process(int indices[${rank}]) { + int a[${arank}]; + int b[${brank}]; + bcastMatmulIndices_A(indices, a); + bcastMatmulIndices_B(indices, b); + + float value; + for (int k=0; k<${sharedDim}; ++k) { + a[${arank - 1}] = k; + b[${brank - 2}] = k; + value += _A(a) * _B(b); + } + ${processBias} + ${applyActivation} + return value; + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + } + function createMatmulProgramInfoLoader(inputs, activationAttributes) { + const metadata = createMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey); + return { ...metadata, get: () => createMatmulProgramInfo(metadata, inputs, activationAttributes) }; + } + function getBiasForMatmul(coordsDataType, allGlChannels, inShape, outShape, isPacked) { + let unpackedCoordsSnippet = ""; + const inRank = inShape.length; + const outRank = outShape.length; + const rankDiff = outRank - inRank; + if (outRank < 2 && inRank > 0) { + unpackedCoordsSnippet = "coords"; + } else { + unpackedCoordsSnippet = inShape.map((_s, i) => `coords.${allGlChannels[i + rankDiff]}`).join(", "); + } + const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); + const coordsSnippet = broadcastDims.map((d) => `coords.${allGlChannels[d + rankDiff]} = 0;`).join("\n"); + const inSize = ShapeUtil.size(inShape); + const isInputScalar = inSize === 1; + let output = "vec4(outputValue.xx, outputValue.yy)"; + if (isInputScalar) { + output = "vec4(outputValue.x)"; + } + const getBiasForMatmulSource = isPacked ? ` +vec4 getBiasForMatmul() { + ${coordsDataType} coords = getOutputCoords(); + ${coordsSnippet} + vec4 outputValue = getBias(${unpackedCoordsSnippet}); + return ${output}; +}` : ` +float getBiasForMatmul() { + ${coordsDataType} coords = getOutputCoords(); + ${coordsSnippet} + return getBias(coords.x); +}`; + return getBiasForMatmulSource; + } + var matMul, parseMatMulAttributes, createMatmulProgramMetadata, validateInputs4; + var init_matmul = __esm({ + "web/lib/onnxjs/backends/webgl/ops/matmul.ts"() { + "use strict"; + init_util(); + init_types(); + init_utils(); + init_fuse_utils(); + init_matmul_pack(); + matMul = (inferenceHandler, inputs, attributes) => { + validateInputs4(inputs); + if (inferenceHandler.session.pack) { + return [inferenceHandler.run(createPackedMatmulProgramInfoLoader(inferenceHandler, inputs, attributes), inputs)]; + } else { + return [inferenceHandler.run(createMatmulProgramInfoLoader(inputs, attributes), inputs)]; + } + }; + parseMatMulAttributes = (node) => parseInternalActivationAttributes(node.attributes); + createMatmulProgramMetadata = (hasBias, cacheHint) => ({ + name: "MatMul", + inputNames: hasBias ? ["A", "B", "Bias"] : ["A", "B"], + inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + cacheHint + }); + validateInputs4 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("MatMul requires 2 inputs."); + } + if (inputs[0].dims[inputs[0].dims.length - 1] !== inputs[1].dims[inputs[1].dims.length - 2]) { + throw new Error("shared dimension does not match."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64" || inputs[1].type !== "float32" && inputs[1].type !== "float64") { + throw new Error("inputs should be float type"); + } + if (inputs[0].type !== inputs[1].type) { + throw new Error("inputs types should match"); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts + function getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outShape) { + let unpackedACoordsSnippet = []; + let unpackedBCoordsSnippet = []; + const inAShape = inputs[0].dims; + const inBShape = inputs[1].dims; + const inARank = inAShape.length; + const inBRank = inBShape.length; + const outRank = outShape.length; + const rankADiff = outRank - inARank; + const rankBDiff = outRank - inBRank; + unpackedACoordsSnippet = inAShape.map((_s, i) => `coords.${allGlChannels[i + rankADiff]}`); + unpackedACoordsSnippet[inARank - 1] = "i*2"; + unpackedACoordsSnippet.join(", "); + unpackedBCoordsSnippet = inBShape.map((_s, i) => `coords.${allGlChannels[i + rankBDiff]}`); + unpackedBCoordsSnippet[inBRank - 2] = "i*2"; + unpackedBCoordsSnippet.join(", "); + const broadcastADims = BroadcastUtil.getBroadcastDims(inAShape, outShape); + const broadcastBDims = BroadcastUtil.getBroadcastDims(inBShape, outShape); + const coordsASnippet = broadcastADims.map((d) => `coords.${allGlChannels[d + rankADiff]} = 0;`).join("\n"); + const coordsBSnippet = broadcastBDims.map((d) => `coords.${allGlChannels[d + rankBDiff]} = 0;`).join("\n"); + const swapDimSnippet = `int lastDim = coords.${allGlChannels[outRank - 1]}; + coords.${allGlChannels[outRank - 1]} = coords.${allGlChannels[outRank - 2]}; + coords.${allGlChannels[outRank - 2]} = lastDim;`; + const getBcastSamplerMatmulSource = ` +vec4 getAAtOutCoordsMatmul(int i) { + ${coordsDataType} coords = getOutputCoords(); + ${swapDimSnippet} + ${coordsASnippet} + vec4 outputValue = getA(${unpackedACoordsSnippet}); + return outputValue; +} + +vec4 getBAtOutCoordsMatmul(int i) { + ${coordsDataType} coords = getOutputCoords(); + ${swapDimSnippet} + ${coordsBSnippet} + vec4 outputValue = getB(${unpackedBCoordsSnippet}); + return outputValue; +}`; + return getBcastSamplerMatmulSource; + } + function getA(allGlChannels, rank) { + let res = ""; + for (let i = 0; i < rank - 2; i++) { + res += `rc.${allGlChannels[i]}, `; + } + res += `rc.${allGlChannels[rank - 2]}, i*2`; + return res; + } + function getB(allGlChannels, rank) { + let res = ""; + for (let i = 0; i < rank - 2; i++) { + res += `rc.${allGlChannels[i]}, `; + } + res += `i*2, rc.${allGlChannels[rank - 1]}`; + return res; + } + var createPackedMatmulProgramMetadata, createPackedMatmulProgramInfo, createPackedMatmulProgramInfoLoader; + var init_matmul_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts"() { + "use strict"; + init_util(); + init_glsl_source(); + init_types(); + init_utils(); + init_fuse_utils(); + init_matmul(); + createPackedMatmulProgramMetadata = (hasBias, cacheHint) => ({ + name: "MatMul (packed)", + inputNames: hasBias ? ["A", "B", "Bias"] : ["A", "B"], + inputTypes: hasBias ? [2 /* packed */, 2 /* packed */, 2 /* packed */] : [2 /* packed */, 2 /* packed */], + cacheHint + }); + createPackedMatmulProgramInfo = (inferenceHandler, metadata, inputs, activationAttributes) => { + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += getBiasForMatmul();" : ""; + const aShape = inputs[0].dims; + const bShape = inputs[1].dims; + const outputShape = BroadcastUtil.calcShape(aShape, bShape, true); + const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims); + if (!outputShape) { + throw new Error("Can't use matmul on the given tensors"); + } + const sharedDim = aShape[aShape.length - 1]; + const sharedDimIndex = Math.ceil(sharedDim / 2); + const aRank = aShape.length; + const bRank = bShape.length; + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const coordsDataType = getCoordsDataType(outputShape.length); + const outRank = outputShape.length; + const allGlChannels = getGlChannels(); + const { activationFunction, applyActivation } = getActivationSnippet(activationAttributes); + const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, true)}` : ""; + const getBcastedSamplerForMatmulSnippet = isBroadcast ? `${getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outputShape)}` : ""; + const getSamplerAInLoopSnippet = isBroadcast ? "getAAtOutCoordsMatmul(i)" : `getA(${getA(allGlChannels, aRank)})`; + const getSamplerBInLoopSnippet = isBroadcast ? "getBAtOutCoordsMatmul(i)" : `getB(${getB(allGlChannels, bRank)})`; + const getOutputCoordsSnippet = isBroadcast ? "" : `${coordsDataType} rc = + getOutputCoords(); int lastDim = rc.${allGlChannels[outRank - 1]}; rc.${allGlChannels[outRank - 1]} = + rc.${allGlChannels[outRank - 2]}; rc.${allGlChannels[outRank - 2]} = lastDim; + `; + const shaderSource = ` + ${getBcastedSamplerForMatmulSnippet} + ${getBiasForMatmulSnippet} + ${activationFunction} + void main() { + ${getOutputCoordsSnippet} + + vec4 value = vec4(0); + for (int i = 0; i < ${sharedDimIndex}; i++) { + vec4 a = ${getSamplerAInLoopSnippet}; + vec4 b = ${getSamplerBInLoopSnippet}; + + value += (a.rrbb * b.rgrg); + value += (a.ggaa * b.baba); + } + ${processBias} + ${applyActivation} + ${glsl.output} = value; + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedMatmulProgramInfoLoader = (inferenceHandler, inputs, activationAttributes) => { + const metadata = createPackedMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey); + return { + ...metadata, + get: () => createPackedMatmulProgramInfo(inferenceHandler, metadata, inputs, activationAttributes) + }; + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/conv-pack.ts + var conv2DPacked; + var init_conv_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv-pack.ts"() { + "use strict"; + init_conv(); + init_im2col_pack(); + init_matmul_pack(); + conv2DPacked = (inferenceHandler, inputs, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); + const im2colOutput = inferenceHandler.run( + createPackedIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), + [inputs[0]] + ); + const kernelReshaped = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1] * kshape[2] * kshape[3]]); + const matmulInputs = inputs.length === 3 ? [kernelReshaped, im2colOutput, inputs[2]] : [kernelReshaped, im2colOutput]; + const matmulOutput = inferenceHandler.run( + createPackedMatmulProgramInfoLoader(inferenceHandler, matmulInputs, attributes), + matmulInputs + ); + const outputReshaped = inferenceHandler.reshapePacked(matmulOutput, outputShape); + return outputReshaped; + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/im2col.ts + var createIm2ColProgramMetadata, createIm2ColProgramInfo, createIm2ColProgramInfoLoader, calculateIm2ColDims; + var init_im2col = __esm({ + "web/lib/onnxjs/backends/webgl/ops/im2col.ts"() { + "use strict"; + init_types(); + createIm2ColProgramMetadata = (cacheHint) => ({ + name: "Im2Col", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint + }); + createIm2ColProgramInfo = (_inferenceHandler, metadata, x, w, outputShape, attributes) => { + const xshape = x.dims; + const wshape = w.dims; + const rank = outputShape.length; + const im2colDims = calculateIm2ColDims(xshape, wshape, outputShape, 4); + const shaderSource = ` + const int XC = ${xshape[1]}; + const int XH = ${xshape[2]}; + const int XW = ${xshape[3]}; + const int KH = ${attributes.kernelShape[0]}; + const int KW = ${attributes.kernelShape[1]}; + const int dilationH = ${attributes.dilations[0]}; + const int dilationW = ${attributes.dilations[1]}; + const int strideH = ${attributes.strides[0]}; + const int strideW = ${attributes.strides[1]}; + const int padH = ${attributes.pads[0]}; + const int padW = ${attributes.pads[1]}; + const int KHKW = KH*KW; + const int XCKHKW = XC * KHKW; + const int outputChannels = 4; + vec4 process(int indices[${rank}]) { + int b = indices[0]; // batch size + int oh = indices[1] * strideH - padH; //output height + int ow = indices[2] * strideW - padW; //output width + int p = indices[3] * outputChannels; //patch + vec4 value = vec4(0.0); + for(int i=0; i < outputChannels; ++i) { + if(p < XCKHKW) { + int patchC = p / KHKW; + int patchH = (p - patchC*KHKW) / KW; + int patchW = (p - patchC*KHKW) - patchH * KW; + int xh2 = oh + patchH * dilationH; + int xw2 = ow + patchW * dilationW; + int x[${xshape.length}]; + x[0] = b; + x[1] = patchC; + x[2] = xh2; + x[3] = xw2; + if(xh2 >= 0 && + xh2 < XH && + xw2 >= 0 && + xw2 < XW) { + value[i] = _X(x); + } + } + ++p; + } + return value; + } + `; + return { + ...metadata, + output: { dims: im2colDims, type: x.type, textureType: 4 /* packedLastDimension */ }, + shaderSource + }; + }; + createIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => { + const metadata = createIm2ColProgramMetadata(attributes.cacheKey); + return { + ...metadata, + get: () => createIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) + }; + }; + calculateIm2ColDims = (inputShape, kernelShape, outputShape, channels = 4) => [ + outputShape[0], + outputShape[2], + outputShape[3], + Math.ceil(inputShape[1] * kernelShape[2] * kernelShape[3] / channels) + ]; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/dot-product.ts + var createDotProductProgramMetadata, createDotProductProgramInfo, createDotProductProgramInfoLoader; + var init_dot_product = __esm({ + "web/lib/onnxjs/backends/webgl/ops/dot-product.ts"() { + "use strict"; + init_util(); + init_glsl_source(); + init_types(); + init_fuse_utils(); + init_im2col(); + createDotProductProgramMetadata = (hasBias, attributes) => ({ + name: "ConvDotProduct", + inputNames: hasBias ? ["Im2Col", "K", "B"] : ["Im2Col", "K"], + inputTypes: hasBias ? [0 /* unpacked */, 4 /* packedLastDimension */, 0 /* unpacked */] : [0 /* unpacked */, 4 /* packedLastDimension */], + cacheKey: attributes.activationCacheKey + }); + createDotProductProgramInfo = (inferenceHandler, metadata, inputs, outputShape, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const adjustedKernelShape = [kshape[0], Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4)]; + const im2colShape = calculateIm2ColDims(xshape, kshape, outputShape); + const [kWidth, kHeight] = inferenceHandler.calculateTextureWidthAndHeight( + adjustedKernelShape, + 4 /* packedLastDimension */ + ); + const im2colStrides = ShapeUtil.computeStrides(im2colShape); + const [im2colWidth, im2colHeight] = inferenceHandler.calculateTextureWidthAndHeight( + im2colShape, + 4 /* packedLastDimension */ + ); + const rank = outputShape.length; + const initValue = inputs.length < 3 ? "0.0" : "_B(b)"; + const sharedDim = Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4); + const { activationFunction, applyActivation } = getActivationSnippet(attributes); + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` +${activationFunction} +float process(int indices[${rank}]) { + int b[1]; + b[0] = indices[1]; + int im2col[4]; + im2col[0] = indices[0]; + im2col[1] = indices[2]; + im2col[2] = indices[3]; + int im2colOffset = im2col[0] * ${im2colStrides[0]} + im2col[1] * ${im2colStrides[1]} + im2col[2] * ${im2colStrides[2]}; + int kernelOffset = indices[1] * ${adjustedKernelShape[1]}; + float value = ${initValue}; + for (int i = 0; i < ${sharedDim}; ++i) { + vec2 im2colCoords = offsetToCoords(im2colOffset, ${im2colWidth}, ${im2colHeight}); + vec2 kernelCoords = offsetToCoords(kernelOffset, ${kWidth}, ${kHeight}); + value += dot(${glsl.texture2D}(Im2Col, im2colCoords), ${glsl.texture2D}(K, kernelCoords)); + ++im2colOffset; + ++kernelOffset; + } + ${applyActivation} + return value; +}`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createDotProductProgramInfoLoader = (inferenceHandler, inputs, outputShape, attributes) => { + const metadata = createDotProductProgramMetadata(inputs.length > 2, attributes); + return { + ...metadata, + get: () => createDotProductProgramInfo(inferenceHandler, metadata, inputs, outputShape, attributes) + }; + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/conv.ts + var calculateOutputShape, conv, conv2d, conv2DUnpackedPointwise, conv2DUnpacked, getAdjustedConvAttributes, parseConvAttributes, validateInputs5; + var init_conv = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_conv_grouped(); + init_conv_pack(); + init_dot_product(); + init_fuse_utils(); + init_im2col(); + init_matmul(); + calculateOutputShape = (inputShape, kernelShape, dilations, adjustPads, strides) => { + const batchSize = inputShape[0]; + const inputSpatialShape = inputShape.slice(2); + const spatialRank = inputSpatialShape.length; + const outChannels = kernelShape[0]; + const kernelSpatialShape = kernelShape.slice(2); + const dilatedKernelShape = kernelSpatialShape.map((v, i) => v + (v - 1) * (dilations[i] - 1)); + const inputSpatialShapeWithPad = inputSpatialShape.map((v, i) => v + adjustPads[i] + adjustPads[i + spatialRank]); + const outputSpatialShape = inputSpatialShapeWithPad.map( + (v, i) => Math.floor((v - dilatedKernelShape[i] + strides[i]) / strides[i]) + ); + const outputShape = [batchSize, outChannels].concat(...outputSpatialShape); + return outputShape; + }; + conv = (inferenceHandler, inputs, attributes) => { + validateInputs5(inputs, attributes); + return conv2d(inferenceHandler, inputs, attributes); + }; + conv2d = (inferenceHandler, inputs, attributes) => { + const adjustedAttributes = getAdjustedConvAttributes(attributes, inputs); + const packMode = inferenceHandler.session.pack; + const isPointwise = adjustedAttributes.kernelShape[0] === 1 && adjustedAttributes.kernelShape[1] === 1; + if (adjustedAttributes.group > 1) { + const result = inferenceHandler.run( + createUnpackedGroupedConvProgramInfoLoader(inferenceHandler, inputs, adjustedAttributes), + inputs + ); + return [result]; + } else if (isPointwise && packMode) { + return [conv2DUnpackedPointwise(inferenceHandler, inputs, adjustedAttributes)]; + } else if (packMode && inputs[0].dims.length === 4 && inputs[0].dims[0] === 1 && !isPointwise) { + return [conv2DPacked(inferenceHandler, inputs, adjustedAttributes)]; + } else { + return [conv2DUnpacked(inferenceHandler, inputs, adjustedAttributes)]; + } + }; + conv2DUnpackedPointwise = (inferenceHandler, inputs, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); + const reshapedX = inferenceHandler.reshapeUnpacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]); + const reshapedK = inferenceHandler.reshapeUnpacked(inputs[1], [kshape[0], kshape[1]]); + const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX]; + const matmulOutput = inferenceHandler.run(createMatmulProgramInfoLoader(matmulInputs, attributes), matmulInputs); + return inferenceHandler.reshapeUnpacked(matmulOutput, outputShape); + }; + conv2DUnpacked = (inferenceHandler, inputs, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); + const xIm2Col = inferenceHandler.run( + createIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), + [inputs[0]] + ); + const dotProductInputs = inputs.length === 3 ? [xIm2Col, inputs[1], inputs[2]] : [xIm2Col, inputs[1]]; + const output = inferenceHandler.run( + createDotProductProgramInfoLoader(inferenceHandler, inputs, outputShape, attributes), + dotProductInputs + ); + return output; + }; + getAdjustedConvAttributes = (attributes, inputs) => { + const kernelShape = attributes.kernelShape.slice(); + if (attributes.kernelShape.length === 0) { + for (let i = 2; i < inputs[1].dims.length; ++i) { + kernelShape.push(inputs[1].dims[i]); + } + } + const pads = attributes.pads.slice(); + PoolConvUtil.adjustPadsBasedOnAutoPad( + inputs[0].dims, + attributes.strides, + attributes.dilations, + kernelShape, + pads, + attributes.autoPad + ); + const newAttributes = Object.assign({}, attributes); + Object.assign(newAttributes, { kernelShape, pads, cacheKey: attributes.cacheKey }); + return newAttributes; + }; + parseConvAttributes = (node) => { + const attributes = node.attributes; + const activationAttributes = parseInternalActivationAttributes(attributes); + const autoPad = attributes.getString("auto_pad", "NOTSET"); + const dilations = attributes.getInts("dilations", [1, 1]); + const group = attributes.getInt("group", 1); + const kernelShape = attributes.getInts("kernel_shape", []); + const pads = attributes.getInts("pads", [0, 0, 0, 0]); + const strides = attributes.getInts("strides", [1, 1]); + return createAttributeWithCacheKey({ + autoPad, + dilations, + group, + kernelShape, + pads, + strides, + ...activationAttributes + }); + }; + validateInputs5 = (inputs, attributes) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Conv requires 2 or 3 inputs"); + } + if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) { + throw new Error("currently only support 2-dimensional conv"); + } + const dataChannel = inputs[0].dims[1]; + const filterInChannel = inputs[1].dims[1] * attributes.group; + if (dataChannel !== filterInChannel) { + throw new Error("FILTER_IN_CHANNEL should be equal to DATA_CHANNEL"); + } + if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[1].dims[0] !== inputs[2].dims[0])) { + throw new Error("invalid bias"); + } + const spatialRank = inputs[0].dims.length - 2; + if (attributes.dilations.length !== spatialRank) { + throw new Error(`dilations should be ${spatialRank}D`); + } + if (attributes.strides.length !== spatialRank) { + throw new Error(`strides should be ${spatialRank}D`); + } + if (attributes.pads.length !== spatialRank * 2) { + throw new Error(`pads should be ${spatialRank * 2}D`); + } + if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) { + throw new Error("invalid kernel shape"); + } + if (inputs[0].type !== "float32" || inputs[1].type !== "float32") { + throw new Error("Conv input(X,W) should be float tensor"); + } + if (inputs.length === 3 && inputs[2].type !== "float32") { + throw new Error("Conv input(bias) should be float tensor"); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts + var computeTotalPad, distributePadding, calculateOutputShapeAndPads, convTranspose, convTranspose2d, createConvTransposeProgramMetadata, createUnpackedConvTransposeProgramInfo, createUnpackedConvTransposeProgramInfoLoader, convTranspose2DUnpacked, getAdjustedConvTransposeAttributes, parseConvTransposeAttributes, validateInputs6; + var init_conv_transpose = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_glsl_source(); + init_types(); + init_fuse_utils(); + computeTotalPad = (inDim, stride, adj, kernel, dilation, outSize) => (inDim - 1) * stride + adj + (kernel - 1) * dilation + 1 - outSize; + distributePadding = (totalPad, autoPad, pads, head, tail) => { + const smallPad = Math.floor(totalPad / 2); + if (autoPad === "SAME_UPPER") { + pads[head] = smallPad; + pads[tail] = totalPad - smallPad; + } else if (autoPad === "SAME_LOWER") { + pads[head] = totalPad - smallPad; + pads[tail] = smallPad; + } + }; + calculateOutputShapeAndPads = (inputShape, kernelShape, dilations, autoPad, pads, strides, outputPadding, outputShape) => { + const spatialRank = inputShape.length - 2; + const updateShape = outputShape.length === 0; + for (let i = 0; i < spatialRank; ++i) { + const outSize = updateShape ? inputShape[i + 2] * strides[i] : outputShape[i]; + const totalPad = computeTotalPad(inputShape[i + 2], strides[i], pads[i], kernelShape[i], dilations[i], outSize); + distributePadding(totalPad, autoPad, pads, i, i + spatialRank); + if (updateShape) { + outputShape.push( + strides[i] * (inputShape[i + 2] - 1) + outputPadding[i] + (kernelShape[i] - 1) * dilations[i] + 1 - pads[i] - pads[i + spatialRank] + ); + } + } + }; + convTranspose = (inferenceHandler, inputs, attributes) => { + validateInputs6(inputs, attributes); + return convTranspose2d(inferenceHandler, inputs, attributes); + }; + convTranspose2d = (inferenceHandler, inputs, attributes) => { + const adjustedAttributes = getAdjustedConvTransposeAttributes(attributes, inputs); + return [convTranspose2DUnpacked(inferenceHandler, inputs, adjustedAttributes)]; + }; + createConvTransposeProgramMetadata = (hasBias, cacheHint) => ({ + name: "ConvTranspose", + inputNames: hasBias ? ["X", "W", "B"] : ["X", "W"], + inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + cacheHint + }); + createUnpackedConvTransposeProgramInfo = (inferenceHandler, inputs, metadata, attributes) => { + const hasBias = inputs.length > 2; + const valueInit = hasBias ? "getB(output_channel)" : "0.0"; + const xShape = inputs[0].dims; + const wShape = inputs[1].dims; + const outputChannelsPerGroup = wShape[1]; + const inputChannelsPerGroup = wShape[0] / attributes.group; + const outputShape = [inputs[0].dims[0], inputs[1].dims[1] * attributes.group, ...attributes.outputShape]; + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const { activationFunction, applyActivation } = getActivationSnippet(attributes); + const shaderSource = ` + const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]}); + const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]}); + ${activationFunction} + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + int output_channel = coords.y; + + ivec2 loc = coords.zw + pads; + + int group_id = output_channel / ${outputChannelsPerGroup}; + int wOutChannel = output_channel - group_id * ${outputChannelsPerGroup}; + + float value = ${valueInit}; + for (int inChannelOffset = 0; inChannelOffset < ${inputChannelsPerGroup}; inChannelOffset++) { + int input_channel = group_id * ${inputChannelsPerGroup} + inChannelOffset; + for (int wWOff = 0; wWOff < ${wShape[2]}; wWOff++) { + for (int wHOff = 0; wHOff < ${wShape[3]}; wHOff++) { + ivec2 wOff = ivec2(wWOff * ${attributes.dilations[0]}, wHOff * ${attributes.dilations[1]}); + ivec2 wLoc = loc - wOff; + ivec2 wLocIn = wLoc / strides; + if ( + wLocIn * strides == wLoc && + wLocIn.x >= 0 && wLocIn.x < ${xShape[2]} && + wLocIn.y >= 0 && wLocIn.y < ${xShape[3]} + ) { + float xVal = getX(batch, input_channel, wLocIn.y, wLocIn.x); + float wVal = getW(input_channel, wOutChannel, wHOff, wWOff); + value += xVal * wVal; + } + } + } + } + ${applyActivation} + ${glsl.output} = vec4(value, .0, .0, .0); + } +`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource, + hasMain: true + }; + }; + createUnpackedConvTransposeProgramInfoLoader = (inferenceHandler, inputs, attributes) => { + const metadata = createConvTransposeProgramMetadata(inputs.length > 2, attributes.cacheKey); + return { + ...metadata, + get: () => createUnpackedConvTransposeProgramInfo(inferenceHandler, inputs, metadata, attributes) + }; + }; + convTranspose2DUnpacked = (inferenceHandler, inputs, attributes) => { + const result = inferenceHandler.run( + createUnpackedConvTransposeProgramInfoLoader(inferenceHandler, inputs, attributes), + inputs + ); + return result; + }; + getAdjustedConvTransposeAttributes = (attributes, inputs) => { + const kernelShape = attributes.kernelShape.slice(); + if (attributes.kernelShape.length === 0) { + for (let i = 2; i < inputs[1].dims.length; ++i) { + kernelShape.push(inputs[1].dims[i]); + } + } + const pads = attributes.pads.slice(); + const outputShape = attributes.outputShape.slice(); + const inputShape = inputs[0].dims; + calculateOutputShapeAndPads( + inputShape, + kernelShape, + attributes.dilations, + attributes.autoPad, + pads, + attributes.strides, + attributes.outputPadding, + outputShape + ); + const newAttributes = Object.assign({}, attributes); + Object.assign(newAttributes, { kernelShape, pads, outputShape, cacheKey: attributes.cacheKey }); + return newAttributes; + }; + parseConvTransposeAttributes = (node) => { + const attributes = node.attributes; + const activationAttributes = parseInternalActivationAttributes(attributes); + const autoPad = attributes.getString("auto_pad", "NOTSET"); + const dilations = attributes.getInts("dilations", [1, 1]); + const group = attributes.getInt("group", 1); + const kernelShape = attributes.getInts("kernel_shape", []); + const outputPadding = attributes.getInts("output_padding", [0, 0]); + const outputShape = attributes.getInts("output_shape", []); + const pads = attributes.getInts("pads", [0, 0, 0, 0]); + const strides = attributes.getInts("strides", [1, 1]); + return createAttributeWithCacheKey({ + autoPad, + dilations, + group, + kernelShape, + outputPadding, + outputShape, + pads, + strides, + ...activationAttributes + }); + }; + validateInputs6 = (inputs, attributes) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Conv requires 2 or 3 inputs"); + } + if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) { + throw new Error("currently only support 2-dimensional conv"); + } + const dataChannel = inputs[0].dims[1]; + const filterInChannel = inputs[1].dims[0]; + if (dataChannel !== filterInChannel) { + throw new Error("FILTER_IN_CHANNEL should be equal to DATA_CHANNEL"); + } + const featureMaps = inputs[1].dims[1] * attributes.group; + if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[2].dims[0] !== featureMaps)) { + throw new Error("invalid bias"); + } + const spatialRank = inputs[0].dims.length - 2; + if (attributes.dilations.length !== spatialRank) { + throw new Error(`dilations should be ${spatialRank}D`); + } + if (attributes.strides.length !== spatialRank) { + throw new Error(`strides should be ${spatialRank}D`); + } + if (attributes.pads.length !== spatialRank * 2) { + throw new Error(`pads should be ${spatialRank * 2}D`); + } + if (attributes.outputPadding.length !== spatialRank) { + throw new Error(`output_padding should be ${spatialRank}D`); + } + if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) { + throw new Error("invalid kernel shape"); + } + if (attributes.outputShape.length !== 0 && attributes.outputShape.length !== inputs[0].dims.length - 2) { + throw new Error("invalid output shape"); + } + if (inputs[0].type !== "float32" || inputs[1].type !== "float32") { + throw new Error("ConvTranspose input(X,W) should be float tensor"); + } + if (inputs.length === 3 && inputs[2].type !== "float32") { + throw new Error("ConvTranspose input(bias) should be float tensor"); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/transpose.ts + var transposeProgramMetadata, transpose, parseTransposeAttributes, createTransposeProgramInfo, getAdjustedPerm, getOutputShape, getPermFunctionBody, validateInputs7; + var init_transpose = __esm({ + "web/lib/onnxjs/backends/webgl/ops/transpose.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + transposeProgramMetadata = { + name: "Transpose", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + transpose = (inferenceHandler, inputs, attributes) => { + validateInputs7(inputs); + const output = inferenceHandler.run( + { + ...transposeProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createTransposeProgramInfo(inferenceHandler, inputs[0], attributes.perm) + }, + inputs + ); + return [output]; + }; + parseTransposeAttributes = (node) => createAttributeWithCacheKey({ perm: node.attributes.getInts("perm", []) }); + createTransposeProgramInfo = (_inferenceHandler, input, perm) => { + const inputShape = input.dims; + perm = getAdjustedPerm(inputShape, perm); + const unpackedOutputShape = getOutputShape(inputShape, perm); + const rank = inputShape.length; + const shaderSource = ` + ${getPermFunctionBody("perm", perm, rank)} + float process(int indices[${rank}]) { + int a[${rank}]; + perm(a, indices); + return _A(a); + }`; + return { + ...transposeProgramMetadata, + output: { dims: unpackedOutputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + getAdjustedPerm = (inputShape, perm) => { + if (perm && perm.length !== inputShape.length) { + perm = [...inputShape.keys()].reverse(); + } + return perm; + }; + getOutputShape = (inputShape, perm) => { + perm = getAdjustedPerm(inputShape, perm); + return ShapeUtil.sortBasedOnPerm(inputShape, perm); + }; + getPermFunctionBody = (name2, perm, rank) => { + const reverseFunc = []; + reverseFunc.push(`void ${name2}(out int a[${rank}], int src[${rank}]) {`); + for (let i = 0; i < rank; ++i) { + reverseFunc.push(` a[${perm[i]}]=src[${i}];`); + } + reverseFunc.push(" }"); + return reverseFunc.join("\n"); + }; + validateInputs7 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Transpose requires 1 input."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("input should be float tensor"); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts + var depthToSpace, parseDepthToSpaceAttributes, validateInputs8; + var init_depth_to_space = __esm({ + "web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts"() { + "use strict"; + init_transpose(); + depthToSpace = (inferenceHandler, inputs, attributes) => { + validateInputs8(inputs); + const blocksize = attributes.blocksize; + const blocksizeSqr = blocksize * blocksize; + const transposePerm = attributes.mode === "DCR" ? [0, 3, 4, 1, 5, 2] : [0, 1, 4, 2, 5, 3]; + const firstReshapeShape = attributes.mode === "DCR" ? [ + inputs[0].dims[0], + blocksize, + blocksize, + inputs[0].dims[1] / blocksizeSqr, + inputs[0].dims[2], + inputs[0].dims[3] + ] : [ + inputs[0].dims[0], + inputs[0].dims[1] / blocksizeSqr, + blocksize, + blocksize, + inputs[0].dims[2], + inputs[0].dims[3] + ]; + const firstReshapedTensor = inferenceHandler.reshapeUnpacked(inputs[0], firstReshapeShape); + const transposeAttributes = { perm: transposePerm, cacheKey: `${transposePerm}` }; + const [transposeOutput] = transpose(inferenceHandler, [firstReshapedTensor], transposeAttributes); + const secondReshapeShape = [ + inputs[0].dims[0], + inputs[0].dims[1] / blocksizeSqr, + inputs[0].dims[2] * blocksize, + inputs[0].dims[3] * blocksize + ]; + const result = inferenceHandler.reshapeUnpacked(transposeOutput, secondReshapeShape); + return [result]; + }; + parseDepthToSpaceAttributes = (node) => { + const blocksize = node.attributes.getInt("blocksize"); + if (blocksize < 1) { + throw new Error(`blocksize must be >= 1, but got : ${blocksize} for DepthToSpace`); + } + const mode = node.attributes.getString("mode", "DCR"); + if (mode !== "DCR" && mode !== "CRD") { + throw new Error(`unrecognized mode: ${mode} for DepthToSpace`); + } + return { mode, blocksize }; + }; + validateInputs8 = (inputs) => { + if (inputs.length !== 1) { + throw new Error(`DepthToSpace expect 1 inputs, but got ${inputs.length}`); + } + if (inputs[0].type === "string" || inputs[0].dims.length !== 4) { + throw new TypeError("DepthToSpace input should be a 4-D numeric tensor"); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/flatten.ts + var flatten, parseFlattenAttributes, validateInputs9; + var init_flatten = __esm({ + "web/lib/onnxjs/backends/webgl/ops/flatten.ts"() { + "use strict"; + init_util(); + flatten = (inferenceHandler, inputs, axis) => { + validateInputs9(inputs, axis); + const outputDims = ShapeUtil.flattenShape(inputs[0].dims, axis); + return [inferenceHandler.reshapeUnpacked(inputs[0], outputDims)]; + }; + parseFlattenAttributes = (node) => node.attributes.getInt("axis", 1); + validateInputs9 = (inputs, axis) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Flatten requires 1 input."); + } + const r = inputs[0].dims.length; + if (r === 0) { + throw new Error("scalar tensor is not supported."); + } + if (axis < -r || axis > r) { + throw new Error("Invalid axis"); + } + if (inputs[0].type === "string") { + throw new Error("string tensor is not supported."); + } + }; + } + }); + + // web/lib/onnxjs/operators.ts + var NUMBER_TYPES; + var init_operators = __esm({ + "web/lib/onnxjs/operators.ts"() { + "use strict"; + NUMBER_TYPES = [ + "float32", + "float64", + "int32", + "int16", + "int8", + "uint16", + "uint32", + "uint8" + ]; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/gather.ts + var gather, parseGatherAttributes, gatherProgramMetadata, createGatherProgramInfo, createGatherProgramInfoLoader, validateInputs10; + var init_gather = __esm({ + "web/lib/onnxjs/backends/webgl/ops/gather.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_operators(); + init_util(); + init_types(); + gather = (inferenceHandler, inputs, attributes) => { + validateInputs10(inputs, attributes.axis); + const output = inferenceHandler.run(createGatherProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); + return [output]; + }; + parseGatherAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", 0) }); + gatherProgramMetadata = { + name: "Gather", + inputNames: ["A", "B"], + inputTypes: [0 /* unpacked */, 0 /* unpacked */] + }; + createGatherProgramInfo = (_handler, metadata, inputs, axis) => { + const inputShape = inputs[0].dims.slice(); + const indexDataShape = inputs[1].dims.slice(); + const outputShape = new Array(inputShape.length + indexDataShape.length - 1); + axis = ShapeUtil.normalizeAxis(axis, inputShape.length); + const indexCopyOps = []; + for (let i = 0; i < outputShape.length; i++) { + if (i < axis) { + outputShape[i] = inputShape[i]; + indexCopyOps.push(`inputIdx[${i}] = outputIdx[${i}];`); + } else { + if (i < axis + indexDataShape.length) { + outputShape[i] = indexDataShape[i - axis]; + indexCopyOps.push(`indexDataIdx[${i - axis}] = outputIdx[${i}];`); + } else { + outputShape[i] = inputShape[i - indexDataShape.length + 1]; + indexCopyOps.push(`inputIdx[${i - indexDataShape.length + 1}] = outputIdx[${i}];`); + } + } + } + const orank = outputShape.length || 1; + const irank = inputShape.length; + const iDrank = indexDataShape.length || 1; + const shaderSource = ` + float process(int outputIdx[${orank}]) { + int inputIdx[${irank}]; + int indexDataIdx[${iDrank}]; + indexDataIdx[0] = 0; + ${indexCopyOps.join("\n ")} + int idx = int(_B(indexDataIdx)); + inputIdx[${axis}] = idx < 0 ? idx + ${inputShape[axis]} : idx; + return _A(inputIdx); + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createGatherProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = { ...gatherProgramMetadata, cacheHint: attributes.cacheKey }; + return { ...metadata, get: () => createGatherProgramInfo(handler, metadata, inputs, attributes.axis) }; + }; + validateInputs10 = (inputs, axis) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Gather requires 2 inputs."); + } + const tensorRank = inputs[0].dims.length; + if (tensorRank < 1) { + throw new Error("Invalid input shape."); + } + if (axis < -tensorRank || axis > tensorRank - 1) { + throw new Error("Invalid axis."); + } + if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { + throw new Error("Invaid input type."); + } + if (inputs[1].type !== "int32" && inputs[1].type !== "int16") { + throw new Error("Invaid input type."); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/gemm.ts + var gemm, parseGemmAttributes, parseGemmAttributesV7, parseGemmAttributesV11, createGemmProgramInfoLoader, createGemmProgramInfo, validateInputs11; + var init_gemm = __esm({ + "web/lib/onnxjs/backends/webgl/ops/gemm.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + gemm = (inferenceHandler, inputs, attributes) => { + validateInputs11(inputs, attributes); + const output = inferenceHandler.run(createGemmProgramInfoLoader(inputs, attributes), inputs); + return [output]; + }; + parseGemmAttributes = (node, isOptionalC) => { + const transA = node.attributes.getInt("transA", 0) !== 0; + const transB = node.attributes.getInt("transB", 0) !== 0; + const alpha = node.attributes.getFloat("alpha", 1); + const beta = node.attributes.getFloat("beta", 1); + return createAttributeWithCacheKey({ transA, transB, alpha, beta, isOptionalC }); + }; + parseGemmAttributesV7 = (node) => parseGemmAttributes(node, false); + parseGemmAttributesV11 = (node) => parseGemmAttributes(node, true); + createGemmProgramInfoLoader = (inputs, attributes) => { + const metadata = { + name: "Gemm", + inputNames: inputs.length === 3 ? ["A", "B", "C"] : ["A", "B"], + inputTypes: inputs.length === 3 ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + key: attributes.cacheKey + }; + return { ...metadata, get: () => createGemmProgramInfo(metadata, inputs, attributes) }; + }; + createGemmProgramInfo = (metadata, inputs, attributes) => { + const aShape = inputs[0].dims.slice(); + const bShape = inputs[1].dims.slice(); + const [M, N] = GemmUtil.getShapeOfGemmResult( + aShape, + attributes.transA, + bShape, + attributes.transB, + inputs.length === 3 ? inputs[2].dims : void 0 + ); + const outputShape = [M, N]; + if (!outputShape) { + throw new Error("Can't use gemm on the given tensors"); + } + let sharedDim = aShape[aShape.length - 1]; + let line = ""; + if (attributes.transA) { + sharedDim = aShape[0]; + } + if (attributes.transA && attributes.transB) { + line = "value += _A_T(a) * _B_T(b);"; + } else if (attributes.transA && !attributes.transB) { + line = "value += _A_T(a) * _B(b);"; + } else if (!attributes.transA && attributes.transB) { + line = "value += _A(a) * _B_T(b);"; + } else if (!attributes.transA && !attributes.transB) { + line = "value += _A(a) * _B(b);"; + } + const rank = outputShape.length; + const declareC = inputs.length === 3 ? `int c[${inputs[2].dims.length}];` : ""; + const broadcastC = inputs.length === 3 ? "bcastIndices_C(indices, c);" : ""; + const calculateC = inputs.length === 3 ? "value += beta * _C(c);" : ""; + const shaderSource = ` + float process(int indices[${rank}]) { + int a[${rank}]; + int b[${rank}]; + ${declareC} + + copyVec(indices, a); + copyVec(indices, b); + ${broadcastC} + + float value = 0.0; + for (int k=0; k<${sharedDim}; ++k) { + a[${rank - 1}] = k; + b[${rank - 2}] = k; + ${line} + } + + value = value * alpha; + ${calculateC} + return value; + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + variables: [ + { name: "alpha", type: "float", data: attributes.alpha }, + { name: "beta", type: "float", data: attributes.beta } + ], + shaderSource + }; + }; + validateInputs11 = (inputs, attributes) => { + if (!inputs) { + throw new Error("Input is missing"); + } + if (attributes.isOptionalC && (inputs.length < 2 || inputs.length > 3)) { + throw new Error("Invaid input shape."); + } + if (!attributes.isOptionalC && inputs.length !== 3) { + throw new Error("Gemm requires 3 inputs"); + } + if (inputs.length === 3 && inputs[2].dims.length !== 1 && inputs[2].dims.length !== 2) { + throw new Error("Invalid input shape of C"); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64" || inputs[1].type !== "float32" && inputs[1].type !== "float64" || inputs.length === 3 && inputs[2].type !== "float32" && inputs[2].type !== "float64") { + throw new Error("Invalid input type."); + } + if (inputs[0].type !== inputs[1].type || inputs.length === 3 && inputs[0].type !== inputs[2].type) { + throw new Error("Input types are mismatched"); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/image-scaler.ts + var imageScaler, parseImageScalerAttributes, imageScalerProgramMetadata, createImageScalerProgramInfo, createImageScalerProgramInfoLoader, createGetBiasMethod, validateInputs12; + var init_image_scaler = __esm({ + "web/lib/onnxjs/backends/webgl/ops/image-scaler.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_types(); + imageScaler = (inferenceHandler, inputs, attributes) => { + validateInputs12(inputs); + const output = inferenceHandler.run(createImageScalerProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); + return [output]; + }; + parseImageScalerAttributes = (node) => { + const scale = node.attributes.getFloat("scale"); + const bias = node.attributes.getFloats("bias"); + return createAttributeWithCacheKey({ scale, bias }); + }; + imageScalerProgramMetadata = { + name: "ImageScaler", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + createImageScalerProgramInfo = (_handler, metadata, inputs, attributes) => { + const outputShape = inputs[0].dims.slice(); + const rank = outputShape.length; + const getBiasMethod = createGetBiasMethod(attributes.bias.length); + const shaderSource = ` + ${getBiasMethod} + float process(int indices[${rank}]) { + return _X(indices) * scale + getBias(bias, indices[1]); + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + variables: [ + { name: "bias", type: "float", arrayLength: attributes.bias.length, data: attributes.bias }, + { name: "scale", type: "float", data: attributes.scale } + ], + shaderSource + }; + }; + createImageScalerProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = { ...imageScalerProgramMetadata, cacheHint: attributes.cacheKey }; + return { ...metadata, get: () => createImageScalerProgramInfo(handler, metadata, inputs, attributes) }; + }; + createGetBiasMethod = (numChannels) => { + const codeLines = [`float getBias(float bias[${numChannels}], int channel) {`]; + for (let i = 0; i < numChannels; ++i) { + if (i === 0) { + codeLines.push(` if (channel == ${i}) { return bias[${i}]; }`); + } else if (i === numChannels - 1) { + codeLines.push(` else { return bias[${i}]; }`); + } else { + codeLines.push(` else if (channel == ${i}) { return bias[${i}]; }`); + } + } + codeLines.push(" }"); + return codeLines.join("\n"); + }; + validateInputs12 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("ImageScaler requires 1 input."); + } + if (inputs[0].dims.length !== 4) { + throw new Error("Invalid input shape."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts + var instanceNormalization, parseInstanceNormalizationAttributes, meanAndVarianceProgramMetadata, createMeanAndVarianceProgramInfo, createMeanAndVarianceProgramInfoLoader, computeOutputProgramMetadata, createComputeOutputProgramInfo, createComputeOutputProgramInfoLoader, validateInputs13; + var init_instance_normalization = __esm({ + "web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + instanceNormalization = (inferenceHandler, inputs, epsilon) => { + validateInputs13(inputs); + const meanAndVariance = inferenceHandler.run(createMeanAndVarianceProgramInfoLoader(inputs[0]), inputs); + const output = inferenceHandler.run( + createComputeOutputProgramInfoLoader(inferenceHandler, inputs[0], epsilon, meanAndVariance.dims), + [inputs[0], meanAndVariance, inputs[1], inputs[2]] + ); + return [output]; + }; + parseInstanceNormalizationAttributes = (node) => node.attributes.getFloat("epsilon", 1e-5); + meanAndVarianceProgramMetadata = { + name: "InstanceNormalization_MeanAndVariance", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + createMeanAndVarianceProgramInfo = (metadata, input) => { + const xDims = input.dims.slice(); + const channel = xDims[1]; + const channelSize = xDims[2] * xDims[3]; + const outputShape = [xDims[0], channel]; + const shaderSource = ` + vec4 process(int[2] indices) { + vec4 v = vec4(0.0); + int a[4]; + a[0] = indices[0]; + a[1] = indices[1]; + float temp = 0.0; + for(int a2=0; a2<${xDims[2]}; a2++) { + a[2] = a2; + for(int a3=0; a3<${xDims[3]}; a3++) { + a[3] = a3; + float x = _X(a); + temp += x; + } + } + float mean = temp / float(${channelSize}); + temp = 0.0; + for(int a2=0; a2<${xDims[2]}; a2++) { + a[2] = a2; + for(int a3=0; a3<${xDims[3]}; a3++) { + a[3] = a3; + float x = _X(a); + temp += (x - mean) * (x - mean); + } + } + v.r = mean; + v.g = temp / float(${channelSize}); + + return v; + }`; + return { + ...metadata, + output: { dims: outputShape, type: input.type, textureType: 4 /* packedLastDimension */ }, + shaderSource + }; + }; + createMeanAndVarianceProgramInfoLoader = (input) => ({ + ...meanAndVarianceProgramMetadata, + get: () => createMeanAndVarianceProgramInfo(meanAndVarianceProgramMetadata, input) + }); + computeOutputProgramMetadata = { + name: "InstanceNormalization_ComputeOutput", + inputNames: ["X", "MeanAndVariance", "Scale", "B"], + inputTypes: [0 /* unpacked */, 4 /* packedLastDimension */, 0 /* unpacked */, 0 /* unpacked */] + }; + createComputeOutputProgramInfo = (inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight( + meanAndVarianceShape, + 4 /* packedLastDimension */ + ); + const [meanAndVarianceWidth, meanAndVarianceHeight] = [textureWidth / 4, textureHeight]; + const shaderSource = ` + vec4 get_MeanAndVariance(int[2] mv) { + int offset = indicesToOffset_MeanAndVariance(mv); + vec2 coords = offsetToCoords(offset, ${meanAndVarianceWidth}, ${meanAndVarianceHeight}); + return ${glsl.texture2D}(MeanAndVariance, coords); + } + + float process(int[4] indices) { + int mv[2]; + mv[0] = indices[0]; + mv[1] = indices[1]; + vec4 mean_and_variance = get_MeanAndVariance(mv); + float mean = mean_and_variance.r; + float variance = mean_and_variance.g; + + int sb[1]; + sb[0] = indices[1]; + float scale = _Scale(sb); + float b = _B(sb); + + return scale * (_X(indices) - mean) / sqrt(variance + epsilon) + b; + }`; + return { + ...metadata, + output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, + variables: [{ name: "epsilon", type: "float", data: epsilon }], + shaderSource + }; + }; + createComputeOutputProgramInfoLoader = (inferenceHandler, input, epsilon, meanAndVarianceShape) => { + const metadata = { ...computeOutputProgramMetadata, cacheHint: `${epsilon}` }; + return { + ...metadata, + get: () => createComputeOutputProgramInfo(inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) + }; + }; + validateInputs13 = (inputs) => { + if (!inputs || inputs.length !== 3) { + throw new Error("InstanceNormalization requires 3 inputs."); + } + const X = inputs[0]; + const scale = inputs[1]; + const B = inputs[2]; + if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1) { + throw new Error("Invalid input shape."); + } + if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1]) { + throw new Error("Input shapes are mismatched."); + } + if (X.type !== "float32" && X.type !== "float64" || scale.type !== "float32" && scale.type !== "float64" || B.type !== "float32" && B.type !== "float64") { + throw new Error("Invalid input type."); + } + if (inputs[0].dims.length !== 4) { + throw new Error("Only support 4-D input shape."); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/lrn.ts + function createLrnProgramInfo(inputs, attributes) { + const C = inputs[0].dims[1]; + const rank = inputs[0].dims.length; + const from = -Math.floor((attributes.size - 1) / 2); + const to = Math.ceil((attributes.size - 1) / 2); + const alpha = `float(${attributes.alpha}) / float(${attributes.size})`; + const bias = `float(${attributes.bias})`; + const beta = `float(${attributes.beta})`; + const shaderSource = ` + float process(int indices[${rank}]) { + int c = indices[1]; + float x = _X(indices); + float square_sum = 0.0; + + for (int i = ${from}; i <= ${to}; i++) { + int idx = c + i; + if (c >= 0 && c < ${C}) { + indices[1] = idx; + float j = _X(indices); + square_sum += j * j; + } + } + return x / pow(${bias} + ${alpha} * square_sum, ${beta}); + }`; + return { + ...lrnProgramMetadata, + cacheHint: attributes.cacheKey, + output: { dims: inputs[0].dims, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + } + function createLrnProgramInfoLoader(inputs, attributes) { + return { ...lrnProgramMetadata, cacheHint: attributes.cacheKey, get: () => createLrnProgramInfo(inputs, attributes) }; + } + var lrn, parseLrnAttributes, lrnProgramMetadata, validateInputs14; + var init_lrn = __esm({ + "web/lib/onnxjs/backends/webgl/ops/lrn.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_types(); + lrn = (inferenceHandler, inputs, attributes) => { + validateInputs14(inputs); + return [inferenceHandler.run(createLrnProgramInfoLoader(inputs, attributes), inputs)]; + }; + parseLrnAttributes = (node) => { + const alpha = node.attributes.getFloat("alpha", 1e-4); + const beta = node.attributes.getFloat("beta", 0.75); + const bias = node.attributes.getFloat("bias", 1); + const size = node.attributes.getInt("size"); + return createAttributeWithCacheKey({ alpha, beta, bias, size }); + }; + lrnProgramMetadata = { + name: "LRN", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + validateInputs14 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("LRN requires 1 input."); + } + if (inputs[0].dims.length !== 4) { + throw new Error('currently only support LRN for input with "NCHW" format'); + } + if (inputs[0].type !== "float32") { + throw new Error("input should be float type"); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/pad.ts + var padProgramMetadata, padV2, parsePadAttributesV2, padV11, parsePadAttributesV11, generatePadAttributesFromInputs, createPadProgramInfo, validateInputsV2, validateInputsV11, getPadFunction, getPadConstant, getPadReflect, getPadEdge; + var init_pad = __esm({ + "web/lib/onnxjs/backends/webgl/ops/pad.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_glsl_source(); + init_types(); + padProgramMetadata = { + name: "Pad", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + padV2 = (inferenceHandler, inputs, attributes) => { + validateInputsV2(inputs); + const output = inferenceHandler.run( + { + ...padProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createPadProgramInfo(inferenceHandler, inputs[0], attributes) + }, + inputs + ); + return [output]; + }; + parsePadAttributesV2 = (node) => { + const mode = node.attributes.getString("mode", "constant"); + const value = node.attributes.getFloat("value", 0); + const pads = node.attributes.getInts("pads"); + return createAttributeWithCacheKey({ mode, value, pads }); + }; + padV11 = (inferenceHandler, inputs, mode) => { + validateInputsV11(inputs); + const attrubutes = generatePadAttributesFromInputs(inferenceHandler, inputs, mode); + return padV2(inferenceHandler, [inputs[0]], attrubutes); + }; + parsePadAttributesV11 = (node) => node.attributes.getString("mode", "constant"); + generatePadAttributesFromInputs = (inferenceHandler, inputs, mode) => { + if (!inferenceHandler.session.isInitializer(inputs[1].dataId) || inputs.length >= 3 && !inferenceHandler.session.isInitializer(inputs[2].dataId)) { + throw new Error("dynamic pad attributes are not allowed"); + } + const pads = Array.from(inputs[1].integerData); + const value = inputs.length >= 3 ? inputs[2].floatData[0] : 0; + return createAttributeWithCacheKey({ mode, pads, value }); + }; + createPadProgramInfo = (inferenceHandler, input, attributes) => { + const outputShape = ShapeUtil.padShape(input.dims.slice(), attributes.pads); + const rank = outputShape.length; + const padFunction = getPadFunction(inferenceHandler, input, attributes); + const shaderSource = ` + ${padFunction} + float process(int[${rank}] indices) { + return padA(indices); + }`; + return { + name: "Pad", + inputNames: ["A"], + inputTypes: [0 /* unpacked */], + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputsV2 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Pad requires 1 input"); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + }; + validateInputsV11 = (inputs) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Pad requires 2 or 3 inputs"); + } + if (inputs[1].type !== "int32") { + throw new Error("Invalid input type."); + } + if (inputs.length >= 3 && inputs[2].type === "string") { + throw new Error("Invalid input type."); + } + }; + getPadFunction = (inferenceHandler, input, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [width, height] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, 0 /* unpacked */); + const strides = ShapeUtil.computeStrides(input.dims); + switch (attributes.mode) { + case "constant": + return getPadConstant(glsl, input.dims, strides, width, height, attributes.pads, attributes.value); + case "reflect": + return getPadReflect(glsl, input.dims, strides, width, height, attributes.pads); + case "edge": + return getPadEdge(glsl, input.dims, strides, width, height, attributes.pads); + default: + throw new Error("Invalid mode"); + } + }; + getPadConstant = (glsl, shape2, strides, width, height, pads, value) => { + const rank = shape2.length; + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + k = m[${i}] - ${pads[i]}; + if (k < 0) return constant; + if (k >= ${shape2[i]}) return constant; + offset += k * ${strides[i]}; + `; + } + return ` + float padA(int m[${rank}]) { + const float constant = float(${value}); + int offset = 0; + int k = 0; + ${block} + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(A, coords)); + return value; + } + `; + }; + getPadReflect = (glsl, shape2, strides, width, height, pads) => { + const rank = shape2.length; + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + k = m[${i}] - ${pads[i]}; + if (k < 0) { k = -k; } + { + const int _2n_1 = ${2 * (shape2[i] - 1)}; + k = int( mod( float(k), float(_2n_1) ) ) ; + if(k >= ${shape2[i]}) { k = _2n_1 - k; } + } + offset += k * ${strides[i]}; + `; + } + return ` + float padA(int m[${rank}]) { + int offset = 0; + int k = 0; + ${block} + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(A, coords)); + return value; + } + `; + }; + getPadEdge = (glsl, shape2, strides, width, height, pads) => { + const rank = shape2.length; + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + k = m[${i}] - ${pads[i]}; + if (k < 0) k = 0; + if (k >= ${shape2[i]}) k = ${shape2[i] - 1}; + offset += k * ${strides[i]}; + `; + } + return ` + float padA(int m[${rank}]) { + int offset = 0; + int k = 0; + ${block} + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(A, coords)); + return value; + } + `; + }; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/pool.ts + var averagePool, parseAveragePoolAttributes, createAveragePoolProgramInfo, globalAveragePool, parseGlobalAveragePoolAttributes, maxPool, parseMaxPoolAttributes, createMaxPoolProgramInfo, getAdjustedPoolAttributesAndOutputShape, globalMaxPoolAttributes, globalMaxPoolMetadata, globalMaxPool, validateInputs15, generatePoolingCode, copyArray, offsetToIndices; + var init_pool = __esm({ + "web/lib/onnxjs/backends/webgl/ops/pool.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + averagePool = (inferenceHandler, inputs, attributes) => { + validateInputs15(inputs); + const metadata = { + name: "AveragePool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint: attributes.cacheKey + }; + const output = inferenceHandler.run( + { ...metadata, get: () => createAveragePoolProgramInfo(inputs, metadata, false, attributes) }, + inputs + ); + return [output]; + }; + parseAveragePoolAttributes = (node) => { + const autoPad = node.attributes.getString("auto_pad", "NOTSET"); + const ceilMode = node.attributes.getInt("ceil_mode", 0); + const countIncludePad = node.attributes.getInt("count_include_pad", 0) === 0 ? false : true; + const kernelShape = node.attributes.getInts("kernel_shape"); + const strides = node.attributes.getInts("strides", []); + const pads = node.attributes.getInts("pads", []); + if (ceilMode !== 0) { + throw new Error("using ceil() in shape computation is not yet supported for AveragePool"); + } + return createAttributeWithCacheKey({ autoPad, ceilMode, countIncludePad, kernelShape, strides, pads }); + }; + createAveragePoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => { + const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape( + inputs, + attributes, + isGlobalOperator + ); + const kernelSize = ShapeUtil.size(adjustedAttributes.kernelShape); + const op1 = "value += _X(x);"; + let op2 = ""; + if (adjustedAttributes.countIncludePad) { + op2 += `value /= float(${kernelSize});`; + } else { + op2 += `value /= float(${kernelSize} - pad);`; + } + const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, "0.0"); + const shaderSource = ` + ${poolingCode} + `; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + globalAveragePool = (inferenceHandler, inputs, attributes) => { + validateInputs15(inputs); + const metadata = { + name: "GlobalAveragePool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint: `${attributes.countIncludePad}` + }; + const output = inferenceHandler.run( + { ...metadata, get: () => createAveragePoolProgramInfo(inputs, metadata, true, attributes) }, + inputs + ); + return [output]; + }; + parseGlobalAveragePoolAttributes = (node) => { + const countIncludePad = node.attributes.getInt("count_include_pad", 0) === 0 ? false : true; + return createAttributeWithCacheKey({ + autoPad: "", + ceilMode: 0, + countIncludePad, + kernelShape: [], + strides: [], + pads: [] + }); + }; + maxPool = (inferenceHandler, inputs, attributes) => { + validateInputs15(inputs); + const metadata = { + name: "MaxPool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint: attributes.cacheKey + }; + const output = inferenceHandler.run( + { ...metadata, get: () => createMaxPoolProgramInfo(inputs, metadata, false, attributes) }, + inputs + ); + return [output]; + }; + parseMaxPoolAttributes = (node) => { + const autoPad = node.attributes.getString("auto_pad", "NOTSET"); + const ceilMode = node.attributes.getInt("ceil_mode", 0); + const kernelShape = node.attributes.getInts("kernel_shape"); + const strides = node.attributes.getInts("strides", []); + const pads = node.attributes.getInts("pads", []); + const storageOrder = node.attributes.getInt("storage_order", 0); + const dilations = node.attributes.getInts("dilations", []); + if (storageOrder !== 0) { + throw new Error("column major storage order is not yet supported for MaxPool"); + } + if (ceilMode !== 0) { + throw new Error("using ceil() in shape computation is not yet supported for MaxPool"); + } + return createAttributeWithCacheKey({ + autoPad, + ceilMode, + countIncludePad: false, + kernelShape, + strides, + pads, + storageOrder, + dilations + }); + }; + createMaxPoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => { + const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape( + inputs, + attributes, + isGlobalOperator + ); + const op1 = ` + value = max(_X(x), value); + `; + const op2 = ""; + const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, "-1e5"); + const shaderSource = ` + ${poolingCode} + `; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + getAdjustedPoolAttributesAndOutputShape = (inputs, attributes, isGlobalOperator) => { + const inputShape = inputs[0].dims.slice(); + const hasDilations = Object.hasOwnProperty.call(attributes, "dilations"); + const kernelShape = attributes.kernelShape.slice(); + const strides = attributes.strides.slice(); + const dilations = hasDilations ? attributes.dilations.slice() : []; + const pads = attributes.pads.slice(); + PoolConvUtil.adjustPoolAttributes(isGlobalOperator, inputShape, kernelShape, strides, dilations, pads); + const outputShape = PoolConvUtil.computePoolOutputShape( + isGlobalOperator, + inputShape, + strides, + dilations, + kernelShape, + pads, + attributes.autoPad + ); + const newAttributes = Object.assign({}, attributes); + if (hasDilations) { + Object.assign(newAttributes, { kernelShape, strides, pads, dilations, cacheKey: attributes.cacheKey }); + } else { + Object.assign(newAttributes, { kernelShape, strides, pads, cacheKey: attributes.cacheKey }); + } + return [newAttributes, outputShape]; + }; + globalMaxPoolAttributes = { + autoPad: "", + ceilMode: 0, + countIncludePad: false, + kernelShape: [], + strides: [], + pads: [], + storageOrder: 0, + dilations: [], + cacheKey: "" + }; + globalMaxPoolMetadata = { + name: "GlobalMaxPool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + globalMaxPool = (inferenceHandler, inputs) => { + validateInputs15(inputs); + const output = inferenceHandler.run( + { + ...globalMaxPoolMetadata, + get: () => createMaxPoolProgramInfo(inputs, globalMaxPoolMetadata, true, globalMaxPoolAttributes) + }, + inputs + ); + return [output]; + }; + validateInputs15 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Pool ops requires 1 input."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + }; + generatePoolingCode = (inputDims, attributes, op1, op2, start) => { + const rank = inputDims.length; + if (attributes.kernelShape.length <= 2) { + const kw = attributes.kernelShape[attributes.kernelShape.length - 1]; + const sw = attributes.strides[attributes.strides.length - 1]; + const pwStart = attributes.pads[attributes.pads.length / 2 - 1]; + const pwEnd = attributes.pads[attributes.pads.length - 1]; + const dimW = inputDims[rank - 1]; + let codeW = ""; + let codeH = ""; + let codeHEnd = ""; + if (pwStart + pwEnd !== 0) { + codeW = ` + for (int i = 0; i < ${kw}; i++) { + x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i; + if (x[${rank} - 1] < 0 || x[${rank} - 1] >= ${dimW}) { + pad++; + continue; + } + ${op1} + }`; + } else { + codeW = ` + for (int i = 0; i < ${kw}; i++) { + x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i; + ${op1} + }`; + } + if (attributes.kernelShape.length === 2) { + const kh = attributes.kernelShape[attributes.kernelShape.length - 2]; + const sh = attributes.strides[attributes.strides.length - 2]; + const phStart = attributes.pads[attributes.pads.length / 2 - 2]; + const phEnd = attributes.pads[attributes.pads.length - 2]; + const dimH = inputDims[rank - 2]; + if (phStart + phEnd !== 0) { + codeH = ` + for (int j = 0; j < ${kh}; j++) { + x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j; + if (x[${rank} - 2] < 0 || x[${rank} - 2] >= ${dimH}) { + pad+= ${kw}; + continue; + } + `; + } else { + codeH = ` + for (int j = 0; j < ${kh}; j++) { + x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j; + `; + } + codeHEnd = ` + } + `; + } + const poolingCode = ` + float process(int indices[${rank}]) { + int x[${rank}]; + copyVec(indices, x); + + float value = ${start}; + int pad = 0; + ${codeH} + ${codeW} + ${codeHEnd} + ${op2} + return value; + } + `; + return poolingCode; + } else { + const kernelSize = ShapeUtil.size(attributes.kernelShape); + const kernelStrides = ShapeUtil.computeStrides(attributes.kernelShape); + const stridesRank = kernelStrides.length; + const padsRank = attributes.pads.length; + const offsetToIndicesFunction = offsetToIndices(stridesRank); + const copyInputDims = copyArray(inputDims, "inputDims"); + const copyPads = copyArray(attributes.pads, "pads"); + const copyKernelStrides = copyArray(kernelStrides, "kernelStrides"); + const copyStrides = copyArray(attributes.strides, "strides"); + const hasPads = attributes.pads.reduce((sum2, cur) => sum2 + cur); + let padCode = ""; + if (hasPads) { + padCode = ` + if (x[j] >= inputDims[j] || x[j] < 0) { + pad++; + isPad = true; + break; + } + } + if (!isPad) { + ${op1} + }`; + } else { + padCode = ` + } + ${op1} + `; + } + const poolingCode = ` + ${offsetToIndicesFunction} + float process(int indices[${rank}]) { + int x[${rank}]; + copyVec(indices, x); + int offset[${stridesRank}]; + int pads[${padsRank}]; + int inputDims[${rank}]; + int kernelStrides[${stridesRank}]; + int strides[${stridesRank}]; + ${copyPads} + ${copyInputDims} + ${copyStrides} + ${copyKernelStrides} + + float value = ${start}; + int pad = 0; + bool isPad = false; + for (int i = 0; i < ${kernelSize}; i++) { + offsetToIndices(i, kernelStrides, offset); + isPad = false; + for (int j = ${rank} - ${stridesRank}; j < ${rank}; j++) { + x[j] = indices[j] * strides[j - ${rank} + ${stridesRank}] + + offset[j - ${rank} + ${stridesRank}] - pads[j - 2]; + ${padCode} + } + ${op2} + + return value; + } + `; + return poolingCode; + } + }; + copyArray = (array, arrayName) => { + let block = ""; + for (let i = 0; i < array.length; i++) { + block += ` + ${arrayName}[${i}] = ${array[i]}; + `; + } + return block; + }; + offsetToIndices = (rank) => ` + void offsetToIndices(int offset, int[${rank}] strides, out int[${rank}] indices) { + if (${rank} == 0) { + return; + } + for (int i = 0; i < ${rank} - 1; ++i) { + indices[i] = offset / strides[i]; + offset -= indices[i] * strides[i]; + } + indices[${rank} - 1] = offset; + }`; + } + }); + + // web/lib/onnxjs/backends/webgl/ops/reduce.ts + var reduce, parseReduceAttributes, createReduceProgramInfo, validateInputs16, reduceSum, reduceMean, reduceMax, reduceMin, reduceProd, reduceLogSum, reduceLogSumSquare; + var init_reduce = __esm({ + "web/lib/onnxjs/backends/webgl/ops/reduce.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_operators(); + init_util(); + init_types(); + reduce = (inferenceHandler, inputs, attributes, name2, reduceOp) => { + validateInputs16(inputs); + const reduceProgramMetadata = { + name: name2, + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + const output = inferenceHandler.run( + { + ...reduceProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createReduceProgramInfo(inferenceHandler, inputs, attributes, name2, reduceOp, reduceProgramMetadata) + }, + inputs + ); + return [output]; + }; + parseReduceAttributes = (node) => { + const axes = node.attributes.getInts("axes", []); + const keepDims = node.attributes.getInt("keepdims", 1) === 1; + return createAttributeWithCacheKey({ axes, keepDims }); + }; + createReduceProgramInfo = (_handler, inputs, attributes, _name, reduceOp, reduceProgramMetadata) => { + const outputShape = []; + const iRank = inputs[0].dims.length || 1; + const idxCopy = []; + const axes = ShapeUtil.normalizeAxes(attributes.axes, inputs[0].dims.length); + const ops = reduceOp(inputs, axes); + let reduceOps2 = 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); + } + reduceOps2 = ` + for(int j${k} = 0; j${k} < ${inputs[0].dims[k]}; j${k}++) { + inputIdx[${k}] = j${k}; + ${reduceOps2} + }`; + } 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 + ${reduceOps2} + ${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 split3 = node.attributes.getInts("split", []); + const numOutputs = node.outputs.length; + return createAttributeWithCacheKey({ axis, split: split3, 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, transpose3) { + let name2 = `_${varName}`; + if (transpose3) { + 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, transpose3) { + let name2 = `_${varName}_Pack`; + if (transpose3) { + 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: location2, 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], location2, texturePosition); + texturePosition++; + break; + case "float": + if (arrayLength) { + gl.uniform1fv(location2, value); + } else { + gl.uniform1f(location2, value); + } + break; + case "int": + if (arrayLength) { + gl.uniform1iv(location2, value); + } else { + gl.uniform1i(location2, value); + } + break; + default: + throw new Error(`Uniform not implemented: ${type}`); + } + } + } + bindTexture(td, uniformHandle, position) { + this.glContext.bindTextureToUniform(td.texture, position, uniformHandle); + } + getAttribLocations(program) { + return { + position: this.getAttribLocation(program, "position"), + textureCoord: this.getAttribLocation(program, "textureCoord") + }; + } + getUniformLocations(program, samplers, variables) { + const uniformLocations = []; + if (samplers) { + for (const sampler of samplers) { + uniformLocations.push({ + name: sampler, + type: "sampler2D", + location: this.getUniformLocation(program, sampler) + }); + } + } + if (variables) { + for (const variable of variables) { + uniformLocations.push({ ...variable, location: this.getUniformLocation(program, variable.name) }); + } + } + return uniformLocations; + } + getUniformLocation(program, name2) { + const gl = this.glContext.gl; + const reference = gl.getUniformLocation(program, name2); + if (reference === null) { + throw new Error(`Uniform ${name2} not found.`); + } + return reference; + } + getAttribLocation(program, name2) { + const gl = this.glContext.gl; + const attributeLocation = gl.getAttribLocation(program, name2); + return attributeLocation; + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/texture-manager.ts + var TextureManager; + var init_texture_manager = __esm({ + "web/lib/onnxjs/backends/webgl/texture-manager.ts"() { + "use strict"; + init_instrument(); + init_texture_data_encoder(); + TextureManager = class { + constructor(glContext, layoutStrategy, profiler, config) { + this.glContext = glContext; + this.layoutStrategy = layoutStrategy; + this.profiler = profiler; + this.config = config; + this.pendingRead = /* @__PURE__ */ new Map(); + if (config.reuseTextures) { + this.inUseTextures = /* @__PURE__ */ new Map(); + this.idleTextures = /* @__PURE__ */ new Map(); + this.textureLookup = /* @__PURE__ */ new Map(); + } + } + createTextureFromLayout(dataType, layout, data, usage) { + const textureDataType = this.toEncoderType(dataType); + const encoder = this.glContext.getEncoder(textureDataType, layout.channels || 1, usage); + if (layout.isPacked && usage === 1 /* UploadOnly */) { + throw new Error("not implemented"); + } + const width = layout.width; + const height = layout.height; + let key; + let inUseTextures; + if (this.config.reuseTextures) { + key = `${width}x${height}_${encoder.format}_${encoder.internalFormat}_${encoder.textureType}`; + inUseTextures = this.inUseTextures.get(key); + if (!inUseTextures) { + inUseTextures = []; + this.inUseTextures.set(key, inUseTextures); + } + const idleTextures = this.idleTextures.get(key); + if (idleTextures && idleTextures.length > 0) { + const texture2 = idleTextures.pop(); + inUseTextures.push(texture2); + if (usage === 1 /* UploadOnly */) { + this.glContext.updateTexture(texture2, width, height, encoder, this.toTextureData(dataType, data)); + } + return texture2; + } + } + Logger.verbose("TextureManager", `Creating new texture of size ${layout.width}x${layout.height}`); + const texture = this.glContext.allocateTexture(width, height, encoder, this.toTextureData(dataType, data)); + if (this.config.reuseTextures) { + inUseTextures.push(texture); + this.textureLookup.set(texture, key); + } + return texture; + } + readTexture(td, dataType, channels) { + if (!channels) { + channels = 1; + } + return this.profiler.event("backend", "TextureManager.readTexture", () => { + const dataSize = td.shape.reduce((a, b) => a * b) * channels; + const data = this.glContext.readTexture( + td.texture, + td.width, + td.height, + dataSize, + this.toEncoderType(dataType), + channels + ); + return this.toTensorData(dataType, data); + }); + } + async readTextureAsync(td, dataType, channels) { + const dataId = td.tensor.dataId; + if (!channels) { + channels = 1; + } + if (this.pendingRead.has(dataId)) { + const subscribers = this.pendingRead.get(dataId); + return new Promise((resolve) => subscribers?.push(resolve)); + } + return this.profiler.event("backend", "TextureManager.readTextureAsync", async () => { + this.pendingRead.set(dataId, []); + const dataSize = td.shape.reduce((a, b) => a * b) * channels; + await this.glContext.createAndWaitForFence(); + const data = this.glContext.readTexture( + td.texture, + td.width, + td.height, + dataSize, + this.toEncoderType(dataType), + channels + ); + const tensorData = this.toTensorData(dataType, data); + const subscribers = this.pendingRead.get(dataId); + this.pendingRead.delete(dataId); + subscribers?.forEach((resolve) => resolve(tensorData)); + return tensorData; + }); + } + readUint8TextureAsFloat(td) { + return this.profiler.event("backend", "TextureManager.readUint8TextureAsFloat", () => { + const dataSize = td.shape.reduce((a, b) => a * b); + const data = this.glContext.readTexture(td.texture, td.width, td.height, dataSize * 4, "byte", 4); + return new Float32Array(data.buffer, data.byteOffset, dataSize); + }); + } + releaseTexture(textureData, deleteTexture) { + let key; + if (this.config.reuseTextures) { + key = this.textureLookup.get(textureData.texture); + if (key) { + if (deleteTexture) { + this.textureLookup.delete(key); + } + const inUseTextures = this.inUseTextures.get(key); + if (inUseTextures) { + const index = inUseTextures.indexOf(textureData.texture); + if (index !== -1) { + inUseTextures.splice(index, 1); + let idleTextures = this.idleTextures.get(key); + if (!idleTextures) { + idleTextures = []; + this.idleTextures.set(key, idleTextures); + } + idleTextures.push(textureData.texture); + } + } + } + } + if (!key || deleteTexture) { + Logger.verbose("TextureManager", `Deleting texture of size ${textureData.width}x${textureData.height}`); + this.glContext.deleteTexture(textureData.texture); + } + } + toTensorData(dataType, data) { + switch (dataType) { + case "int16": + return data instanceof Int16Array ? data : Int16Array.from(data); + case "int32": + return data instanceof Int32Array ? data : Int32Array.from(data); + case "int8": + return data instanceof Int8Array ? data : Int8Array.from(data); + case "uint16": + return data instanceof Uint16Array ? data : Uint16Array.from(data); + case "uint32": + return data instanceof Uint32Array ? data : Uint32Array.from(data); + case "uint8": + case "bool": + return data instanceof Uint8Array ? data : Uint8Array.from(data); + case "float32": + return data instanceof Float32Array ? data : Float32Array.from(data); + case "float64": + return data instanceof Float64Array ? data : Float64Array.from(data); + default: + throw new Error(`TensorData type ${dataType} is not supported`); + } + } + toTextureData(_dataType, data) { + if (!data) { + return void 0; + } + return data instanceof Float32Array ? data : new Float32Array(data); + } + toEncoderType(_dataType) { + return "float"; + } + clearActiveTextures() { + this.glContext.clearActiveTextures(); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/session-handler.ts + var WebGLSessionHandler; + var init_session_handler = __esm({ + "web/lib/onnxjs/backends/webgl/session-handler.ts"() { + "use strict"; + init_instrument(); + init_opset(); + init_inference_handler(); + init_op_resolve_rules(); + init_program_manager(); + init_texture_layout_strategy(); + init_texture_manager(); + WebGLSessionHandler = class { + constructor(backend2, context) { + this.backend = backend2; + this.context = context; + this.layoutStrategy = new PreferLogicalStrategy(backend2.glContext.maxTextureSize); + this.programManager = new ProgramManager(this.context.profiler, backend2.glContext, this.layoutStrategy); + this.textureManager = new TextureManager(backend2.glContext, this.layoutStrategy, this.context.profiler, { + reuseTextures: backend2.textureCacheMode === "full" + }); + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + this.pack = backend2.pack; + this.pack2unpackMap = /* @__PURE__ */ new Map(); + this.unpack2packMap = /* @__PURE__ */ new Map(); + } + createInferenceHandler() { + return new WebGLInferenceHandler(this); + } + onGraphInitialized(graph) { + const initializers = graph.getValues().filter((v) => v.from === -1 && v.tensor).map((v) => v.tensor.dataId); + this.initializers = new Set(initializers); + } + isInitializer(tensorId) { + return this.initializers ? this.initializers.has(tensorId) : false; + } + addInitializer(tensorId) { + this.initializers.add(tensorId); + } + getTextureData(tensorId, isPacked) { + if (isPacked) { + return this.packedTextureDataCache.get(tensorId); + } else { + return this.unpackedTextureDataCache.get(tensorId); + } + } + setTextureData(tensorId, textureData, isPacked = false) { + Logger.verbose("WebGLSessionHandler", "Storing Texture data in cache"); + if (isPacked) { + this.packedTextureDataCache.set(tensorId, textureData); + } else { + this.unpackedTextureDataCache.set(tensorId, textureData); + } + } + dispose() { + this.programManager.dispose(); + this.textureManager.clearActiveTextures(); + this.packedTextureDataCache.forEach((td) => this.textureManager.releaseTexture(td, true)); + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache.forEach((td) => this.textureManager.releaseTexture(td, true)); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + } + resolve(node, opsets, graph) { + const op = resolveOperator(node, opsets, WEBGL_OP_RESOLVE_RULES); + return { impl: op.opImpl, context: op.opInit ? op.opInit(node, graph) : node }; + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/webgl-context.ts + function linearSearchLastTrue(arr) { + let i = 0; + for (; i < arr.length; ++i) { + const isDone = arr[i](); + if (!isDone) { + break; + } + } + return i - 1; + } + var WebGLContext; + var init_webgl_context = __esm({ + "web/lib/onnxjs/backends/webgl/webgl-context.ts"() { + "use strict"; + init_esm(); + init_texture_data_encoder(); + init_texture_data_encoder(); + init_utils(); + WebGLContext = class { + constructor(gl, version3) { + this.frameBufferBound = false; + this.itemsToPoll = []; + this.gl = gl; + this.version = version3; + this.getExtensions(); + this.vertexbuffer = this.createVertexbuffer(); + this.framebuffer = this.createFramebuffer(); + this.queryVitalParameters(); + } + allocateTexture(width, height, encoder, data) { + const gl = this.gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + const buffer = data ? encoder.encode(data, width * height) : null; + gl.texImage2D( + gl.TEXTURE_2D, + 0, + // Level of detail. + encoder.internalFormat, + width, + height, + 0, + // Always 0 in OpenGL ES. + encoder.format, + encoder.textureType, + buffer + ); + this.checkError(); + return texture; + } + updateTexture(texture, width, height, encoder, data) { + const gl = this.gl; + gl.bindTexture(gl.TEXTURE_2D, texture); + const buffer = encoder.encode(data, width * height); + gl.texSubImage2D( + gl.TEXTURE_2D, + 0, + // level + 0, + // xoffset + 0, + // yoffset + width, + height, + encoder.format, + encoder.textureType, + buffer + ); + this.checkError(); + } + attachFramebuffer(texture, width, height) { + const gl = this.gl; + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + this.checkError(); + gl.viewport(0, 0, width, height); + gl.scissor(0, 0, width, height); + } + readTexture(texture, width, height, dataSize, dataType, channels) { + const gl = this.gl; + if (!channels) { + channels = 1; + } + if (!this.frameBufferBound) { + this.attachFramebuffer(texture, width, height); + } + const encoder = this.getEncoder(dataType, channels); + const buffer = encoder.allocate(width * height); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + gl.readPixels(0, 0, width, height, gl.RGBA, encoder.textureType, buffer); + this.checkError(); + return encoder.decode(buffer, dataSize); + } + isFramebufferReady() { + return true; + } + getActiveTexture() { + const gl = this.gl; + const n = gl.getParameter(this.gl.ACTIVE_TEXTURE); + return `TEXTURE${n - gl.TEXTURE0}`; + } + getTextureBinding() { + return this.gl.getParameter(this.gl.TEXTURE_BINDING_2D); + } + getFramebufferBinding() { + return this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING); + } + setVertexAttributes(positionHandle, textureCoordHandle) { + const gl = this.gl; + gl.vertexAttribPointer(positionHandle, 3, gl.FLOAT, false, 20, 0); + gl.enableVertexAttribArray(positionHandle); + if (textureCoordHandle !== -1) { + gl.vertexAttribPointer(textureCoordHandle, 2, gl.FLOAT, false, 20, 12); + gl.enableVertexAttribArray(textureCoordHandle); + } + this.checkError(); + } + createProgram(vertexShader, fragShader) { + const gl = this.gl; + const program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragShader); + gl.linkProgram(program); + return program; + } + compileShader(shaderSource, shaderType) { + const gl = this.gl; + const shader = gl.createShader(shaderType); + if (!shader) { + throw new Error(`createShader() returned null with type ${shaderType}`); + } + gl.shaderSource(shader, shaderSource); + gl.compileShader(shader); + if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) === false) { + throw new Error(`Failed to compile shader: ${gl.getShaderInfoLog(shader)} +Shader source: +${shaderSource}`); + } + return shader; + } + deleteShader(shader) { + this.gl.deleteShader(shader); + } + bindTextureToUniform(texture, position, uniformHandle) { + const gl = this.gl; + gl.activeTexture(gl.TEXTURE0 + position); + this.checkError(); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.checkError(); + gl.uniform1i(uniformHandle, position); + this.checkError(); + } + draw() { + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + this.checkError(); + } + checkError() { + if (env2.debug) { + const gl = this.gl; + const error = gl.getError(); + let label = ""; + switch (error) { + case gl.NO_ERROR: + return; + case gl.INVALID_ENUM: + label = "INVALID_ENUM"; + break; + case gl.INVALID_VALUE: + label = "INVALID_VALUE"; + break; + case gl.INVALID_OPERATION: + label = "INVALID_OPERATION"; + break; + case gl.INVALID_FRAMEBUFFER_OPERATION: + label = "INVALID_FRAMEBUFFER_OPERATION"; + break; + case gl.OUT_OF_MEMORY: + label = "OUT_OF_MEMORY"; + break; + case gl.CONTEXT_LOST_WEBGL: + label = "CONTEXT_LOST_WEBGL"; + break; + default: + label = `Unknown WebGL Error: ${error.toString(16)}`; + } + throw new Error(label); + } + } + deleteTexture(texture) { + this.gl.deleteTexture(texture); + } + deleteProgram(program) { + this.gl.deleteProgram(program); + } + getEncoder(dataType, channels, usage = 0 /* Default */) { + if (this.version === 2) { + return new RedFloat32DataEncoder(this.gl, channels); + } + switch (dataType) { + case "float": + if (usage === 1 /* UploadOnly */ || this.isRenderFloat32Supported) { + return new RGBAFloatDataEncoder(this.gl, channels); + } else { + return new RGBAFloatDataEncoder( + this.gl, + channels, + this.textureHalfFloatExtension.HALF_FLOAT_OES + ); + } + case "int": + throw new Error("not implemented"); + case "byte": + return new Uint8DataEncoder(this.gl, channels); + default: + throw new Error(`Invalid dataType: ${dataType}`); + } + } + clearActiveTextures() { + const gl = this.gl; + for (let unit = 0; unit < this.maxTextureImageUnits; ++unit) { + gl.activeTexture(gl.TEXTURE0 + unit); + gl.bindTexture(gl.TEXTURE_2D, null); + } + } + dispose() { + if (this.disposed) { + return; + } + const gl = this.gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(this.framebuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.deleteBuffer(this.vertexbuffer); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + gl.finish(); + this.disposed = true; + } + createDefaultGeometry() { + return new Float32Array([ + -1, + 1, + 0, + 0, + 1, + // upper left + -1, + -1, + 0, + 0, + 0, + // lower left + 1, + 1, + 0, + 1, + 1, + // upper right + 1, + -1, + 0, + 1, + 0 + // lower right + ]); + } + createVertexbuffer() { + const gl = this.gl; + const buffer = gl.createBuffer(); + if (!buffer) { + throw new Error("createBuffer() returned null"); + } + const geometry = this.createDefaultGeometry(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, geometry, gl.STATIC_DRAW); + this.checkError(); + return buffer; + } + createFramebuffer() { + const fb = this.gl.createFramebuffer(); + if (!fb) { + throw new Error("createFramebuffer returned null"); + } + return fb; + } + queryVitalParameters() { + const gl = this.gl; + this.isFloatTextureAttachableToFrameBuffer = this.checkFloatTextureAttachableToFrameBuffer(); + this.isRenderFloat32Supported = this.checkRenderFloat32(); + this.isFloat32DownloadSupported = this.checkFloat32Download(); + if (this.version === 1 && !this.textureHalfFloatExtension && !this.isRenderFloat32Supported) { + throw new Error("both float32 and float16 TextureType are not supported"); + } + this.isBlendSupported = !this.isRenderFloat32Supported || this.checkFloat32Blend(); + this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this.maxTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + if (this.version === 2) { + } + } + getExtensions() { + if (this.version === 2) { + this.colorBufferFloatExtension = this.gl.getExtension("EXT_color_buffer_float"); + this.disjointTimerQueryWebgl2Extension = this.gl.getExtension("EXT_disjoint_timer_query_webgl2"); + } else { + this.textureFloatExtension = this.gl.getExtension("OES_texture_float"); + this.textureHalfFloatExtension = this.gl.getExtension("OES_texture_half_float"); + } + } + checkFloatTextureAttachableToFrameBuffer() { + const gl = this.gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA; + gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); + const frameBuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + const isComplete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE; + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteTexture(texture); + gl.deleteFramebuffer(frameBuffer); + return isComplete; + } + checkRenderFloat32() { + if (this.version === 2) { + if (!this.colorBufferFloatExtension) { + return false; + } + } else { + if (!this.textureFloatExtension) { + return false; + } + } + return this.isFloatTextureAttachableToFrameBuffer; + } + checkFloat32Download() { + if (this.version === 2) { + if (!this.colorBufferFloatExtension) { + return false; + } + } else { + if (!this.textureFloatExtension) { + return false; + } + if (!this.gl.getExtension("WEBGL_color_buffer_float")) { + return false; + } + } + return this.isFloatTextureAttachableToFrameBuffer; + } + /** + * Check whether GL_BLEND is supported + */ + checkFloat32Blend() { + const gl = this.gl; + let texture; + let frameBuffer; + let vertexShader; + let fragmentShader; + let program; + try { + texture = gl.createTexture(); + frameBuffer = gl.createFramebuffer(); + gl.bindTexture(gl.TEXTURE_2D, texture); + const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA; + gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + gl.enable(gl.BLEND); + vertexShader = gl.createShader(gl.VERTEX_SHADER); + if (!vertexShader) { + return false; + } + gl.shaderSource(vertexShader, "void main(){}"); + gl.compileShader(vertexShader); + fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + if (!fragmentShader) { + return false; + } + gl.shaderSource(fragmentShader, "precision highp float;void main(){gl_FragColor=vec4(0.5);}"); + gl.compileShader(fragmentShader); + program = gl.createProgram(); + if (!program) { + return false; + } + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + gl.useProgram(program); + gl.drawArrays(gl.POINTS, 0, 1); + return gl.getError() === gl.NO_ERROR; + } finally { + gl.disable(gl.BLEND); + if (program) { + gl.deleteProgram(program); + } + if (vertexShader) { + gl.deleteShader(vertexShader); + } + if (fragmentShader) { + gl.deleteShader(fragmentShader); + } + if (frameBuffer) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(frameBuffer); + } + if (texture) { + gl.bindTexture(gl.TEXTURE_2D, null); + gl.deleteTexture(texture); + } + } + } + beginTimer() { + if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { + const gl2 = this.gl; + const ext = this.disjointTimerQueryWebgl2Extension; + const query = gl2.createQuery(); + gl2.beginQuery(ext.TIME_ELAPSED_EXT, query); + return query; + } else { + throw new Error("WebGL1 profiling currently not supported."); + } + } + endTimer() { + if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { + const gl2 = this.gl; + const ext = this.disjointTimerQueryWebgl2Extension; + gl2.endQuery(ext.TIME_ELAPSED_EXT); + return; + } else { + throw new Error("WebGL1 profiling currently not supported"); + } + } + isTimerResultAvailable(query) { + let available = false, disjoint = false; + if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { + const gl2 = this.gl; + const ext = this.disjointTimerQueryWebgl2Extension; + available = gl2.getQueryParameter(query, gl2.QUERY_RESULT_AVAILABLE); + disjoint = gl2.getParameter(ext.GPU_DISJOINT_EXT); + } else { + throw new Error("WebGL1 profiling currently not supported"); + } + return available && !disjoint; + } + getTimerResult(query) { + let timeElapsed = 0; + if (this.version === 2) { + const gl2 = this.gl; + timeElapsed = gl2.getQueryParameter(query, gl2.QUERY_RESULT); + gl2.deleteQuery(query); + } else { + throw new Error("WebGL1 profiling currently not supported"); + } + return timeElapsed / 1e6; + } + async waitForQueryAndGetTime(query) { + await repeatedTry(() => this.isTimerResultAvailable(query)); + return this.getTimerResult(query); + } + async createAndWaitForFence() { + const fenceContext = this.createFence(this.gl); + return this.pollFence(fenceContext); + } + createFence(gl) { + let isFencePassed; + const gl2 = gl; + const query = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0); + gl.flush(); + if (query === null) { + isFencePassed = () => true; + } else { + isFencePassed = () => { + const status = gl2.clientWaitSync(query, 0, 0); + return status === gl2.ALREADY_SIGNALED || status === gl2.CONDITION_SATISFIED; + }; + } + return { query, isFencePassed }; + } + async pollFence(fenceContext) { + return new Promise((resolve) => { + void this.addItemToPoll( + () => fenceContext.isFencePassed(), + () => resolve() + ); + }); + } + pollItems() { + const index = linearSearchLastTrue(this.itemsToPoll.map((x) => x.isDoneFn)); + for (let i = 0; i <= index; ++i) { + const { resolveFn } = this.itemsToPoll[i]; + resolveFn(); + } + this.itemsToPoll = this.itemsToPoll.slice(index + 1); + } + async addItemToPoll(isDoneFn, resolveFn) { + this.itemsToPoll.push({ isDoneFn, resolveFn }); + if (this.itemsToPoll.length > 1) { + return; + } + await repeatedTry(() => { + this.pollItems(); + return this.itemsToPoll.length === 0; + }); + } + }; + } + }); + + // web/lib/onnxjs/backends/webgl/webgl-context-factory.ts + function createWebGLContext(contextId) { + let context; + if ((!contextId || contextId === "webgl2") && "webgl2" in cache) { + context = cache.webgl2; + } else if ((!contextId || contextId === "webgl") && "webgl" in cache) { + context = cache.webgl; + } + if (!context) { + try { + const offscreenCanvas = createOffscreenCanvas(); + context = createNewWebGLContext(offscreenCanvas, contextId); + } catch (e) { + const canvas = createCanvas(); + context = createNewWebGLContext(canvas, contextId); + } + } + contextId = contextId || context.version === 1 ? "webgl" : "webgl2"; + const gl = context.gl; + cache[contextId] = context; + if (gl.isContextLost()) { + delete cache[contextId]; + return createWebGLContext(contextId); + } + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.STENCIL_TEST); + gl.disable(gl.BLEND); + gl.disable(gl.DITHER); + gl.disable(gl.POLYGON_OFFSET_FILL); + gl.disable(gl.SAMPLE_COVERAGE); + gl.enable(gl.SCISSOR_TEST); + gl.enable(gl.CULL_FACE); + gl.cullFace(gl.BACK); + return context; + } + function createNewWebGLContext(canvas, contextId) { + const contextAttributes = { + alpha: false, + depth: false, + antialias: false, + stencil: false, + preserveDrawingBuffer: false, + premultipliedAlpha: false, + failIfMajorPerformanceCaveat: false + }; + let gl; + const ca = contextAttributes; + if (!contextId || contextId === "webgl2") { + gl = canvas.getContext("webgl2", ca); + if (gl) { + try { + return new WebGLContext(gl, 2); + } catch (err) { + Logger.warning("GlContextFactory", `failed to create WebGLContext using contextId 'webgl2'. Error: ${err}`); + } + } + } + if (!contextId || contextId === "webgl") { + gl = canvas.getContext("webgl", ca) || canvas.getContext("experimental-webgl", ca); + if (gl) { + try { + return new WebGLContext(gl, 1); + } catch (err) { + Logger.warning( + "GlContextFactory", + `failed to create WebGLContext using contextId 'webgl' or 'experimental-webgl'. Error: ${err}` + ); + } + } + } + throw new Error("WebGL is not supported"); + } + function createCanvas() { + if (typeof document === "undefined") { + throw new TypeError("failed to create canvas: document is not supported"); + } + const canvas = document.createElement("canvas"); + canvas.width = 1; + canvas.height = 1; + return canvas; + } + function createOffscreenCanvas() { + if (typeof OffscreenCanvas === "undefined") { + throw new TypeError("failed to create offscreen canvas: OffscreenCanvas is not supported"); + } + return new OffscreenCanvas(1, 1); + } + var cache; + var init_webgl_context_factory = __esm({ + "web/lib/onnxjs/backends/webgl/webgl-context-factory.ts"() { + "use strict"; + init_instrument(); + init_webgl_context(); + cache = {}; + } + }); + + // web/lib/onnxjs/backends/backend-webgl.ts + var WebGLBackend; + var init_backend_webgl = __esm({ + "web/lib/onnxjs/backends/backend-webgl.ts"() { + "use strict"; + init_esm(); + init_instrument(); + init_session_handler(); + init_webgl_context_factory(); + WebGLBackend = class { + get contextId() { + return env2.webgl.contextId; + } + set contextId(value) { + env2.webgl.contextId = value; + } + get matmulMaxBatchSize() { + return env2.webgl.matmulMaxBatchSize; + } + set matmulMaxBatchSize(value) { + env2.webgl.matmulMaxBatchSize = value; + } + get textureCacheMode() { + return env2.webgl.textureCacheMode; + } + set textureCacheMode(value) { + env2.webgl.textureCacheMode = value; + } + get pack() { + return env2.webgl.pack; + } + set pack(value) { + env2.webgl.pack = value; + } + get async() { + return env2.webgl.async; + } + set async(value) { + env2.webgl.async = value; + } + initialize() { + try { + this.glContext = createWebGLContext(this.contextId); + if (typeof this.matmulMaxBatchSize !== "number") { + this.matmulMaxBatchSize = 16; + } + if (typeof this.textureCacheMode !== "string") { + this.textureCacheMode = "full"; + } + if (typeof this.pack !== "boolean") { + this.pack = false; + } + if (typeof this.async !== "boolean") { + this.async = false; + } + Logger.setWithEnv(env2); + if (!env2.webgl.context) { + Object.defineProperty(env2.webgl, "context", { value: this.glContext.gl }); + } + Logger.verbose( + "WebGLBackend", + `Created WebGLContext: ${typeof this.glContext} with matmulMaxBatchSize: ${this.matmulMaxBatchSize}; textureCacheMode: ${this.textureCacheMode}; pack: ${this.pack}; async: ${this.async}.` + ); + return true; + } catch (e) { + Logger.warning("WebGLBackend", `Unable to initialize WebGLBackend. ${e}`); + return false; + } + } + createSessionHandler(context) { + return new WebGLSessionHandler(this, context); + } + dispose() { + this.glContext.dispose(); + } + }; + } + }); + + // web/lib/onnxjs/backend.ts + async function resolveBackend(hint) { + if (!hint) { + return resolveBackend(["webgl"]); + } else { + const hints = typeof hint === "string" ? [hint] : hint; + for (const backendHint of hints) { + const cache2 = backendsCache.get(backendHint); + if (cache2) { + return cache2; + } + const backend2 = await tryLoadBackend(backendHint); + if (backend2) { + return backend2; + } + } + } + throw new Error("no available backend to use"); + } + async function tryLoadBackend(backendHint) { + const backendObj = backend; + if (typeof backendObj[backendHint] !== "undefined" && isBackend(backendObj[backendHint])) { + const backend2 = backendObj[backendHint]; + let init2 = backend2.initialize(); + if (typeof init2 === "object" && "then" in init2) { + init2 = await init2; + } + if (init2) { + backendsCache.set(backendHint, backend2); + return backend2; + } + } + return void 0; + } + function isBackend(obj) { + const o = obj; + if ("initialize" in o && typeof o.initialize === "function" && // initialize() + "createSessionHandler" in o && typeof o.createSessionHandler === "function" && // createSessionHandler() + "dispose" in o && typeof o.dispose === "function") { + return true; + } + return false; + } + var backendsCache, backend; + var init_backend2 = __esm({ + "web/lib/onnxjs/backend.ts"() { + "use strict"; + init_backend_webgl(); + backendsCache = /* @__PURE__ */ new Map(); + backend = { + webgl: new WebGLBackend() + }; + } + }); + + // web/lib/onnxjs/execution-plan.ts + var KernelOp, ExecutionPlan; + var init_execution_plan = __esm({ + "web/lib/onnxjs/execution-plan.ts"() { + "use strict"; + init_instrument(); + KernelOp = class { + constructor(op, node) { + this.op = op; + this.node = node; + } + }; + ExecutionPlan = class { + constructor(graph, ops, profiler) { + this.graph = graph; + this.profiler = profiler; + this.initialize(ops); + } + initialize(ops) { + this.profiler.event("session", "ExecutionPlan.initialize", () => { + const graphNodes = this.graph.getNodes(); + if (graphNodes.length !== ops.length) { + throw new Error("The size of nodes and OPs do not match."); + } + this._ops = ops.map((op, i) => new KernelOp(op, graphNodes[i])); + this.reset(); + this._starter = []; + this._ops.forEach((op, i) => { + let resolved = true; + for (const input of op.node.inputs) { + if (!this._values[input] && // not an initialized input + this.graph.getInputIndices().indexOf(input) === -1) { + resolved = false; + break; + } + } + if (resolved) { + this._starter.push(i); + } + }); + }); + } + reset() { + this._values = this.graph.getValues().map((i) => i.tensor); + } + async execute(sessionHandler, modelInputs) { + return this.profiler.event("session", "ExecutionPlan.execute", async () => { + this.reset(); + const inferenceHandler = sessionHandler.createInferenceHandler(); + const graphInputs = this.graph.getInputIndices(); + if (modelInputs.length !== graphInputs.length) { + throw new Error( + `number of input tensors don't match the number of inputs to the model: actual: ${modelInputs.length} expected: ${graphInputs.length}` + ); + } + modelInputs.forEach((input, i) => { + const index = graphInputs[i]; + this._values[index] = input; + }); + const sequence = this._starter.slice(0); + const graphValues = this.graph.getValues(); + const graphNodes = this.graph.getNodes(); + let rear = 0; + while (rear < sequence.length) { + const thisOpIndex = sequence[rear++]; + const thisOp = this._ops[thisOpIndex]; + const inputList = thisOp.node.inputs.map((i) => this._values[i]); + if (inputList.indexOf(void 0) !== -1) { + throw new Error(`unresolved input detected: op: ${thisOp.node}`); + } + const inputTensors = inputList; + Logger.verbose( + "ExecPlan", + `Running op:${thisOp.node.name} (${inputTensors.map((t, i) => `'${thisOp.node.inputs[i]}': ${t.type}[${t.dims.join(",")}]`).join(", ")})` + ); + const outputList = await this.profiler.event( + "node", + thisOp.node.name, + async () => thisOp.op.impl(inferenceHandler, inputTensors, thisOp.op.context) + ); + if (outputList.length !== thisOp.node.outputs.length) { + throw new Error("the size of output does not match model definition."); + } + outputList.forEach((output2, i) => { + const j = thisOp.node.outputs[i]; + if (this._values[j]) { + throw new Error(`output [${j}] already has value: op:${thisOp.node.name}`); + } + this._values[j] = output2; + }); + const downstreamNodes = /* @__PURE__ */ new Set(); + outputList.forEach((_output, i) => { + const j = thisOp.node.outputs[i]; + for (const currentDownstreamNodeIndex of graphValues[j].to) { + const currentDownstreamNode = graphNodes[currentDownstreamNodeIndex]; + let resolved = true; + for (const k of currentDownstreamNode.inputs) { + if (!this._values[k]) { + resolved = false; + break; + } + } + if (resolved) { + downstreamNodes.add(currentDownstreamNodeIndex); + } + } + }); + sequence.push(...downstreamNodes); + } + const output = []; + for (let i = 0; i < this.graph.getOutputIndices().length; i++) { + const outputIndex = this.graph.getOutputIndices()[i]; + const outputTensor = this._values[outputIndex]; + if (outputTensor === void 0) { + throw new Error(`required output [${outputIndex}] does not have value`); + } + if (outputIndex === 0) { + await outputTensor.getData(); + } else { + outputTensor.data; + } + output.push(outputTensor); + } + Logger.verbose("ExecPlan", "disposing of inferenceHandler"); + inferenceHandler.dispose(); + return output; + }); + } + }; + } + }); + + // web/lib/onnxjs/attribute.ts + var import_onnx3, Attribute2; + var init_attribute = __esm({ + "web/lib/onnxjs/attribute.ts"() { + "use strict"; + init_ort_generated(); + import_onnx3 = __toESM(require_onnx()); + init_tensor2(); + init_util(); + Attribute2 = class _Attribute { + constructor(attributes) { + this._attributes = /* @__PURE__ */ new Map(); + if (attributes !== null && attributes !== void 0) { + for (const attr of attributes) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + this._attributes.set(attr.name, [_Attribute.getValue(attr), _Attribute.getType(attr)]); + } else if (attr instanceof import_attribute.Attribute) { + this._attributes.set(attr.name(), [_Attribute.getValue(attr), _Attribute.getType(attr)]); + } + } + if (this._attributes.size < attributes.length) { + throw new Error("duplicated attribute names"); + } + } + } + set(key, type, value) { + this._attributes.set(key, [value, type]); + } + delete(key) { + this._attributes.delete(key); + } + getFloat(key, defaultValue) { + return this.get(key, "float", defaultValue); + } + getInt(key, defaultValue) { + return this.get(key, "int", defaultValue); + } + getString(key, defaultValue) { + return this.get(key, "string", defaultValue); + } + getTensor(key, defaultValue) { + return this.get(key, "tensor", defaultValue); + } + getFloats(key, defaultValue) { + return this.get(key, "floats", defaultValue); + } + getInts(key, defaultValue) { + return this.get(key, "ints", defaultValue); + } + getStrings(key, defaultValue) { + return this.get(key, "strings", defaultValue); + } + getTensors(key, defaultValue) { + return this.get(key, "tensors", defaultValue); + } + get(key, type, defaultValue) { + const valueAndType = this._attributes.get(key); + if (valueAndType === void 0) { + if (defaultValue !== void 0) { + return defaultValue; + } + throw new Error(`required attribute not found: ${key}`); + } + if (valueAndType[1] !== type) { + throw new Error(`type mismatch: expected ${type} but got ${valueAndType[1]}`); + } + return valueAndType[0]; + } + static getType(attr) { + const type = attr instanceof import_onnx3.onnx.AttributeProto ? attr.type : attr.type(); + switch (type) { + case import_onnx3.onnx.AttributeProto.AttributeType.FLOAT: + return "float"; + case import_onnx3.onnx.AttributeProto.AttributeType.INT: + return "int"; + case import_onnx3.onnx.AttributeProto.AttributeType.STRING: + return "string"; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSOR: + return "tensor"; + case import_onnx3.onnx.AttributeProto.AttributeType.FLOATS: + return "floats"; + case import_onnx3.onnx.AttributeProto.AttributeType.INTS: + return "ints"; + case import_onnx3.onnx.AttributeProto.AttributeType.STRINGS: + return "strings"; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSORS: + return "tensors"; + default: + throw new Error(`attribute type is not supported yet: ${import_onnx3.onnx.AttributeProto.AttributeType[type]}`); + } + } + static getValue(attr) { + const attrType = attr instanceof import_onnx3.onnx.AttributeProto ? attr.type : attr.type(); + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.GRAPH || attrType === import_onnx3.onnx.AttributeProto.AttributeType.GRAPHS) { + throw new Error("graph attribute is not supported yet"); + } + const value = this.getValueNoCheck(attr); + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.INT && LongUtil.isLong(value)) { + return LongUtil.longToNumber(value); + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.INTS) { + const arr = value; + const numberValue = new Array(arr.length); + for (let i = 0; i < arr.length; i++) { + const maybeLong = arr[i]; + numberValue[i] = LongUtil.longToNumber(maybeLong); + } + return numberValue; + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.TENSOR) { + return attr instanceof import_onnx3.onnx.AttributeProto ? Tensor4.fromProto(value) : Tensor4.fromOrtTensor(value); + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.TENSORS) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + const tensorProtos = value; + return tensorProtos.map((value2) => Tensor4.fromProto(value2)); + } else if (attr instanceof import_attribute.Attribute) { + const tensorProtos = value; + return tensorProtos.map((value2) => Tensor4.fromOrtTensor(value2)); + } + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.STRING) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + const utf8String = value; + return decodeUtf8String(utf8String); + } + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.STRINGS) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + const utf8Strings = value; + return utf8Strings.map(decodeUtf8String); + } + } + return value; + } + static getValueNoCheck(attr) { + return attr instanceof import_onnx3.onnx.AttributeProto ? this.getValueNoCheckFromOnnxFormat(attr) : this.getValueNoCheckFromOrtFormat(attr); + } + static getValueNoCheckFromOnnxFormat(attr) { + switch (attr.type) { + case import_onnx3.onnx.AttributeProto.AttributeType.FLOAT: + return attr.f; + case import_onnx3.onnx.AttributeProto.AttributeType.INT: + return attr.i; + case import_onnx3.onnx.AttributeProto.AttributeType.STRING: + return attr.s; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSOR: + return attr.t; + case import_onnx3.onnx.AttributeProto.AttributeType.GRAPH: + return attr.g; + case import_onnx3.onnx.AttributeProto.AttributeType.FLOATS: + return attr.floats; + case import_onnx3.onnx.AttributeProto.AttributeType.INTS: + return attr.ints; + case import_onnx3.onnx.AttributeProto.AttributeType.STRINGS: + return attr.strings; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSORS: + return attr.tensors; + case import_onnx3.onnx.AttributeProto.AttributeType.GRAPHS: + return attr.graphs; + default: + throw new Error(`unsupported attribute type: ${import_onnx3.onnx.AttributeProto.AttributeType[attr.type]}`); + } + } + static getValueNoCheckFromOrtFormat(attr) { + switch (attr.type()) { + case import_attribute_type.AttributeType.FLOAT: + return attr.f(); + case import_attribute_type.AttributeType.INT: + return attr.i(); + case import_attribute_type.AttributeType.STRING: + return attr.s(); + case import_attribute_type.AttributeType.TENSOR: + return attr.t(); + case import_attribute_type.AttributeType.GRAPH: + return attr.g(); + case import_attribute_type.AttributeType.FLOATS: + return attr.floatsArray(); + case import_attribute_type.AttributeType.INTS: { + const ints = []; + for (let i = 0; i < attr.intsLength(); i++) { + ints.push(attr.ints(i)); + } + return ints; + } + case import_attribute_type.AttributeType.STRINGS: { + const strings = []; + for (let i = 0; i < attr.stringsLength(); i++) { + strings.push(attr.strings(i)); + } + return strings; + } + case import_attribute_type.AttributeType.TENSORS: { + const tensors = []; + for (let i = 0; i < attr.tensorsLength(); i++) { + tensors.push(attr.tensors(i)); + } + return tensors; + } + // case ortFbs.AttributeType.GRAPHS: + // TODO: Subgraph not supported yet. + // const graphs = []; + // for (let i = 0; i < attr.graphsLength(); i++) { + // graphs.push(attr.graphs(i)!); + // } + // return graphs; + default: + throw new Error(`unsupported attribute type: ${import_attribute_type.AttributeType[attr.type()]}`); + } + } + }; + } + }); + + // web/lib/onnxjs/graph.ts + var import_onnx4, Graph2, Value, Node2, GraphImpl; + var init_graph = __esm({ + "web/lib/onnxjs/graph.ts"() { + "use strict"; + init_attribute(); + init_ort_generated(); + import_onnx4 = __toESM(require_onnx()); + init_tensor2(); + init_util(); + Graph2 = { + /** + * construct a graph from a graph protobuf type + */ + from: (graphProto, initializer) => new GraphImpl(graphProto, initializer) + }; + Value = class { + constructor(valueInfo) { + this._from = void 0; + this._to = []; + this.tensor = void 0; + this.type = void 0; + if (valueInfo) { + this.type = ProtoUtil.tensorValueTypeFromProto(valueInfo.type.tensorType); + } + } + // -1 represent from initializer + get from() { + return this._from; + } + get to() { + return this._to; + } + }; + Node2 = class { + constructor(_nodeProto, name2) { + if (_nodeProto instanceof import_onnx4.onnx.NodeProto) { + this.name = _nodeProto.name; + this.opType = _nodeProto.opType; + this.attributes = new Attribute2(_nodeProto.attribute); + } else if (_nodeProto instanceof import_node.Node) { + this.name = name2 ?? _nodeProto.name(); + this.opType = _nodeProto.opType(); + this.attributes = new Attribute2(ProtoUtil.tensorAttributesFromORTFormat(_nodeProto)); + } + this.inputs = []; + this.outputs = []; + this.executeNode = true; + } + }; + GraphImpl = class { + constructor(graph, graphInitializer) { + if (!graph) { + throw new TypeError("graph is empty"); + } + this.buildGraph(graph); + this.transformGraph(graphInitializer); + this.checkIsAcyclic(); + } + getInputIndices() { + return this._allInputIndices; + } + getInputNames() { + return this._allInputNames; + } + getOutputIndices() { + return this._allOutputIndices; + } + getOutputNames() { + return this._allOutputNames; + } + getValues() { + return this._allData; + } + getNodes() { + return this._nodes; + } + buildGraph(graph) { + if (graph instanceof import_onnx4.onnx.GraphProto) { + this.buildGraphFromOnnxFormat(graph); + } else if (graph instanceof import_graph.Graph) { + this.buildGraphFromOrtFormat(graph); + } else { + throw new TypeError("Graph type is not supported."); + } + } + buildGraphFromOnnxFormat(graph) { + const dataIndices = /* @__PURE__ */ new Map(); + this._allData = []; + this._allInputIndices = []; + this._allInputNames = []; + this._allOutputIndices = []; + this._allOutputNames = []; + this._nodes = []; + const nodesIndices = /* @__PURE__ */ new Map(); + if (!graph.input) { + throw new Error("missing information in graph: input"); + } + const inputValueNames = []; + for (const i of graph.input) { + if (dataIndices.has(i.name)) { + throw new Error(`duplicated input name: ${i.name}`); + } + const currentIndex = this._allData.push(new Value(i)) - 1; + dataIndices.set(i.name, currentIndex); + inputValueNames.push(i.name); + } + if (!graph.initializer) { + throw new Error("missing information in graph: initializer"); + } + for (const i of graph.initializer) { + let index = dataIndices.get(i.name); + if (index === void 0) { + const value = new Value(); + value.type = { + shape: { dims: ProtoUtil.tensorDimsFromProto(i.dims) }, + tensorType: ProtoUtil.tensorDataTypeFromProto(i.dataType) + }; + index = this._allData.push(value) - 1; + dataIndices.set(i.name, index); + } + this._allData[index]._from = -1; + this._allData[index].tensor = Tensor4.fromProto(i); + } + for (let i = 0; i < this._allData.length; i++) { + if (!this._allData[i].tensor) { + this._allInputIndices.push(i); + this._allInputNames.push(inputValueNames[i]); + } + } + if (!graph.output) { + throw new Error("missing information in graph: output"); + } + for (const i of graph.output) { + if (dataIndices.has(i.name)) { + throw new Error(`duplicated output name: ${i.name}`); + } + const currentIndex = this._allData.push(new Value(i)) - 1; + dataIndices.set(i.name, currentIndex); + this._allOutputIndices.push(currentIndex); + this._allOutputNames.push(i.name); + } + if (!graph.node) { + throw new Error("missing information in graph: node"); + } + for (const nodeProto of graph.node) { + if (!nodeProto.name) { + for (let pick = 0; ; pick++) { + const name2 = `unnamed_${nodeProto.opType}_${pick}`; + if (!nodesIndices.has(name2)) { + nodeProto.name = name2; + break; + } + } + } + if (nodesIndices.has(nodeProto.name)) { + throw new Error(`duplicated node name: ${nodeProto.name}`); + } + const currentIndex = this._nodes.push(new Node2(nodeProto)) - 1; + nodesIndices.set(nodeProto.name, currentIndex); + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.node[i]; + if (!nodeProto.output) { + throw new Error(`missing output for node: ${nodeProto.name}`); + } + for (const output of nodeProto.output) { + let dataIndex = dataIndices.get(output); + if (typeof dataIndex === "undefined") { + dataIndex = this._allData.push(new Value()) - 1; + dataIndices.set(output, dataIndex); + } + node.outputs.push(dataIndex); + if (this._allData[dataIndex]._from !== void 0) { + throw new Error(`multiple nodes output to one data value: ${dataIndex}`); + } + this._allData[dataIndex]._from = i; + if (nodeProto.opType === "Constant") { + if (!nodeProto.attribute || nodeProto.attribute.length !== 1 || !nodeProto.attribute[0].t) { + throw new Error("missing attributes or missing tensor value in attributes for this Constant operator"); + } + if (!nodeProto.output || nodeProto.output.length !== 1) { + throw new Error("missing output or incorrect number of outputs for this Constant operator"); + } + node.outputs.pop(); + node.executeNode = false; + this._allData[dataIndex]._from = -1; + this._allData[dataIndex].tensor = Tensor4.fromProto(nodeProto.attribute[0].t); + } + } + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.node[i]; + if (!nodeProto.input) { + throw new Error(`missing input for node: ${nodeProto.name}`); + } + for (const input of nodeProto.input) { + const dataIndex = dataIndices.get(input); + if (typeof dataIndex === "undefined") { + if (input === "" && (nodeProto.input.length === 3 || nodeProto.input.length === 4) && nodeProto.opType === "Resize") { + continue; + } + throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name}`); + } + node.inputs.push(dataIndex); + this._allData[dataIndex]._to.push(i); + } + } + return true; + } + buildGraphFromOrtFormat(graph) { + const dataIndices = /* @__PURE__ */ new Map(); + this._allData = []; + this._allInputIndices = []; + this._allInputNames = []; + this._allOutputIndices = []; + this._allOutputNames = []; + this._nodes = []; + const nodesIndices = /* @__PURE__ */ new Map(); + const inputValueNames = []; + for (let i = 0; i < graph.inputsLength(); i++) { + const inputName = graph.inputs(i); + if (dataIndices.has(inputName)) { + throw new Error(`duplicated input name: ${inputName}`); + } + for (let j = 0; j < graph.nodeArgsLength(); j++) { + if (graph.nodeArgs(j)?.name() === inputName) { + const value = new Value(); + const valueType = graph.nodeArgs(j)?.type()?.valueType(); + if (valueType !== import_type_info_value.TypeInfoValue.tensor_type) { + throw new Error("Unexpected value type for the nodeArg."); + } + const valueInfo = graph.nodeArgs(j).type().value(new import_tensor_type_and_shape.TensorTypeAndShape()); + const type = ProtoUtil.tensorDataTypeFromProto(valueInfo.elemType()); + const shape2 = valueInfo.shape(); + const dims = []; + for (let k = 0; k < shape2.dimLength(); k++) { + dims.push(LongUtil.longToNumber(shape2.dim(k).value().dimValue())); + } + value.type = { shape: { dims }, tensorType: type }; + const currentIndex = this._allData.push(value) - 1; + dataIndices.set(inputName, currentIndex); + inputValueNames.push(inputName); + } + } + } + for (let i = 0; i < graph.initializersLength(); i++) { + const initializer = graph.initializers(i); + let index = dataIndices.get(initializer.name()); + if (index === void 0) { + const value = new Value(); + const dims = ProtoUtil.tensorDimsFromORTFormat(initializer); + const type = ProtoUtil.tensorDataTypeFromProto(initializer.dataType()); + value.type = { shape: { dims }, tensorType: type }; + index = this._allData.push(value) - 1; + dataIndices.set(initializer.name(), index); + } + this._allData[index]._from = -1; + this._allData[index].tensor = Tensor4.fromOrtTensor(initializer); + } + for (let i = 0; i < this._allData.length; i++) { + if (!this._allData[i].tensor) { + this._allInputIndices.push(i); + this._allInputNames.push(inputValueNames[i]); + } + } + for (let i = 0; i < graph.outputsLength(); i++) { + const outputName = graph.outputs(i); + if (dataIndices.has(outputName)) { + throw new Error(`duplicated output name: ${outputName}`); + } + const currentIndex = this._allData.push(new Value()) - 1; + dataIndices.set(outputName, currentIndex); + this._allOutputIndices.push(currentIndex); + this._allOutputNames.push(outputName); + } + if (!graph.nodes) { + throw new Error("missing information in graph: node"); + } + for (let i = 0; i < graph.nodesLength(); i++) { + const nodeProto = graph.nodes(i); + let name2 = nodeProto.name(); + if (!name2) { + for (let pick = 0; ; pick++) { + name2 = `unnamed_${nodeProto.opType()}_${pick}`; + if (!nodesIndices.has(name2)) { + break; + } + } + } + if (nodesIndices.has(name2)) { + throw new Error(`duplicated node name: ${name2}`); + } + const currentIndex = this._nodes.push(new Node2(nodeProto, name2)) - 1; + nodesIndices.set(name2, currentIndex); + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.nodes(i); + if (nodeProto == null) { + throw new Error(`No node exists at index ${i}`); + } + if (nodeProto?.outputsLength() === 0) { + throw new Error(`missing output for node: ${nodeProto.name}`); + } + for (let j = 0; j < nodeProto?.outputsLength(); j++) { + const output = nodeProto?.outputs(j); + let dataIndex = dataIndices.get(output); + if (typeof dataIndex === "undefined") { + dataIndex = this._allData.push(new Value()) - 1; + dataIndices.set(output, dataIndex); + } + node.outputs.push(dataIndex); + if (this._allData[dataIndex]._from !== void 0) { + throw new Error(`multiple nodes output to one data value: ${dataIndex}`); + } + this._allData[dataIndex]._from = i; + if (nodeProto.opType() === "Constant") { + if (nodeProto.attributesLength() !== 1 || !nodeProto.attributes(0).t()) { + throw new Error("missing attributes or missing tensor value in attributes for this Constant operator"); + } + if (nodeProto.outputsLength() !== 1) { + throw new Error("missing output or incorrect number of outputs for this Constant operator"); + } + node.outputs.pop(); + node.executeNode = false; + this._allData[dataIndex]._from = -1; + this._allData[dataIndex].tensor = Tensor4.fromOrtTensor(nodeProto.attributes(0).t()); + } + } + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.nodes(i); + if (nodeProto.inputsLength() === 0) { + throw new Error(`missing input for node: ${nodeProto.name}`); + } + for (let j = 0; j < nodeProto.inputsLength(); j++) { + const input = nodeProto.inputs(j); + const dataIndex = dataIndices.get(input); + if (typeof dataIndex === "undefined") { + throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name()}`); + } + node.inputs.push(dataIndex); + this._allData[dataIndex]._to.push(i); + } + } + } + checkIsAcyclic() { + const starters = /* @__PURE__ */ new Set(); + this._allInputIndices.forEach((i) => { + const data = this._allData[i]; + data._to.forEach((j) => { + starters.add(j); + }); + }); + const nodesStack = Array.from(starters); + const nodesState = new Array(this._nodes.length).fill("white"); + while (nodesStack.length > 0) { + const nodeIndex = nodesStack.pop(); + if (nodesState[nodeIndex] === "gray") { + nodesState[nodeIndex] = "black"; + } else { + nodesStack.push(nodeIndex); + nodesState[nodeIndex] = "gray"; + this._nodes[nodeIndex].outputs.forEach((outgoingEdgeIndex) => { + const data = this._allData[outgoingEdgeIndex]; + if (typeof data.tensor !== "undefined") { + throw new Error("node outputs should not be initialized"); + } + if (data._from !== nodeIndex) { + throw new Error("from property of the Value object doesn't match index of Node being processed"); + } + data._to.forEach((downstreamNodeIndex) => { + if (nodesState[downstreamNodeIndex] === "gray") { + throw new Error("model graph is cyclic"); + } else if (nodesState[downstreamNodeIndex] === "white") { + nodesStack.push(downstreamNodeIndex); + } + }); + }); + } + } + } + transformGraph(graphInitializer) { + this.removeAllIdentityNodes(); + this.removeAllDropoutNodes(); + this.fuseConvActivationNodes(); + if (graphInitializer) { + graphInitializer.transformGraph(this); + } + this.finalizeGraph(); + } + /** + * finalize the graph. + * + * this function should be called after all the transformation completed. + * this function removes all unnecessary nodes and values from the graph + */ + finalizeGraph() { + let offset = 0; + const newIndices = new Array(this._nodes.length, 0); + let nodePossition = 0; + for (let i = 0; i < this._nodes.length; i++) { + newIndices[i] = nodePossition; + if (this._nodes[i].executeNode) { + if (nodePossition !== i) { + this._nodes[nodePossition] = this._nodes[i]; + } + nodePossition++; + } else { + this._nodes[i].outputs.forEach((ind) => { + this._allData[ind]._from = -2; + }); + } + } + this._nodes.splice(nodePossition, this._nodes.length - nodePossition); + for (let i = 0; i < this._allData.length; i++) { + const currentData = this._allData[i]; + if (currentData._from !== void 0 && currentData._from !== -1 && currentData._from !== -2) { + currentData._from = newIndices[currentData._from]; + } + for (let j = 0; j < currentData._to.length; j++) { + if (currentData._to[j] >= 0) { + currentData._to[j] = newIndices[currentData._to[j]]; + } else { + throw new Error("Trying to update a removed node"); + } + } + } + offset = 0; + for (let i = 0; i < this._allData.length; i++) { + if (this._allData[i].from === -2 && this._allOutputIndices.indexOf(i + offset) === -1) { + offset++; + this._allData.splice(i, 1); + i--; + continue; + } + if (offset > 0) { + let ind = -1; + if (this._allData[i].from !== void 0 && this._allData[i].from !== -1) { + ind = this._nodes[this._allData[i].from].outputs.indexOf(i + offset); + if (ind !== -1) { + this._nodes[this._allData[i].from].outputs[ind] = i; + } + } else { + ind = this._allInputIndices.indexOf(i + offset); + if (ind !== -1) { + this._allInputIndices[ind] = i; + } + } + this._allData[i].to.forEach((node) => { + ind = this._nodes[node].inputs.indexOf(i + offset); + if (ind !== -1) { + this._nodes[node].inputs[ind] = i; + } + }); + if (this._allData[i].to.length === 0) { + ind = this._allOutputIndices.indexOf(i + offset); + if (ind !== -1) { + this._allOutputIndices[ind] = i; + } + } + } + } + } + /** + * Delete the specified node. Assume the node has one incoming input and the first output connected to other nodes. + * An input validation must be done before calling this function. + * @param nodeIndex The index of node to be deleted + */ + deleteNode(nodeIndex) { + const node = this._nodes[nodeIndex]; + if (node.outputs.length > 1) { + for (let i = 1; i < node.outputs.length; i++) { + if (this._allData[node.outputs[i]].to.length > 0) { + throw new Error("Node deletion with more than one output connected to other nodes is not supported. "); + } + } + } + node.executeNode = false; + const inputValueIndex = node.inputs[0]; + const outputValueIndex = node.outputs[0]; + const nodesConsumingOutput = this._allData[outputValueIndex].to; + for (let i = 0; i < node.inputs.length; i++) { + const delIndex = this._allData[node.inputs[i]].to.indexOf(nodeIndex); + if (delIndex === -1) { + throw new Error("The Value object doesn't have the current Node in it's 'to' property "); + } + this._allData[node.inputs[i]].to.splice(delIndex, 1); + } + this._allData[outputValueIndex]._to = []; + const index = this._allOutputIndices.indexOf(outputValueIndex); + if (index !== -1) { + this._allOutputIndices[index] = inputValueIndex; + } + if (nodesConsumingOutput && nodesConsumingOutput.length > 0) { + for (const nodeIndex2 of nodesConsumingOutput) { + const replaceIndex = this._nodes[nodeIndex2].inputs.indexOf(outputValueIndex); + if (replaceIndex === -1) { + throw new Error("The Node object doesn't have the output Value in it's 'inputs' property "); + } + this._nodes[nodeIndex2].inputs[replaceIndex] = inputValueIndex; + this._allData[inputValueIndex].to.push(nodeIndex2); + } + } + } + removeAllDropoutNodes() { + let nodeIndex = 0; + for (const node of this._nodes) { + if (node.opType === "Dropout") { + if (node.inputs.length !== 1) { + throw new Error("Dropout nodes should only contain one input. "); + } + if (node.outputs.length !== 1 && node.outputs.length !== 2) { + throw new Error("Dropout nodes should contain either 1 or 2 output(s)"); + } + if (node.outputs.length === 2 && this._allData[node.outputs[1]]._to.length !== 0) { + throw new Error("Dropout nodes's second output should not be referenced by other nodes"); + } + this.deleteNode(nodeIndex); + } + nodeIndex++; + } + } + removeAllIdentityNodes() { + let nodeIndex = 0; + for (const node of this._nodes) { + if (node.opType === "Identity") { + this.deleteNode(nodeIndex); + } + nodeIndex++; + } + } + isActivation(n) { + switch (n.opType) { + // TODO: add other activation methods + case "Relu": + case "Sigmoid": + case "Clip": + return true; + default: + return false; + } + } + fuseConvActivationNodes() { + for (const node of this._nodes) { + if (node.opType === "Conv") { + const next = this._allData[node.outputs[0]]._to; + if (next.length === 1 && this.isActivation(this._nodes[next[0]])) { + const child = this._nodes[next[0]]; + if (child.opType === "Clip") { + if (child.inputs.length === 1) { + try { + node.attributes.set("activation_params", "floats", [ + child.attributes.getFloat("min"), + child.attributes.getFloat("max") + ]); + } catch (e) { + node.attributes.set("activation_params", "floats", [MIN_CLIP, MAX_CLIP]); + } + } else if (child.inputs.length >= 3 && this._allData[child.inputs[1]].tensor !== void 0 && this._allData[child.inputs[2]].tensor !== void 0) { + node.attributes.set("activation_params", "floats", [ + this._allData[child.inputs[1]].tensor.floatData[0], + this._allData[child.inputs[2]].tensor.floatData[0] + ]); + } else { + continue; + } + } + node.attributes.set("activation", "string", child.opType); + this.deleteNode(next[0]); + } + } + } + } + }; + } + }); + + // web/lib/onnxjs/model.ts + var flatbuffers, import_onnx5, Model2; + var init_model = __esm({ + "web/lib/onnxjs/model.ts"() { + "use strict"; + flatbuffers = __toESM(require_flatbuffers()); + init_graph(); + init_ort_generated(); + import_onnx5 = __toESM(require_onnx()); + init_util(); + Model2 = class { + // empty model + constructor() { + } + load(buf, graphInitializer, isOrtFormat) { + let onnxError; + if (!isOrtFormat) { + try { + this.loadFromOnnxFormat(buf, graphInitializer); + return; + } catch (e) { + if (isOrtFormat !== void 0) { + throw e; + } + onnxError = e; + } + } + try { + this.loadFromOrtFormat(buf, graphInitializer); + } catch (e) { + if (isOrtFormat !== void 0) { + throw e; + } + throw new Error(`Failed to load model as ONNX format: ${onnxError} +as ORT format: ${e}`); + } + } + loadFromOnnxFormat(buf, graphInitializer) { + const modelProto = import_onnx5.onnx.ModelProto.decode(buf); + const irVersion = LongUtil.longToNumber(modelProto.irVersion); + if (irVersion < 3) { + throw new Error("only support ONNX model with IR_VERSION>=3"); + } + this._opsets = modelProto.opsetImport.map((i) => ({ + domain: i.domain, + version: LongUtil.longToNumber(i.version) + })); + this._graph = Graph2.from(modelProto.graph, graphInitializer); + } + loadFromOrtFormat(buf, graphInitializer) { + const fb = new flatbuffers.ByteBuffer(buf); + const ortModel = import_inference_session.InferenceSession.getRootAsInferenceSession(fb).model(); + const irVersion = LongUtil.longToNumber(ortModel.irVersion()); + if (irVersion < 3) { + throw new Error("only support ONNX model with IR_VERSION>=3"); + } + this._opsets = []; + for (let i = 0; i < ortModel.opsetImportLength(); i++) { + const opsetId = ortModel.opsetImport(i); + this._opsets.push({ domain: opsetId?.domain(), version: LongUtil.longToNumber(opsetId.version()) }); + } + this._graph = Graph2.from(ortModel.graph(), graphInitializer); + } + get graph() { + return this._graph; + } + get opsets() { + return this._opsets; + } + }; + } + }); + + // web/lib/onnxjs/session.ts + var Session; + var init_session = __esm({ + "web/lib/onnxjs/session.ts"() { + "use strict"; + init_backend2(); + init_execution_plan(); + init_instrument(); + init_model(); + Session = class { + constructor(config = {}) { + this._initialized = false; + this.backendHint = config.backendHint; + this.profiler = Profiler.create(config.profiler); + this.context = { profiler: this.profiler, graphInputTypes: [], graphInputDims: [] }; + } + get inputNames() { + return this._model.graph.getInputNames(); + } + get outputNames() { + return this._model.graph.getOutputNames(); + } + startProfiling() { + this.profiler.start(); + } + endProfiling() { + this.profiler.stop(); + } + async loadModel(arg, byteOffset, length) { + await this.profiler.event("session", "Session.loadModel", async () => { + const backend2 = await resolveBackend(this.backendHint); + this.sessionHandler = backend2.createSessionHandler(this.context); + this._model = new Model2(); + if (typeof arg === "string") { + const isOrtFormat = arg.endsWith(".ort"); + if (false) { + const { readFile } = null; + const buf = await readFile(arg); + this.initialize(buf, isOrtFormat); + } else { + const response = await fetch(arg); + const buf = await response.arrayBuffer(); + this.initialize(new Uint8Array(buf), isOrtFormat); + } + } else if (!ArrayBuffer.isView(arg)) { + const arr = new Uint8Array(arg, byteOffset || 0, length || arg.byteLength); + this.initialize(arr); + } else { + this.initialize(arg); + } + }); + } + initialize(modelProtoBlob, isOrtFormat) { + if (this._initialized) { + throw new Error("already initialized"); + } + this.profiler.event("session", "Session.initialize", () => { + const graphInitializer = this.sessionHandler.transformGraph ? this.sessionHandler : void 0; + this._model.load(modelProtoBlob, graphInitializer, isOrtFormat); + if (this.sessionHandler.onGraphInitialized) { + this.sessionHandler.onGraphInitialized(this._model.graph); + } + this.initializeOps(this._model.graph); + this._executionPlan = new ExecutionPlan(this._model.graph, this._ops, this.profiler); + }); + this._initialized = true; + } + async run(inputs) { + if (!this._initialized) { + throw new Error("session not initialized yet"); + } + return this.profiler.event("session", "Session.run", async () => { + const inputTensors = this.normalizeAndValidateInputs(inputs); + const outputTensors = await this._executionPlan.execute(this.sessionHandler, inputTensors); + return this.createOutput(outputTensors); + }); + } + normalizeAndValidateInputs(inputs) { + const modelInputNames = this._model.graph.getInputNames(); + if (Array.isArray(inputs)) { + if (inputs.length !== modelInputNames.length) { + throw new Error(`incorrect input array length: expected ${modelInputNames.length} but got ${inputs.length}`); + } + } else { + if (inputs.size !== modelInputNames.length) { + throw new Error(`incorrect input map size: expected ${modelInputNames.length} but got ${inputs.size}`); + } + const sortedInputs = new Array(inputs.size); + let sortedInputsIndex = 0; + for (let i = 0; i < modelInputNames.length; ++i) { + const tensor = inputs.get(modelInputNames[i]); + if (!tensor) { + throw new Error(`missing input tensor for: '${name}'`); + } + sortedInputs[sortedInputsIndex++] = tensor; + } + inputs = sortedInputs; + } + if (!this.context.graphInputTypes || this.context.graphInputTypes.length === 0 || !this.context.graphInputDims || this.context.graphInputDims.length === 0) { + const modelInputIndices = this._model.graph.getInputIndices(); + const modelValues = this._model.graph.getValues(); + const graphInputDims = new Array(modelInputIndices.length); + for (let i = 0; i < modelInputIndices.length; ++i) { + const graphInput = modelValues[modelInputIndices[i]]; + graphInputDims[i] = graphInput.type.shape.dims; + this.context.graphInputTypes.push(graphInput.type.tensorType); + this.context.graphInputDims.push(inputs[i].dims); + } + this.validateInputTensorDims(graphInputDims, inputs, true); + } else { + this.validateInputTensorDims(this.context.graphInputDims, inputs, false); + } + this.validateInputTensorTypes(this.context.graphInputTypes, inputs); + return inputs; + } + validateInputTensorTypes(graphInputTypes, givenInputs) { + for (let i = 0; i < givenInputs.length; i++) { + const expectedType = graphInputTypes[i]; + const actualType = givenInputs[i].type; + if (expectedType !== actualType) { + throw new Error(`input tensor[${i}] check failed: expected type '${expectedType}' but got ${actualType}`); + } + } + } + validateInputTensorDims(graphInputDims, givenInputs, noneDimSupported) { + for (let i = 0; i < givenInputs.length; i++) { + const expectedDims = graphInputDims[i]; + const actualDims = givenInputs[i].dims; + if (!this.compareTensorDims(expectedDims, actualDims, noneDimSupported)) { + throw new Error( + `input tensor[${i}] check failed: expected shape '[${expectedDims.join(",")}]' but got [${actualDims.join( + "," + )}]` + ); + } + } + } + compareTensorDims(expectedDims, actualDims, noneDimSupported) { + if (expectedDims.length !== actualDims.length) { + return false; + } + for (let i = 0; i < expectedDims.length; ++i) { + if (expectedDims[i] !== actualDims[i] && (!noneDimSupported || expectedDims[i] !== 0)) { + return false; + } + } + return true; + } + createOutput(outputTensors) { + const modelOutputNames = this._model.graph.getOutputNames(); + if (outputTensors.length !== modelOutputNames.length) { + throw new Error("expected number of outputs do not match number of generated outputs"); + } + const output = /* @__PURE__ */ new Map(); + for (let i = 0; i < modelOutputNames.length; ++i) { + output.set(modelOutputNames[i], outputTensors[i]); + } + return output; + } + initializeOps(graph) { + const nodes = graph.getNodes(); + this._ops = new Array(nodes.length); + for (let i = 0; i < nodes.length; i++) { + this._ops[i] = this.sessionHandler.resolve(nodes[i], this._model.opsets, graph); + } + } + }; + } + }); + + // web/lib/onnxjs/session-handler-inference.ts + var OnnxjsSessionHandler; + var init_session_handler_inference = __esm({ + "web/lib/onnxjs/session-handler-inference.ts"() { + "use strict"; + init_esm(); + init_tensor2(); + OnnxjsSessionHandler = class { + constructor(session) { + this.session = session; + this.inputNames = this.session.inputNames; + this.outputNames = this.session.outputNames; + } + get inputMetadata() { + throw new Error("Getting model metadata is not supported in webgl backend."); + } + get outputMetadata() { + throw new Error("Getting model metadata is not supported in webgl backend."); + } + async dispose() { + } + async run(feeds, _fetches, _options) { + const inputMap = /* @__PURE__ */ new Map(); + for (const name2 in feeds) { + if (Object.hasOwnProperty.call(feeds, name2)) { + const feed = feeds[name2]; + inputMap.set( + name2, + new Tensor4( + feed.dims, + feed.type, + void 0, + void 0, + feed.data + ) + ); + } + } + const outputMap = await this.session.run(inputMap); + const output = {}; + outputMap.forEach((tensor, name2) => { + output[name2] = new Tensor2(tensor.type, tensor.data, tensor.dims); + }); + return output; + } + startProfiling() { + this.session.startProfiling(); + } + endProfiling() { + this.session.endProfiling(); + } + }; + } + }); + + // web/lib/backend-onnxjs.ts + var backend_onnxjs_exports = {}; + __export(backend_onnxjs_exports, { + onnxjsBackend: () => onnxjsBackend + }); + var OnnxjsBackend, onnxjsBackend; + var init_backend_onnxjs = __esm({ + "web/lib/backend-onnxjs.ts"() { + "use strict"; + init_session(); + init_session_handler_inference(); + OnnxjsBackend = class { + // eslint-disable-next-line @typescript-eslint/no-empty-function + async init() { + } + async createInferenceSessionHandler(pathOrBuffer, options) { + const session = new Session(options); + if (typeof pathOrBuffer === "string") { + await session.loadModel(pathOrBuffer); + } else { + await session.loadModel(pathOrBuffer); + } + return new OnnxjsSessionHandler(session); + } + }; + onnxjsBackend = new OnnxjsBackend(); + } + }); + + // web/lib/wasm/wasm-utils-env.ts + var isNode; + var init_wasm_utils_env = __esm({ + "web/lib/wasm/wasm-utils-env.ts"() { + "use strict"; + isNode = false; + } + }); + + // web/lib/wasm/proxy-worker/main.ts + var main_exports = {}; + __export(main_exports, { + default: () => main_default + }); + var WORKER_NAME, isProxyWorker, main_default; + var init_main = __esm({ + "web/lib/wasm/proxy-worker/main.ts"() { + "use strict"; + init_wasm_core_impl(); + init_wasm_factory(); + init_wasm_utils_import(); + WORKER_NAME = "ort-wasm-proxy-worker"; + isProxyWorker = globalThis.self?.name === WORKER_NAME; + if (isProxyWorker) { + self.onmessage = (ev) => { + const { type, in: message } = ev.data; + try { + switch (type) { + case "init-wasm": + initializeWebAssembly(message.wasm).then( + () => { + initRuntime(message).then( + () => { + postMessage({ type }); + }, + (err) => { + postMessage({ type, err }); + } + ); + }, + (err) => { + postMessage({ type, err }); + } + ); + break; + case "init-ep": { + const { epName, env: env3 } = message; + initEp(env3, epName).then( + () => { + postMessage({ type }); + }, + (err) => { + postMessage({ type, err }); + } + ); + break; + } + case "copy-from": { + const { buffer } = message; + const bufferData = copyFromExternalBuffer(buffer); + postMessage({ type, out: bufferData }); + break; + } + case "create": { + const { model, options } = message; + createSession(model, options).then( + (sessionMetadata) => { + postMessage({ type, out: sessionMetadata }); + }, + (err) => { + postMessage({ type, err }); + } + ); + break; + } + case "release": + releaseSession(message); + postMessage({ type }); + break; + case "run": { + const { sessionId, inputIndices, inputs, outputIndices, options } = message; + run(sessionId, inputIndices, inputs, outputIndices, new Array(outputIndices.length).fill(null), options).then( + (outputs) => { + if (outputs.some((o) => o[3] !== "cpu")) { + postMessage({ type, err: "Proxy does not support non-cpu tensor location." }); + } else { + postMessage( + { type, out: outputs }, + extractTransferableBuffers([...inputs, ...outputs]) + ); + } + }, + (err) => { + postMessage({ type, err }); + } + ); + break; + } + case "end-profiling": + endProfiling(message); + postMessage({ type }); + break; + default: + } + } catch (err) { + postMessage({ type, err }); + } + }; + } + main_default = isProxyWorker ? null : (urlOverride) => new Worker(urlOverride ?? scriptSrc, { type: false ? "module" : "classic", name: WORKER_NAME }); + } + }); + + // web/lib/wasm/wasm-utils-import.ts + var origin, getScriptSrc, scriptSrc, inferWasmPathPrefixFromScriptSrc, isSameOrigin, normalizeUrl, fallbackUrl, preload, dynamicImportDefault, createProxyWorker, importProxyWorker, embeddedWasmModule, importWasmModule; + var init_wasm_utils_import = __esm({ + "web/lib/wasm/wasm-utils-import.ts"() { + "use strict"; + init_wasm_utils_env(); + origin = isNode || typeof location === "undefined" ? void 0 : location.origin; + getScriptSrc = () => { + if (isNode) { + return void 0; + } + if (false) { + if (isEsmImportMetaUrlHardcodedAsFileUri) { + const URL2 = URL; + return new URL(new URL2("ort.all.js", void 0).href, origin).href; + } + return void 0; + } + return typeof document !== "undefined" ? document.currentScript?.src : ( + // use `self.location.href` if available + typeof self !== "undefined" ? self.location?.href : void 0 + ); + }; + scriptSrc = getScriptSrc(); + inferWasmPathPrefixFromScriptSrc = () => { + if (scriptSrc && !scriptSrc.startsWith("blob:")) { + return scriptSrc.substring(0, scriptSrc.lastIndexOf("/") + 1); + } + return void 0; + }; + isSameOrigin = (filename, prefixOverride) => { + try { + const baseUrl = prefixOverride ?? scriptSrc; + const url = baseUrl ? new URL(filename, baseUrl) : new URL(filename); + return url.origin === origin; + } catch { + return false; + } + }; + normalizeUrl = (filename, prefixOverride) => { + const baseUrl = prefixOverride ?? scriptSrc; + try { + const url = baseUrl ? new URL(filename, baseUrl) : new URL(filename); + return url.href; + } catch { + return void 0; + } + }; + fallbackUrl = (filename, prefixOverride) => `${prefixOverride ?? "./"}${filename}`; + preload = async (absoluteUrl) => { + const response = await fetch(absoluteUrl, { credentials: "same-origin" }); + const blob = await response.blob(); + return URL.createObjectURL(blob); + }; + dynamicImportDefault = async (url) => (await import( + /* webpackIgnore: true */ + url + )).default; + createProxyWorker = // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires + false ? void 0 : (init_main(), __toCommonJS(main_exports)).default; + importProxyWorker = async () => { + if (!scriptSrc) { + throw new Error("Failed to load proxy worker: cannot determine the script source URL."); + } + if (isSameOrigin(scriptSrc)) { + return [void 0, createProxyWorker()]; + } + const url = await preload(scriptSrc); + return [url, createProxyWorker(url)]; + }; + embeddedWasmModule = false ? ( + // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires + (true ? null : null).default + ) : void 0; + importWasmModule = async (urlOverride, prefixOverride, isMultiThreaded) => { + if (!urlOverride && !prefixOverride && embeddedWasmModule && scriptSrc && isSameOrigin(scriptSrc)) { + return [void 0, embeddedWasmModule]; + } else { + const wasmModuleFilename = true ? "ort-wasm-simd-threaded.jsep.mjs" : "ort-wasm-simd-threaded.mjs"; + const wasmModuleUrl = urlOverride ?? normalizeUrl(wasmModuleFilename, prefixOverride); + const needPreload = !isNode && isMultiThreaded && wasmModuleUrl && !isSameOrigin(wasmModuleUrl, prefixOverride); + const url = needPreload ? await preload(wasmModuleUrl) : wasmModuleUrl ?? fallbackUrl(wasmModuleFilename, prefixOverride); + return [needPreload ? url : void 0, await dynamicImportDefault(url)]; + } + }; + } + }); + + // web/lib/wasm/wasm-factory.ts + var wasm2, initialized, initializing, aborted, isMultiThreadSupported, isSimdSupported, isRelaxedSimdSupported, initializeWebAssembly, getInstance; + var init_wasm_factory = __esm({ + "web/lib/wasm/wasm-factory.ts"() { + "use strict"; + init_wasm_utils_import(); + initialized = false; + initializing = false; + aborted = false; + isMultiThreadSupported = () => { + if (typeof SharedArrayBuffer === "undefined") { + return false; + } + try { + if (typeof MessageChannel !== "undefined") { + new MessageChannel().port1.postMessage(new SharedArrayBuffer(1)); + } + return WebAssembly.validate( + new Uint8Array([ + 0, + 97, + 115, + 109, + 1, + 0, + 0, + 0, + 1, + 4, + 1, + 96, + 0, + 0, + 3, + 2, + 1, + 0, + 5, + 4, + 1, + 3, + 1, + 1, + 10, + 11, + 1, + 9, + 0, + 65, + 0, + 254, + 16, + 2, + 0, + 26, + 11 + ]) + ); + } catch (e) { + return false; + } + }; + isSimdSupported = () => { + try { + return WebAssembly.validate( + new Uint8Array([ + 0, + 97, + 115, + 109, + 1, + 0, + 0, + 0, + 1, + 4, + 1, + 96, + 0, + 0, + 3, + 2, + 1, + 0, + 10, + 30, + 1, + 28, + 0, + 65, + 0, + 253, + 15, + 253, + 12, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 253, + 186, + 1, + 26, + 11 + ]) + ); + } catch (e) { + return false; + } + }; + isRelaxedSimdSupported = () => { + try { + return WebAssembly.validate( + new Uint8Array([ + 0, + 97, + 115, + 109, + 1, + 0, + 0, + 0, + 1, + 5, + 1, + 96, + 0, + 1, + 123, + 3, + 2, + 1, + 0, + 10, + 19, + 1, + 17, + 0, + 65, + 1, + 253, + 15, + 65, + 2, + 253, + 15, + 65, + 3, + 253, + 15, + 253, + 147, + 2, + 11 + ]) + ); + } catch (e) { + return false; + } + }; + initializeWebAssembly = async (flags) => { + if (initialized) { + return Promise.resolve(); + } + if (initializing) { + throw new Error("multiple calls to 'initializeWebAssembly()' detected."); + } + if (aborted) { + throw new Error("previous call to 'initializeWebAssembly()' failed."); + } + initializing = true; + const timeout = flags.initTimeout; + let numThreads = flags.numThreads; + if (flags.simd === false) { + } else if (flags.simd === "relaxed") { + if (!isRelaxedSimdSupported()) { + throw new Error("Relaxed WebAssembly SIMD is not supported in the current environment."); + } + } else if (!isSimdSupported()) { + throw new Error("WebAssembly SIMD is not supported in the current environment."); + } + const multiThreadSupported = isMultiThreadSupported(); + if (numThreads > 1 && !multiThreadSupported) { + if (typeof self !== "undefined" && !self.crossOriginIsolated) { + console.warn( + "env.wasm.numThreads is set to " + numThreads + ", but this will not work unless you enable crossOriginIsolated mode. See https://web.dev/cross-origin-isolation-guide/ for more info." + ); + } + console.warn( + "WebAssembly multi-threading is not supported in the current environment. Falling back to single-threading." + ); + flags.numThreads = numThreads = 1; + } + const wasmPaths = flags.wasmPaths; + const wasmPrefixOverride = typeof wasmPaths === "string" ? wasmPaths : void 0; + const mjsPathOverrideFlag = wasmPaths?.mjs; + const mjsPathOverride = mjsPathOverrideFlag?.href ?? mjsPathOverrideFlag; + const wasmPathOverrideFlag = wasmPaths?.wasm; + const wasmPathOverride = wasmPathOverrideFlag?.href ?? wasmPathOverrideFlag; + const wasmBinaryOverride = flags.wasmBinary; + const [objectUrl, ortWasmFactory] = await importWasmModule(mjsPathOverride, wasmPrefixOverride, numThreads > 1); + let isTimeout = false; + const tasks = []; + if (timeout > 0) { + tasks.push( + new Promise((resolve) => { + setTimeout(() => { + isTimeout = true; + resolve(); + }, timeout); + }) + ); + } + tasks.push( + new Promise((resolve, reject) => { + const config = { + /** + * The number of threads. WebAssembly will create (Module.numThreads - 1) workers. If it is 1, no worker will be + * created. + */ + numThreads + }; + if (wasmBinaryOverride) { + config.wasmBinary = wasmBinaryOverride; + } else if (wasmPathOverride || wasmPrefixOverride) { + config.locateFile = (fileName) => wasmPathOverride ?? wasmPrefixOverride + fileName; + } else if (mjsPathOverride && mjsPathOverride.indexOf("blob:") !== 0) { + config.locateFile = (fileName) => new URL(fileName, mjsPathOverride).href; + } else if (objectUrl) { + const inferredWasmPathPrefix = inferWasmPathPrefixFromScriptSrc(); + if (inferredWasmPathPrefix) { + config.locateFile = (fileName) => inferredWasmPathPrefix + fileName; + } + } + ortWasmFactory(config).then( + // wasm module initialized successfully + (module2) => { + initializing = false; + initialized = true; + wasm2 = module2; + resolve(); + if (objectUrl) { + URL.revokeObjectURL(objectUrl); + } + }, + // wasm module failed to initialize + (what) => { + initializing = false; + aborted = true; + reject(what); + } + ); + }) + ); + await Promise.race(tasks); + if (isTimeout) { + throw new Error(`WebAssembly backend initializing failed due to timeout: ${timeout}ms`); + } + }; + getInstance = () => { + if (initialized && wasm2) { + return wasm2; + } + throw new Error("WebAssembly is not initialized yet."); + }; + } + }); + + // web/lib/wasm/wasm-utils.ts + var allocWasmString, iterateExtraOptions, checkLastError; + var init_wasm_utils = __esm({ + "web/lib/wasm/wasm-utils.ts"() { + "use strict"; + init_wasm_factory(); + allocWasmString = (data, allocs) => { + const wasm3 = getInstance(); + const dataLength = wasm3.lengthBytesUTF8(data) + 1; + const dataOffset = wasm3._malloc(dataLength); + wasm3.stringToUTF8(data, dataOffset, dataLength); + allocs.push(dataOffset); + return dataOffset; + }; + iterateExtraOptions = (options, prefix, seen, handler) => { + if (typeof options == "object" && options !== null) { + if (seen.has(options)) { + throw new Error("Circular reference in options"); + } else { + seen.add(options); + } + } + Object.entries(options).forEach(([key, value]) => { + const name2 = prefix ? prefix + key : key; + if (typeof value === "object") { + iterateExtraOptions(value, name2 + ".", seen, handler); + } else if (typeof value === "string" || typeof value === "number") { + handler(name2, value.toString()); + } else if (typeof value === "boolean") { + handler(name2, value ? "1" : "0"); + } else { + throw new Error(`Can't handle extra config type: ${typeof value}`); + } + }); + }; + checkLastError = (message) => { + const wasm3 = getInstance(); + const stack = wasm3.stackSave(); + try { + const ptrSize = wasm3.PTR_SIZE; + const paramsOffset = wasm3.stackAlloc(2 * ptrSize); + wasm3._OrtGetLastError(paramsOffset, paramsOffset + ptrSize); + const errorCode = Number(wasm3.getValue(paramsOffset, ptrSize === 4 ? "i32" : "i64")); + const errorMessagePointer = wasm3.getValue(paramsOffset + ptrSize, "*"); + const errorMessage = errorMessagePointer ? wasm3.UTF8ToString(errorMessagePointer) : ""; + throw new Error(`${message} ERROR_CODE: ${errorCode}, ERROR_MESSAGE: ${errorMessage}`); + } finally { + wasm3.stackRestore(stack); + } + }; + } + }); + + // web/lib/wasm/run-options.ts + var setRunOptions; + var init_run_options = __esm({ + "web/lib/wasm/run-options.ts"() { + "use strict"; + init_wasm_factory(); + init_wasm_utils(); + setRunOptions = (options) => { + const wasm3 = getInstance(); + let runOptionsHandle = 0; + const allocs = []; + const runOptions = options || {}; + try { + if (options?.logSeverityLevel === void 0) { + runOptions.logSeverityLevel = 2; + } else if (typeof options.logSeverityLevel !== "number" || !Number.isInteger(options.logSeverityLevel) || options.logSeverityLevel < 0 || options.logSeverityLevel > 4) { + throw new Error(`log serverity level is not valid: ${options.logSeverityLevel}`); + } + if (options?.logVerbosityLevel === void 0) { + runOptions.logVerbosityLevel = 0; + } else if (typeof options.logVerbosityLevel !== "number" || !Number.isInteger(options.logVerbosityLevel)) { + throw new Error(`log verbosity level is not valid: ${options.logVerbosityLevel}`); + } + if (options?.terminate === void 0) { + runOptions.terminate = false; + } + let tagDataOffset = 0; + if (options?.tag !== void 0) { + tagDataOffset = allocWasmString(options.tag, allocs); + } + runOptionsHandle = wasm3._OrtCreateRunOptions( + runOptions.logSeverityLevel, + runOptions.logVerbosityLevel, + !!runOptions.terminate, + tagDataOffset + ); + if (runOptionsHandle === 0) { + checkLastError("Can't create run options."); + } + if (options?.extra !== void 0) { + iterateExtraOptions(options.extra, "", /* @__PURE__ */ new WeakSet(), (key, value) => { + const keyDataOffset = allocWasmString(key, allocs); + const valueDataOffset = allocWasmString(value, allocs); + if (wasm3._OrtAddRunConfigEntry(runOptionsHandle, keyDataOffset, valueDataOffset) !== 0) { + checkLastError(`Can't set a run config entry: ${key} - ${value}.`); + } + }); + } + return [runOptionsHandle, allocs]; + } catch (e) { + if (runOptionsHandle !== 0) { + wasm3._OrtReleaseRunOptions(runOptionsHandle); + } + allocs.forEach((alloc) => wasm3._free(alloc)); + throw e; + } + }; + } + }); + + // web/lib/wasm/session-options.ts + var getGraphOptimzationLevel, getExecutionMode, appendDefaultOptions, appendSessionConfig, setExecutionProviders, setSessionOptions; + var init_session_options = __esm({ + "web/lib/wasm/session-options.ts"() { + "use strict"; + init_wasm_factory(); + init_wasm_utils(); + getGraphOptimzationLevel = (graphOptimizationLevel) => { + switch (graphOptimizationLevel) { + case "disabled": + return 0; + case "basic": + return 1; + case "extended": + return 2; + case "all": + return 99; + default: + throw new Error(`unsupported graph optimization level: ${graphOptimizationLevel}`); + } + }; + getExecutionMode = (executionMode) => { + switch (executionMode) { + case "sequential": + return 0; + case "parallel": + return 1; + default: + throw new Error(`unsupported execution mode: ${executionMode}`); + } + }; + appendDefaultOptions = (options) => { + if (!options.extra) { + options.extra = {}; + } + if (!options.extra.session) { + options.extra.session = {}; + } + const session = options.extra.session; + if (!session.use_ort_model_bytes_directly) { + session.use_ort_model_bytes_directly = "1"; + } + if (options.executionProviders && options.executionProviders.some((ep) => (typeof ep === "string" ? ep : ep.name) === "webgpu")) { + options.enableMemPattern = false; + } + }; + appendSessionConfig = (sessionOptionsHandle, key, value, allocs) => { + const keyDataOffset = allocWasmString(key, allocs); + const valueDataOffset = allocWasmString(value, allocs); + if (getInstance()._OrtAddSessionConfigEntry(sessionOptionsHandle, keyDataOffset, valueDataOffset) !== 0) { + checkLastError(`Can't set a session config entry: ${key} - ${value}.`); + } + }; + setExecutionProviders = async (sessionOptionsHandle, executionProviders, allocs) => { + for (const ep of executionProviders) { + let epName = typeof ep === "string" ? ep : ep.name; + const epOptions = []; + switch (epName) { + case "webnn": + epName = "WEBNN"; + if (typeof ep !== "string") { + const webnnOptions = ep; + const deviceType = webnnOptions?.deviceType; + if (deviceType) { + appendSessionConfig(sessionOptionsHandle, "deviceType", deviceType, allocs); + } + } + break; + case "webgpu": + if (false) { + epName = "WebGPU"; + let customDevice; + if (typeof ep !== "string") { + const customOptions = ep; + if (customOptions.device) { + if (typeof GPUDevice !== "undefined" && customOptions.device instanceof GPUDevice) { + customDevice = customOptions.device; + } else { + throw new Error("Invalid GPU device set in WebGPU EP options."); + } + } + } + const info = getInstance().webgpuRegisterDevice(customDevice); + if (info) { + const [deviceId, instanceHandle, deviceHandle] = info; + appendEpOption(epOptions, "deviceId", deviceId.toString(), allocs); + appendEpOption(epOptions, "webgpuInstance", instanceHandle.toString(), allocs); + appendEpOption(epOptions, "webgpuDevice", deviceHandle.toString(), allocs); + } + } else { + epName = "JS"; + if (typeof ep !== "string") { + const webgpuOptions = ep; + if (webgpuOptions?.preferredLayout) { + if (webgpuOptions.preferredLayout !== "NCHW" && webgpuOptions.preferredLayout !== "NHWC") { + throw new Error(`preferredLayout must be either 'NCHW' or 'NHWC': ${webgpuOptions.preferredLayout}`); + } + appendSessionConfig(sessionOptionsHandle, "preferredLayout", webgpuOptions.preferredLayout, allocs); + } + } + } + break; + case "wasm": + case "cpu": + continue; + default: + throw new Error(`not supported execution provider: ${epName}`); + } + const epNameDataOffset = allocWasmString(epName, allocs); + const epOptionsCount = epOptions.length; + let keysOffset = 0; + let valuesOffset = 0; + if (epOptionsCount > 0) { + keysOffset = getInstance()._malloc(epOptionsCount * getInstance().PTR_SIZE); + allocs.push(keysOffset); + valuesOffset = getInstance()._malloc(epOptionsCount * getInstance().PTR_SIZE); + allocs.push(valuesOffset); + for (let i = 0; i < epOptionsCount; i++) { + getInstance().setValue(keysOffset + i * getInstance().PTR_SIZE, epOptions[i][0], "*"); + getInstance().setValue(valuesOffset + i * getInstance().PTR_SIZE, epOptions[i][1], "*"); + } + } + if (await getInstance()._OrtAppendExecutionProvider( + sessionOptionsHandle, + epNameDataOffset, + keysOffset, + valuesOffset, + epOptionsCount + ) !== 0) { + checkLastError(`Can't append execution provider: ${epName}.`); + } + } + }; + setSessionOptions = async (options) => { + const wasm3 = getInstance(); + let sessionOptionsHandle = 0; + const allocs = []; + const sessionOptions = options || {}; + appendDefaultOptions(sessionOptions); + try { + const graphOptimizationLevel = getGraphOptimzationLevel(sessionOptions.graphOptimizationLevel ?? "all"); + const executionMode = getExecutionMode(sessionOptions.executionMode ?? "sequential"); + const logIdDataOffset = typeof sessionOptions.logId === "string" ? allocWasmString(sessionOptions.logId, allocs) : 0; + const logSeverityLevel = sessionOptions.logSeverityLevel ?? 2; + if (!Number.isInteger(logSeverityLevel) || logSeverityLevel < 0 || logSeverityLevel > 4) { + throw new Error(`log serverity level is not valid: ${logSeverityLevel}`); + } + const logVerbosityLevel = sessionOptions.logVerbosityLevel ?? 0; + if (!Number.isInteger(logVerbosityLevel) || logVerbosityLevel < 0 || logVerbosityLevel > 4) { + throw new Error(`log verbosity level is not valid: ${logVerbosityLevel}`); + } + const optimizedModelFilePathOffset = typeof sessionOptions.optimizedModelFilePath === "string" ? allocWasmString(sessionOptions.optimizedModelFilePath, allocs) : 0; + sessionOptionsHandle = wasm3._OrtCreateSessionOptions( + graphOptimizationLevel, + !!sessionOptions.enableCpuMemArena, + !!sessionOptions.enableMemPattern, + executionMode, + !!sessionOptions.enableProfiling, + 0, + logIdDataOffset, + logSeverityLevel, + logVerbosityLevel, + optimizedModelFilePathOffset + ); + if (sessionOptionsHandle === 0) { + checkLastError("Can't create session options."); + } + if (sessionOptions.executionProviders) { + await setExecutionProviders(sessionOptionsHandle, sessionOptions.executionProviders, allocs); + } + if (sessionOptions.enableGraphCapture !== void 0) { + if (typeof sessionOptions.enableGraphCapture !== "boolean") { + throw new Error(`enableGraphCapture must be a boolean value: ${sessionOptions.enableGraphCapture}`); + } + appendSessionConfig( + sessionOptionsHandle, + "enableGraphCapture", + sessionOptions.enableGraphCapture.toString(), + allocs + ); + } + if (sessionOptions.freeDimensionOverrides) { + for (const [name2, value] of Object.entries(sessionOptions.freeDimensionOverrides)) { + if (typeof name2 !== "string") { + throw new Error(`free dimension override name must be a string: ${name2}`); + } + if (typeof value !== "number" || !Number.isInteger(value) || value < 0) { + throw new Error(`free dimension override value must be a non-negative integer: ${value}`); + } + const nameOffset = allocWasmString(name2, allocs); + if (wasm3._OrtAddFreeDimensionOverride(sessionOptionsHandle, nameOffset, value) !== 0) { + checkLastError(`Can't set a free dimension override: ${name2} - ${value}.`); + } + } + } + if (sessionOptions.extra !== void 0) { + iterateExtraOptions(sessionOptions.extra, "", /* @__PURE__ */ new WeakSet(), (key, value) => { + appendSessionConfig(sessionOptionsHandle, key, value, allocs); + }); + } + return [sessionOptionsHandle, allocs]; + } catch (e) { + if (sessionOptionsHandle !== 0) { + if (wasm3._OrtReleaseSessionOptions(sessionOptionsHandle) !== 0) { + checkLastError("Can't release session options."); + } + } + allocs.forEach((alloc) => wasm3._free(alloc)); + throw e; + } + }; + } + }); + + // web/lib/wasm/wasm-common.ts + var tensorDataTypeStringToEnum, tensorDataTypeEnumToString, calculateTensorSizeInBytes, tensorTypeToTypedArrayConstructor, logLevelStringToEnum, isGpuBufferSupportedType, isMLTensorSupportedType, dataLocationStringToEnum; + var init_wasm_common = __esm({ + "web/lib/wasm/wasm-common.ts"() { + "use strict"; + tensorDataTypeStringToEnum = (type) => { + switch (type) { + case "int8": + return 3 /* int8 */; + case "uint8": + return 2 /* uint8 */; + case "bool": + return 9 /* bool */; + case "int16": + return 5 /* int16 */; + case "uint16": + return 4 /* uint16 */; + case "int32": + return 6 /* int32 */; + case "uint32": + return 12 /* uint32 */; + case "float16": + return 10 /* float16 */; + case "float32": + return 1 /* float */; + case "float64": + return 11 /* double */; + case "string": + return 8 /* string */; + case "int64": + return 7 /* int64 */; + case "uint64": + return 13 /* uint64 */; + case "int4": + return 22 /* int4 */; + case "uint4": + return 21 /* uint4 */; + default: + throw new Error(`unsupported data type: ${type}`); + } + }; + tensorDataTypeEnumToString = (typeProto) => { + switch (typeProto) { + case 3 /* int8 */: + return "int8"; + case 2 /* uint8 */: + return "uint8"; + case 9 /* bool */: + return "bool"; + case 5 /* int16 */: + return "int16"; + case 4 /* uint16 */: + return "uint16"; + case 6 /* int32 */: + return "int32"; + case 12 /* uint32 */: + return "uint32"; + case 10 /* float16 */: + return "float16"; + case 1 /* float */: + return "float32"; + case 11 /* double */: + return "float64"; + case 8 /* string */: + return "string"; + case 7 /* int64 */: + return "int64"; + case 13 /* uint64 */: + return "uint64"; + case 22 /* int4 */: + return "int4"; + case 21 /* uint4 */: + return "uint4"; + default: + throw new Error(`unsupported data type: ${typeProto}`); + } + }; + calculateTensorSizeInBytes = (dateType, dimsOrSize) => { + const elementSize = [ + -1, + // undefined = 0 + 4, + // float = 1 + 1, + // uint8 = 2 + 1, + // int8 = 3 + 2, + // uint16 = 4 + 2, + // int16 = 5 + 4, + // int32 = 6 + 8, + // int64 = 7 + -1, + // string = 8 + 1, + // bool = 9 + 2, + // float16 = 10 + 8, + // double = 11 + 4, + // uint32 = 12 + 8, + // uint64 = 13 + -1, + // complex64 = 14 + -1, + // complex128 = 15 + -1, + // bfloat16 = 16 + -1, + // FLOAT8E4M3FN = 17 + -1, + // FLOAT8E4M3FNUZ = 18 + -1, + // FLOAT8E5M2 = 19 + -1, + // FLOAT8E5M2FNUZ = 20 + 0.5, + // uint4 = 21 + 0.5 + // int4 = 22 + ][dateType]; + const size = typeof dimsOrSize === "number" ? dimsOrSize : dimsOrSize.reduce((a, b) => a * b, 1); + return elementSize > 0 ? Math.ceil(size * elementSize) : void 0; + }; + tensorTypeToTypedArrayConstructor = (type) => { + switch (type) { + case "float16": + return typeof Float16Array !== "undefined" && Float16Array.from ? Float16Array : Uint16Array; + case "float32": + return Float32Array; + case "uint8": + return Uint8Array; + case "int8": + return Int8Array; + case "uint16": + return Uint16Array; + case "int16": + return Int16Array; + case "int32": + return Int32Array; + case "bool": + return Uint8Array; + case "float64": + return Float64Array; + case "uint32": + return Uint32Array; + case "int64": + return BigInt64Array; + case "uint64": + return BigUint64Array; + default: + throw new Error(`unsupported type: ${type}`); + } + }; + logLevelStringToEnum = (logLevel) => { + switch (logLevel) { + case "verbose": + return 0; + case "info": + return 1; + case "warning": + return 2; + case "error": + return 3; + case "fatal": + return 4; + default: + throw new Error(`unsupported logging level: ${logLevel}`); + } + }; + isGpuBufferSupportedType = (type) => type === "float32" || type === "float16" || type === "int32" || type === "int64" || type === "uint32" || type === "uint8" || type === "bool" || type === "uint4" || type === "int4"; + isMLTensorSupportedType = (type) => type === "float32" || type === "float16" || type === "int32" || type === "int64" || type === "uint32" || type === "uint64" || type === "int8" || type === "uint8" || type === "bool" || type === "uint4" || type === "int4"; + dataLocationStringToEnum = (location2) => { + switch (location2) { + case "none": + return 0; + case "cpu": + return 1; + case "cpu-pinned": + return 2; + case "texture": + return 3; + case "gpu-buffer": + return 4; + case "ml-tensor": + return 5; + default: + throw new Error(`unsupported data location: ${location2}`); + } + }; + } + }); + + // web/lib/wasm/wasm-utils-load-file.ts + var loadFile; + var init_wasm_utils_load_file = __esm({ + "web/lib/wasm/wasm-utils-load-file.ts"() { + "use strict"; + init_wasm_utils_env(); + loadFile = async (file) => { + if (typeof file === "string") { + if (isNode) { + try { + const { readFile } = __require("node:fs/promises"); + return new Uint8Array(await readFile(file)); + } catch (e) { + if (e.code === "ERR_FS_FILE_TOO_LARGE") { + const { createReadStream } = __require("node:fs"); + const stream = createReadStream(file); + const chunks = []; + for await (const chunk of stream) { + chunks.push(chunk); + } + return new Uint8Array(Buffer.concat(chunks)); + } + throw e; + } + } else { + const response = await fetch(file); + if (!response.ok) { + throw new Error(`failed to load external data file: ${file}`); + } + const contentLengthHeader = response.headers.get("Content-Length"); + const fileSize = contentLengthHeader ? parseInt(contentLengthHeader, 10) : 0; + if (fileSize < 1073741824) { + return new Uint8Array(await response.arrayBuffer()); + } else { + if (!response.body) { + throw new Error(`failed to load external data file: ${file}, no response body.`); + } + const reader = response.body.getReader(); + let buffer; + try { + buffer = new ArrayBuffer(fileSize); + } catch (e) { + if (e instanceof RangeError) { + const pages = Math.ceil(fileSize / 65536); + buffer = new WebAssembly.Memory({ initial: pages, maximum: pages }).buffer; + } else { + throw e; + } + } + let offset = 0; + while (true) { + const { done, value } = await reader.read(); + if (done) { + break; + } + const chunkSize = value.byteLength; + const chunk = new Uint8Array(buffer, offset, chunkSize); + chunk.set(value); + offset += chunkSize; + } + return new Uint8Array(buffer, 0, fileSize); + } + } + } else if (file instanceof Blob) { + return new Uint8Array(await file.arrayBuffer()); + } else if (file instanceof Uint8Array) { + return file; + } else { + return new Uint8Array(file); + } + }; + } + }); + + // web/lib/wasm/jsep/log.ts + var logLevelPrefix, doLog, configLogLevel, debug, configureLogger, LOG, LOG_DEBUG; + var init_log = __esm({ + "web/lib/wasm/jsep/log.ts"() { + "use strict"; + init_wasm_common(); + logLevelPrefix = ["V", "I", "W", "E", "F"]; + doLog = (level, message) => { + console.log(`[${logLevelPrefix[level]},${(/* @__PURE__ */ new Date()).toISOString()}]${message}`); + }; + configureLogger = ($configLogLevel, $debug) => { + configLogLevel = $configLogLevel; + debug = $debug; + }; + LOG = (logLevel, msg) => { + const messageLevel = logLevelStringToEnum(logLevel); + const configLevel = logLevelStringToEnum(configLogLevel); + if (messageLevel >= configLevel) { + doLog(messageLevel, typeof msg === "function" ? msg() : msg); + } + }; + LOG_DEBUG = (...args) => { + if (debug) { + LOG(...args); + } + }; + } + }); + + // web/lib/wasm/jsep/util.ts + var MatMulUtil2, BroadcastUtil2, ShapeUtil2, PoolConvUtil2, GemmUtil2, MIN_CLIP2, MAX_CLIP2; + var init_util2 = __esm({ + "web/lib/wasm/jsep/util.ts"() { + "use strict"; + MatMulUtil2 = class { + /** + * 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]]; + } + }; + BroadcastUtil2 = class { + /** + * 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 = MatMulUtil2.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; + } + const max = Math.max(aLen, bLen); + if (aLen && bLen) { + cdims[crank - i] = Math.max(aLen, bLen); + } else { + if (max > 1) { + return void 0; + } + cdims[crank - i] = 0; + } + } + return cdims; + } + /** + * 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; + } + }; + ShapeUtil2 = class _ShapeUtil { + /** + * calculate the size (number of elements) + */ + static size(dims) { + return _ShapeUtil.getSizeFromDimensionRange(dims, 0, dims.length); + } + /** + * convert dims corresponding to type change to pack. ex. uint8 data to uint32 + */ + static convertShape(dims, size = 4) { + const rank = dims.length; + if (rank === 0) { + return []; + } + const newDims = new Array(rank); + let i = rank - 1; + while (i >= 0) { + if (dims[i] % size === 0) { + newDims[i] = dims[i] / size; + break; + } + if (size % dims[i] !== 0) { + throw new Error("cannot convert shape"); + } + newDims[i] = 1; + size /= dims[i]; + i--; + } + for (i--; i >= 0; i--) { + newDims[i] = dims[i]; + } + return newDims; + } + /** + * calculate the size (number of elements) from the given 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); + } + /** + * calculate the size (number of elements) to the given 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); + } + /** + * calculate the size (number of elements) from and to the given axis [start, end) + */ + static getSizeFromDimensionRange(dims, start, end) { + let size = 1; + for (let i = start; i < end; i++) { + if (dims[i] < 0) { + throw new Error( + // eslint-disable-next-line max-len + "cannot get valid size from specified dimension range. Most likely the range contains negative values in them." + ); + } + size *= Number(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; + } + /** + * normailze axis of range [-r, r) into [0, r). + */ + static normalizeAxis(axis, tensorRank) { + if (axis < -tensorRank && axis >= tensorRank) { + throw new Error("unsupported axis for this operation."); + } + return axis < 0 ? axis + tensorRank : axis; + } + static normalizeAxes(axes, tensorRank) { + return axes.map((x) => this.normalizeAxis(x, tensorRank ?? axes.length)); + } + /** + * 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, pad2) { + const rank = dims.length; + return dims.map((v, i) => v + pad2[i] + pad2[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]); + } + }; + PoolConvUtil2 = 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, isChannelLast, 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 + (isChannelLast ? 1 : 2)], + strides[dim], + dilations[dim], + kernelShape[dim], + pads, + dim, + dim + inputDims.length - 2, + autoPad + ); + } + } + /** + * Calculate the output shape for Pool ops based on input attributes. (Should be used only for Pool ops) + * @param isGlobalOperator If true, perform global pooling. + * @param inputDims The input tensor dimension. (inputs[0].dims) + * @param strides Stride along each axis. + * @param dilations Dilation along each axis. + * @param kernelShape The size of the kernel along each axis. + * @param pads Padding for the beginning and ending along each axis. + * @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each + * dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID. + */ + static computePoolOutputShape(isGlobalOperator, inputDims, strides, dilations, kernelShape, pads, autoPad) { + if (inputDims.length <= 0) { + throw new Error("input shape must be of size greater than 0"); + } + const outputDims = [inputDims[0], inputDims[1]]; + _PoolConvUtil.computeShapeHelper( + isGlobalOperator, + inputDims, + outputDims, + strides, + dilations, + kernelShape, + pads, + autoPad + ); + return outputDims; + } + /** + * Calculate the output shape for Conv op based on input attributes. (Should be used only for Conv op) + * @param inputDims The input tensor dimension. (inputs[0].dims) + * @param filterDims The filter tensor dimension. (inputs[1].dims) + * @param strides Stride along each axis. + * @param kernelShape The size of the kernel along each axis. + * @param pads Padding for the beginning and ending along each axis. + * @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each + * dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID. + */ + static computeConvOutputShape(inputDims, filterDims, strides, dilations, kernelShape, pads, autoPad) { + if (inputDims.length <= 0 || filterDims.length <= 0) { + throw new Error("invalid input tensor dims or invalid filter tensor dims"); + } + const outputDims = [inputDims[0], filterDims[0]]; + _PoolConvUtil.computeShapeHelper(false, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad); + return outputDims; + } + // will compute output shapes for data dimensions ONLY (i.e.) no batch size and channels + // called by computePoolOutputShape() and computeConvOutputShape() + // adjust pads based on 'autoPad' attribute prior to shape computation + static computeShapeHelper(isGlobalOperator, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad) { + if (isGlobalOperator) { + for (let dim = 0; dim < inputDims.length - 2; dim++) { + outputDims.push(1); + } + } else { + for (let dim = 0; dim < inputDims.length - 2; dim++) { + outputDims.push( + _PoolConvUtil.adjustPadAndReturnShape( + inputDims[dim + 2], + strides[dim], + dilations[dim], + kernelShape[dim], + pads, + dim, + dim + inputDims.length - 2, + autoPad + ) + ); + } + } + } + // helper for computeShapeHelper() and adjustPadsBasedOnAutoPad() + // adjusts pad value for given 'autoPad' string and computes output shape along a particular dimension + static adjustPadAndReturnShape(inSize, stride, dilation, kernel, pads, padHeadIndex, padTailIndex, autoPad) { + const dkernel = dilation * (kernel - 1) + 1; + if (autoPad && autoPad !== "NOTSET") { + switch (autoPad) { + case "VALID": + pads[padHeadIndex] = 0; + pads[padTailIndex] = 0; + return Math.floor((inSize - dkernel) / stride + 1); + case "SAME_LOWER": + case "SAME_UPPER": + if (dilation !== 1) { + throw new Error("Dilation not supported for SAME_UPPER or SAME_LOWER"); + } else { + const legacyTargetSize = (inSize + stride - 1) / stride; + const padNeeded = (legacyTargetSize - 1) * stride + kernel - inSize; + pads[padHeadIndex] = autoPad === "SAME_LOWER" ? Math.floor((padNeeded + 1) / 2) : Math.floor(padNeeded / 2); + pads[padTailIndex] = padNeeded - pads[padHeadIndex]; + return Math.floor((inSize + padNeeded - kernel) / stride + 1); + } + default: + throw new Error("Unsupported AutoPad type"); + } + } else { + return Math.floor((inSize + pads[padHeadIndex] + pads[padTailIndex] - dkernel) / stride + 1); + } + } + }; + GemmUtil2 = 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 && !BroadcastUtil2.isValidBroadcast(biasShape, [M, N])) { + throw new Error("gemm: invalid bias shape for broadcast"); + } + return [M, N, K]; + } + }; + MIN_CLIP2 = -34028234663852886e22; + MAX_CLIP2 = 34028234663852886e22; + } + }); + + // web/lib/wasm/jsep/tensor-view.ts + var createView2; + var init_tensor_view = __esm({ + "web/lib/wasm/jsep/tensor-view.ts"() { + "use strict"; + init_wasm_common(); + createView2 = (dataBuffer, type) => new (tensorTypeToTypedArrayConstructor(type))(dataBuffer); + } + }); + + // web/lib/wasm/jsep/webnn/tensor-manager.ts + var webnnDataTypeToSize, convertDataToInt32, convertInt32ToData, tensorGuid, createNewTensorId, webnnDataTypeToFallback, calculateByteLength, TensorWrapper, TensorIdTracker, TensorManagerImpl, createTensorManager; + var init_tensor_manager = __esm({ + "web/lib/wasm/jsep/webnn/tensor-manager.ts"() { + "use strict"; + init_wasm_common(); + init_log(); + webnnDataTypeToSize = /* @__PURE__ */ new Map([ + ["float32", 32], + ["float16", 16], + ["int32", 32], + ["uint32", 32], + ["int64", 64], + ["uint64", 64], + ["int8", 8], + ["uint8", 8], + ["int4", 4], + ["uint4", 4] + ]); + convertDataToInt32 = (data, dataType) => { + if (dataType === "int32") { + return data; + } + const dataTypeSize = webnnDataTypeToSize.get(dataType); + if (!dataTypeSize) { + throw new Error(`WebNN backend does not support data type: ${dataType}`); + } + const bytesPerElement = dataTypeSize / 8; + if (data.byteLength % bytesPerElement !== 0) { + throw new Error(`Invalid Uint8Array length - must be a multiple of ${bytesPerElement}.`); + } + const numElements = data.byteLength / bytesPerElement; + const originalArray = new (tensorTypeToTypedArrayConstructor(dataType))(data.buffer, data.byteOffset, numElements); + switch (dataType) { + case "int64": + case "uint64": { + const int32Array = new Int32Array(numElements); + for (let i = 0; i < numElements; i++) { + const value = originalArray[i]; + if (value > 2147483647n || value < -2147483648n) { + throw new Error(`Can not convert int64 data to int32 - value out of range.`); + } + int32Array[i] = Number(value); + } + return new Uint8Array(int32Array.buffer); + } + case "int8": + case "uint8": + case "uint32": { + if (dataType === "uint32") { + if (originalArray.some((value) => value > 2147483647)) { + throw new Error(`Can not convert uint32 data to int32 - value out of range.`); + } + } + const int32Array = Int32Array.from(originalArray, Number); + return new Uint8Array(int32Array.buffer); + } + default: + throw new Error(`Unsupported data conversion from ${dataType} to 'int32'`); + } + }; + convertInt32ToData = (data, dataType) => { + if (dataType === "int32") { + return data; + } + if (data.byteLength % 4 !== 0) { + throw new Error("Invalid Uint8Array length - must be a multiple of 4 (int32)."); + } + const numElements = data.byteLength / 4; + const int32Array = new Int32Array(data.buffer, data.byteOffset, numElements); + switch (dataType) { + case "int64": { + const bigInt64Array = BigInt64Array.from(int32Array, BigInt); + return new Uint8Array(bigInt64Array.buffer); + } + case "uint64": { + if (int32Array.some((value) => value < 0)) { + throw new Error("Can not convert int32 data to uin64 - negative value found."); + } + const bigUint64Array = BigUint64Array.from(int32Array, BigInt); + return new Uint8Array(bigUint64Array.buffer); + } + case "int8": { + if (int32Array.some((value) => value < -128 || value > 127)) { + throw new Error("Can not convert int32 data to int8 - value out of range."); + } + const int8Array = Int8Array.from(int32Array, Number); + return new Uint8Array(int8Array.buffer); + } + case "uint8": { + if (int32Array.some((value) => value < 0 || value > 255)) { + throw new Error("Can not convert int32 data to uint8 - value out of range."); + } + return Uint8Array.from(int32Array, Number); + } + case "uint32": { + if (int32Array.some((value) => value < 0)) { + throw new Error("Can not convert int32 data to uint32 - negative value found."); + } + const uint32Array = Uint32Array.from(int32Array, Number); + return new Uint8Array(uint32Array.buffer); + } + default: + throw new Error(`Unsupported data conversion from 'int32' to ${dataType}`); + } + }; + tensorGuid = 1; + createNewTensorId = () => tensorGuid++; + webnnDataTypeToFallback = /* @__PURE__ */ new Map([ + ["int8", "int32"], + ["uint8", "int32"], + ["uint32", "int32"], + ["int64", "int32"] + ]); + calculateByteLength = (dataType, shape2) => { + const dataTypeSize = webnnDataTypeToSize.get(dataType); + if (!dataTypeSize) { + throw new Error(`WebNN backend does not support data type: ${dataType}`); + } + return shape2.length > 0 ? Math.ceil(shape2.reduce((a, b) => a * b) * dataTypeSize / 8) : 0; + }; + TensorWrapper = class { + constructor(descriptor) { + // This flag is used to indicate whether the data has been converted to fallback data type. + this.isDataConverted = false; + const { sessionId, context, tensor, dataType, shape: shape2, fallbackDataType } = descriptor; + this.sessionId = sessionId; + this.mlContext = context; + this.mlTensor = tensor; + this.dataType = dataType; + this.tensorShape = shape2; + this.fallbackDataType = fallbackDataType; + } + get tensor() { + return this.mlTensor; + } + get type() { + return this.dataType; + } + get fallbackType() { + return this.fallbackDataType; + } + get shape() { + return this.tensorShape; + } + get byteLength() { + return calculateByteLength(this.dataType, this.tensorShape); + } + destroy() { + LOG_DEBUG("verbose", () => "[WebNN] TensorWrapper.destroy"); + this.mlTensor.destroy(); + } + write(data) { + this.mlContext.writeTensor(this.mlTensor, data); + } + async read(dstBuffer) { + if (this.fallbackDataType) { + const data = await this.mlContext.readTensor(this.mlTensor); + const originalData = convertInt32ToData(new Uint8Array(data), this.dataType); + if (dstBuffer) { + const targetBuffer = dstBuffer instanceof ArrayBuffer ? new Uint8Array(dstBuffer) : new Uint8Array(dstBuffer.buffer, dstBuffer.byteOffset, dstBuffer.byteLength); + targetBuffer.set(originalData); + return void 0; + } else { + return originalData.buffer; + } + } else { + return dstBuffer ? this.mlContext.readTensor(this.mlTensor, dstBuffer) : this.mlContext.readTensor(this.mlTensor); + } + } + canReuseTensor(context, dataType, shape2) { + return this.mlContext === context && this.dataType === dataType && this.tensorShape.length === shape2.length && this.tensorShape.every((v, i) => v === shape2[i]); + } + setIsDataConverted(isConverted) { + this.isDataConverted = isConverted; + } + }; + TensorIdTracker = class { + constructor(tensorManager, wrapper) { + this.tensorManager = tensorManager; + this.wrapper = wrapper; + } + get tensorWrapper() { + return this.wrapper; + } + releaseTensor() { + if (this.tensorWrapper) { + this.tensorManager.releaseTensor(this.tensorWrapper); + this.wrapper = void 0; + } + } + async ensureTensor(sessionId, dataType, shape2, copyOld) { + const context = this.tensorManager.getMLContext(sessionId); + let fallbackDataType; + if (!context.opSupportLimits().input.dataTypes.includes(dataType)) { + fallbackDataType = webnnDataTypeToFallback.get(dataType); + if (!fallbackDataType || !context.opSupportLimits().input.dataTypes.includes(fallbackDataType)) { + throw new Error(`WebNN backend does not support data type: ${dataType}`); + } + LOG_DEBUG( + "verbose", + () => `[WebNN] TensorIdTracker.ensureTensor: fallback dataType from ${dataType} to ${fallbackDataType}` + ); + } + if (this.wrapper) { + if (this.wrapper.canReuseTensor(context, dataType, shape2)) { + return this.wrapper.tensor; + } else { + if (copyOld) { + if (this.wrapper.byteLength !== calculateByteLength(dataType, shape2)) { + throw new Error("Unable to copy data to tensor with different size."); + } + this.activeUpload = new Uint8Array(await this.wrapper.read()); + } + this.tensorManager.releaseTensor(this.wrapper); + } + } + const usage = typeof MLTensorUsage == "undefined" ? void 0 : MLTensorUsage.READ | MLTensorUsage.WRITE; + this.wrapper = await this.tensorManager.getCachedTensor( + sessionId, + dataType, + shape2, + usage, + true, + true, + fallbackDataType + ); + if (copyOld && this.activeUpload) { + this.wrapper.write(this.activeUpload); + this.activeUpload = void 0; + } + return this.wrapper.tensor; + } + upload(data) { + let newData = data; + if (this.wrapper) { + if (this.wrapper.fallbackType) { + if (this.wrapper.fallbackType === "int32") { + newData = convertDataToInt32(data, this.wrapper.type); + this.wrapper.setIsDataConverted(true); + } else { + throw new Error(`Unsupported fallback data type: ${this.wrapper.fallbackType}`); + } + } + if (data.byteLength === this.wrapper.byteLength) { + this.wrapper.write(newData); + return; + } else { + LOG_DEBUG("verbose", () => "Data size does not match tensor size. Releasing tensor."); + this.releaseTensor(); + } + } + if (this.activeUpload) { + this.activeUpload.set(newData); + } else { + this.activeUpload = new Uint8Array(newData); + } + } + async download(dstBuffer) { + if (this.activeUpload) { + const dstData = this.wrapper?.isDataConverted ? convertInt32ToData(this.activeUpload, this.wrapper?.type) : this.activeUpload; + if (dstBuffer) { + if (dstBuffer instanceof ArrayBuffer) { + new Uint8Array(dstBuffer).set(dstData); + } else { + new Uint8Array(dstBuffer.buffer, dstBuffer.byteOffset, dstBuffer.byteLength).set(dstData); + } + return; + } else { + return dstData.buffer; + } + } + if (!this.wrapper) { + throw new Error("Tensor has not been created."); + } + if (!dstBuffer) { + return this.wrapper.read(); + } + return this.wrapper.read(dstBuffer); + } + }; + TensorManagerImpl = class { + constructor(backend2) { + this.backend = backend2; + this.tensorTrackersById = /* @__PURE__ */ new Map(); + this.freeTensors = []; + this.externalTensors = /* @__PURE__ */ new Set(); + } + getMLContext(sessionId) { + const context = this.backend.getMLContext(sessionId); + if (!context) { + throw new Error("MLContext not found for session."); + } + return context; + } + reserveTensorId() { + const tensorId = createNewTensorId(); + this.tensorTrackersById.set(tensorId, new TensorIdTracker(this)); + return tensorId; + } + releaseTensorId(tensorId) { + const tensorTracker = this.tensorTrackersById.get(tensorId); + if (!tensorTracker) { + return; + } + this.tensorTrackersById.delete(tensorId); + if (tensorTracker.tensorWrapper) { + this.releaseTensor(tensorTracker.tensorWrapper); + } + } + async ensureTensor(sessionId, tensorId, dataType, shape2, copyOld) { + LOG_DEBUG( + "verbose", + () => `[WebNN] TensorManager.ensureTensor {tensorId: ${tensorId}, dataType: ${dataType}, shape: ${shape2}, copyOld: ${copyOld}}` + ); + const tensor = this.tensorTrackersById.get(tensorId); + if (!tensor) { + throw new Error("Tensor not found."); + } + return tensor.ensureTensor(sessionId, dataType, shape2, copyOld); + } + upload(tensorId, data) { + const tensor = this.tensorTrackersById.get(tensorId); + if (!tensor) { + throw new Error("Tensor not found."); + } + tensor.upload(data); + } + async download(tensorId, dstBuffer) { + LOG_DEBUG( + "verbose", + () => `[WebNN] TensorManager.download {tensorId: ${tensorId}, dstBuffer: ${dstBuffer?.byteLength}}` + ); + const tensorTracker = this.tensorTrackersById.get(tensorId); + if (!tensorTracker) { + throw new Error("Tensor not found."); + } + return tensorTracker.download(dstBuffer); + } + releaseTensorsForSession(sessionId) { + for (const tensor of this.freeTensors) { + if (tensor.sessionId === sessionId) { + tensor.destroy(); + } + } + this.freeTensors = this.freeTensors.filter((tensor) => tensor.sessionId !== sessionId); + } + registerTensor(sessionId, mlTensor, dataType, shape2) { + const context = this.getMLContext(sessionId); + const tensorId = createNewTensorId(); + const wrapper = new TensorWrapper({ + sessionId, + context, + tensor: mlTensor, + dataType, + shape: shape2 + }); + this.tensorTrackersById.set(tensorId, new TensorIdTracker(this, wrapper)); + this.externalTensors.add(wrapper); + return tensorId; + } + /** + * Get or create an MLTensor with the given data type and shape. + */ + async getCachedTensor(sessionId, dataType, shape2, usage, writable, readable, fallbackDataType) { + const context = this.getMLContext(sessionId); + for (const [index, tensor2] of this.freeTensors.entries()) { + if (tensor2.canReuseTensor(context, dataType, shape2)) { + LOG_DEBUG( + "verbose", + () => `[WebNN] Reusing tensor {dataType: ${dataType}, ${fallbackDataType ? `fallbackDataType: ${fallbackDataType},` : ""} shape: ${shape2}` + ); + const wrapper = this.freeTensors.splice(index, 1)[0]; + wrapper.sessionId = sessionId; + return wrapper; + } + } + LOG_DEBUG( + "verbose", + () => `[WebNN] MLContext.createTensor {dataType: ${dataType}, ${fallbackDataType ? `fallbackDataType: ${fallbackDataType},` : ""} shape: ${shape2}}` + ); + const tensor = await context.createTensor({ + dataType: fallbackDataType ?? dataType, + // If fallback data type is provided, use it. + shape: shape2, + dimensions: shape2, + usage, + writable, + readable + }); + return new TensorWrapper({ sessionId, context, tensor, dataType, shape: shape2, fallbackDataType }); + } + /** + * Release tensor for reuse unless external. + */ + releaseTensor(tensorWrapper) { + if (this.externalTensors.has(tensorWrapper)) { + this.externalTensors.delete(tensorWrapper); + } + this.freeTensors.push(tensorWrapper); + } + }; + createTensorManager = (...args) => new TensorManagerImpl(...args); + } + }); + + // web/lib/wasm/jsep/backend-webnn.ts + var onnxDataTypeToWebnnDataType, compareMLContextOptions, WebNNBackend; + var init_backend_webnn = __esm({ + "web/lib/wasm/jsep/backend-webnn.ts"() { + "use strict"; + init_wasm_common(); + init_wasm_factory(); + init_tensor_view(); + init_tensor_manager(); + init_log(); + onnxDataTypeToWebnnDataType = /* @__PURE__ */ new Map([ + [1 /* float */, "float32"], + [10 /* float16 */, "float16"], + [6 /* int32 */, "int32"], + [12 /* uint32 */, "uint32"], + [7 /* int64 */, "int64"], + [13 /* uint64 */, "uint64"], + [22 /* int4 */, "int4"], + [21 /* uint4 */, "uint4"], + [3 /* int8 */, "int8"], + [2 /* uint8 */, "uint8"], + [9 /* bool */, "uint8"] + ]); + compareMLContextOptions = (a, b) => { + if (a === b) { + return true; + } + if (a === void 0 || b === void 0) { + return false; + } + const aKeys = Object.keys(a).sort(); + const bKeys = Object.keys(b).sort(); + return aKeys.length === bKeys.length && aKeys.every((key, index) => key === bKeys[index] && a[key] === b[key]); + }; + WebNNBackend = class { + constructor(env3) { + /** + * Tensor managers for each session. + */ + this.tensorManager = createTensorManager(this); + /** + * Maps from session id to MLContexts. + */ + this.mlContextBySessionId = /* @__PURE__ */ new Map(); + /** + * Maps from MLContext to session ids. + */ + this.sessionIdsByMLContext = /* @__PURE__ */ new Map(); + /** + * Cache of MLContexts. + */ + this.mlContextCache = []; + /** + * Maps from session id to list of graph inputs. + */ + this.sessionGraphInputs = /* @__PURE__ */ new Map(); + /** + * Maps from session id to list of graph outputs. + */ + this.sessionGraphOutputs = /* @__PURE__ */ new Map(); + /** + * Temporary graph inputs for the current session. + * These inputs will be registered when the session is created. + */ + this.temporaryGraphInputs = []; + /** + * Temporary graph outputs for the current session. + * These outputs will be registered when the session is created. + */ + this.temporaryGraphOutputs = []; + /** + * Temporary tensors for the current session. + */ + this.temporarySessionTensorIds = /* @__PURE__ */ new Map(); + configureLogger(env3.logLevel, !!env3.debug); + } + get currentSessionId() { + if (this.activeSessionId === void 0) { + throw new Error("No active session"); + } + return this.activeSessionId; + } + onRunStart(sessionId) { + LOG_DEBUG("verbose", () => `[WebNN] onRunStart {sessionId: ${sessionId}}`); + this.activeSessionId = sessionId; + } + onRunEnd(sessionId) { + LOG_DEBUG("verbose", () => `[WebNN] onRunEnd {sessionId: ${sessionId}}`); + const tensorIds = this.temporarySessionTensorIds.get(sessionId); + if (!tensorIds) { + return; + } + for (const tensorId of tensorIds) { + LOG_DEBUG("verbose", () => `[WebNN] releasing temporary tensor {tensorId: ${tensorId}}`); + this.tensorManager.releaseTensorId(tensorId); + } + this.temporarySessionTensorIds.delete(sessionId); + this.activeSessionId = void 0; + } + async createMLContext(optionsOrDevice) { + if (optionsOrDevice instanceof GPUDevice) { + const mlContextIndex2 = this.mlContextCache.findIndex((entry) => entry.gpuDevice === optionsOrDevice); + if (mlContextIndex2 !== -1) { + return this.mlContextCache[mlContextIndex2].mlContext; + } else { + const mlContext = await navigator.ml.createContext(optionsOrDevice); + this.mlContextCache.push({ gpuDevice: optionsOrDevice, mlContext }); + return mlContext; + } + } else if (optionsOrDevice === void 0) { + const mlContextIndex2 = this.mlContextCache.findIndex( + (entry) => entry.options === void 0 && entry.gpuDevice === void 0 + ); + if (mlContextIndex2 !== -1) { + return this.mlContextCache[mlContextIndex2].mlContext; + } else { + const mlContext = await navigator.ml.createContext(); + this.mlContextCache.push({ mlContext }); + return mlContext; + } + } + const mlContextIndex = this.mlContextCache.findIndex( + (entry) => compareMLContextOptions(entry.options, optionsOrDevice) + ); + if (mlContextIndex !== -1) { + return this.mlContextCache[mlContextIndex].mlContext; + } else { + const mlContext = await navigator.ml.createContext(optionsOrDevice); + this.mlContextCache.push({ options: optionsOrDevice, mlContext }); + return mlContext; + } + } + registerMLContext(sessionId, mlContext) { + this.mlContextBySessionId.set(sessionId, mlContext); + let sessionIds = this.sessionIdsByMLContext.get(mlContext); + if (!sessionIds) { + sessionIds = /* @__PURE__ */ new Set(); + this.sessionIdsByMLContext.set(mlContext, sessionIds); + } + sessionIds.add(sessionId); + if (this.temporaryGraphInputs.length > 0) { + this.sessionGraphInputs.set(sessionId, this.temporaryGraphInputs); + this.temporaryGraphInputs = []; + } + if (this.temporaryGraphOutputs.length > 0) { + this.sessionGraphOutputs.set(sessionId, this.temporaryGraphOutputs); + this.temporaryGraphOutputs = []; + } + } + onReleaseSession(sessionId) { + this.sessionGraphInputs.delete(sessionId); + this.sessionGraphOutputs.delete(sessionId); + const mlContext = this.mlContextBySessionId.get(sessionId); + if (!mlContext) { + return; + } + this.tensorManager.releaseTensorsForSession(sessionId); + this.mlContextBySessionId.delete(sessionId); + const sessionIds = this.sessionIdsByMLContext.get(mlContext); + sessionIds.delete(sessionId); + if (sessionIds.size === 0) { + this.sessionIdsByMLContext.delete(mlContext); + const mlContextIndex = this.mlContextCache.findIndex((entry) => entry.mlContext === mlContext); + if (mlContextIndex !== -1) { + this.mlContextCache.splice(mlContextIndex, 1); + } + } + } + getMLContext(sessionId) { + return this.mlContextBySessionId.get(sessionId); + } + reserveTensorId() { + return this.tensorManager.reserveTensorId(); + } + releaseTensorId(tensorId) { + LOG_DEBUG("verbose", () => `[WebNN] releaseTensorId {tensorId: ${tensorId}}`); + this.tensorManager.releaseTensorId(tensorId); + } + async ensureTensor(sessionId, tensorId, onnxDataType, dimensions, copyOld) { + const webnnDataType = onnxDataTypeToWebnnDataType.get(onnxDataType); + if (!webnnDataType) { + throw new Error(`Unsupported ONNX data type: ${onnxDataType}`); + } + return this.tensorManager.ensureTensor( + sessionId ?? this.currentSessionId, + tensorId, + webnnDataType, + dimensions, + copyOld + ); + } + async createTemporaryTensor(sessionId, onnxDataType, shape2) { + LOG_DEBUG("verbose", () => `[WebNN] createTemporaryTensor {onnxDataType: ${onnxDataType}, shape: ${shape2}}`); + const dataType = onnxDataTypeToWebnnDataType.get(onnxDataType); + if (!dataType) { + throw new Error(`Unsupported ONNX data type: ${onnxDataType}`); + } + const tensorId = this.tensorManager.reserveTensorId(); + await this.tensorManager.ensureTensor(sessionId, tensorId, dataType, shape2, false); + const tensorIds = this.temporarySessionTensorIds.get(sessionId); + if (!tensorIds) { + this.temporarySessionTensorIds.set(sessionId, [tensorId]); + } else { + tensorIds.push(tensorId); + } + return tensorId; + } + uploadTensor(tensorId, data) { + const wasm3 = getInstance(); + if (!wasm3.shouldTransferToMLTensor) { + throw new Error("Trying to upload to a MLTensor while shouldTransferToMLTensor is false"); + } + LOG_DEBUG("verbose", () => `[WebNN] uploadTensor {tensorId: ${tensorId}, data: ${data.byteLength}}`); + this.tensorManager.upload(tensorId, data); + } + async downloadTensor(tensorId, dstBuffer) { + return this.tensorManager.download(tensorId, dstBuffer); + } + createMLTensorDownloader(tensorId, type) { + return async () => { + const data = await this.tensorManager.download(tensorId); + return createView2(data, type); + }; + } + registerMLTensor(sessionId, tensor, onnxDataType, dimensions) { + const webnnDataType = onnxDataTypeToWebnnDataType.get(onnxDataType); + if (!webnnDataType) { + throw new Error(`Unsupported ONNX data type: ${onnxDataType}`); + } + const id = this.tensorManager.registerTensor(sessionId, tensor, webnnDataType, dimensions); + LOG_DEBUG( + "verbose", + () => `[WebNN] registerMLTensor {tensor: ${tensor}, dataType: ${webnnDataType}, dimensions: ${dimensions}} -> {tensorId: ${id}}` + ); + return id; + } + // Register a WebNN Constant operand from external data. + registerMLConstant(externalFilePath, dataOffset, dataLength, builder, desc, mountedFiles, shouldConvertInt64ToInt32 = false) { + if (!mountedFiles) { + throw new Error("External mounted files are not available."); + } + let filePath = externalFilePath; + if (externalFilePath.startsWith("./")) { + filePath = externalFilePath.substring(2); + } + const fileData = mountedFiles.get(filePath); + if (!fileData) { + throw new Error(`File with name ${filePath} not found in preloaded files.`); + } + if (dataOffset + dataLength > fileData.byteLength) { + throw new Error("Out of bounds: data offset and length exceed the external file data size."); + } + const buffer = fileData.slice(dataOffset, dataOffset + dataLength).buffer; + let bufferView; + switch (desc.dataType) { + case "float32": + bufferView = new Float32Array(buffer); + break; + case "float16": + bufferView = typeof Float16Array !== "undefined" && Float16Array.from ? new Float16Array(buffer) : new Uint16Array(buffer); + break; + case "int32": + bufferView = new Int32Array(buffer); + break; + case "uint32": + bufferView = new Uint32Array(buffer); + break; + case "int64": + if (shouldConvertInt64ToInt32) { + const int32Buffer = convertDataToInt32(new Uint8Array(buffer), "int64"); + bufferView = new Int32Array(int32Buffer.buffer); + desc.dataType = "int32"; + } else { + bufferView = new BigInt64Array(buffer); + } + break; + case "uint64": + bufferView = new BigUint64Array(buffer); + break; + case "int8": + bufferView = new Int8Array(buffer); + break; + case "int4": + case "uint4": + case "uint8": + bufferView = new Uint8Array(buffer); + break; + default: + throw new Error(`Unsupported data type: ${desc.dataType} in creating WebNN Constant from external data.`); + } + LOG_DEBUG( + "verbose", + () => `[WebNN] registerMLConstant {dataType: ${desc.dataType}, shape: ${desc.shape}}} ${shouldConvertInt64ToInt32 ? "(Note: it was int64 data type and registered to int32 as workaround)" : ""}` + ); + return builder.constant(desc, bufferView); + } + registerGraphInput(inputName) { + this.temporaryGraphInputs.push(inputName); + } + registerGraphOutput(outputName) { + this.temporaryGraphOutputs.push(outputName); + } + isGraphInput(sessionId, inputName) { + const inputNames = this.sessionGraphInputs.get(sessionId); + if (!inputNames) { + return false; + } + return inputNames.includes(inputName); + } + isGraphOutput(sessionId, outputName) { + const outputNames = this.sessionGraphOutputs.get(sessionId); + if (!outputNames) { + return false; + } + return outputNames.includes(outputName); + } + isGraphInputOutputTypeSupported(sessionId, type, isInput = true) { + const context = this.mlContextBySessionId.get(sessionId); + const dataType = onnxDataTypeToWebnnDataType.get(tensorDataTypeStringToEnum(type)); + if (typeof dataType === "undefined") { + return false; + } + if (isInput) { + return !!context?.opSupportLimits().input.dataTypes.includes(dataType); + } else { + return !!context?.opSupportLimits().output.dataTypes.includes(dataType); + } + } + flush() { + } + }; + } + }); + + // web/lib/wasm/jsep/webgpu/types.ts + var init_types2 = __esm({ + "web/lib/wasm/jsep/webgpu/types.ts"() { + "use strict"; + } + }); + + // web/lib/wasm/jsep/webgpu/gpu-data-manager.ts + var bucketFreelist, bucketArr, calcNormalizedBufferSize, calcBucketBufferSize, guid, createNewGpuDataId, downloadGpuData, GpuDataManagerImpl, createGpuDataManager; + var init_gpu_data_manager = __esm({ + "web/lib/wasm/jsep/webgpu/gpu-data-manager.ts"() { + "use strict"; + init_log(); + init_types2(); + bucketFreelist = /* @__PURE__ */ new Map([ + [64, 250], + [128, 200], + [256, 200], + [512, 200], + [2048, 230], + [4096, 200], + [8192, 50], + [16384, 50], + [32768, 50], + [65536, 50], + [131072, 50], + [262144, 50], + [524288, 50], + [1048576, 50], + [2097152, 30], + [4194304, 20], + [8388608, 10], + [12582912, 10], + [16777216, 10], + [26214400, 15], + [33554432, 22], + [44236800, 2], + [58982400, 6], + // we don't want to cache the bucket sizes below but not caching them + // results in some major performance hits for models like sd-turbo. + [67108864, 6], + [134217728, 6], + [167772160, 6] + ]); + bucketArr = []; + calcNormalizedBufferSize = (size) => Math.ceil(Number(size) / 16) * 16; + calcBucketBufferSize = (size) => { + for (let idx = 0; idx < bucketArr.length; idx++) { + const sizeForBucket = bucketArr[idx]; + if (size <= sizeForBucket) { + return sizeForBucket; + } + } + return Math.ceil(size / 16) * 16; + }; + guid = 1; + createNewGpuDataId = () => guid++; + downloadGpuData = async (backend2, gpuBuffer, originalSize, getTargetBuffer) => { + const bufferSize = calcNormalizedBufferSize(originalSize); + const gpuReadBuffer = backend2.device.createBuffer( + // eslint-disable-next-line no-bitwise + { size: bufferSize, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ } + ); + try { + const commandEncoder = backend2.getCommandEncoder(); + backend2.endComputePass(); + commandEncoder.copyBufferToBuffer( + gpuBuffer, + 0, + gpuReadBuffer, + 0, + bufferSize + ); + backend2.flush(); + await gpuReadBuffer.mapAsync(GPUMapMode.READ); + const arrayBuffer = gpuReadBuffer.getMappedRange(); + if (getTargetBuffer) { + const targetBuffer = getTargetBuffer(); + targetBuffer.set(new Uint8Array(arrayBuffer, 0, originalSize)); + return targetBuffer; + } else { + return new Uint8Array(arrayBuffer.slice(0, originalSize)); + } + } finally { + gpuReadBuffer.destroy(); + } + }; + GpuDataManagerImpl = class { + constructor(backend2) { + this.backend = backend2; + this.storageCache = /* @__PURE__ */ new Map(); + this.freeBuffers = /* @__PURE__ */ new Map(); + this.freeUniformBuffers = /* @__PURE__ */ new Map(); + this.buffersPending = []; + this.capturedPendingBuffers = /* @__PURE__ */ new Map(); + for (const [key] of bucketFreelist) { + bucketArr.push(key); + this.freeBuffers.set(key, []); + this.freeUniformBuffers.set(key, []); + } + this.sessionCount = 0; + } + upload(id, data) { + const srcArrayBuffer = data.buffer; + const srcOffset = data.byteOffset; + const srcLength = data.byteLength; + const size = calcNormalizedBufferSize(srcLength); + const gpuDataCache = this.storageCache.get(id); + if (!gpuDataCache) { + throw new Error("gpu data for uploading does not exist"); + } + if (Number(gpuDataCache.originalSize) !== srcLength) { + throw new Error(`inconsistent data size. gpu data size=${gpuDataCache.originalSize}, data size=${srcLength}`); + } + const gpuBufferForUploading = this.backend.device.createBuffer( + // eslint-disable-next-line no-bitwise + { mappedAtCreation: true, size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.COPY_SRC } + ); + const arrayBuffer = gpuBufferForUploading.getMappedRange(); + new Uint8Array(arrayBuffer).set(new Uint8Array(srcArrayBuffer, srcOffset, srcLength)); + gpuBufferForUploading.unmap(); + const commandEncoder = this.backend.device.createCommandEncoder(); + commandEncoder.copyBufferToBuffer(gpuBufferForUploading, 0, gpuDataCache.gpuData.buffer, 0, size); + this.backend.device.queue.submit([commandEncoder.finish()]); + gpuBufferForUploading.destroy(); + LOG_DEBUG("verbose", () => `[WebGPU] GpuDataManager.upload(id=${id})`); + } + memcpy(sourceId, destinationId) { + const sourceGpuDataCache = this.storageCache.get(sourceId); + if (!sourceGpuDataCache) { + throw new Error("source gpu data for memcpy does not exist"); + } + const destinationGpuDataCache = this.storageCache.get(destinationId); + if (!destinationGpuDataCache) { + throw new Error("destination gpu data for memcpy does not exist"); + } + if (sourceGpuDataCache.originalSize !== destinationGpuDataCache.originalSize) { + throw new Error("inconsistent source and destination gpu data size"); + } + const size = calcNormalizedBufferSize(sourceGpuDataCache.originalSize); + const commandEncoder = this.backend.getCommandEncoder(); + this.backend.endComputePass(); + commandEncoder.copyBufferToBuffer( + sourceGpuDataCache.gpuData.buffer, + 0, + destinationGpuDataCache.gpuData.buffer, + 0, + size + ); + } + registerExternalBuffer(buffer, originalSize, previous) { + let id; + if (previous) { + id = previous[0]; + if (buffer === previous[1]) { + LOG_DEBUG( + "verbose", + () => `[WebGPU] GpuDataManager.registerExternalBuffer(size=${originalSize}) => id=${id}, buffer is the same, skip.` + ); + return id; + } else if (this.backend.capturedCommandList.has(this.backend.currentSessionId)) { + throw new Error(`Registering a different external buffer under graph capture mode is not supported yet. + Please use the previous external buffer!`); + } + } else { + id = createNewGpuDataId(); + } + this.storageCache.set(id, { gpuData: { id, type: 0 /* default */, buffer }, originalSize }); + LOG_DEBUG( + "verbose", + () => `[WebGPU] GpuDataManager.registerExternalBuffer(size=${originalSize}) => id=${id}, registered.` + ); + return id; + } + unregisterExternalBuffer(id) { + if (id !== void 0) { + this.storageCache.delete(id); + LOG_DEBUG("verbose", () => `[WebGPU] GpuDataManager.unregisterExternalBuffer() => id=${id}`); + } + } + // eslint-disable-next-line no-bitwise + create(size, usage = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST) { + const bufferSize = calcBucketBufferSize(size); + let gpuBuffer; + const isStorage = (usage & GPUBufferUsage.STORAGE) === GPUBufferUsage.STORAGE; + const isUniform = (usage & GPUBufferUsage.UNIFORM) === GPUBufferUsage.UNIFORM; + if (isStorage || isUniform) { + const freeBuffers = isStorage ? this.freeBuffers : this.freeUniformBuffers; + const buffers = freeBuffers.get(bufferSize); + if (!buffers) { + gpuBuffer = this.backend.device.createBuffer({ size: bufferSize, usage }); + } else { + if (buffers.length > 0) { + gpuBuffer = buffers.pop(); + } else { + gpuBuffer = this.backend.device.createBuffer({ size: bufferSize, usage }); + } + } + } else { + gpuBuffer = this.backend.device.createBuffer({ size: bufferSize, usage }); + } + const gpuData = { id: createNewGpuDataId(), type: 0 /* default */, buffer: gpuBuffer }; + this.storageCache.set(gpuData.id, { gpuData, originalSize: Number(size) }); + LOG_DEBUG("verbose", () => `[WebGPU] GpuDataManager.create(size=${size}) => id=${gpuData.id}`); + return gpuData; + } + get(id) { + return this.storageCache.get(id)?.gpuData; + } + release(idInput) { + const id = typeof idInput === "bigint" ? Number(idInput) : idInput; + const cachedData = this.storageCache.get(id); + if (!cachedData) { + if (this.storageCache.size === 0) { + return 0; + } else { + throw new Error("releasing data does not exist"); + } + } + LOG_DEBUG("verbose", () => `[WebGPU] GpuDataManager.release(id=${id}), gpuDataId=${cachedData.gpuData.id}`); + this.storageCache.delete(id); + this.buffersPending.push(cachedData.gpuData.buffer); + return cachedData.originalSize; + } + async download(id, getTargetBuffer) { + const cachedData = this.storageCache.get(Number(id)); + if (!cachedData) { + throw new Error("data does not exist"); + } + await downloadGpuData(this.backend, cachedData.gpuData.buffer, cachedData.originalSize, getTargetBuffer); + } + refreshPendingBuffers() { + if (this.buffersPending.length === 0) { + return; + } + if (this.backend.sessionStatus === "default") { + for (const buffer of this.buffersPending) { + const maxInFreeList = bucketFreelist.get(buffer.size); + if ((buffer.usage & GPUBufferUsage.STORAGE) === GPUBufferUsage.STORAGE) { + const freelist = this.freeBuffers.get(buffer.size) || []; + if (maxInFreeList === void 0 || freelist.length >= maxInFreeList) { + buffer.destroy(); + } else { + freelist.push(buffer); + } + } else if ((buffer.usage & GPUBufferUsage.UNIFORM) === GPUBufferUsage.UNIFORM) { + const freelist = this.freeUniformBuffers.get(buffer.size) || []; + if (maxInFreeList === void 0 || freelist.length >= maxInFreeList) { + buffer.destroy(); + } else { + freelist.push(buffer); + } + } else { + buffer.destroy(); + } + } + this.buffersPending = []; + } else { + let capturedBuffers = this.capturedPendingBuffers.get(this.backend.currentSessionId); + if (!capturedBuffers) { + capturedBuffers = []; + this.capturedPendingBuffers.set(this.backend.currentSessionId, capturedBuffers); + } + for (const buffer of this.buffersPending) { + capturedBuffers.push(buffer); + } + this.buffersPending = []; + } + } + dispose() { + this.freeBuffers.forEach((buffers) => { + buffers.forEach((buffer) => { + buffer.destroy(); + }); + }); + this.freeUniformBuffers.forEach((buffers) => { + buffers.forEach((buffer) => { + buffer.destroy(); + }); + }); + this.storageCache.forEach((storage) => { + storage.gpuData.buffer.destroy(); + }); + this.capturedPendingBuffers.forEach((buffers) => { + buffers.forEach((buffer) => { + buffer.destroy(); + }); + }); + this.storageCache = /* @__PURE__ */ new Map(); + this.freeBuffers = /* @__PURE__ */ new Map(); + this.freeUniformBuffers = /* @__PURE__ */ new Map(); + this.capturedPendingBuffers = /* @__PURE__ */ new Map(); + } + onCreateSession() { + this.sessionCount += 1; + } + onReleaseSession(sessionId) { + const pendingBuffers = this.capturedPendingBuffers.get(sessionId); + if (pendingBuffers) { + pendingBuffers.forEach((buffer) => { + buffer.destroy(); + }); + this.capturedPendingBuffers.delete(sessionId); + } + this.sessionCount -= 1; + if (this.sessionCount === 0) { + LOG_DEBUG("warning", () => "[WebGPU] Clearing webgpu buffer cache"); + this.storageCache.forEach((storage) => { + storage.gpuData.buffer.destroy(); + }); + this.storageCache = /* @__PURE__ */ new Map(); + } + } + }; + createGpuDataManager = (...args) => new GpuDataManagerImpl(...args); + } + }); + + // web/lib/wasm/jsep/webgpu/attribute-with-cache-key.ts + var AttributeWithCacheKeyImpl2, createAttributeWithCacheKey2; + var init_attribute_with_cache_key2 = __esm({ + "web/lib/wasm/jsep/webgpu/attribute-with-cache-key.ts"() { + "use strict"; + AttributeWithCacheKeyImpl2 = 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; + } + }; + createAttributeWithCacheKey2 = (attribute) => new AttributeWithCacheKeyImpl2(attribute); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/common.ts + var WORKGROUP_SIZE, getWgslMappedType, tensorTypeToWsglStorageType, tensorTypeToWsglValueType, createTensorShapeVariables, getMaxComponents, fillVector, castToF32, sumVector, getElementAt, createIndicesHelper, inputVariable, outputVariable, atomicOutputVariable, internalVariable, ShaderHelperImpl, createShaderHelper; + var init_common = __esm({ + "web/lib/wasm/jsep/webgpu/ops/common.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + WORKGROUP_SIZE = 64; + getWgslMappedType = (type, components) => { + if (components === 3) { + throw new Error("vec3 has same alignment as vec4, use vec4 instead"); + } + switch (Number(type)) { + case 10 /* float16 */: + return components > 1 ? `vec${components}` : "f16"; + case 1 /* float */: + return components > 1 ? `vec${components}` : "f32"; + case 6 /* int32 */: + return components > 1 ? `vec${components}` : "i32"; + case 12 /* uint32 */: + return components > 1 ? `vec${components}` : "u32"; + case 7 /* int64 */: + if (components > 1) { + throw new Error("currently not supported vecX of uint64 yet"); + } + return ["vec2", "i32"]; + case 13 /* uint64 */: + if (components > 1) { + throw new Error("currently not supported vecX of uint64 yet"); + } + return ["vec2", "u32"]; + case 9 /* bool */: + if (components !== 4) { + throw new Error("bool must be vec4"); + } + return ["u32", "vec4"]; + case 22 /* int4 */: + return "i32"; + case 21 /* uint4 */: + return "u32"; + default: + throw new Error(`Unknown data type: ${type}`); + } + }; + tensorTypeToWsglStorageType = (type, components = 1) => { + const mappedType = getWgslMappedType(type, components); + return typeof mappedType === "string" ? mappedType : mappedType[0]; + }; + tensorTypeToWsglValueType = (type, components = 1) => { + const mappedType = getWgslMappedType(type, components); + return typeof mappedType === "string" ? mappedType : mappedType[1]; + }; + createTensorShapeVariables = (...dims) => { + const programUniforms = []; + dims.forEach((dim) => { + if (dim.length !== 0) { + programUniforms.push( + { type: 12 /* uint32 */, data: dim }, + { type: 12 /* uint32 */, data: ShapeUtil2.computeStrides(dim) } + ); + } + }); + return programUniforms; + }; + getMaxComponents = (size) => { + if (size % 4 === 0) { + return 4; + } else if (size % 2 === 0) { + return 2; + } + return 1; + }; + fillVector = (dataType = "f32", components, value = "0") => { + if (!components || components === 1) { + return `${dataType}(${value})`; + } + return `vec${components}<${dataType}>(${value})`; + }; + castToF32 = (dataType, components, value) => { + if (dataType === "f32") { + return value; + } + if (components === 1) { + return `f32(${value})`; + } + return `vec${components}(${value})`; + }; + sumVector = (name2, components) => { + if (components === 4) { + return `(${name2}.x + ${name2}.y + ${name2}.z + ${name2}.w)`; + } else if (components === 2) { + return `(${name2}.x + ${name2}.y)`; + } else if (components === 3) { + return `(${name2}.x + ${name2}.y + ${name2}.z)`; + } + return name2; + }; + getElementAt = (name2, index, length, type) => { + if (name2.startsWith("uniforms.") && length > 4) { + if (typeof index === "string") { + if (type === "f16") { + return `${name2}[(${index}) / 8][(${index}) % 8 / 4][(${index}) % 8 % 4]`; + } else { + return `${name2}[(${index}) / 4][(${index}) % 4]`; + } + } else { + if (type === "f16") { + return `${name2}[${Math.floor(index / 8)}][${Math.floor(index % 8 / 4)}][${index % 8 % 4}]`; + } else { + return `${name2}[${Math.floor(index / 4)}][${index % 4}]`; + } + } + } else { + return length > 1 ? `${name2}[${index}]` : name2; + } + }; + createIndicesHelper = (name2, tensorType, shapeOrRank, usage, components) => { + const useUniform = typeof shapeOrRank === "number"; + const rank = useUniform ? shapeOrRank : shapeOrRank.length; + const rankIdentity = [...new Array(rank).keys()]; + const indicesType = rank < 2 ? "u32" : rank <= 4 ? `vec${rank}` : `array`; + const mappedType = getWgslMappedType(tensorType, components); + const valueType = typeof mappedType === "string" ? mappedType : mappedType[1]; + const storageType = typeof mappedType === "string" ? mappedType : mappedType[0]; + const type = { indices: indicesType, value: valueType, storage: storageType, tensor: tensorType }; + const normalizeDim = (dim) => typeof dim === "string" ? dim : `${dim}u`; + const implementationUsed = { + offsetToIndices: false, + indicesToOffset: false, + broadcastedIndicesToOffset: false, + set: false, + setByIndices: false, + get: false, + getByIndices: false + }; + const uniformPrefix = useUniform ? "uniforms." : ""; + const shape2 = `${uniformPrefix}${name2}_shape`; + const strides = `${uniformPrefix}${name2}_strides`; + let o2iSnippet = ""; + for (let i = 0; i < rank - 1; i++) { + o2iSnippet += ` + let dim${i} = current / ${getElementAt(strides, i, rank)}; + let rest${i} = current % ${getElementAt(strides, i, rank)}; + indices[${i}] = dim${i}; + current = rest${i}; + `; + } + o2iSnippet += `indices[${rank - 1}] = current;`; + const offsetToIndicesImplementation = rank < 2 ? "" : ` + fn o2i_${name2}(offset: u32) -> ${type.indices} { + var indices: ${type.indices}; + var current = offset; + ${o2iSnippet} + return indices; + }`; + const offsetToIndices2 = (varOffset) => { + implementationUsed.offsetToIndices = true; + return rank < 2 ? varOffset : `o2i_${name2}(${varOffset})`; + }; + const offsets = []; + if (rank >= 2) { + for (let i = rank - 1; i >= 0; i--) { + offsets.push(`${getElementAt(strides, i, rank)} * (indices[${i}])`); + } + } + const indicesToOffsetImplementation = rank < 2 ? "" : ` + fn i2o_${name2}(indices: ${type.indices}) -> u32 { + return ${offsets.join("+")}; + }`; + const indicesToOffset = (varIndices) => { + implementationUsed.indicesToOffset = true; + return rank < 2 ? varIndices : `i2o_${name2}(${varIndices})`; + }; + const indices = (...init2) => rank === 0 ? "0u" : `${type.indices}(${init2.map(normalizeDim).join(",")})`; + const indicesGet = (varIndices, idx) => { + if (rank < 2) { + return `${varIndices}`; + } else { + return `${getElementAt(varIndices, idx, rank)}`; + } + }; + const indicesSet = (varIndices, idx, value) => { + if (rank < 2) { + return `${varIndices}=${value};`; + } else { + return `${getElementAt(varIndices, idx, rank)}=${value};`; + } + }; + const broadcastedIndicesToOffsetImplementation = {}; + const broadcastedIndicesToOffset = (varIndices, output) => { + implementationUsed.broadcastedIndicesToOffset = true; + const implKey = `${output.name}broadcastedIndicesTo${name2}Offset`; + if (implKey in broadcastedIndicesToOffsetImplementation) { + return `${implKey}(${varIndices})`; + } + const offsets2 = []; + for (let i = rank - 1; i >= 0; i--) { + const idx = output.indicesGet("outputIndices", i + output.rank - rank); + offsets2.push(`${indicesGet(strides, i)} * (${idx} % ${indicesGet(shape2, i)})`); + } + broadcastedIndicesToOffsetImplementation[implKey] = `fn ${implKey}(outputIndices: ${output.type.indices}) -> u32 { + return ${offsets2.length > 0 ? offsets2.join("+") : "0u"}; + }`; + return `${implKey}(${varIndices})`; + }; + const setByOffset = (offset, value) => (() => { + if (type.storage === type.value) { + return `${name2}[${offset}]=${value};`; + } else if (type.storage === "vec2" && type.value === "i32") { + return `${name2}[${offset}]=vec2(u32(${value}), select(0u, 0xFFFFFFFFu, ${value} < 0));`; + } else if (type.storage === "vec2" && type.value === "u32") { + return `${name2}[${offset}]=vec2(u32(${value}), 0u);`; + } else if (type.storage === "u32" && type.value === "vec4") { + return `${name2}[${offset}]=dot(vec4(0x1, 0x100, 0x10000, 0x1000000), vec4(${value}));`; + } else { + throw new Error(`not supported combination of storage type ${type.storage} and value type ${type.value} yet`); + } + })(); + const getByOffset = (offset) => (() => { + if (type.storage === type.value) { + return `${name2}[${offset}]`; + } else if (type.storage === "vec2" && type.value === "i32") { + return `i32(${name2}[${offset}].x)`; + } else if (type.storage === "vec2" && type.value === "u32") { + return `u32(${name2}[${offset}].x)`; + } else if (type.storage === "u32" && type.value === "vec4") { + return `vec4(bool(${name2}[${offset}] & 0xFFu), bool(${name2}[${offset}] & 0xFF00u), bool(${name2}[${offset}] & 0xFF0000u), bool(${name2}[${offset}] & 0xFF000000u))`; + } else { + throw new Error(`not supported combination of storage type ${type.storage} and value type ${type.value} yet`); + } + })(); + const getByIndicesImplementation = rank < 2 ? "" : ` + fn get_${name2}ByIndices(indices: ${type.indices}) -> ${valueType} { + return ${getByOffset(`i2o_${name2}(indices)`)}; + }`; + const getImplementation = rank < 2 ? "" : (() => { + const functionParams = rankIdentity.map((i) => `d${i}: u32`).join(", "); + const dimsParams = rankIdentity.map((i) => `d${i}`).join(", "); + return ` + fn get_${name2}(${functionParams}) -> ${valueType} { + return get_${name2}ByIndices(${indices(dimsParams)}); + }`; + })(); + const get = (...indices2) => { + if (indices2.length !== rank) { + throw new Error(`indices length must be ${rank}`); + } + const normalizedIndices = indices2.map(normalizeDim).join(","); + if (rank === 0) { + return getByOffset("0u"); + } else if (rank === 1) { + return getByOffset(normalizedIndices[0]); + } else { + implementationUsed.get = true; + implementationUsed.getByIndices = true; + implementationUsed.indicesToOffset = true; + return `get_${name2}(${normalizedIndices})`; + } + }; + const getByIndices = (varIndices) => { + if (rank < 2) { + return getByOffset(varIndices); + } else { + implementationUsed.getByIndices = true; + implementationUsed.indicesToOffset = true; + return `get_${name2}ByIndices(${varIndices})`; + } + }; + const setByIndicesImplementation = rank < 2 ? "" : ` + fn set_${name2}ByIndices(indices: ${type.indices}, value: ${valueType}) { + ${setByOffset(`i2o_${name2}(indices)`, "value")} + }`; + const setImplementation = rank < 2 ? "" : (() => { + const functionParams = rankIdentity.map((i) => `d${i}: u32`).join(", "); + const dimsParams = rankIdentity.map((i) => `d${i}`).join(", "); + return ` + fn set_${name2}(${functionParams}, value: ${valueType}) { + set_${name2}ByIndices(${indices(dimsParams)}, value); + }`; + })(); + const set = (...indicesAndValue) => { + if (indicesAndValue.length !== rank + 1) { + throw new Error(`indices length must be ${rank}`); + } + const value = indicesAndValue[rank]; + if (typeof value !== "string") { + throw new Error("value must be string"); + } + const normalizedIndices = indicesAndValue.slice(0, rank).map(normalizeDim).join(","); + if (rank === 0) { + return setByOffset("0u", value); + } else if (rank === 1) { + return setByOffset(normalizedIndices[0], value); + } else { + implementationUsed.set = true; + implementationUsed.setByIndices = true; + implementationUsed.indicesToOffset = true; + return `set_${name2}(${normalizedIndices}, ${value})`; + } + }; + const setByIndices = (varIndices, value) => { + if (rank < 2) { + return setByOffset(varIndices, value); + } else { + implementationUsed.setByIndices = true; + implementationUsed.indicesToOffset = true; + return `set_${name2}ByIndices(${varIndices}, ${value});`; + } + }; + const impl = () => { + const impls = []; + let needShapeStrides = false; + if (implementationUsed.offsetToIndices) { + impls.push(offsetToIndicesImplementation); + needShapeStrides = true; + } + if (implementationUsed.indicesToOffset) { + impls.push(indicesToOffsetImplementation); + needShapeStrides = true; + } + if (implementationUsed.broadcastedIndicesToOffset) { + Object.values(broadcastedIndicesToOffsetImplementation).forEach((impl2) => impls.push(impl2)); + needShapeStrides = true; + } + if (implementationUsed.set) { + impls.push(setImplementation); + needShapeStrides = true; + } + if (implementationUsed.setByIndices) { + impls.push(setByIndicesImplementation); + needShapeStrides = true; + } + if (implementationUsed.get) { + impls.push(getImplementation); + needShapeStrides = true; + } + if (implementationUsed.getByIndices) { + impls.push(getByIndicesImplementation); + needShapeStrides = true; + } + if (!useUniform && needShapeStrides) { + impls.unshift( + `const ${shape2} = ${type.indices}(${shapeOrRank.join(",")});`, + `const ${strides} = ${type.indices}(${ShapeUtil2.computeStrides(shapeOrRank).join(",")});` + ); + } + return impls.join("\n"); + }; + return { + impl, + type, + offsetToIndices: offsetToIndices2, + indicesToOffset, + broadcastedIndicesToOffset, + indices, + indicesGet, + indicesSet, + set, + setByOffset, + setByIndices, + get, + getByOffset, + getByIndices, + // isVec4, + usage, + name: name2, + strides, + shape: shape2, + rank + }; + }; + inputVariable = (name2, type, shapeOrRank, components = 1) => createIndicesHelper(name2, type, shapeOrRank, "input", components); + outputVariable = (name2, type, shapeOrRank, components = 1) => createIndicesHelper(name2, type, shapeOrRank, "output", components); + atomicOutputVariable = (name2, type, shapeOrRank) => createIndicesHelper(name2, type, shapeOrRank, "atomicOutput", 1); + internalVariable = (name2, type, shapeOrRank, components = 1) => createIndicesHelper(name2, type, shapeOrRank, "internal", components); + ShaderHelperImpl = class { + constructor(normalizedDispatchGroup, limits) { + this.normalizedDispatchGroup = normalizedDispatchGroup; + this.limits = limits; + this.internalVariables = []; + this.variables = []; + this.uniforms = []; + this.variableIndex = 0; + } + guardAgainstOutOfBoundsWorkgroupSizes(size) { + const sizeInCode = typeof size === "number" ? `${size}u` : size; + return `if (global_idx >= ${sizeInCode}) { return; }`; + } + mainStart(workgroupSize = WORKGROUP_SIZE) { + const workgroupSizeX = typeof workgroupSize === "number" ? workgroupSize : workgroupSize[0]; + const workgroupSizeY = typeof workgroupSize === "number" ? 1 : workgroupSize[1]; + const workgroupSizeZ = typeof workgroupSize === "number" ? 1 : workgroupSize[2]; + if (workgroupSizeX > this.limits.maxComputeWorkgroupSizeX || workgroupSizeY > this.limits.maxComputeWorkgroupSizeY || workgroupSizeZ > this.limits.maxComputeWorkgroupSizeZ) { + throw new Error( + `workgroup size [${workgroupSizeX}, ${workgroupSizeY}, ${workgroupSizeZ}] exceeds the maximum workgroup size [${this.limits.maxComputeWorkgroupSizeX}, ${this.limits.maxComputeWorkgroupSizeY}, ${this.limits.maxComputeWorkgroupSizeZ}].` + ); + } + if (workgroupSizeX * workgroupSizeY * workgroupSizeZ > this.limits.maxComputeInvocationsPerWorkgroup) { + throw new Error( + `workgroup size [${workgroupSizeX}, ${workgroupSizeY}, ${workgroupSizeZ}] exceeds the maximum workgroup invocations ${this.limits.maxComputeInvocationsPerWorkgroup}.` + ); + } + const is1DimensionDispatch = this.normalizedDispatchGroup[1] === 1 && this.normalizedDispatchGroup[2] === 1; + const paramList = is1DimensionDispatch ? `@builtin(global_invocation_id) global_id : vec3, + @builtin(workgroup_id) workgroup_id : vec3, + @builtin(local_invocation_index) local_idx : u32, + @builtin(local_invocation_id) local_id : vec3` : `@builtin(global_invocation_id) global_id : vec3, + @builtin(local_invocation_id) local_id : vec3, + @builtin(local_invocation_index) local_idx : u32, + @builtin(workgroup_id) workgroup_id : vec3, + @builtin(num_workgroups) num_workgroups : vec3`; + const globalIdxDefinition = is1DimensionDispatch ? `let global_idx = global_id.x; + let workgroup_index = workgroup_id.x;` : `let workgroup_index = workgroup_id.z * num_workgroups[0] * num_workgroups[1] + + workgroup_id.y * num_workgroups[0] + workgroup_id.x; + let global_idx = workgroup_index * ${workgroupSizeX * workgroupSizeY * workgroupSizeZ}u + local_idx;`; + return `@compute @workgroup_size(${workgroupSizeX}, ${workgroupSizeY}, ${workgroupSizeZ}) + fn main(${paramList}) { + ${globalIdxDefinition} + `; + } + appendVariableUniforms(variable) { + if (variable.rank !== 0) { + if (variable.shape.startsWith("uniforms.")) { + this.uniforms.push({ name: variable.shape.replace("uniforms.", ""), type: "u32", length: variable.rank }); + } + if (variable.strides.startsWith("uniforms.")) { + this.uniforms.push({ name: variable.strides.replace("uniforms.", ""), type: "u32", length: variable.rank }); + } + } + } + declareVariable(variable, bindingIndex) { + if (variable.usage === "internal") { + throw new Error("cannot use internal variable with declareVariable(). use registerInternalVariables() instead."); + } + this.variables.push(variable); + this.appendVariableUniforms(variable); + const access = variable.usage === "input" ? "read" : "read_write"; + const storageType = variable.usage === "atomicOutput" ? `atomic` : variable.type.storage; + return `@group(0) @binding(${bindingIndex}) var ${variable.name}: array<${storageType}>;`; + } + declareVariables(...variables) { + return variables.map((v) => this.declareVariable(v, this.variableIndex++)).join("\n"); + } + registerInternalVariable(variable) { + if (variable.usage !== "internal") { + throw new Error( + "cannot use input or output variable with registerInternalVariable(). use declareVariables() instead." + ); + } + this.internalVariables.push(variable); + this.appendVariableUniforms(variable); + } + registerInternalVariables(...variables) { + variables.forEach((v) => this.registerInternalVariable(v)); + return this; + } + registerUniform(name2, type, length = 1) { + this.uniforms.push({ name: name2, type, length }); + return this; + } + registerUniforms(additionalUniforms) { + this.uniforms = this.uniforms.concat(additionalUniforms); + return this; + } + uniformDeclaration() { + if (this.uniforms.length === 0) { + return ""; + } + const uniformSnippets = []; + for (const { name: name2, type, length } of this.uniforms) { + if (length && length > 4) { + if (type === "f16") { + uniformSnippets.push(`@align(16) ${name2}:array, ${Math.ceil(length / 8)}>`); + } else { + uniformSnippets.push(`${name2}:array, ${Math.ceil(length / 4)}>`); + } + } else { + const typeTemp = length == null || length === 1 ? type : `vec${length}<${type}>`; + uniformSnippets.push(`${name2}:${typeTemp}`); + } + } + return ` + struct Uniforms { ${uniformSnippets.join(", ")} }; + @group(0) @binding(${this.variableIndex}) var uniforms: Uniforms;`; + } + /** + * Get additional implementation that needs to be added to the shader source. + */ + get additionalImplementations() { + return this.uniformDeclaration() + this.variables.map((i) => i.impl()).join("\n") + this.internalVariables.map((i) => i.impl()).join("\n"); + } + /** + * Get the variable info of the shader program. + */ + get variablesInfo() { + if (this.uniforms.length === 0) { + return void 0; + } + const uniformWgslTypeToDataType = (type) => [12 /* uint32 */, 10 /* float16 */, 1 /* float */, 6 /* int32 */][["u32", "f16", "f32", "i32"].indexOf(type)]; + return this.uniforms.map((u) => [uniformWgslTypeToDataType(u.type), u.length ?? 1]); + } + }; + createShaderHelper = (dispatchGroup, limits) => new ShaderHelperImpl(dispatchGroup, limits); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/transpose.ts + var validateInputs26, getAdjustedPerm2, getOutputShape2, permFunctionBody, squeezeShape2, isTransposeReshape, createTransposeProgramInfo2, transpose2, parseTransposeAttributes2; + var init_transpose2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/transpose.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs26 = (inputs, perm) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Transpose requires 1 input."); + } + if (perm.length !== 0 && perm.length !== inputs[0].dims.length) { + throw new Error(`perm size ${perm.length} does not match input rank ${inputs[0].dims.length}`); + } + }; + getAdjustedPerm2 = (inputRank, perm) => perm.length !== 0 ? perm : [...new Array(inputRank).keys()].reverse(); + getOutputShape2 = (inputShape, perm) => ShapeUtil2.sortBasedOnPerm(inputShape, getAdjustedPerm2(inputShape.length, perm)); + permFunctionBody = (perm, rank, input, output) => { + let reverseFunc = `fn perm(i: ${output.type.indices}) -> ${input.type.indices} { + var a: ${input.type.indices};`; + for (let i = 0; i < rank; ++i) { + reverseFunc += `a[${perm[i]}]=i[${i}];`; + } + return reverseFunc += "return a;}"; + }; + squeezeShape2 = (shape2, adjustedPerm) => { + const newShape = []; + const newPerm = []; + for (let i = 0; i < shape2.length; ++i) { + if (shape2[i] !== 1) { + newShape.push(shape2[i]); + } + if (shape2[adjustedPerm[i]] !== 1) { + newPerm.push(adjustedPerm[i]); + } + } + return { newShape, newPerm }; + }; + isTransposeReshape = (perm, shape2) => { + let lastPermutedAxis = 0; + for (let i = 0; i < perm.length; ++i) { + if (shape2[perm[i]] === 1) { + continue; + } + if (perm[i] < lastPermutedAxis) { + return false; + } + lastPermutedAxis = perm[i]; + } + return true; + }; + createTransposeProgramInfo2 = (inputTensor, permAttr) => { + const inputDataType = inputTensor.dataType; + const inputRank = inputTensor.dims.length; + const perm = getAdjustedPerm2(inputRank, permAttr); + const outputShape = getOutputShape2(inputTensor.dims, perm); + let newInputShape = inputTensor.dims; + let newOutputShape = outputShape; + const transposeAsReshape = inputRank < 2 || isTransposeReshape(perm, inputTensor.dims); + let getShaderSource; + if (transposeAsReshape) { + getShaderSource = (shaderHelper) => { + const input = inputVariable("input", inputDataType, newInputShape, 4); + const output = outputVariable("output", inputDataType, newOutputShape, 4); + return ` + ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + output[global_idx] = input[global_idx]; + }`; + }; + return { + name: "TransposeCopy", + shaderCache: { inputDependencies: ["type"] }, + getRunData: () => { + const outputSize = ShapeUtil2.size(outputShape); + return { + outputs: [{ dims: outputShape, dataType: inputTensor.dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 / 4 + /* components */ + ) }, + programUniforms: [{ type: 12 /* uint32 */, data: Math.ceil(outputSize / 4) }] + }; + }, + getShaderSource + }; + } + const { newShape, newPerm } = squeezeShape2(inputTensor.dims, perm); + const channelsLast = ShapeUtil2.areEqual(newPerm, [2, 3, 1]); + const channelsFirst = ShapeUtil2.areEqual(newPerm, [3, 1, 2]); + const useShared = newShape.length === 2 || channelsLast || channelsFirst; + if (useShared) { + newInputShape = channelsLast ? [newShape[0], newShape[1] * newShape[2]] : channelsFirst ? [newShape[0] * newShape[1], newShape[2]] : newShape; + newOutputShape = [newInputShape[1], newInputShape[0]]; + const tileSize = 16; + getShaderSource = (shaderHelper) => { + const input = inputVariable("a", inputDataType, newInputShape.length); + const output = outputVariable("output", inputDataType, newOutputShape.length); + return ` + ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} + var tile : array, ${tileSize}>; + ${shaderHelper.mainStart([tileSize, tileSize, 1])} + let stride = (uniforms.output_shape[1] - 1) / ${tileSize} + 1; + let workgroup_id_x = workgroup_index % stride; + let workgroup_id_y = workgroup_index / stride; + let input_col = workgroup_id_y * ${tileSize}u + local_id.x; + let input_row = workgroup_id_x * ${tileSize}u + local_id.y; + if (input_row < uniforms.a_shape[0] && input_col < uniforms.a_shape[1]) { + tile[local_id.y][local_id.x] = ${input.getByIndices(`${input.type.indices}(input_row, input_col)`)}; + } + workgroupBarrier(); + + let output_col = workgroup_id_x * ${tileSize}u + local_id.x; + let output_row = workgroup_id_y * ${tileSize}u + local_id.y; + if (output_row < uniforms.output_shape[0] && output_col < uniforms.output_shape[1]) { + ${output.setByIndices(`${output.type.indices}(output_row, output_col)`, "tile[local_id.x][local_id.y]")} + } + }`; + }; + return { + name: "TransposeShared", + shaderCache: { inputDependencies: ["type"] }, + getRunData: () => { + const outputSize = ShapeUtil2.size(outputShape); + return { + outputs: [{ dims: outputShape, dataType: inputTensor.dataType }], + dispatchGroup: { x: Math.ceil(newOutputShape[1] / tileSize), y: Math.ceil(newOutputShape[0] / tileSize) }, + programUniforms: [ + { type: 12 /* uint32 */, data: outputSize }, + ...createTensorShapeVariables(newInputShape, newOutputShape) + ] + }; + }, + getShaderSource + }; + } + getShaderSource = (shaderHelper) => { + const input = inputVariable("a", inputDataType, newInputShape.length); + const output = outputVariable("output", inputDataType, newOutputShape.length); + return ` + ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} + + ${permFunctionBody(perm, inputRank, input, output)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + + let indices = ${output.offsetToIndices("global_idx")}; + let aIndices = perm(indices); + + ${output.setByOffset("global_idx", input.getByIndices("aIndices"))} + }`; + }; + return { + name: "Transpose", + shaderCache: { hint: `${permAttr}`, inputDependencies: ["rank"] }, + getRunData: () => { + const outputSize = ShapeUtil2.size(outputShape); + return { + outputs: [{ dims: outputShape, dataType: inputTensor.dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms: [ + { type: 12 /* uint32 */, data: outputSize }, + ...createTensorShapeVariables(newInputShape, newOutputShape) + ] + }; + }, + getShaderSource + }; + }; + transpose2 = (context, attributes) => { + validateInputs26(context.inputs, attributes.perm); + context.compute(createTransposeProgramInfo2(context.inputs[0], attributes.perm)); + }; + parseTransposeAttributes2 = (attributes) => createAttributeWithCacheKey2({ perm: attributes.perm }); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/reduce-shared.ts + var reduceOps, reduceSharedOps, reduceInitValues, reduceOutputValues, getInnerMostAxes, computeOutAndReduceShapes, expandShapeToKeepDim, areAxesInnerMostDims, getAxesPermutation, createReduceSharedProgramInfo, reduceCommon, reduceMeanShared, reduceL1Shared, reduceL2Shared, reduceLogSumExpShared, reduceMaxShared, reduceMinShared, reduceProdShared, reduceSumShared, reduceSumSquareShared, reduceLogSumShared; + var init_reduce_shared = __esm({ + "web/lib/wasm/jsep/webgpu/ops/reduce-shared.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + init_reduce2(); + init_transpose2(); + reduceOps = { + max: "select(bestValue, candidate, candidate > bestValue)", + min: "select(bestValue, candidate, candidate < bestValue)", + mean: "bestValue + candidate", + sum: "bestValue + candidate", + prod: "bestValue * candidate", + sumSquare: "bestValue + candidate * candidate", + logSumExp: "bestValue + exp(candidate)", + l1: "bestValue + abs(candidate)", + l2: "bestValue + candidate * candidate", + logSum: "bestValue + candidate" + }; + reduceSharedOps = { + max: "select(bestValue, candidate, candidate > bestValue)", + min: "select(bestValue, candidate, candidate < bestValue)", + mean: "bestValue + candidate", + sum: "bestValue + candidate", + prod: "bestValue * candidate", + sumSquare: "bestValue + candidate", + logSumExp: "bestValue + candidate", + l1: "bestValue + candidate", + l2: "bestValue + candidate", + logSum: "bestValue + candidate" + }; + reduceInitValues = { + max: "_A[offset]", + min: "_A[offset]", + mean: "0", + sum: "0", + prod: "1", + sumSquare: "0", + logSumExp: "0", + l1: "0", + l2: "0", + logSum: "0" + }; + reduceOutputValues = { + max: "bestValue", + min: "bestValue", + sum: "bestValue", + prod: "bestValue", + sumSquare: "bestValue", + logSumExp: "log(bestValue)", + l1: "bestValue", + l2: "sqrt(bestValue)", + logSum: "log(bestValue)" + }; + getInnerMostAxes = (numInnerAxes, rank) => { + const res = []; + for (let i = rank - numInnerAxes; i < rank; ++i) { + res.push(i); + } + return res; + }; + computeOutAndReduceShapes = (shape2, axes) => { + const outputShape = []; + const rank = shape2.length; + for (let dim = 0; dim < rank; dim++) { + if (axes.indexOf(dim) === -1) { + outputShape.push(shape2[dim]); + } + } + const reduceShape = axes.map((dim) => shape2[dim]); + return [outputShape, reduceShape]; + }; + expandShapeToKeepDim = (shape2, axes) => { + const rank = shape2.length + axes.length; + const expandShape = []; + let shapeIdx = 0; + for (let dim = 0; dim < rank; dim++) { + if (axes.indexOf(dim) === -1) { + expandShape.push(shape2[shapeIdx++]); + } else { + expandShape.push(1); + } + } + return expandShape; + }; + areAxesInnerMostDims = (axes, rank) => { + for (let i = 0; i < axes.length; ++i) { + if (axes[axes.length - i - 1] !== rank - 1 - i) { + return false; + } + } + return true; + }; + getAxesPermutation = (axes, rank) => { + const res = []; + if (!areAxesInnerMostDims(axes, rank)) { + for (let i = 0; i < rank; ++i) { + if (axes.indexOf(i) === -1) { + res.push(i); + } + } + axes.forEach((axis) => res.push(axis)); + } + return res; + }; + createReduceSharedProgramInfo = (name2, cacheKey, inputs, reduceType, outputDataType, outputShape, reduceShape) => { + const inputShape = inputs[0].dims; + const outputSize = ShapeUtil2.size(outputShape); + const reduceSize = ShapeUtil2.size(reduceShape); + const input = inputVariable("_A", inputs[0].dataType, inputShape); + const output = outputVariable("output", outputDataType, outputShape); + let workgroupSize = 64; + if (outputSize === 1) { + workgroupSize = 256; + } + const sharedMemorySnippet = ` + var aBestValues : array; + `; + const getShaderSource = (shaderHelper) => ` + ${shaderHelper.registerUniform("reduceSize", "u32").declareVariables(input, output)} + ${sharedMemorySnippet} + fn DIV_CEIL(a : u32, b : u32) -> u32 { + return ((a - 1u) / b + 1u); + } + ${shaderHelper.mainStart(workgroupSize)} + + let outputIndex = global_idx / ${workgroupSize}; + let offset = outputIndex * uniforms.reduceSize; + + var bestValue = f32(${reduceInitValues[reduceType]}); + let Length = uniforms.reduceSize; + for (var k = local_idx; k < Length; k = k + ${workgroupSize}) { + let candidate = f32(${input.getByOffset("offset + k")}); + bestValue = ${reduceOps[reduceType]}; + } + aBestValues[local_idx] = bestValue; + workgroupBarrier(); + + var reduceSize = min(Length, ${workgroupSize}u); + for (var currentSize = reduceSize / 2u; reduceSize > 1u; + currentSize = reduceSize / 2u) { + let interval = DIV_CEIL(reduceSize, 2u); + if (local_idx < currentSize) { + let candidate = aBestValues[local_idx + interval]; + bestValue = ${reduceSharedOps[reduceType]}; + aBestValues[local_idx] = bestValue; + } + reduceSize = interval; + workgroupBarrier(); + } + + if (local_idx == 0u) { + ${output.setByOffset( + "outputIndex", + `${reduceType === "mean" ? `${output.type.storage}(bestValue / f32(uniforms.reduceSize))` : `${output.type.storage}(${reduceOutputValues[reduceType]})`}` + )}; + } + }`; + return { + name: name2, + // Note that in JSEP, WG size is not included in cache by default, but WebGPU EP it is. + shaderCache: { hint: `${cacheKey};${workgroupSize}`, inputDependencies: ["type"] }, + getShaderSource, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: outputDataType }], + dispatchGroup: { x: outputSize }, + programUniforms: [{ type: 12 /* uint32 */, data: reduceSize }] + }) + }; + }; + reduceCommon = (context, name2, attributes, reduceType) => { + const updatedAttributes = context.inputs.length === 1 ? attributes : createReduceAttributesFromInputs(context.inputs, attributes); + let updatedAxes = updatedAttributes.axes; + if (updatedAxes.length === 0 && !updatedAttributes.noopWithEmptyAxes) { + updatedAxes = context.inputs[0].dims.map((_dim, i) => i); + } + const normalizeAxes = ShapeUtil2.normalizeAxes(updatedAxes, context.inputs[0].dims.length); + let axes = normalizeAxes; + let input = context.inputs[0]; + const permutedAxes = getAxesPermutation(axes, context.inputs[0].dims.length); + if (permutedAxes.length > 0) { + input = context.compute(createTransposeProgramInfo2(context.inputs[0], permutedAxes), { + inputs: [0], + outputs: [-1] + })[0]; + axes = getInnerMostAxes(axes.length, input.dims.length); + } + const [outputShape, reduceShape] = computeOutAndReduceShapes(input.dims, axes); + let finalOutputShape = outputShape; + if (updatedAttributes.keepDims) { + finalOutputShape = expandShapeToKeepDim(outputShape, normalizeAxes); + } + context.compute( + createReduceSharedProgramInfo( + name2, + updatedAttributes.cacheKey, + [input], + reduceType, + context.inputs[0].dataType, + finalOutputShape, + reduceShape + ), + { inputs: [input] } + ); + }; + reduceMeanShared = (context, attributes) => { + reduceCommon(context, "ReduceMeanShared", attributes, "mean"); + }; + reduceL1Shared = (context, attributes) => { + reduceCommon(context, "ReduceL1Shared", attributes, "l1"); + }; + reduceL2Shared = (context, attributes) => { + reduceCommon(context, "ReduceL2Shared", attributes, "l2"); + }; + reduceLogSumExpShared = (context, attributes) => { + reduceCommon(context, "ReduceLogSumExpShared", attributes, "logSumExp"); + }; + reduceMaxShared = (context, attributes) => { + reduceCommon(context, "ReduceMaxShared", attributes, "max"); + }; + reduceMinShared = (context, attributes) => { + reduceCommon(context, "ReduceMinShared", attributes, "min"); + }; + reduceProdShared = (context, attributes) => { + reduceCommon(context, "ReduceProdShared", attributes, "prod"); + }; + reduceSumShared = (context, attributes) => { + reduceCommon(context, "ReduceSumShared", attributes, "sum"); + }; + reduceSumSquareShared = (context, attributes) => { + reduceCommon(context, "ReduceSumSquareShared", attributes, "sumSquare"); + }; + reduceLogSumShared = (context, attributes) => { + reduceCommon(context, "ReduceLogSumShared", attributes, "logSum"); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/reduce.ts + var validateInputs27, noOp, createReduceProgramInfo2, createReduceAttributesFromInputs, runReduceProgram, reduceLogSumNaive, reduceL1Naive, reduceL2Naive, reduceLogSumExpNaive, reduceMaxNaive, reduceMeanNaive, reduceMinNaive, reduceProdNaive, reduceSumNaive, reduceSumSquareNaive, useNaiveReduceMethod, reduceMean2, reduceL1, reduceL2, reduceLogSumExp, reduceMax2, reduceMin2, reduceProd2, reduceSum2, reduceSumSquare, reduceLogSum2; + var init_reduce2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/reduce.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + init_reduce_shared(); + validateInputs27 = (inputs) => { + if (!inputs || inputs.length === 0 || inputs.length > 2) { + throw new Error("Reduce op requires 1 or 2 inputs."); + } + if (inputs.length === 2 && inputs[1].dims.length !== 1) { + throw new Error("Invalid axes input dims."); + } + }; + noOp = (input) => ["", "", `var value = ${input.getByIndices("input_indices")};`, ""]; + createReduceProgramInfo2 = (name2, shaderCache, inputs, reduceOp, axesInput, outputDataType, keepDims = false, noopWithEmptyAxes = false) => { + const outputShape = []; + const inputShape = inputs[0].dims; + const inputRank = inputShape.length; + const axes = ShapeUtil2.normalizeAxes(axesInput, inputRank); + const reduceOnAllAxes = !noopWithEmptyAxes && axes.length === 0; + inputShape.forEach((d, i) => { + if (reduceOnAllAxes || axes.indexOf(i) >= 0) { + if (keepDims) { + outputShape.push(1); + } + } else { + outputShape.push(d); + } + }); + const outputRank = outputShape.length; + const outputSize = ShapeUtil2.size(outputShape); + const getShaderSource = (shaderHelper) => { + const idxCopy = []; + const input = inputVariable("_A", inputs[0].dataType, inputRank); + const output = outputVariable("output", outputDataType, outputRank); + const ops = reduceOp(input, output, axes); + let reduceOps2 = ops[2]; + for (let k = 0, l = 0; k < inputRank; k++) { + if (reduceOnAllAxes || axes.indexOf(k) >= 0) { + if (keepDims) { + l++; + } + reduceOps2 = `for(var j${k}: u32 = 0; j${k} < ${inputShape[k]}; j${k}++) { + ${ops[2].includes("last_index") ? `let last_index = j${k};` : ""} + ${input.indicesSet("input_indices", k, `j${k}`)} + ${reduceOps2} + }`; + } else { + idxCopy.push(`${input.indicesSet("input_indices", k, output.indicesGet("output_indices", l))};`); + l++; + } + } + return ` + + ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + var input_indices: ${input.type.indices}; + let output_indices = ${output.offsetToIndices("global_idx")}; + + ${idxCopy.join("\n")} + ${ops[0]} // init ops for reduce max/min + ${ops[1]} + ${reduceOps2} + ${ops[3]} + ${ops.length === 4 ? output.setByOffset("global_idx", "value") : ops.slice(4).join("\n")} + }`; + }; + return { + name: name2, + shaderCache, + getShaderSource, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: outputDataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms: [ + { type: 12 /* uint32 */, data: outputSize }, + ...createTensorShapeVariables(inputShape, outputShape) + ] + }) + }; + }; + createReduceAttributesFromInputs = (inputs, attributes) => { + const axes = []; + if (inputs[1].dims[0] > 0) { + inputs[1].getBigInt64Array().forEach((v) => axes.push(Number(v))); + } + return createAttributeWithCacheKey2({ + axes, + keepDims: attributes.keepDims, + noopWithEmptyAxes: attributes.noopWithEmptyAxes + }); + }; + runReduceProgram = (context, name2, attributes, reduceOp) => { + const inputs = context.inputs; + const updatedAttributes = inputs.length === 1 ? attributes : createReduceAttributesFromInputs(inputs, attributes); + context.compute( + createReduceProgramInfo2( + name2, + { hint: updatedAttributes.cacheKey, inputDependencies: ["rank"] }, + [inputs[0]], + updatedAttributes.noopWithEmptyAxes && updatedAttributes.axes.length === 0 ? noOp : reduceOp, + updatedAttributes.axes, + inputs[0].dataType, + updatedAttributes.keepDims, + updatedAttributes.noopWithEmptyAxes + ), + { inputs: [0] } + ); + }; + reduceLogSumNaive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, output) => [ + `var value = ${output.type.storage}(0);`, + "", + `value += ${input.getByIndices("input_indices")};`, + "value = log(value);" + ]; + runReduceProgram(context, "ReduceLogSum", attributes, reduceOp); + }; + reduceL1Naive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, output) => [ + `var value = ${output.type.storage}(0);`, + "", + `value += abs(${input.getByIndices("input_indices")});`, + "" + ]; + runReduceProgram(context, "ReduceL1", attributes, reduceOp); + }; + reduceL2Naive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, output) => [ + `var t = ${output.type.value}(0); var value = ${output.type.value}(0);`, + "", + `t = ${input.getByIndices("input_indices")}; value += (t * t);`, + "value = sqrt(value);" + ]; + runReduceProgram(context, "ReduceL2", attributes, reduceOp); + }; + reduceLogSumExpNaive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, output) => [ + `var value = ${output.type.storage}(0);`, + "", + `value += exp(${input.getByIndices("input_indices")});`, + "value = log(value);" + ]; + runReduceProgram(context, "ReduceLogSumExp", attributes, reduceOp); + }; + reduceMaxNaive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, _output, axes) => { + const idxZero = []; + for (let k = 0; k < input.rank; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + idxZero.push(input.indicesSet("input_indices", k, 0)); + } + } + return [ + `${idxZero.join("\n")}`, + `var value = ${input.getByIndices("input_indices")};`, + `value = max(value, ${input.getByIndices("input_indices")});`, + "" + ]; + }; + runReduceProgram(context, "ReduceMax", attributes, reduceOp); + }; + reduceMeanNaive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, output, axes) => { + let size = 1; + for (let k = 0; k < input.rank; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + size *= context.inputs[0].dims[k]; + } + } + return [ + "var sum = f32(0);", + "", + `sum += f32(${input.getByIndices("input_indices")});`, + `let value = ${output.type.value}(sum / ${size});` + ]; + }; + runReduceProgram(context, "ReduceMean", attributes, reduceOp); + }; + reduceMinNaive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, _output, axes) => { + const idxZero = []; + for (let k = 0; k < input.rank; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + idxZero.push(`input_indices[${k}] = 0;`); + } + } + return [ + `${idxZero.join("\n")}`, + `var value = ${input.getByIndices("input_indices")};`, + `value = min(value, ${input.getByIndices("input_indices")});`, + "" + ]; + }; + runReduceProgram(context, "ReduceMin", attributes, reduceOp); + }; + reduceProdNaive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, output) => [ + `var value = ${output.type.storage}(1);`, + "", + `value *= ${input.getByIndices("input_indices")};`, + "" + ]; + runReduceProgram(context, "ReduceProd", attributes, reduceOp); + }; + reduceSumNaive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, output) => [ + `var value = ${output.type.storage}(0);`, + "", + `value += ${input.getByIndices("input_indices")};`, + "" + ]; + runReduceProgram(context, "ReduceSum", attributes, reduceOp); + }; + reduceSumSquareNaive = (context, attributes) => { + validateInputs27(context.inputs); + const reduceOp = (input, output) => [ + `var t = ${output.type.value}(0); var value = ${output.type.value}(0);`, + "", + `t = ${input.getByIndices("input_indices")}; value += t * t;`, + "" + ]; + runReduceProgram(context, "ReduceSumSquare", attributes, reduceOp); + }; + useNaiveReduceMethod = (shape2, axes, noopWithEmptyAxes) => { + if (axes.length === 0) { + return noopWithEmptyAxes; + } + let outputSize = 1; + let reduceSize = 1; + for (let dim = 0; dim < axes.length; dim++) { + if (axes.indexOf(dim) === -1) { + outputSize *= shape2[dim]; + } else { + reduceSize *= shape2[dim]; + } + } + return reduceSize < 32 && outputSize > 1024; + }; + reduceMean2 = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceMeanNaive(context, attributes); + } else { + reduceMeanShared(context, attributes); + } + }; + reduceL1 = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceL1Naive(context, attributes); + } else { + reduceL1Shared(context, attributes); + } + }; + reduceL2 = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceL2Naive(context, attributes); + } else { + reduceL2Shared(context, attributes); + } + }; + reduceLogSumExp = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceLogSumExpNaive(context, attributes); + } else { + reduceLogSumExpShared(context, attributes); + } + }; + reduceMax2 = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceMaxNaive(context, attributes); + } else { + reduceMaxShared(context, attributes); + } + }; + reduceMin2 = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceMinNaive(context, attributes); + } else { + reduceMinShared(context, attributes); + } + }; + reduceProd2 = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceProdNaive(context, attributes); + } else { + reduceProdShared(context, attributes); + } + }; + reduceSum2 = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceSumNaive(context, attributes); + } else { + reduceSumShared(context, attributes); + } + }; + reduceSumSquare = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceSumSquareNaive(context, attributes); + } else { + reduceSumSquareShared(context, attributes); + } + }; + reduceLogSum2 = (context, attributes) => { + if (useNaiveReduceMethod(context.inputs[0].dims, attributes.axes, attributes.noopWithEmptyAxes)) { + reduceLogSumNaive(context, attributes); + } else { + reduceLogSumShared(context, attributes); + } + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/argminmax.ts + var validateInputs28, argMin, argMax, parseArgMinMaxAttributes; + var init_argminmax = __esm({ + "web/lib/wasm/jsep/webgpu/ops/argminmax.ts"() { + "use strict"; + init_wasm_common(); + init_attribute_with_cache_key2(); + init_reduce2(); + validateInputs28 = (inputs) => { + if (!inputs || inputs.length === 0 || inputs.length > 2) { + throw new Error("ArgMinMaxOp op requires 1 or 2 inputs."); + } + if (inputs[0].dataType !== 1 /* float */) { + throw new Error("Invalid input type."); + } + }; + argMin = (context, attributes) => { + validateInputs28(context.inputs); + const argMinMaxOp = (input, output, axes) => { + const idxZero = []; + for (let k = 0; k < input.rank; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + idxZero.push(`input_indices[${k}] = 0;`); + } + } + return [ + `${idxZero.join("\n")}`, + `var value = ${input.getByIndices("input_indices")}; +var best_index : i32 = 0;`, + `if (${input.getByIndices("input_indices")} ${attributes.selectLastIndex > 0 ? "<=" : "<"} value) { + value = ${input.getByIndices("input_indices")}; + best_index = i32(last_index); + }`, + "", + output.setByOffset("global_idx", "best_index") + ]; + }; + context.compute( + createReduceProgramInfo2( + "ArgMin", + { hint: attributes.cacheKey, inputDependencies: ["rank"] }, + [context.inputs[0]], + argMinMaxOp, + [attributes.axis], + 7 /* int64 */, + attributes.keepDims + ), + { inputs: [0] } + ); + }; + argMax = (context, attributes) => { + validateInputs28(context.inputs); + const argMinMaxOp = (input, output, axes) => { + const idxZero = []; + for (let k = 0; k < input.rank; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + idxZero.push(`input_indices[${k}] = 0;`); + } + } + return [ + `${idxZero.join("\n")}`, + `var value = ${input.getByIndices("input_indices")}; +var best_index : i32 = 0;`, + `if (${input.getByIndices("input_indices")} ${attributes.selectLastIndex > 0 ? ">=" : ">"} value) { + value = ${input.getByIndices("input_indices")}; + best_index = i32(last_index); + }`, + "", + output.setByOffset("global_idx", "best_index") + ]; + }; + context.compute( + createReduceProgramInfo2( + "argMax", + { hint: attributes.cacheKey, inputDependencies: ["rank"] }, + [context.inputs[0]], + argMinMaxOp, + [attributes.axis], + 7 /* int64 */, + attributes.keepDims + ), + { inputs: [0] } + ); + }; + parseArgMinMaxAttributes = (attributes) => createAttributeWithCacheKey2(attributes); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/attention.ts + var validateAttentionInputs, initVarStub, createInPlaceSoftmaxProgramInfo, createAttentionProbsProgramInfo, createVxAttentionScoreProgramInfo, applyAttention, prepare, attention; + var init_attention = __esm({ + "web/lib/wasm/jsep/webgpu/ops/attention.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_types2(); + init_common(); + validateAttentionInputs = (inputs, attributes) => { + const input = inputs[0]; + const weights = inputs[1]; + const bias = inputs[2]; + const maskIndex = inputs[3]; + const past = inputs[4]; + const attentionBias = inputs[5]; + if (past && attentionBias) { + throw new Error("Attention cannot have both past and attention_bias"); + } + if (input.dims.length !== 3) { + throw new Error('Input "input" must have 3 dimensions'); + } + const batchSize = input.dims[0]; + const sequenceLength = input.dims[1]; + const inputHiddenSize = input.dims[2]; + if (bias.dims.length !== 1) { + throw new Error('Input "bias" is expected to have 1 dimensions'); + } + if (weights.dims.length !== 2) { + throw new Error('Input "weights" is expected to have 2 dimensions'); + } + if (weights.dims[0] !== inputHiddenSize) { + throw new Error("Input 1 dimension 0 should have same length as dimension 2 of input 0"); + } + if (bias.dims[0] !== weights.dims[1]) { + throw new Error('Input "bias" dimension 0 should have same length as dimension 1 of input "weights"'); + } + let qHiddenSize = bias.dims[0] / 3; + let kHiddenSize = qHiddenSize; + let vHiddenSize = kHiddenSize; + if (attributes.qkvHiddenSizes.length > 0) { + if (attributes.qkvHiddenSizes.length !== 3) { + throw new Error("qkv_hidden_sizes attribute should have 3 elements"); + } + for (const sz of attributes.qkvHiddenSizes) { + if (sz % attributes.numHeads !== 0) { + throw new Error("qkv_hidden_sizes should be divisible by num_heads"); + } + } + qHiddenSize = attributes.qkvHiddenSizes[0]; + kHiddenSize = attributes.qkvHiddenSizes[1]; + vHiddenSize = attributes.qkvHiddenSizes[2]; + } + const kvSequenceLength = sequenceLength; + if (qHiddenSize !== kHiddenSize) { + throw new Error("qkv_hidden_sizes first element should be same as the second"); + } + if (bias.dims[0] !== qHiddenSize + kHiddenSize + vHiddenSize) { + throw new Error('Input "bias" dimension 0 should have same length as sum of Q/K/V hidden sizes'); + } + let pastSequenceLength = 0; + if (past) { + if (kHiddenSize !== vHiddenSize) { + throw new Error('Input "past" expect k_hidden_size == v_hidden_size'); + } + if (past.dims.length !== 5) { + throw new Error('Input "past" must have 5 dimensions'); + } + if (past.dims[0] !== 2) { + throw new Error('Input "past" first dimension must be 2'); + } + if (past.dims[1] !== batchSize) { + throw new Error('Input "past" second dimension must be batch_size'); + } + if (past.dims[2] !== attributes.numHeads) { + throw new Error('Input "past" third dimension must be num_heads'); + } + if (past.dims[4] !== kHiddenSize / attributes.numHeads) { + throw new Error('Input "past" fifth dimension must be k_hidden_size / num_heads'); + } + if (!attributes.pastPresentShareBuffer) { + pastSequenceLength = past.dims[3]; + } + } + const totalSequenceLength = kvSequenceLength + pastSequenceLength; + const maxSequenceLength = -1; + const maskType = 0 /* none */; + if (maskIndex) { + throw new Error("Mask not supported"); + } + if (past) { + throw new Error("past is not supported"); + } + if (attentionBias) { + if (attentionBias.dims.length !== 4) { + throw new Error('Input "attention_bias" must have 4 dimensions'); + } + if (attentionBias.dims[0] !== batchSize || attentionBias.dims[1] !== attributes.numHeads || attentionBias.dims[2] !== sequenceLength || attentionBias.dims[3] !== totalSequenceLength) { + throw new Error('Expect "attention_bias" shape (batch_size, num_heads, sequence_length, total_sequence_length)'); + } + } + return { + batchSize, + sequenceLength, + pastSequenceLength, + kvSequenceLength, + totalSequenceLength, + maxSequenceLength, + inputHiddenSize, + hiddenSize: qHiddenSize, + vHiddenSize, + headSize: Math.floor(qHiddenSize / attributes.numHeads), + vHeadSize: Math.floor(vHiddenSize / attributes.numHeads), + numHeads: attributes.numHeads, + isUnidirectional: false, + pastPresentShareBuffer: false, + maskFilterValue: attributes.maskFilterValue, + maskType, + scale: attributes.scale, + broadcastResPosBias: false, + passPastInKv: false, + qkvFormat: 1 /* qkvBNSH */ + }; + }; + initVarStub = (seqLensInput, totalSequenceLengthInput, initPastSequenceLength) => { + if (totalSequenceLengthInput && seqLensInput) { + return ` + let total_sequence_length_input = u32(${totalSequenceLengthInput.getByOffset("0")}); + let present_sequence_length = max(total_sequence_length_input, uniforms.past_sequence_length); + let is_subsequent_prompt: bool = sequence_length > 1 && sequence_length != total_sequence_length_input; + let is_first_prompt: bool = is_subsequent_prompt == false && sequence_length == total_sequence_length_input; + total_sequence_length = u32(${seqLensInput?.getByOffset("batchIdx")}) + 1; + var past_sequence_length: u32 = 0; + if (is_first_prompt == false) { + past_sequence_length = total_sequence_length - sequence_length; + } + `; + } else { + return ` + ${initPastSequenceLength ? "let past_sequence_length = uniforms.past_sequence_length" : ""}; + let present_sequence_length = total_sequence_length; + `; + } + }; + createInPlaceSoftmaxProgramInfo = (input, batchSize, numHeads, pastSequenceLength, sequenceLength, totalSequenceLength, seqLens, totalSequenceLengthInput) => { + const components = getMaxComponents(seqLens ? 1 : totalSequenceLength); + let WG = 64; + const totalSequenceLengthComp = totalSequenceLength / components; + if (totalSequenceLengthComp < WG) { + WG = 32; + } + const elementsPerThread = Math.ceil(totalSequenceLength / components / WG); + const programUniforms = [ + { type: 12 /* uint32 */, data: batchSize }, + { type: 12 /* uint32 */, data: numHeads }, + { type: 12 /* uint32 */, data: pastSequenceLength }, + { type: 12 /* uint32 */, data: sequenceLength }, + { type: 12 /* uint32 */, data: totalSequenceLengthComp }, + { type: 12 /* uint32 */, data: elementsPerThread } + ]; + const dataType = tensorTypeToWsglStorageType(input.dataType, components); + const f32Type = tensorTypeToWsglValueType(1 /* float */, components); + const inputDependencies = ["type"]; + if (seqLens) { + inputDependencies.push("type"); + } + if (totalSequenceLengthInput) { + inputDependencies.push("type"); + } + const getShaderSource = (shaderHelper) => { + const inputHelper = outputVariable("x", input.dataType, input.dims, components); + const inputHelpers = [inputHelper]; + const seqLensInputHelper = seqLens ? inputVariable("seq_lens", seqLens.dataType, seqLens.dims) : void 0; + if (seqLensInputHelper) { + inputHelpers.push(seqLensInputHelper); + } + const totalSequenceLengthInputHelper = totalSequenceLengthInput ? inputVariable("total_sequence_length_input", totalSequenceLengthInput.dataType, totalSequenceLengthInput.dims) : void 0; + if (totalSequenceLengthInputHelper) { + inputHelpers.push(totalSequenceLengthInputHelper); + } + const elemValueType = tensorTypeToWsglValueType(input.dataType); + const uniforms = [ + { name: "batch_size", type: "u32" }, + { name: "num_heads", type: "u32" }, + { name: "past_sequence_length", type: "u32" }, + { name: "sequence_length", type: "u32" }, + { name: "total_sequence_length", type: "u32" }, + { name: "elements_per_thread", type: "u32" } + ]; + return ` + var thread_max: array; + var thread_sum: array; + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputHelpers)} + ${shaderHelper.mainStart([WG, 1, 1])} + let batchIdx = workgroup_id.z / uniforms.num_heads; + let headIdx = workgroup_id.z % uniforms.num_heads; + let sequence_length = uniforms.sequence_length; + var total_sequence_length = uniforms.total_sequence_length; + ${initVarStub(seqLensInputHelper, totalSequenceLengthInputHelper, false)} + let local_offset = local_idx * uniforms.elements_per_thread; + let offset = (global_idx / ${WG}) * uniforms.total_sequence_length + local_offset; + let seq_causal_length = ${seqLens ? "u32(past_sequence_length + workgroup_id.y + 1)" : "total_sequence_length"}; + var thread_max_vector = ${f32Type}(-3.402823e+38f); + for (var i: u32 = 0; i < uniforms.elements_per_thread && i + local_offset < seq_causal_length; i++) { + thread_max_vector = max(${f32Type}(x[offset + i]), thread_max_vector); + } + thread_max[local_idx] = ${(() => { + switch (components) { + case 1: + return "thread_max_vector"; + case 2: + return "max(thread_max_vector.x, thread_max_vector.y)"; + case 4: + return "max(max(thread_max_vector.x, thread_max_vector.y), max(thread_max_vector.z, thread_max_vector.w))"; + default: + throw new Error(`Unsupported components: ${components}`); + } + })()}; + workgroupBarrier(); + + var max_value = f32(-3.402823e+38f); + for (var i = 0u; i < ${WG}; i++) { + max_value = max(thread_max[i], max_value); + } + + var sum_vector = ${f32Type}(0); + for (var i: u32 = 0; i < uniforms.elements_per_thread && i + local_offset < seq_causal_length; i++) { + sum_vector += exp(${f32Type}(x[offset + i]) - max_value); + } + thread_sum[local_idx] = ${(() => { + switch (components) { + case 1: + return "sum_vector"; + case 2: + return "sum_vector.x + sum_vector.y"; + case 4: + return "sum_vector.x + sum_vector.y + sum_vector.z + sum_vector.w"; + default: + throw new Error(`Unsupported components: ${components}`); + } + })()}; + workgroupBarrier(); + + var sum: f32 = 0; + for (var i = 0u; i < ${WG}; i++) { + sum += thread_sum[i]; + } + + if (sum == 0) { + for (var i: u32 = 0; i < uniforms.elements_per_thread && i + local_offset < seq_causal_length; i++) { + x[offset + i] = ${inputHelper.type.value}(${elemValueType}(1.0) / ${elemValueType}(seq_causal_length)); + } + } else { + for (var i: u32 = 0; i < uniforms.elements_per_thread && i + local_offset < seq_causal_length; i++) { + var f32input = ${f32Type}(x[offset + i]); + x[offset + i] = ${inputHelper.type.value}(exp(f32input - max_value) / sum); + } + } + ${seqLens ? ` + for (var total_seq_id: u32 = seq_causal_length; total_seq_id + local_offset < uniforms.total_sequence_length; total_seq_id++) { + x[offset + total_seq_id] = ${inputHelper.type.value}(${elemValueType}(0)); + }` : ""}; + }`; + }; + return { + name: "AttentionProbsSoftmax", + shaderCache: { hint: `${WG};${dataType};${components}`, inputDependencies }, + getShaderSource, + getRunData: () => ({ + outputs: [], + dispatchGroup: { x: 1, y: sequenceLength, z: batchSize * numHeads }, + programUniforms + }) + }; + }; + createAttentionProbsProgramInfo = (outputCount, q, key, pastKey, attentionBias, parameters, pastSequenceLength, seqLens, totalSequenceLengthInput) => { + const totalSequenceLength = pastSequenceLength + parameters.kvSequenceLength; + const probsShape = [parameters.batchSize, parameters.numHeads, parameters.sequenceLength, totalSequenceLength]; + const presentKey = outputCount > 1 && pastKey; + const kvNumHeads = parameters.kvNumHeads ? parameters.kvNumHeads : parameters.numHeads; + const presentKeyShape = presentKey ? [parameters.batchSize, kvNumHeads, totalSequenceLength, parameters.headSize] : void 0; + const nReps = parameters.nReps ? parameters.nReps : 1; + const alpha = parameters.scale === 0 ? 1 / Math.sqrt(parameters.headSize) : parameters.scale; + const components = getMaxComponents(parameters.headSize); + const vectorizedHeadSize = parameters.headSize / components; + const TILE_SIZE = 12; + const dispatch = { + x: Math.ceil(totalSequenceLength / TILE_SIZE), + y: Math.ceil(parameters.sequenceLength / TILE_SIZE), + z: parameters.batchSize * parameters.numHeads + }; + const programUniforms = [ + { type: 12 /* uint32 */, data: parameters.sequenceLength }, + { type: 12 /* uint32 */, data: vectorizedHeadSize }, + { type: 12 /* uint32 */, data: totalSequenceLength }, + { type: 12 /* uint32 */, data: parameters.numHeads }, + { type: 12 /* uint32 */, data: parameters.headSize }, + { type: 1 /* float */, data: alpha }, + { type: 12 /* uint32 */, data: pastSequenceLength }, + { type: 12 /* uint32 */, data: parameters.kvSequenceLength }, + { type: 12 /* uint32 */, data: nReps } + ]; + const feedPastKey = presentKey && pastKey && ShapeUtil2.size(pastKey.dims) > 0; + const inputDependencies = ["type", "type"]; + if (feedPastKey) { + inputDependencies.push("type"); + } + if (attentionBias) { + inputDependencies.push("type"); + } + if (seqLens) { + inputDependencies.push("type"); + } + if (totalSequenceLengthInput) { + inputDependencies.push("type"); + } + const outputs = [{ dims: probsShape, dataType: q.dataType, gpuDataType: 0 /* default */ }]; + if (presentKey) { + outputs.push({ dims: presentKeyShape, dataType: q.dataType, gpuDataType: 0 /* default */ }); + } + const getShaderSource = (shaderHelper) => { + const qInput = inputVariable("q", q.dataType, q.dims, components); + const kInput = inputVariable("key", key.dataType, key.dims, components); + const inputVars = [qInput, kInput]; + if (feedPastKey) { + const pastKeyInput = inputVariable("past_key", pastKey.dataType, pastKey.dims, components); + inputVars.push(pastKeyInput); + } + if (attentionBias) { + inputVars.push(inputVariable("attention_bias", attentionBias.dataType, attentionBias.dims)); + } + const seqLensInputVariable = seqLens ? inputVariable("seq_lens", seqLens.dataType, seqLens.dims) : void 0; + if (seqLensInputVariable) { + inputVars.push(seqLensInputVariable); + } + const totalSequenceLengthInputVariable = totalSequenceLengthInput ? inputVariable("total_sequence_length_input", totalSequenceLengthInput.dataType, totalSequenceLengthInput.dims) : void 0; + if (totalSequenceLengthInputVariable) { + inputVars.push(totalSequenceLengthInputVariable); + } + const output = outputVariable("output", q.dataType, probsShape); + const outputVars = [output]; + if (presentKey) { + outputVars.push(outputVariable("present_key", q.dataType, presentKeyShape, components)); + } + const f32Type = tensorTypeToWsglValueType(1 /* float */, components); + const uniforms = [ + { name: "M", type: "u32" }, + { name: "K", type: "u32" }, + { name: "N", type: "u32" }, + { name: "num_heads", type: "u32" }, + { name: "head_size", type: "u32" }, + { name: "alpha", type: "f32" }, + { name: "past_sequence_length", type: "u32" }, + { name: "kv_sequence_length", type: "u32" }, + { name: "n_reps", type: "u32" } + ]; + return ` + const TILE_SIZE = ${TILE_SIZE}u; + + var tileQ: array<${qInput.type.storage}, ${TILE_SIZE * TILE_SIZE}>; + var tileK: array<${qInput.type.storage}, ${TILE_SIZE * TILE_SIZE}>; + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVars, ...outputVars)} + ${shaderHelper.mainStart([TILE_SIZE, TILE_SIZE, 1])} + // x holds the N and y holds the M + let headIdx = workgroup_id.z % uniforms.num_heads; + let kvHeadIdx = ${nReps === 1 ? "headIdx" : "headIdx / uniforms.n_reps"}; + let kv_num_heads = ${nReps === 1 ? "uniforms.num_heads" : "uniforms.num_heads / uniforms.n_reps"}; + let batchIdx = workgroup_id.z / uniforms.num_heads; + let m = workgroup_id.y * TILE_SIZE; + let n = workgroup_id.x * TILE_SIZE; + let sequence_length = uniforms.M; + var total_sequence_length = uniforms.N; + ${initVarStub(seqLensInputVariable, totalSequenceLengthInputVariable, true)} + let absKvHeadIdx = batchIdx * kv_num_heads + kvHeadIdx; + let qOffset = workgroup_id.z * uniforms.M * uniforms.K + m * uniforms.K; + ${feedPastKey && presentKey ? "let pastKeyOffset = absKvHeadIdx * uniforms.past_sequence_length * uniforms.K;" : ""}; + let kOffset = absKvHeadIdx * uniforms.kv_sequence_length * uniforms.K; + ${presentKey ? "let presentKeyOffset = absKvHeadIdx * uniforms.N * uniforms.K;" : ""} + var value = ${f32Type}(0); + for (var w: u32 = 0u; w < uniforms.K; w += TILE_SIZE) { + if (global_id.y < uniforms.M && w + local_id.x < uniforms.K) { + tileQ[TILE_SIZE * local_id.y + local_id.x] = q[qOffset + local_id.y * uniforms.K + w + local_id.x]; + } + if (n + local_id.y < uniforms.N && w + local_id.x < uniforms.K) { + var idx = TILE_SIZE * local_id.y + local_id.x; + ${(() => { + if (feedPastKey && presentKey) { + return ` + if (n + local_id.y < past_sequence_length) { + tileK[idx] = past_key[pastKeyOffset + (n + local_id.y) * uniforms.K + w + local_id.x]; + } else if (n + local_id.y - past_sequence_length < uniforms.kv_sequence_length) { + tileK[idx] = key[kOffset + (n + local_id.y - past_sequence_length) * uniforms.K + w + local_id.x]; + }`; + } else { + return ` + if (n + local_id.y < uniforms.kv_sequence_length) { + tileK[idx] = key[kOffset + (n + local_id.y) * uniforms.K + w + local_id.x]; + }`; + } + })()} + ${presentKey ? `if (n + local_id.y < present_sequence_length) { + present_key[presentKeyOffset + (n + local_id.y) * uniforms.K + w + local_id.x] = tileK[idx]; + }` : ""} + } + workgroupBarrier(); + + for (var k: u32 = 0u; k < TILE_SIZE && w+k < uniforms.K; k++) { + value += ${f32Type}(tileQ[TILE_SIZE * local_id.y + k] * tileK[TILE_SIZE * local_id.x + k]); + } + + workgroupBarrier(); + } + + if (global_id.y < uniforms.M && global_id.x < total_sequence_length) { + let headOffset = workgroup_id.z * uniforms.M * uniforms.N; + let outputIdx = headOffset + global_id.y * uniforms.N + global_id.x; + var sum: f32 = ${(() => { + switch (components) { + case 1: + return "value"; + case 2: + return "value.x + value.y"; + case 4: + return "value.x + value.y + value.z + value.w"; + default: + throw new Error(`Unsupported components: ${components}`); + } + })()}; + output[outputIdx] = ${output.type.value} (sum * uniforms.alpha) + ${attentionBias ? "attention_bias[outputIdx]" : "0.0"}; + } + }`; + }; + return { + name: "AttentionProbs", + shaderCache: { + hint: `${components};${attentionBias !== void 0};${pastKey !== void 0};${outputCount}`, + inputDependencies + }, + getRunData: () => ({ outputs, dispatchGroup: dispatch, programUniforms }), + getShaderSource + }; + }; + createVxAttentionScoreProgramInfo = (outputCount, probs, v, pastValue, params, pastSequenceLength, seqLens = void 0, totalSequenceLengthInput = void 0) => { + const totalSequenceLength = pastSequenceLength + params.kvSequenceLength; + const nReps = params.nReps ? params.nReps : 1; + const repeatedVHiddenSize = params.vHiddenSize * nReps; + const presentValue = outputCount > 1 && pastValue; + const kvNumHeads = params.kvNumHeads ? params.kvNumHeads : params.numHeads; + const presentValueShape = presentValue ? [params.batchSize, kvNumHeads, totalSequenceLength, params.headSize] : void 0; + const outputShape = [params.batchSize, params.sequenceLength, repeatedVHiddenSize]; + const TILE_SIZE = 12; + const dispatch = { + x: Math.ceil(params.vHeadSize / TILE_SIZE), + y: Math.ceil(params.sequenceLength / TILE_SIZE), + z: params.batchSize * params.numHeads + }; + const programUniforms = [ + { type: 12 /* uint32 */, data: params.sequenceLength }, + { type: 12 /* uint32 */, data: totalSequenceLength }, + { type: 12 /* uint32 */, data: params.vHeadSize }, + { type: 12 /* uint32 */, data: params.numHeads }, + { type: 12 /* uint32 */, data: params.headSize }, + { type: 12 /* uint32 */, data: repeatedVHiddenSize }, + { type: 12 /* uint32 */, data: pastSequenceLength }, + { type: 12 /* uint32 */, data: params.kvSequenceLength }, + { type: 12 /* uint32 */, data: nReps } + ]; + const feedPastValue = presentValue && pastValue && ShapeUtil2.size(pastValue.dims) > 0; + const inputDependencies = ["type", "type"]; + if (feedPastValue) { + inputDependencies.push("type"); + } + if (seqLens) { + inputDependencies.push("type"); + } + if (totalSequenceLengthInput) { + inputDependencies.push("type"); + } + const outputs = [{ dims: outputShape, dataType: probs.dataType, gpuDataType: 0 /* default */ }]; + if (presentValue) { + outputs.push({ dims: presentValueShape, dataType: probs.dataType, gpuDataType: 0 /* default */ }); + } + const getShaderSource = (shaderHelper) => { + const probsHelper = inputVariable("probs", probs.dataType, probs.dims); + const vHelper = inputVariable("v", v.dataType, v.dims); + const inputVars = [probsHelper, vHelper]; + if (feedPastValue) { + inputVars.push(inputVariable("past_value", pastValue.dataType, pastValue.dims)); + } + const seqLensInputVariable = seqLens ? inputVariable("seq_lens", seqLens.dataType, seqLens.dims) : void 0; + if (seqLens) { + inputVars.push(seqLensInputVariable); + } + const totalSequenceLengthInputVariable = totalSequenceLengthInput ? inputVariable("total_sequence_length_input", totalSequenceLengthInput.dataType, totalSequenceLengthInput.dims) : void 0; + if (totalSequenceLengthInput) { + inputVars.push(totalSequenceLengthInputVariable); + } + const output = outputVariable("output", probs.dataType, outputShape); + const outputVars = [output]; + if (presentValue) { + outputVars.push(outputVariable("present_value", probs.dataType, presentValueShape)); + } + const uniforms = [ + { name: "M", type: "u32" }, + { name: "K", type: "u32" }, + { name: "N", type: "u32" }, + { name: "num_heads", type: "u32" }, + { name: "head_size", type: "u32" }, + { name: "v_hidden_size", type: "u32" }, + { name: "past_sequence_length", type: "u32" }, + { name: "kv_sequence_length", type: "u32" }, + { name: "n_reps", type: "u32" } + ]; + return ` + const TILE_SIZE = ${TILE_SIZE}u; + var tileQ: array<${probsHelper.type.value}, ${TILE_SIZE * TILE_SIZE}>; + var tileV: array<${probsHelper.type.value}, ${TILE_SIZE * TILE_SIZE}>; + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVars, ...outputVars)} + ${shaderHelper.mainStart([TILE_SIZE, TILE_SIZE, 1])} + let headIdx = workgroup_id.z % uniforms.num_heads; + let batchIdx = workgroup_id.z / uniforms.num_heads; + let kvHeadIdx = ${nReps === 1 ? "headIdx" : "headIdx / uniforms.n_reps"}; + let kv_num_heads = ${nReps === 1 ? "uniforms.num_heads" : "uniforms.num_heads / uniforms.n_reps"}; + let m = global_id.y; + let n = global_id.x; + let sequence_length = uniforms.M; + var total_sequence_length = uniforms.K; + ${initVarStub(seqLensInputVariable, totalSequenceLengthInputVariable, true)} + let offsetA = workgroup_id.z * uniforms.M * uniforms.K + m * uniforms.K; + let absKvHeadIdx = batchIdx * kv_num_heads + kvHeadIdx; // kvHeadIdx is relative to the batch + ${feedPastValue && presentValue ? "let pastValueOffset = absKvHeadIdx * uniforms.N * uniforms.past_sequence_length + n;" : ""}; + let vOffset = absKvHeadIdx * uniforms.N * uniforms.kv_sequence_length + n; + ${presentValue ? "let presentValueOffset = absKvHeadIdx * uniforms.N * uniforms.K + n;" : ""} + var value = ${probsHelper.type.storage}(0); + for (var w: u32 = 0u; w < uniforms.K; w += TILE_SIZE) { + if (m < uniforms.M && w + local_id.x < uniforms.K) { + tileQ[TILE_SIZE * local_id.y + local_id.x] = probs[offsetA + w + local_id.x]; + } + if (n < uniforms.N && w + local_id.y < uniforms.K) { + var idx = TILE_SIZE * local_id.y + local_id.x; + ${(() => { + if (feedPastValue && presentValue) { + return ` + if (w + local_id.y < past_sequence_length) { + tileV[idx] = past_value[pastValueOffset + (w + local_id.y) * uniforms.N]; + } else if (w + local_id.y - past_sequence_length < uniforms.kv_sequence_length) { + tileV[idx] = v[vOffset + (w + local_id.y - past_sequence_length) * uniforms.N]; + } + `; + } else { + return ` + if (w + local_id.y < uniforms.kv_sequence_length) { + tileV[idx] = v[vOffset + (w + local_id.y) * uniforms.N]; + }`; + } + })()} + ${presentValue ? ` + if (w + local_id.y < present_sequence_length) { + present_value[presentValueOffset + (w + local_id.y) * uniforms.N] = tileV[idx]; + }` : ""} + } + workgroupBarrier(); + for (var k: u32 = 0u; k < TILE_SIZE && w+k < total_sequence_length; k++) { + value += tileQ[TILE_SIZE * local_id.y + k] * tileV[TILE_SIZE * k + local_id.x]; + } + workgroupBarrier(); + } + + // we need to transpose output from BNSH_v to BSND_v + if (m < uniforms.M && n < uniforms.N) { + let outputIdx = batchIdx * uniforms.M * uniforms.v_hidden_size + m * uniforms.v_hidden_size + + headIdx * uniforms.N + n; + output[outputIdx] = value; + } + }`; + }; + return { + name: "AttentionScore", + shaderCache: { hint: `${pastValue !== void 0};${outputCount}`, inputDependencies }, + getRunData: () => ({ outputs, dispatchGroup: dispatch, programUniforms }), + getShaderSource + }; + }; + applyAttention = (context, q, k, v, _maskIndex, _past, pastKey, pastValue, attentionBiasInput, parameters, seqLens = void 0, totalSequenceLengthInput = void 0) => { + const outputCount = Math.min(context.outputCount, 1 + (pastKey ? 1 : 0) + (pastValue ? 1 : 0)); + const pastSequenceLength = outputCount > 1 ? parameters.pastSequenceLength : 0; + const totalSequenceLength = pastSequenceLength + parameters.kvSequenceLength; + const attentionBias = attentionBiasInput && ShapeUtil2.size(attentionBiasInput.dims) > 0 ? attentionBiasInput : void 0; + const inputsK = [q, k]; + if (outputCount > 1 && pastKey && ShapeUtil2.size(pastKey.dims) > 0) { + inputsK.push(pastKey); + } + if (attentionBias) { + inputsK.push(attentionBias); + } + if (seqLens) { + inputsK.push(seqLens); + } + if (totalSequenceLengthInput) { + inputsK.push(totalSequenceLengthInput); + } + const probs = context.compute( + createAttentionProbsProgramInfo( + outputCount, + q, + k, + pastKey, + attentionBias, + parameters, + pastSequenceLength, + seqLens, + totalSequenceLengthInput + ), + { inputs: inputsK, outputs: outputCount > 1 ? [-1, 1] : [-1] } + )[0]; + context.compute( + createInPlaceSoftmaxProgramInfo( + probs, + parameters.batchSize, + parameters.numHeads, + pastSequenceLength, + parameters.sequenceLength, + totalSequenceLength, + seqLens, + totalSequenceLengthInput + ), + { inputs: seqLens && totalSequenceLengthInput ? [probs, seqLens, totalSequenceLengthInput] : [probs], outputs: [] } + ); + const inputsV = [probs, v]; + if (outputCount > 1 && pastValue && ShapeUtil2.size(pastValue.dims) > 0) { + inputsV.push(pastValue); + } + if (seqLens) { + inputsV.push(seqLens); + } + if (totalSequenceLengthInput) { + inputsV.push(totalSequenceLengthInput); + } + context.compute( + createVxAttentionScoreProgramInfo( + outputCount, + probs, + v, + pastValue, + parameters, + pastSequenceLength, + seqLens, + totalSequenceLengthInput + ), + { + inputs: inputsV, + outputs: outputCount > 1 ? [0, 2] : [0] + } + ); + }; + prepare = (context, parameters) => { + const outputShape = [parameters.batchSize, parameters.numHeads, parameters.sequenceLength, parameters.headSize]; + const M = parameters.sequenceLength; + const K = parameters.inputHiddenSize; + const N = parameters.headSize; + const TILE_SIZE = 12; + const dispatch = { + x: Math.ceil(parameters.headSize / TILE_SIZE), + y: Math.ceil(parameters.sequenceLength / TILE_SIZE), + z: parameters.batchSize * parameters.numHeads + }; + const inputs = [context.inputs[0], context.inputs[1], context.inputs[2]]; + const programUniforms = [ + { type: 12 /* uint32 */, data: M }, + { type: 12 /* uint32 */, data: K }, + { type: 12 /* uint32 */, data: N }, + { type: 12 /* uint32 */, data: parameters.numHeads }, + { type: 12 /* uint32 */, data: parameters.headSize }, + { type: 12 /* uint32 */, data: parameters.hiddenSize }, + { type: 12 /* uint32 */, data: parameters.hiddenSize + parameters.hiddenSize + parameters.vHiddenSize } + ]; + const getShaderSource = (shaderHelper) => { + const outputQ = outputVariable("output_q", inputs[0].dataType, outputShape); + const outputK = outputVariable("output_k", inputs[0].dataType, outputShape); + const outputV = outputVariable("output_v", inputs[0].dataType, outputShape); + const input = inputVariable("input", inputs[0].dataType, inputs[0].dims); + const weight = inputVariable("weight", inputs[1].dataType, inputs[1].dims); + const bias = inputVariable("bias", inputs[2].dataType, inputs[2].dims); + const dataType = input.type.storage; + const uniforms = [ + { name: "M", type: "u32" }, + { name: "K", type: "u32" }, + { name: "N", type: "u32" }, + { name: "num_heads", type: "u32" }, + { name: "head_size", type: "u32" }, + { name: "hidden_size", type: "u32" }, + { name: "ldb", type: "u32" } + ]; + return ` + const TILE_SIZE = ${TILE_SIZE}u; + var tileInput: array<${dataType}, ${TILE_SIZE * TILE_SIZE}>; + var tileWeightQ: array<${dataType}, ${TILE_SIZE * TILE_SIZE}>; + var tileWeightK: array<${dataType}, ${TILE_SIZE * TILE_SIZE}>; + var tileWeightV: array<${dataType}, ${TILE_SIZE * TILE_SIZE}>; + ${shaderHelper.registerUniforms(uniforms).declareVariables(input, weight, bias, outputQ, outputK, outputV)} + ${shaderHelper.mainStart([TILE_SIZE, TILE_SIZE, 1])} + let batchIndex = workgroup_id.z / uniforms.num_heads; + let headNumber = workgroup_id.z % uniforms.num_heads; + let m = global_id.y; + let n = global_id.x; + + let inputOffset = batchIndex * (uniforms.M * uniforms.K) + m * uniforms.K; + let biasOffsetQ = headNumber * uniforms.head_size; + let biasOffsetK = uniforms.hidden_size + biasOffsetQ; + let biasOffsetV = uniforms.hidden_size + biasOffsetK; + + var valueQ = ${dataType}(0); + var valueK = ${dataType}(0); + var valueV = ${dataType}(0); + for (var w: u32 = 0u; w < uniforms.K; w += TILE_SIZE) { + if (m < uniforms.M && w + local_id.x < uniforms.K) { + tileInput[TILE_SIZE * local_id.y + local_id.x] = input[inputOffset + w + local_id.x]; + } + if (n < uniforms.N && w + local_id.y < uniforms.K) { + let offset = n + (w + local_id.y) * uniforms.ldb; + tileWeightQ[TILE_SIZE * local_id.y + local_id.x] = weight[biasOffsetQ + offset]; + tileWeightK[TILE_SIZE * local_id.y + local_id.x] = weight[biasOffsetK + offset]; + tileWeightV[TILE_SIZE * local_id.y + local_id.x] = weight[biasOffsetV + offset]; + } + workgroupBarrier(); + for (var k: u32 = 0u; k ({ + outputs: [ + { dims: outputShape, dataType: context.inputs[0].dataType, gpuDataType: 0 /* default */ }, + { dims: outputShape, dataType: context.inputs[0].dataType, gpuDataType: 0 /* default */ }, + { dims: outputShape, dataType: context.inputs[0].dataType, gpuDataType: 0 /* default */ } + ], + dispatchGroup: dispatch, + programUniforms + }), + getShaderSource + }, + { inputs, outputs: [-1, -1, -1] } + ); + }; + attention = (context, attributes) => { + const params = validateAttentionInputs(context.inputs, attributes); + const [q, k, v] = prepare(context, params); + return applyAttention( + context, + q, + k, + v, + context.inputs[4], + void 0, + void 0, + void 0, + context.inputs[5], + params + ); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/batch-norm.ts + var validateInputs29, createBatchNormInferenceProgramInfo, parseBatchNormAttributes, batchNorm; + var init_batch_norm = __esm({ + "web/lib/wasm/jsep/webgpu/ops/batch-norm.ts"() { + "use strict"; + init_esm(); + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs29 = (inputs, attributes) => { + if (!inputs || inputs.length !== 5) { + throw new Error("BatchNormalization requires 5 inputs"); + } + const checkShapeEqual = (actual, expected, message) => { + const r = expected.length; + if (r !== actual.length) { + throw new Error(`${message}: num dimensions != ${r}`); + } + expected.forEach((v, i) => { + if (v !== actual[i]) { + throw new Error(`${message}: dim[${i}] do not match`); + } + }); + }; + if (inputs[0].dims.length > 1) { + const shape2 = attributes.format === "NHWC" ? attributes.spatial ? inputs[0].dims.slice(-1) : inputs[0].dims.slice(-1).concat(inputs[0].dims.slice(1, inputs[0].dims.length - 1)) : inputs[0].dims.slice(1, attributes.spatial ? 2 : void 0); + checkShapeEqual(inputs[1].dims, shape2, "Invalid input scale"); + checkShapeEqual(inputs[2].dims, shape2, "Invalid input B"); + checkShapeEqual(inputs[3].dims, shape2, "Invalid input mean"); + checkShapeEqual(inputs[4].dims, shape2, "Invalid input var"); + } else { + checkShapeEqual(inputs[1].dims, [1], "Invalid input scale"); + checkShapeEqual(inputs[2].dims, [1], "Invalid input B"); + checkShapeEqual(inputs[3].dims, [1], "Invalid input mean"); + checkShapeEqual(inputs[4].dims, [1], "Invalid input var"); + } + }; + createBatchNormInferenceProgramInfo = (inputs, attributes) => { + const { epsilon, spatial, format } = attributes; + const yShape = inputs[0].dims; + const components = spatial ? getMaxComponents(yShape[yShape.length - 1]) : 1; + const cComponents = format === "NHWC" && yShape.length > 1 ? components : 1; + const outputSize = ShapeUtil2.size(yShape) / components; + const useShapesUniforms = spatial; + const shapeOrRank = useShapesUniforms ? yShape.length : yShape; + const x = inputVariable("x", inputs[0].dataType, inputs[0].dims, components); + const scale = inputVariable("scale", inputs[1].dataType, inputs[1].dims, cComponents); + const bias = inputVariable("bias", inputs[2].dataType, inputs[2].dims, cComponents); + const inputMean = inputVariable("inputMean", inputs[3].dataType, inputs[3].dims, cComponents); + const inputVar = inputVariable("inputVar", inputs[4].dataType, inputs[4].dims, cComponents); + const y = outputVariable("y", inputs[0].dataType, shapeOrRank, components); + const calcCOffset = () => { + let cOffset = ""; + if (spatial) { + cOffset = `let cOffset = ${yShape.length === 1 ? "0u" : format === "NHWC" ? `outputIndices[${yShape.length - 1}] / ${components}` : "outputIndices[1]"};`; + } else { + if (format === "NCHW") { + cOffset = ` + ${y.indicesSet("outputIndices", "0", "0")} + let cOffset = ${y.indicesToOffset("outputIndices")};`; + } else { + cOffset = `var cIndices = ${scale.type.indices}(0); + cIndices[0] = outputIndices[${yShape.length - 1}];`; + for (let i = 1; i < scale.rank; i++) { + cOffset += `cIndices[${i}] = outputIndices[${i}];`; + } + cOffset += `let cOffset = ${scale.indicesToOffset("cIndices")};`; + } + } + return cOffset; + }; + const getInferenceModeShaderSource = (helper) => ` + const epsilon = ${epsilon}; + ${helper.registerUniform("outputSize", "u32").declareVariables(x, scale, bias, inputMean, inputVar, y)} + ${helper.mainStart()} + ${helper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + var outputIndices = ${y.offsetToIndices(`global_idx * ${components}`)}; + ${calcCOffset()} + let scale = ${scale.getByOffset("cOffset")}; + let bias = ${bias.getByOffset("cOffset")}; + let inputMean = ${inputMean.getByOffset("cOffset")}; + let inputVar = ${inputVar.getByOffset("cOffset")}; + let x = ${x.getByOffset("global_idx")}; + let value = (x - inputMean) * inverseSqrt(inputVar + epsilon) * scale + bias; + ${y.setByOffset("global_idx", "value")} + }`; + return { + name: "BatchNormalization", + shaderCache: { + hint: `${attributes.epsilon}_${attributes.format}_${spatial}_${components}`, + inputDependencies: useShapesUniforms ? ["rank", "type", "type", "type", "type"] : void 0 + }, + getShaderSource: getInferenceModeShaderSource, + getRunData: () => ({ + outputs: [{ dims: inputs[0].dims, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms: useShapesUniforms ? [{ type: 12 /* uint32 */, data: outputSize }, ...createTensorShapeVariables(yShape)] : [{ type: 12 /* uint32 */, data: outputSize }] + }) + }; + }; + parseBatchNormAttributes = (attributes) => createAttributeWithCacheKey2(attributes); + batchNorm = (context, attributes) => { + const { inputs, outputCount } = context; + const updatedAttributes = parseBatchNormAttributes({ ...attributes, outputCount }); + if (env2.webgpu.validateInputContent) { + validateInputs29(inputs, updatedAttributes); + } + if (attributes.trainingMode) { + throw new Error("BatchNormalization trainingMode is not supported yet."); + } else { + context.compute(createBatchNormInferenceProgramInfo(inputs, updatedAttributes)); + } + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/bias-add.ts + var validateInputs30, createBiasAddProgramInfo, biasAdd; + var init_bias_add = __esm({ + "web/lib/wasm/jsep/webgpu/ops/bias-add.ts"() { + "use strict"; + init_util2(); + init_common(); + validateInputs30 = (inputs) => { + if (inputs[0].dims.length !== 3) { + throw new Error("input should have 3 dimensions"); + } + if (![320, 640, 1280].includes(inputs[0].dims[2])) { + throw new Error("number of channels should be 320, 640 or 1280"); + } + if (inputs[1].dims.length !== 1) { + throw new Error("bias is expected to have 1 dimensions"); + } + if (inputs[0].dims[2] !== inputs[1].dims[0]) { + throw new Error("last dimension of input and bias are not the same"); + } + }; + createBiasAddProgramInfo = (inputs) => { + const outputShape = inputs[0].dims; + const channels = inputs[0].dims[2]; + const outputSize = ShapeUtil2.size(outputShape) / 4; + const dataType = inputs[0].dataType; + const input = inputVariable("input", dataType, outputShape, 4); + const bias = inputVariable("bias", dataType, [channels], 4); + const residual = inputVariable("residual", dataType, outputShape, 4); + const output = outputVariable("output", dataType, outputShape, 4); + const getShaderSource = (shaderHelper) => ` + const channels = ${channels}u / 4; + ${shaderHelper.declareVariables(input, bias, residual, output)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes(outputSize)} + let value = ${input.getByOffset("global_idx")} + + ${bias.getByOffset("global_idx % channels")} + ${residual.getByOffset("global_idx")}; + ${output.setByOffset("global_idx", "value")} + }`; + return { + name: "BiasAdd", + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) } + }), + getShaderSource + }; + }; + biasAdd = (context) => { + validateInputs30(context.inputs); + context.compute(createBiasAddProgramInfo(context.inputs)); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/unary-op.ts + var createElementwiseProgramShader, createElementwiseProgramInfo2, abs2, acos2, acosh, asin2, asinh, atan2, atanh, parseCastAttributes2, cast2, generateClipAttributesFromInputs2, clip2, ceil2, cos2, cosh, parseAlphaAttributes, elu2, erfImpl, erf, exp2, floor2, gelu, leakyRelu2, not3, neg2, reciprocal, relu2, sigmoid2, parseHardSigmoidAttributes, hardSigmoid, sin2, sinh, sqrt2, tan2, tanhExpression, tanh2, fastGeluImpl, fastGeluExpression, fastGelu, thresholdedRelu, log3, quickGeluImpl, quickGeluExpression, quickgelu; + var init_unary_op2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/unary-op.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + createElementwiseProgramShader = (shaderHelper, datasize, inputDataType, outputDataType, funcCall, additionalImplementation, additionalUniformsType) => { + const vecSize = Math.ceil(datasize / 4); + let expression = ""; + if (typeof funcCall === "string") { + expression = `${funcCall}(a)`; + } else { + expression = funcCall("a"); + } + const input = inputVariable("inputData", inputDataType, [vecSize], 4); + const output = outputVariable("outputData", outputDataType, [vecSize], 4); + const uniforms = [{ name: "vec_size", type: "u32" }]; + if (additionalUniformsType) { + uniforms.push(...additionalUniformsType); + } + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(input, output)} + + ${additionalImplementation ?? ""} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.vec_size")} + + let a = ${input.getByOffset("global_idx")}; + ${output.setByOffset("global_idx", expression)} + }`; + }; + createElementwiseProgramInfo2 = (input, name2, funcCall, additionalImplementation, cacheKey, outputDataType = input.dataType, additionalUniforms, additionalUniformsType) => { + const programUniforms = [ + { type: 12 /* uint32 */, data: Math.ceil(ShapeUtil2.size(input.dims) / 4) } + ]; + if (additionalUniforms) { + programUniforms.push(...additionalUniforms); + } + return { + name: name2, + shaderCache: { hint: cacheKey, inputDependencies: ["type"] }, + getShaderSource: (shaderHelper) => createElementwiseProgramShader( + shaderHelper, + ShapeUtil2.size(input.dims), + input.dataType, + outputDataType, + funcCall, + additionalImplementation, + additionalUniformsType + ), + getRunData: (inputTensors) => ({ + outputs: [{ dims: input.dims, dataType: outputDataType }], + dispatchGroup: { + x: Math.ceil( + ShapeUtil2.size(inputTensors[0].dims) / 64 / 4 + /* vec size */ + ) + }, + programUniforms + }) + }; + }; + abs2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Abs", "abs")); + }; + acos2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Acos", "acos")); + }; + acosh = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Acosh", "acosh")); + }; + asin2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Asin", "asin")); + }; + asinh = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Asinh", "asinh")); + }; + atan2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Atan", "atan")); + }; + atanh = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Atanh", "atanh")); + }; + parseCastAttributes2 = (attributes) => createAttributeWithCacheKey2(attributes); + cast2 = (context, attributes) => { + let func; + switch (attributes.to) { + case 10 /* float16 */: + func = "vec4"; + break; + case 1 /* float */: + func = "vec4"; + break; + case 12 /* uint32 */: + func = "vec4"; + break; + case 6 /* int32 */: + func = "vec4"; + break; + case 9 /* bool */: + func = "vec4"; + break; + default: + throw new RangeError(`not supported type (specified in attribute 'to' from 'Cast' operator): ${attributes.to}`); + } + context.compute( + createElementwiseProgramInfo2(context.inputs[0], "Cast", func, void 0, attributes.cacheKey, attributes.to) + ); + }; + generateClipAttributesFromInputs2 = (inputs) => { + let min; + let max; + const hasMin = inputs.length >= 2 && inputs[1].data !== 0; + const hasMax = inputs.length >= 3 && inputs[2].data !== 0; + switch (inputs[0].dataType) { + case 1 /* float */: + min = hasMin ? inputs[1].getFloat32Array()[0] : -34028234663852886e22; + max = hasMax ? inputs[2].getFloat32Array()[0] : 34028234663852886e22; + break; + case 10 /* float16 */: + min = hasMin ? inputs[1].getUint16Array()[0] : 64511; + max = hasMax ? inputs[2].getUint16Array()[0] : 31743; + break; + default: + throw new Error("Unsupport data type"); + } + return createAttributeWithCacheKey2({ min, max }); + }; + clip2 = (context, clipAttributes) => { + const attributes = clipAttributes ? clipAttributes : generateClipAttributesFromInputs2(context.inputs); + const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute( + createElementwiseProgramInfo2( + context.inputs[0], + "Clip", + (a) => `clamp(${a}, vec4<${dataType}>(uniforms.min), vec4<${dataType}>(uniforms.max))`, + void 0, + attributes.cacheKey, + void 0, + [ + { type: context.inputs[0].dataType, data: attributes.min }, + { type: context.inputs[0].dataType, data: attributes.max } + ], + [ + { name: "min", type: dataType }, + { name: "max", type: dataType } + ] + ), + { inputs: [0] } + ); + }; + ceil2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Ceil", "ceil")); + }; + cos2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Cos", "cos")); + }; + cosh = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Cosh", "cosh")); + }; + parseAlphaAttributes = (attributes) => createAttributeWithCacheKey2(attributes); + elu2 = (context, attributes) => { + const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute( + createElementwiseProgramInfo2( + context.inputs[0], + "Elu", + (a) => `elu_vf32(${a})`, + ` + const elu_alpha_ = ${dataType}(${attributes.alpha}); + + fn elu_f32(a: ${dataType}) -> ${dataType} { + return select((exp(a) - 1.0) * elu_alpha_, a, a >= 0.0); + } + + fn elu_vf32(v: vec4<${dataType}>) -> vec4<${dataType}> { + return vec4(elu_f32(v.x), elu_f32(v.y), elu_f32(v.z), elu_f32(v.w)); + }`, + attributes.cacheKey + ) + ); + }; + erfImpl = (varType = "f32") => ` +const r0: ${varType} = 0.3275911; +const r1: ${varType} = 0.254829592; +const r2: ${varType} = -0.284496736; +const r3: ${varType} = 1.421413741; +const r4: ${varType} = -1.453152027; +const r5: ${varType} = 1.061405429; + +fn erf_vf32(v: vec4<${varType}>) -> vec4<${varType}> { + let absv = abs(v); + let x = 1.0 / (1.0 + r0 * absv); + return sign(v) * (1.0 - ((((r5 * x + r4) * x + r3) * x + r2) * x + r1) * x * exp(-absv * absv)); +}`; + erf = (context) => { + const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Erf", (a) => `erf_vf32(${a})`, erfImpl(dataType))); + }; + exp2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Exp", "exp")); + }; + floor2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Floor", "floor")); + }; + gelu = (context) => { + const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute( + createElementwiseProgramInfo2( + context.inputs[0], + "Gelu", + (a) => `0.5 * ${a} * (1.0 + erf_vf32(${a} * 0.7071067811865475))`, + erfImpl(dataType) + ) + ); + }; + leakyRelu2 = (context, attributes) => { + const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute( + createElementwiseProgramInfo2( + context.inputs[0], + "LeakyRelu", + (a) => `select(leaky_relu_alpha_ * ${a}, ${a}, ${a} >= vec4<${dataType}>(0.0))`, + `const leaky_relu_alpha_ = ${dataType}(${attributes.alpha});`, + attributes.cacheKey + ) + ); + }; + not3 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Not", (a) => `!${a}`)); + }; + neg2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Neg", (a) => `-${a}`)); + }; + reciprocal = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Reciprocal", (a) => `1.0/${a}`)); + }; + relu2 = (context) => { + const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute( + createElementwiseProgramInfo2( + context.inputs[0], + "Relu", + (a) => `select(vec4<${dataType}>(0.0), ${a}, ${a} > vec4<${dataType}>(0.0))` + ) + ); + }; + sigmoid2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Sigmoid", (a) => `(1.0 / (1.0 + exp(-${a})))`)); + }; + parseHardSigmoidAttributes = (attributes) => createAttributeWithCacheKey2( + attributes + ); + hardSigmoid = (context, attributes) => { + const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute( + createElementwiseProgramInfo2( + context.inputs[0], + "HardSigmoid", + (a) => `max(vec4<${dataType}>(0.0), min(vec4<${dataType}>(1.0), ${attributes.alpha} * ${a} + vec4<${dataType}>(${attributes.beta})))`, + void 0, + attributes.cacheKey + ) + ); + }; + sin2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Sin", "sin")); + }; + sinh = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Sinh", "sinh")); + }; + sqrt2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Sqrt", "sqrt")); + }; + tan2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Tan", "tan")); + }; + tanhExpression = (a) => `sign(${a}) * (1 - exp(-2 * abs(${a}))) / (1 + exp(-2 * abs(${a})))`; + tanh2 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Tanh", tanhExpression)); + }; + fastGeluImpl = (varType = "f32") => ` +const fast_gelu_a: ${varType} = 0.5; +const fast_gelu_b: ${varType} = 0.7978845608028654; +const fast_gelu_c: ${varType} = 0.035677408136300125; + +fn tanh_v(v: vec4<${varType}>) -> vec4<${varType}> { + return ${tanhExpression("v")}; +} +`; + fastGeluExpression = (x) => `(fast_gelu_a + fast_gelu_a * tanh_v(${x} * (fast_gelu_c * ${x} * ${x} + fast_gelu_b))) * ${x}`; + fastGelu = (context) => { + const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute( + createElementwiseProgramInfo2( + context.inputs[0], + "FastGelu", + fastGeluExpression, + fastGeluImpl(dataType), + void 0, + context.inputs[0].dataType + ) + ); + }; + thresholdedRelu = (context, attributes) => { + const dataType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute( + createElementwiseProgramInfo2( + context.inputs[0], + "ThresholdedRelu", + (a) => `select(vec4<${dataType}>(0.0), ${a}, ${a} > thresholded_relu_alpha_)`, + `const thresholded_relu_alpha_ = vec4<${dataType}>(${attributes.alpha});`, + attributes.cacheKey + ) + ); + return 0; + }; + log3 = (context) => { + context.compute(createElementwiseProgramInfo2(context.inputs[0], "Log", "log")); + }; + quickGeluImpl = (varType, alpha) => ` +const alpha = vec4<${varType}>(${alpha}); +const one = ${varType}(1.0); +const zero = ${varType}(0.0); + +fn quick_gelu_impl(x: vec4<${varType}>) -> vec4<${varType}> { + let v = x *alpha; + var x1 : vec4<${varType}>; + for (var i = 0; i < 4; i = i + 1) { + if (v[i] >= zero) { + x1[i] = one / (one + exp(-v[i])); + } else { + x1[i] = one - one / (one + exp(v[i])); + } + } + return x * x1; +} +`; + quickGeluExpression = (x) => `quick_gelu_impl(${x})`; + quickgelu = (context, attributes) => { + const dType = tensorTypeToWsglValueType(context.inputs[0].dataType); + context.compute( + createElementwiseProgramInfo2( + context.inputs[0], + "QuickGelu", + quickGeluExpression, + quickGeluImpl(dType, attributes.alpha), + attributes.cacheKey, + context.inputs[0].dataType + ) + ); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/bias-split-gelu.ts + var validateInputs31, createBiasSplitGeluProgramInfo, biasSplitGelu; + var init_bias_split_gelu = __esm({ + "web/lib/wasm/jsep/webgpu/ops/bias-split-gelu.ts"() { + "use strict"; + init_util2(); + init_common(); + init_unary_op2(); + validateInputs31 = (inputs) => { + if (inputs[0].dims.length !== 3) { + throw new Error("input should have 3 dimensions"); + } + if (![2560, 5120, 10240].includes(inputs[0].dims[2])) { + throw new Error("hidden state should be 2560, 5120 or 10240"); + } + if (inputs[1].dims.length !== 1) { + throw new Error("bias is expected to have 1 dimensions"); + } + if (inputs[0].dims[2] !== inputs[1].dims[0]) { + throw new Error("last dimension of input and bias are not the same"); + } + }; + createBiasSplitGeluProgramInfo = (inputs) => { + const outputShape = inputs[0].dims.slice(); + outputShape[2] = outputShape[2] / 2; + const input = inputVariable("input", inputs[0].dataType, inputs[0].dims, 4); + const bias = inputVariable("bias", inputs[0].dataType, [inputs[0].dims[2]], 4); + const output = outputVariable("output", inputs[0].dataType, outputShape, 4); + const outputSize = ShapeUtil2.size(outputShape) / 4; + const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); + const getShaderSource = (shaderHelper) => ` + const M_SQRT2 = sqrt(2.0); + const halfChannels = ${inputs[0].dims[2] / 4 / 2}u; + + ${shaderHelper.declareVariables(input, bias, output)} + + ${erfImpl(dataType)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes(outputSize)} + let biasIdx = global_idx % halfChannels; + let batchIndex = global_idx / halfChannels; + let inputOffset = biasIdx + batchIndex * halfChannels * 2; + let valueLeft = input[inputOffset] + bias[biasIdx]; + let valueRight = input[inputOffset + halfChannels] + bias[biasIdx + halfChannels]; + let geluRight = valueRight * 0.5 * (erf_vf32(valueRight / M_SQRT2) + 1); + + ${output.setByOffset("global_idx", "valueLeft * geluRight")} + }`; + return { + name: "BiasSplitGelu", + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) } + }), + getShaderSource + }; + }; + biasSplitGelu = (context) => { + validateInputs31(context.inputs); + context.compute(createBiasSplitGeluProgramInfo(context.inputs)); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/binary-op.ts + var createBinaryOpProgramShader, createBinaryOpProgramInfo, runBinaryOp, add3, div2, equal2, mul2, pow2, sub2, greater2, less2, greaterOrEqual, lessOrEqual; + var init_binary_op2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/binary-op.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + createBinaryOpProgramShader = (shaderHelper, dimsA, dimsB, dimsOutput, vectorize, doBroadcast, sharedDimensionDivisibleBy4, funcCall, typeA, typeB, typeOutput, additionalImplementation) => { + let expressionScalar; + let expressionVector; + if (typeof funcCall === "string") { + expressionScalar = expressionVector = (a2, b2) => `${funcCall}((${a2}),(${b2}))`; + } else if (typeof funcCall === "function") { + expressionScalar = expressionVector = funcCall; + } else { + expressionScalar = funcCall.scalar; + expressionVector = funcCall.vector; + } + const output = outputVariable("outputData", typeOutput, dimsOutput.length, 4); + const a = inputVariable("aData", typeA, dimsA.length, 4); + const b = inputVariable("bData", typeB, dimsB.length, 4); + let assignment; + if (vectorize) { + if (doBroadcast) { + const isAOneElement = ShapeUtil2.size(dimsA) === 1; + const isBOneElement = ShapeUtil2.size(dimsB) === 1; + const aLastDimDivisibleBy4 = dimsA.length > 0 && dimsA[dimsA.length - 1] % 4 === 0; + const bLastDimDivisibleBy4 = dimsB.length > 0 && dimsB[dimsB.length - 1] % 4 === 0; + if (isAOneElement || isBOneElement) { + assignment = output.setByOffset( + "global_idx", + expressionVector( + isAOneElement ? `${a.type.value}(${a.getByOffset("0")}.x)` : a.getByOffset("global_idx"), + isBOneElement ? `${b.type.value}(${b.getByOffset("0")}.x)` : b.getByOffset("global_idx") + ) + ); + } else { + assignment = ` + let outputIndices = ${output.offsetToIndices("global_idx * 4u")}; + let offsetA = ${a.broadcastedIndicesToOffset("outputIndices", output)}; + let offsetB = ${b.broadcastedIndicesToOffset("outputIndices", output)}; + ${output.setByOffset( + "global_idx", + expressionVector( + sharedDimensionDivisibleBy4 || aLastDimDivisibleBy4 ? a.getByOffset("offsetA / 4u") : `${a.type.value}(${a.getByOffset("offsetA / 4u")}[offsetA % 4u])`, + sharedDimensionDivisibleBy4 || bLastDimDivisibleBy4 ? b.getByOffset("offsetB / 4u") : `${b.type.value}(${b.getByOffset("offsetB / 4u")}[offsetB % 4u])` + ) + )} + `; + } + } else { + assignment = output.setByOffset( + "global_idx", + expressionVector(a.getByOffset("global_idx"), b.getByOffset("global_idx")) + ); + } + } else { + if (!doBroadcast) { + throw new Error("no necessary to use scalar implementation for element-wise binary op implementation."); + } + const singleAssignment = (resStr, x, typeCast = "") => { + const expressionA = `aData[indexA${x}][componentA${x}]`; + const expressionB = `bData[indexB${x}][componentB${x}]`; + return ` + let outputIndices${x} = ${output.offsetToIndices(`global_idx * 4u + ${x}u`)}; + let offsetA${x} = ${a.broadcastedIndicesToOffset(`outputIndices${x}`, output)}; + let offsetB${x} = ${b.broadcastedIndicesToOffset(`outputIndices${x}`, output)}; + let indexA${x} = offsetA${x} / 4u; + let indexB${x} = offsetB${x} / 4u; + let componentA${x} = offsetA${x} % 4u; + let componentB${x} = offsetB${x} % 4u; + ${resStr}[${x}] = ${typeCast}(${expressionScalar(expressionA, expressionB)}); + `; + }; + if (typeOutput === 9 /* bool */) { + assignment = ` + var data = vec4(0); + ${singleAssignment("data", 0, "u32")} + ${singleAssignment("data", 1, "u32")} + ${singleAssignment("data", 2, "u32")} + ${singleAssignment("data", 3, "u32")} + outputData[global_idx] = dot(vec4(0x1, 0x100, 0x10000, 0x1000000), vec4(data));`; + } else { + assignment = ` + ${singleAssignment("outputData[global_idx]", 0)} + ${singleAssignment("outputData[global_idx]", 1)} + ${singleAssignment("outputData[global_idx]", 2)} + ${singleAssignment("outputData[global_idx]", 3)} + `; + } + } + return ` + ${shaderHelper.registerUniform("vec_size", "u32").declareVariables(a, b, output)} + + ${additionalImplementation ?? ""} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.vec_size")} + ${assignment} + }`; + }; + createBinaryOpProgramInfo = (name2, cacheKey, a, b, funcCall, additionalImplementation, outputDataType = a.dataType) => { + const aDims = a.dims.map((x) => Number(x) ?? 1); + const bDims = b.dims.map((x) => Number(x) ?? 1); + const isBroadcast = !ShapeUtil2.areEqual(aDims, bDims); + let outputShape = aDims; + let outputSize = ShapeUtil2.size(aDims); + let vectorize = false; + let sharedDimensionDivisibleBy4 = false; + const cacheKeyAux = [isBroadcast]; + if (isBroadcast) { + const calculatedShape = BroadcastUtil2.calcShape(aDims, bDims, false); + if (!calculatedShape) { + throw new Error("Can't perform binary op on the given tensors"); + } + outputShape = calculatedShape.slice(); + outputSize = ShapeUtil2.size(outputShape); + const isAOneElement = ShapeUtil2.size(aDims) === 1; + const isBOneElement = ShapeUtil2.size(bDims) === 1; + const aLastDimDivisibleBy4 = aDims.length > 0 && aDims[aDims.length - 1] % 4 === 0; + const bLastDimDivisibleBy4 = bDims.length > 0 && bDims[bDims.length - 1] % 4 === 0; + cacheKeyAux.push(isAOneElement); + cacheKeyAux.push(isBOneElement); + cacheKeyAux.push(aLastDimDivisibleBy4); + cacheKeyAux.push(bLastDimDivisibleBy4); + let sharedDimension = 1; + for (let i = 1; i < outputShape.length; i++) { + const dimA = aDims[aDims.length - i]; + const dimB = bDims[bDims.length - i]; + if (dimA === dimB) { + sharedDimension *= dimA; + } else { + break; + } + } + if (sharedDimension % 4 === 0) { + sharedDimensionDivisibleBy4 = true; + vectorize = true; + } else if (isAOneElement || isBOneElement || aLastDimDivisibleBy4 || bLastDimDivisibleBy4) { + vectorize = true; + } + } else { + vectorize = true; + } + cacheKeyAux.push(vectorize); + return { + name: name2, + shaderCache: { + hint: cacheKey + cacheKeyAux.map((x) => x.toString()).join("_"), + inputDependencies: ["rank", "rank"] + }, + getShaderSource: (shaderHelper) => createBinaryOpProgramShader( + shaderHelper, + aDims, + bDims, + outputShape, + vectorize, + isBroadcast, + sharedDimensionDivisibleBy4, + funcCall, + a.dataType, + b.dataType, + outputDataType, + additionalImplementation + ), + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: outputDataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 / 4 + /* component size */ + ) }, + programUniforms: [ + { type: 12 /* uint32 */, data: Math.ceil(ShapeUtil2.size(outputShape) / 4) }, + ...createTensorShapeVariables(aDims, bDims, outputShape) + ] + }) + }; + }; + runBinaryOp = (context, name2, funcCall, additionalImplementation, cacheKey, outputDataType) => { + context.compute( + createBinaryOpProgramInfo( + name2, + cacheKey ?? "", + context.inputs[0], + context.inputs[1], + funcCall, + additionalImplementation, + outputDataType + ) + ); + }; + add3 = (context) => { + runBinaryOp(context, "Add", (a, b) => `${a}+${b}`); + }; + div2 = (context) => { + runBinaryOp(context, "Div", (a, b) => `${a}/${b}`); + }; + equal2 = (context) => { + runBinaryOp( + context, + "Equal", + { scalar: (a, b) => `u32(${a}==${b})`, vector: (a, b) => `vec4(${a}==${b})` }, + void 0, + void 0, + 9 /* bool */ + ); + }; + mul2 = (context) => { + runBinaryOp(context, "Mul", (a, b) => `${a}*${b}`); + }; + pow2 = (context) => { + const type = inputVariable("input", context.inputs[0].dataType, context.inputs[0].dims).type.value; + const roundStr = type === "i32" ? "round" : ""; + runBinaryOp( + context, + "Pow", + { scalar: (a, b) => `pow_custom(${a},${b})`, vector: (a, b) => `pow_vector_custom(${a},${b})` }, + ` + fn pow_custom(a : ${type}, b : ${type}) -> ${type} { + if (b == ${type}(0.0)) { + return ${type}(1.0); + } else if (a < ${type}(0.0) && f32(b) != floor(f32(b))) { + return ${type}(pow(f32(a), f32(b))); // NaN + } + return select(sign(a), ${type}(1.0), round(f32(abs(b) % ${type}(2.0))) != 1.0) * ${type}(${roundStr}(pow(f32(abs(a)), f32(b)))); + } + fn pow_vector_custom(a : vec4<${type}>, b : vec4<${type}>) -> vec4<${type}> { + // TODO: implement vectorized pow + return vec4<${type}>(pow_custom(a.x, b.x), pow_custom(a.y, b.y), pow_custom(a.z, b.z), pow_custom(a.w, b.w)); + } + ` + ); + }; + sub2 = (context) => { + runBinaryOp(context, "Sub", (a, b) => `${a}-${b}`); + }; + greater2 = (context) => { + runBinaryOp( + context, + "Greater", + { scalar: (a, b) => `u32(${a}>${b})`, vector: (a, b) => `vec4(${a}>${b})` }, + void 0, + void 0, + 9 /* bool */ + ); + }; + less2 = (context) => { + runBinaryOp( + context, + "Less", + { scalar: (a, b) => `u32(${a}<${b})`, vector: (a, b) => `vec4(${a}<${b})` }, + void 0, + void 0, + 9 /* bool */ + ); + }; + greaterOrEqual = (context) => { + runBinaryOp( + context, + "GreaterOrEqual", + { scalar: (a, b) => `u32(${a}>=${b})`, vector: (a, b) => `vec4(${a}>=${b})` }, + void 0, + void 0, + 9 /* bool */ + ); + }; + lessOrEqual = (context) => { + runBinaryOp( + context, + "LessOrEqual", + { scalar: (a, b) => `u32(${a}<=${b})`, vector: (a, b) => `vec4(${a}<=${b})` }, + void 0, + void 0, + 9 /* bool */ + ); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/concat.ts + var validateInputs32, calculateInputIndexImpl, assignOutputData, createConcatProgramInfo, concat2, parseConcatAttributes2; + var init_concat2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/concat.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs32 = (inputs, axis) => { + if (!inputs || inputs.length < 1) { + throw new Error("too few inputs"); + } + const referenceIndex = 0; + const referenceInput = inputs[referenceIndex]; + const inputType = referenceInput.dataType; + const inputRank = referenceInput.dims.length; + inputs.forEach((input, i) => { + if (i === referenceIndex) { + return; + } + if (input.dataType !== inputType) { + throw new Error("input tensors should be one type"); + } + if (input.dims.length !== inputRank) { + throw new Error("input tensors should have the same shape"); + } + input.dims.forEach((dim, i2) => { + if (i2 !== axis && dim !== referenceInput.dims[i2]) { + throw new Error("non concat dimensions must match"); + } + }); + }); + }; + calculateInputIndexImpl = (numberOfTensors, sizeInConcatAxisStr) => ` + fn calculateInputIndex(index: u32) -> u32 { + let sizeInConcatAxis = array(${sizeInConcatAxisStr}); + for (var i: u32 = 0u; i < ${numberOfTensors}; i += 1u ) { + if (index < sizeInConcatAxis[i]) { + return i; + } + } + return ${numberOfTensors}u; + }`; + assignOutputData = (inputs, output) => { + const numberOfTensors = inputs.length; + const codeLines = []; + for (let i = 0; i < numberOfTensors; ++i) { + const returnSnippet = output.setByOffset("global_idx", inputs[i].getByIndices("indices")); + if (numberOfTensors === 1) { + codeLines.push(returnSnippet); + } else if (i === 0) { + codeLines.push(`if (inputIndex == ${i}u) { ${returnSnippet} }`); + } else if (i === numberOfTensors - 1) { + codeLines.push(`else { ${returnSnippet} }`); + } else { + codeLines.push(`else if (inputIndex == ${i}) { ${returnSnippet} }`); + } + } + return codeLines.join("\n"); + }; + createConcatProgramInfo = (inputs, adjustedAxis, outputShape, dataType) => { + const outputSize = ShapeUtil2.size(outputShape); + const sizeInConcatAxis = new Array(inputs.length); + const inputVars = new Array(inputs.length); + let previousSum = 0; + const inputDependencies = []; + const inputRanks = []; + const programUniforms = [{ type: 12 /* uint32 */, data: outputSize }]; + for (let i = 0; i < inputs.length; ++i) { + previousSum += inputs[i].dims[adjustedAxis]; + sizeInConcatAxis[i] = previousSum; + inputRanks.push(inputs[i].dims.length); + inputVars[i] = inputVariable(`input${i}`, dataType, inputRanks[i]); + inputDependencies.push("rank"); + programUniforms.push({ type: 12 /* uint32 */, data: sizeInConcatAxis[i] }); + } + for (let i = 0; i < inputs.length; ++i) { + programUniforms.push(...createTensorShapeVariables(inputs[i].dims)); + } + programUniforms.push(...createTensorShapeVariables(outputShape)); + const output = outputVariable("output", dataType, outputShape.length); + const indicesAxis = output.indicesGet("indices", adjustedAxis); + const sizeInConcatAxisStr = Array.from(Array(sizeInConcatAxis.length).keys()).map((i) => `uniforms.sizeInConcatAxis${i}`).join(","); + const getShaderSource = (shaderHelper) => ` + + ${(() => { + shaderHelper.registerUniform("outputSize", "u32"); + for (let i = 0; i < inputs.length; i++) { + shaderHelper.registerUniform(`sizeInConcatAxis${i}`, "u32"); + } + return shaderHelper.declareVariables(...inputVars, output); + })()} + + ${calculateInputIndexImpl(sizeInConcatAxis.length, sizeInConcatAxisStr)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + + var indices = ${output.offsetToIndices("global_idx")}; + + let inputIndex = calculateInputIndex(${indicesAxis}); + if (inputIndex != 0u) { + let sizeInConcatAxis = array(${sizeInConcatAxisStr}); + ${indicesAxis} -= sizeInConcatAxis[inputIndex - 1u]; + } + + ${assignOutputData(inputVars, output)} + }`; + return { + name: "Concat", + shaderCache: { hint: `${adjustedAxis}`, inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + concat2 = (context, attributes) => { + const inputs = context.inputs; + const inputShape = inputs[0].dims; + const adjustedAxis = ShapeUtil2.normalizeAxis(attributes.axis, inputShape.length); + validateInputs32(inputs, adjustedAxis); + const outputShape = inputShape.slice(); + outputShape[adjustedAxis] = inputs.reduce( + (sum2, input) => sum2 + (input.dims.length > adjustedAxis ? input.dims[adjustedAxis] : 0), + 0 + ); + const nonEmptyInputs = inputs.filter((input) => ShapeUtil2.size(input.dims) > 0); + context.compute(createConcatProgramInfo(nonEmptyInputs, adjustedAxis, outputShape, inputs[0].dataType), { + inputs: nonEmptyInputs + }); + }; + parseConcatAttributes2 = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis }); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/fuse-utils.ts + var getActivationSnippet2, appendActivationUniformsData, appendActivationUniforms, parseInternalActivationAttributes2; + var init_fuse_utils2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/fuse-utils.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + getActivationSnippet2 = (attributes, valueType, baseType = "f32") => { + switch (attributes.activation) { + case "Relu": + return `value = max(value, ${valueType}(0.0));`; + case "Sigmoid": + return `value = (${valueType}(1.0) / (${valueType}(1.0) + exp(-value)));`; + case "Clip": + return `value = clamp(value, ${valueType}(${baseType}(uniforms.clip_min)), ${valueType}(${baseType}(uniforms.clip_max)));`; + case "HardSigmoid": + return `value = max(${valueType}(0.0), min(${valueType}(1.0), ${baseType}(uniforms.alpha) * value + ${baseType}(uniforms.beta)));`; + case "LeakyRelu": + return `value = select(${baseType}(uniforms.alpha) * value, value, value >= ${valueType}(0.0));`; + case "Tanh": + return `let e2x = exp(-2.0 * abs(value)); + value = sign(value) * (1.0 - e2x) / (1.0 + e2x); + `; + case "": + return ""; + // TODO: adding other activations that can be fused. + default: + throw new Error(`Unsupported activation ${attributes.activation}`); + } + }; + appendActivationUniformsData = (attributes, programUniform) => { + if (attributes.activation === "Clip") { + programUniform.push( + { type: 1 /* float */, data: attributes.clipMax }, + { type: 1 /* float */, data: attributes.clipMin } + ); + } else if (attributes.activation === "HardSigmoid") { + programUniform.push( + { type: 1 /* float */, data: attributes.alpha }, + { type: 1 /* float */, data: attributes.beta } + ); + } else if (attributes.activation === "LeakyRelu") { + programUniform.push({ type: 1 /* float */, data: attributes.alpha }); + } + }; + appendActivationUniforms = (attributes, uniforms) => { + if (attributes.activation === "Clip") { + uniforms.push({ name: "clip_max", type: "f32" }, { name: "clip_min", type: "f32" }); + } else if (attributes.activation === "HardSigmoid") { + uniforms.push({ name: "alpha", type: "f32" }, { name: "beta", type: "f32" }); + } else if (attributes.activation === "LeakyRelu") { + uniforms.push({ name: "alpha", type: "f32" }); + } + }; + parseInternalActivationAttributes2 = (attributes) => { + const activation = attributes?.activation || ""; + if (activation === "HardSigmoid") { + const [alpha, beta] = attributes?.activation_params || [0.2, 0.5]; + return { activation, alpha, beta }; + } else if (activation === "Clip") { + const [clipMin, clipMax] = attributes?.activation_params || [MIN_CLIP2, MAX_CLIP2]; + return { activation, clipMax, clipMin }; + } else if (activation === "LeakyRelu") { + const [alpha] = attributes?.activation_params || [0.01]; + return { activation, alpha }; + } + return { activation }; + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/3rd-party/activation_util.ts + var typeSnippet, biasSnippet; + var init_activation_util = __esm({ + "web/lib/wasm/jsep/webgpu/ops/3rd-party/activation_util.ts"() { + "use strict"; + typeSnippet = (component, dataType) => { + switch (component) { + case 1: + return dataType; + case 2: + return `vec2<${dataType}>`; + case 3: + return `vec3<${dataType}>`; + case 4: + return `vec4<${dataType}>`; + default: + throw new Error(`${component}-component is not supported.`); + } + }; + biasSnippet = (hasBias) => ` + ${hasBias ? "value = value + getBiasByOutputCoords(coords);" : ""} + `; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/3rd-party/conv_util.ts + var utilFunctions; + var init_conv_util = __esm({ + "web/lib/wasm/jsep/webgpu/ops/3rd-party/conv_util.ts"() { + "use strict"; + utilFunctions = (strideStr) => ` +fn getIndexFromCoords4D(coords : vec4, shape : vec4) -> i32 { + return dot(coords, vec4( + shape.y * shape.z * shape.w, shape.z * shape.w, shape.w, 1)); +} +fn getOutputIndexFromCoords(coords : vec4) -> i32 { + return dot(coords, vec4( + i32(${strideStr}.x), i32(${strideStr}.y), i32(${strideStr}.z), 1)); +} +`; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/matmul-shaders.ts + var convertOutputBatchIndicesToInputBatchIndices, createNaiveMatmulProgramInfo; + var init_matmul_shaders = __esm({ + "web/lib/wasm/jsep/webgpu/ops/matmul-shaders.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + init_fuse_utils2(); + convertOutputBatchIndicesToInputBatchIndices = (targetIndicesName, inputVariable2, inputBatchRank, outputBatchRank, batchIndicesName) => { + const extendingInputRank = outputBatchRank - inputBatchRank; + return ` + ${Array.from({ length: inputBatchRank }).map( + (_, i) => ` + if (${getElementAt(inputVariable2.shape, i, inputVariable2.rank)} != 1) { + ${inputVariable2.indicesSet(targetIndicesName, i, getElementAt(batchIndicesName, i + extendingInputRank, outputBatchRank))} + } else { + ${inputVariable2.indicesSet(targetIndicesName, i, 0)} + }` + ).join("")} +`; + }; + createNaiveMatmulProgramInfo = (inputs, activationAttributes, outputShape, reshapedOutputShape, isChannelsLast = false, squeezeOutputShapeFunction) => { + const aShape = inputs[0].dims; + const bShape = inputs[1].dims; + const M = aShape[aShape.length - 2]; + const N = bShape[bShape.length - 1]; + const K = aShape[aShape.length - 1]; + const components = getMaxComponents(N); + const aComponents = getMaxComponents(K); + const outputNumber = getMaxComponents(M); + const outputSize = ShapeUtil2.size(outputShape) / components / outputNumber; + const hasBias = inputs.length > 2; + const outerDims = reshapedOutputShape ? reshapedOutputShape.slice(0, -2) : outputShape.slice(0, -2); + const batchSize = ShapeUtil2.size(outerDims); + const outputShapeInShader = [batchSize, M, N]; + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: M }, + { type: 12 /* uint32 */, data: N }, + { type: 12 /* uint32 */, data: K } + ]; + appendActivationUniformsData(activationAttributes, programUniforms); + programUniforms.push(...createTensorShapeVariables(outerDims, aShape, bShape)); + if (hasBias) { + programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); + } + programUniforms.push(...createTensorShapeVariables(outputShapeInShader)); + const getShaderSource = (shaderHelper) => { + const batchDims = internalVariable("batch_dims", inputs[0].dataType, outerDims.length); + const a = inputVariable("a", inputs[0].dataType, aShape.length, aComponents); + const b = inputVariable("b", inputs[1].dataType, bShape.length, components); + const output = outputVariable("output", inputs[0].dataType, outputShapeInShader.length, components); + const baseType = tensorTypeToWsglStorageType(output.type.tensor); + const applyActivation = getActivationSnippet2(activationAttributes, output.type.value, baseType); + const inputVariables = [a, b]; + let processBias = ""; + if (hasBias) { + const biasComponents = isChannelsLast ? components : 1; + inputVariables.push(inputVariable("bias", inputs[2].dataType, inputs[2].dims.length, biasComponents)); + processBias = `${isChannelsLast ? `value += bias[col / ${biasComponents}];` : `value += ${output.type.value}(bias[row + i]);`}`; + } + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "M", type: "u32" }, + { name: "N", type: "u32" }, + { name: "K", type: "u32" } + ]; + appendActivationUniforms(activationAttributes, uniforms); + const calcResult = () => { + let calcStr = `var a_data: ${a.type.value};`; + for (let i = 0; i < aComponents; i++) { + calcStr += ` + let b_data${i} = b[(b_offset + (k + ${i}) * uniforms.N + col) / ${components}];`; + } + for (let i = 0; i < outputNumber; i++) { + calcStr += `a_data = a[(a_offset + (row + ${i}) * uniforms.K + k) / ${aComponents}];`; + for (let j = 0; j < aComponents; j++) { + calcStr += ` + values[${i}] = fma(${b.type.value}(a_data${aComponents === 1 ? "" : `[${j}]`}), b_data${j}, values[${i}]); +`; + } + } + return calcStr; + }; + return ` + ${shaderHelper.registerUniforms(uniforms).registerInternalVariables(batchDims).declareVariables(...inputVariables, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let col = (global_idx % (uniforms.N / ${components})) * ${components}; + var index1 = global_idx / (uniforms.N / ${components}); + let stride1 = uniforms.M / ${outputNumber}; + let row = (index1 % stride1) * ${outputNumber}; + let batch = index1 / stride1; + + ${outputShape.length === 2 ? "" : `let batch_indices = ${batchDims.offsetToIndices("batch")};`} + + var a_indices: ${a.type.indices}; + ${convertOutputBatchIndicesToInputBatchIndices("a_indices", a, a.rank - 2, batchDims.rank, "batch_indices")} + ${a.indicesSet("a_indices", a.rank - 2, 0)} + ${a.indicesSet("a_indices", a.rank - 1, 0)} + let a_offset = ${a.indicesToOffset("a_indices")}; + + var b_indices: ${b.type.indices}; + ${convertOutputBatchIndicesToInputBatchIndices("b_indices", b, b.rank - 2, batchDims.rank, "batch_indices")} + ${b.indicesSet("b_indices", b.rank - 2, 0)} + ${b.indicesSet("b_indices", b.rank - 1, 0)} + let b_offset = ${b.indicesToOffset("b_indices")}; + var values: array<${output.type.value}, ${outputNumber}>; + for (var k: u32 = 0u; k < uniforms.K; k = k + ${aComponents}) { + ${calcResult()} + } + for (var i = 0u; i < ${outputNumber}u; i++) { + var value = values[i]; + ${processBias} + ${applyActivation} + let cur_indices = ${output.type.indices}(batch, row + i, col); + let offset = ${output.indicesToOffset("cur_indices")}; + ${output.setByOffset(`offset / ${components}`, "value")}; + } + } + `; + }; + return { + name: "MatMulNaive", + shaderCache: { + hint: `${activationAttributes.activation};${components};${aComponents};${outputNumber};${isChannelsLast}`, + inputDependencies: hasBias ? ["rank", "rank", "rank"] : ["rank", "rank"] + }, + getRunData: () => ({ + outputs: [ + { + dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, + dataType: inputs[0].dataType + } + ], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/3rd-party/matmul_packed_webgpu.ts + var writeDataToSubAVec4Snippet, calculateResultSnippet, makeMatMulPackedVec4Source, writeDataToSubASnippet, readDataFromSubASnippet, makeMatMulPackedSource, matMulReadWriteFnSource, createMatmulProgramInfo2; + var init_matmul_packed_webgpu = __esm({ + "web/lib/wasm/jsep/webgpu/ops/3rd-party/matmul_packed_webgpu.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + init_fuse_utils2(); + init_matmul_shaders(); + init_activation_util(); + writeDataToSubAVec4Snippet = (transpose3, batchDims) => { + if (transpose3) { + return ` + mm_Asub[inputRow][inputCol] = mm_readA(batch, + kStart + inputRow, + globalRowStart / innerElementSize + inputCol${batchDims ? ", batchIndices" : ""}); + `; + } else { + return ` + mm_Asub[inputRow][inputCol] = mm_readA(batch, + globalRow + innerRow, + kStart / innerElementSize + inputCol${batchDims ? ", batchIndices" : ""}); + `; + } + }; + calculateResultSnippet = (transposeA, innerElementSize) => { + if (transposeA) { + return ` + let ACached0 = mm_Asub[k * innerElementSize][localRow]; + let ACached1 = mm_Asub[k * innerElementSize + 1][localRow]; + let ACached2 = mm_Asub[k * innerElementSize + 2][localRow]; + ${innerElementSize === 3 ? "" : "let ACached3 = mm_Asub[k * innerElementSize + 3][localRow];"} + for (var i = 0; i < rowPerThread; i = i + 1) { + acc[i] = BCached0 * ACached0[i] + acc[i]; + acc[i] = BCached1 * ACached1[i] + acc[i]; + acc[i] = BCached2 * ACached2[i] + acc[i]; + ${innerElementSize === 3 ? "" : "acc[i] = BCached3 * ACached3[i] + acc[i];"} + }`; + } else { + return ` + for (var i = 0; i < rowPerThread; i = i + 1) { + let ACached = mm_Asub[tileRow + i][k]; + acc[i] = BCached0 * ACached.x + acc[i]; + acc[i] = BCached1 * ACached.y + acc[i]; + acc[i] = BCached2 * ACached.z + acc[i]; + ${innerElementSize === 3 ? "" : "acc[i] = BCached3 * ACached.w + acc[i];"} + }`; + } + }; + makeMatMulPackedVec4Source = (workPerThread, workgroupSize, type = "f32", batchDims, transposeA = false, tileInner = 32, splitK = false, splitedDimInner = 32) => { + const tileAOuter = workgroupSize[1] * workPerThread[1]; + const tileBOuter = workgroupSize[0] * workPerThread[0]; + const tileAWidth = transposeA ? tileAOuter : tileInner; + const tileAHight = transposeA ? tileInner : tileAOuter; + const innerElementSize = tileAWidth / workgroupSize[0]; + const rowPerThreadB = tileInner / workgroupSize[1]; + if (!((transposeA && innerElementSize === 4 && workPerThread[1] === 4 || !transposeA && (innerElementSize === 3 || innerElementSize === 4)) && tileAWidth % workgroupSize[0] === 0 && tileInner % workgroupSize[1] === 0 && workPerThread[0] === 4)) { + throw new Error(`If transposeA ${transposeA} is true, innerElementSize ${innerElementSize} and workPerThread[1] ${workPerThread[1]} must be 4. + Otherwise, innerElementSize ${innerElementSize} must be 3 or 4. + tileAWidth ${tileAWidth} must be divisible by workgroupSize[0]${workgroupSize[0]}. tileInner ${tileInner} must be divisible by workgroupSize[1] ${workgroupSize[1]}. colPerThread ${workPerThread[0]} must be 4.`); + } + return ` +var mm_Asub: array, ${tileAWidth / innerElementSize}>, ${tileAHight}>; +var mm_Bsub: array, ${tileBOuter / workPerThread[0]}>, ${tileInner}>; + +const rowPerThread = ${workPerThread[1]}; +const colPerThread = ${workPerThread[0]}; +const innerElementSize = ${innerElementSize}; +const tileInner = ${tileInner}; + +@compute @workgroup_size(${workgroupSize[0]}, ${workgroupSize[1]}, ${workgroupSize[2]}) +fn main(@builtin(local_invocation_id) localId : vec3, + @builtin(global_invocation_id) globalId : vec3, + @builtin(workgroup_id) workgroupId : vec3) { + let localRow = i32(localId.y); + let tileRow = localRow * rowPerThread; + let tileCol = i32(localId.x); + + let globalRow =i32(globalId.y) * rowPerThread; + let globalCol = i32(globalId.x); + let batch = ${splitK ? "0" : "i32(globalId.z)"}; + ${batchDims ? `let batchIndices = ${batchDims.offsetToIndices("u32(batch)")};` : ""} + let globalRowStart = i32(workgroupId.y) * ${tileAOuter}; + + let num_tiles = ${splitK ? `${Math.ceil(splitedDimInner / tileInner)}` : "(uniforms.dim_inner - 1) / tileInner + 1"}; + var kStart = ${splitK ? `i32(globalId.z) * ${splitedDimInner}` : "0"}; + + var acc: array, rowPerThread>; + + // Loop over shared dimension. + let tileRowB = localRow * ${rowPerThreadB}; + for (var t = 0; t < num_tiles; t = t + 1) { + // Load one tile of A into local memory. + for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { + let inputRow = tileRow + innerRow; + let inputCol = tileCol; + ${writeDataToSubAVec4Snippet(transposeA, batchDims)} + } + + // Load one tile of B into local memory. + for (var innerRow = 0; innerRow < ${rowPerThreadB}; innerRow = innerRow + 1) { + let inputRow = tileRowB + innerRow; + let inputCol = tileCol; + mm_Bsub[inputRow][inputCol] = mm_readB(batch, kStart + inputRow, globalCol${batchDims ? ", batchIndices" : ""}); + } + kStart = kStart + tileInner; + workgroupBarrier(); + + // Compute acc values for a single thread. + for (var k = 0; k < tileInner / innerElementSize; k = k + 1) { + let BCached0 = mm_Bsub[k * innerElementSize][tileCol]; + let BCached1 = mm_Bsub[k * innerElementSize + 1][tileCol]; + let BCached2 = mm_Bsub[k * innerElementSize + 2][tileCol]; + ${innerElementSize === 3 ? "" : "let BCached3 = mm_Bsub[k * innerElementSize + 3][tileCol];"} + + ${calculateResultSnippet(transposeA, innerElementSize)} + } + + workgroupBarrier(); + } + + for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { + mm_write(batch, globalRow + innerRow, globalCol, acc[innerRow]); + } +}`; + }; + writeDataToSubASnippet = (transpose3, batchDims) => { + if (transpose3) { + return ` + mm_Asub[inputRow][inputCol] = mm_readA(batch, + kStart + inputRow, + globalRowStart + inputCol${batchDims ? ", batchIndices" : ""}); + `; + } else { + return ` + mm_Asub[inputRow][inputCol] = mm_readA(batch, + globalRowStart + inputRow, + kStart + inputCol${batchDims ? ", batchIndices" : ""}); + `; + } + }; + readDataFromSubASnippet = (transposeA) => transposeA ? "let ACached = mm_Asub[k][tileRow + innerRow];" : "let ACached = mm_Asub[tileRow + innerRow][k];"; + makeMatMulPackedSource = (workPerThread, workgroupSize, type = "f32", batchDims, transposeA = false, tileInner = 32, splitK = false, splitedDimInner = 32, sequentialAccessByThreads = false) => { + const tileAOuter = workPerThread[1] * workgroupSize[1]; + const tileBOuter = workPerThread[0] * workgroupSize[0]; + const tileAWidth = transposeA ? tileAOuter : tileInner; + const tileAHight = transposeA ? tileInner : tileAOuter; + if (!(tileAHight % workgroupSize[1] === 0 && tileAWidth % workgroupSize[0] === 0 && tileInner % workgroupSize[1] === 0)) { + throw new Error( + `tileAHight ${tileAHight} must be divisible by workgroupSize[1]${workgroupSize[1]}, tileAWidth ${tileAWidth} must be divisible by workgroupSize[0]${workgroupSize[0]}, tileInner ${tileInner} must be divisible by workgroupSize[1]${workgroupSize[1]}` + ); + } + const rowPerThreadA = tileAHight / workgroupSize[1]; + const colPerThreadA = tileAWidth / workgroupSize[0]; + const rowPerThreadB = tileInner / workgroupSize[1]; + const matmulSnippet = sequentialAccessByThreads ? ` + let localRow = i32(localId.y); + let localCol = i32(localId.x); + let globalRowStart = i32(workgroupId.y) * ${tileAOuter}; + let globalColStart = i32(workgroupId.x) * ${tileBOuter}; + + // Loop over shared dimension. + for (var t = 0; t < num_tiles; t = t + 1) { + // Load one tile of A into local memory. + for (var inputRow = localRow; inputRow < ${tileAHight}; inputRow = inputRow + ${workgroupSize[1]}) { + for (var inputCol = localCol; inputCol < ${tileAWidth}; inputCol = inputCol + ${workgroupSize[0]}) { + ${writeDataToSubASnippet(transposeA, batchDims)} + } + } + // Load one tile of B into local memory. + for (var inputRow = localRow; inputRow < ${tileInner}; inputRow = inputRow + ${workgroupSize[1]}) { + for (var inputCol = localCol; inputCol < ${tileBOuter}; inputCol = inputCol + ${workgroupSize[0]}) { + mm_Bsub[inputRow][inputCol] = mm_readB(batch, + kStart + inputRow, + globalColStart + inputCol${batchDims ? ", batchIndices" : ""}); + } + } + kStart = kStart + tileInner; + workgroupBarrier(); + + // Compute acc values for a single thread. + var BCached : array<${type}, colPerThread>; + for (var k = 0; k < tileInner; k = k + 1) { + for (var inner = 0; inner < colPerThread; inner = inner + 1) { + BCached[inner] = mm_Bsub[k][localCol + inner * ${workgroupSize[0]}]; + } + for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { + let ACached = ${transposeA ? `mm_Asub[k][localRow + innerRow * ${workgroupSize[1]}];` : `mm_Asub[localRow + innerRow * ${workgroupSize[1]}][k];`} + for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { + acc[innerRow][innerCol] = acc[innerRow][innerCol] + + ACached * BCached[innerCol]; + } + } + } + workgroupBarrier(); + } + for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { + let gRow = globalRowStart + localRow + innerRow * ${workgroupSize[1]}; + for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { + let gCol = globalColStart + localCol + innerCol * ${workgroupSize[0]}; + mm_write(batch, gRow, gCol, acc[innerRow][innerCol]); + } + } + ` : ` +let tileRow = i32(localId.y) * rowPerThread; +let tileCol = i32(localId.x) * colPerThread; + +let globalRow = i32(globalId.y) * rowPerThread; +let globalCol = i32(globalId.x) * colPerThread; +let globalRowStart = i32(workgroupId.y) * ${tileAOuter}; + +let tileRowA = i32(localId.y) * ${rowPerThreadA}; +let tileColA = i32(localId.x) * ${colPerThreadA}; +let tileRowB = i32(localId.y) * ${rowPerThreadB}; +// Loop over shared dimension. +for (var t = 0; t < num_tiles; t = t + 1) { + // Load one tile of A into local memory. + for (var innerRow = 0; innerRow < ${rowPerThreadA}; innerRow = innerRow + 1) { + for (var innerCol = 0; innerCol < ${colPerThreadA}; innerCol = innerCol + 1) { + let inputRow = tileRowA + innerRow; + let inputCol = tileColA + innerCol; + ${writeDataToSubASnippet(transposeA, batchDims)} + } + } + + // Load one tile of B into local memory. + for (var innerRow = 0; innerRow < ${rowPerThreadB}; innerRow = innerRow + 1) { + for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { + let inputRow = tileRowB + innerRow; + let inputCol = tileCol + innerCol; + mm_Bsub[inputRow][inputCol] = mm_readB(batch, + kStart + inputRow, + globalCol + innerCol${batchDims ? ", batchIndices" : ""}); + } + } + kStart = kStart + tileInner; + workgroupBarrier(); + + // Compute acc values for a single thread. + var BCached : array<${type}, colPerThread>; + for (var k = 0; k < tileInner; k = k + 1) { + for (var inner = 0; inner < colPerThread; inner = inner + 1) { + BCached[inner] = mm_Bsub[k][tileCol + inner]; + } + + for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { + ${readDataFromSubASnippet(transposeA)} + for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { + acc[innerRow][innerCol] = acc[innerRow][innerCol] + ACached * BCached[innerCol]; + } + } + } + + workgroupBarrier(); +} + +for (var innerRow = 0; innerRow < rowPerThread; innerRow = innerRow + 1) { + for (var innerCol = 0; innerCol < colPerThread; innerCol = innerCol + 1) { + mm_write(batch, globalRow + innerRow, globalCol + innerCol, + acc[innerRow][innerCol]); + } +} +`; + return ` + var mm_Asub : array, ${tileAHight}>; + var mm_Bsub : array, ${tileInner}>; + const rowPerThread = ${workPerThread[1]}; + const colPerThread = ${workPerThread[0]}; + const tileInner = ${tileInner}; + +@compute @workgroup_size(${workgroupSize[0]}, ${workgroupSize[1]}, ${workgroupSize[2]}) +fn main(@builtin(local_invocation_id) localId : vec3, + @builtin(global_invocation_id) globalId : vec3, + @builtin(workgroup_id) workgroupId : vec3) { + let batch = ${splitK ? "0" : "i32(globalId.z)"}; + ${batchDims ? `let batchIndices = ${batchDims.offsetToIndices("u32(batch)")};` : ""} + let num_tiles = ${splitK ? `${Math.ceil(splitedDimInner / tileInner)}` : "(uniforms.dim_inner - 1) / tileInner + 1"}; + var kStart = ${splitK ? `i32(globalId.z) * ${splitedDimInner}` : "0"}; + + var acc : array, rowPerThread>; + ${matmulSnippet} + } +`; + }; + matMulReadWriteFnSource = (component, hasBias, applyActivation, variables, isChannelsLast = false) => { + const [batchVariable, aVariable, bVariable, outputVariable2] = variables; + const dataType = tensorTypeToWsglStorageType(variables[0].type.tensor); + const source = ` + fn mm_readA(batch: i32, row: i32, colIn: i32, batchIndices: ${batchVariable.type.indices}) -> ${typeSnippet( + component, + dataType + )} { + var value = ${typeSnippet(component, dataType)}(0.0); + let col = colIn * ${component}; + if(row < uniforms.dim_a_outer && col < uniforms.dim_inner) + { + var aIndices: ${aVariable.type.indices}; + ${convertOutputBatchIndicesToInputBatchIndices( + "aIndices", + aVariable, + aVariable.rank - 2, + batchVariable.rank, + "batchIndices" + )} + ${aVariable.indicesSet("aIndices", aVariable.rank - 2, "u32(row)")} + ${aVariable.indicesSet("aIndices", aVariable.rank - 1, "u32(colIn)")} + value = ${aVariable.getByIndices("aIndices")}; + } + return value; + } + + fn mm_readB(batch: i32, row: i32, colIn: i32, batchIndices: ${batchVariable.type.indices}) -> ${typeSnippet( + component, + dataType + )} { + var value = ${typeSnippet(component, dataType)}(0.0); + let col = colIn * ${component}; + if(row < uniforms.dim_inner && col < uniforms.dim_b_outer) + { + var bIndices: ${bVariable.type.indices}; + ${convertOutputBatchIndicesToInputBatchIndices( + "bIndices", + bVariable, + bVariable.rank - 2, + batchVariable.rank, + "batchIndices" + )} + ${bVariable.indicesSet("bIndices", bVariable.rank - 2, "u32(row)")} + ${bVariable.indicesSet("bIndices", bVariable.rank - 1, "u32(colIn)")} + value = ${bVariable.getByIndices("bIndices")}; + } + return value; + } + + fn mm_write(batch: i32, row: i32, colIn: i32, valueIn: ${typeSnippet(component, dataType)}) { + let col = colIn * ${component}; + if (row < uniforms.dim_a_outer && col < uniforms.dim_b_outer) { + var value = valueIn; + let coords = vec3(batch, row, colIn); + ${hasBias ? `value = value + ${isChannelsLast ? "bias[colIn]" : `${typeSnippet(component, dataType)}(bias[row])`};` : ""} + ${applyActivation} + ${outputVariable2.setByIndices("vec3(coords)", "value")} + } + } + `; + return source; + }; + createMatmulProgramInfo2 = (inputs, activationAttributes, outputShape, reshapedOutputShape, isChannelsLast = false, squeezeOutputShapeFunction) => { + const aShape = inputs[0].dims; + const bShape = inputs[1].dims; + const outerDimsA = aShape.slice(0, -2); + const outerDimsB = bShape.slice(0, -2); + const outerDims = reshapedOutputShape ? reshapedOutputShape.slice(0, -2) : outputShape.slice(0, -2); + const batchSize = ShapeUtil2.size(outerDims); + const dimAOuter = aShape[aShape.length - 2]; + const dimInner = aShape[aShape.length - 1]; + const dimBOuter = bShape[bShape.length - 1]; + const isVec4 = dimInner % 4 === 0 && dimBOuter % 4 === 0; + const elementsPerThread = dimAOuter <= 8 ? [4, 1, 1] : [4, 4, 1]; + const workgroupSize = [8, 8, 1]; + const dispatch = [ + Math.ceil(dimBOuter / workgroupSize[0] / elementsPerThread[0]), + Math.ceil(dimAOuter / workgroupSize[1] / elementsPerThread[1]), + Math.ceil(batchSize / workgroupSize[2] / elementsPerThread[2]) + ]; + const components = isVec4 ? 4 : 1; + const aShapeTemp = [...outerDimsA, dimAOuter, dimInner / components]; + const aRank = aShapeTemp.length; + const bShapeTemp = [...outerDimsB, dimInner, dimBOuter / components]; + const bRank = bShapeTemp.length; + const outputShapeTemp = [batchSize, dimAOuter, dimBOuter / components]; + const programUniforms = [ + { type: 6 /* int32 */, data: dimAOuter }, + { type: 6 /* int32 */, data: dimBOuter }, + { type: 6 /* int32 */, data: dimInner } + ]; + appendActivationUniformsData(activationAttributes, programUniforms); + programUniforms.push(...createTensorShapeVariables(outerDims, aShapeTemp, bShapeTemp)); + const inputDependencies = ["rank", "rank"]; + const hasBias = inputs.length > 2; + if (hasBias) { + programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); + inputDependencies.push("rank"); + } + programUniforms.push(...createTensorShapeVariables(outputShapeTemp)); + const getShaderSource = (shaderHelper) => { + const batchRank = outerDims.length; + const batchDims = internalVariable("batchDims", inputs[0].dataType, batchRank, 1); + const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); + const A = inputVariable("a", inputs[0].dataType, aRank, components); + const B = inputVariable("b", inputs[1].dataType, bRank, components); + const output = outputVariable("result", inputs[0].dataType, outputShapeTemp.length, components); + const inputVariables = [A, B]; + if (hasBias) { + const biasComponents = isChannelsLast ? components : 1; + inputVariables.push(inputVariable("bias", inputs[2].dataType, inputs[2].dims.length, biasComponents)); + } + const uniforms = [ + { name: "dim_a_outer", type: "i32" }, + { name: "dim_b_outer", type: "i32" }, + { name: "dim_inner", type: "i32" } + ]; + appendActivationUniforms(activationAttributes, uniforms); + const baseType = tensorTypeToWsglStorageType(output.type.tensor); + const applyActivation = getActivationSnippet2(activationAttributes, output.type.value, baseType); + const declareFunctions = matMulReadWriteFnSource( + components, + hasBias, + applyActivation, + [batchDims, A, B, output], + isChannelsLast + ); + return ` + ${shaderHelper.registerUniforms(uniforms).registerInternalVariables(batchDims).declareVariables(...inputVariables, output)} + ${declareFunctions} + ${isVec4 ? makeMatMulPackedVec4Source(elementsPerThread, workgroupSize, dataType, batchDims) : makeMatMulPackedSource(elementsPerThread, workgroupSize, dataType, batchDims)} + `; + }; + return { + name: "MatMul", + shaderCache: { + hint: `${elementsPerThread};${activationAttributes.activation};${isVec4};${isChannelsLast}`, + inputDependencies + }, + getRunData: () => ({ + outputs: [ + { + dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, + dataType: inputs[0].dataType + } + ], + dispatchGroup: { x: dispatch[0], y: dispatch[1], z: dispatch[2] }, + programUniforms + }), + getShaderSource + }; + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/3rd-party/conv2d_mm_webgpu.ts + var conv2dCommonSnippet, createConv2DMatMulProgramInfo; + var init_conv2d_mm_webgpu = __esm({ + "web/lib/wasm/jsep/webgpu/ops/3rd-party/conv2d_mm_webgpu.ts"() { + "use strict"; + init_wasm_common(); + init_log(); + init_common(); + init_fuse_utils2(); + init_activation_util(); + init_conv_util(); + init_matmul_packed_webgpu(); + conv2dCommonSnippet = (isChannelsLast, fitAOuter, fitBOuter, fitInner, addBias = false, attributes, innerElementSizeX = 4, innerElementSizeW = 4, innerElementSize = 4, dataType = "f32") => { + const getXSnippet = (innerElementSize2) => { + switch (innerElementSize2) { + case 1: + return "resData = x[xIndex];"; + case 3: + return `resData = vec3<${dataType}>(x[xIndex], x[xIndex + 1], x[xIndex + 2]);`; + case 4: + return "resData = x[xIndex / 4];"; + default: + throw new Error(`innerElementSize ${innerElementSize2} is not supported.`); + } + }; + const getWSnippet = (innerElementSize2) => { + switch (innerElementSize2) { + case 1: + return "return w[row * i32(uniforms.w_shape[3]) + colIn];"; + case 4: + return "return w[row * i32(uniforms.w_shape[3]) / 4 + colIn];"; + default: + throw new Error(`innerElementSize ${innerElementSize2} is not supported.`); + } + }; + const coordASnippet = isChannelsLast ? ` + let coord = vec4(batch, xRow, xCol, xCh); + ` : ` + let coord = vec4(batch, xCh, xRow, xCol); + `; + const coordResSnippet = isChannelsLast ? ` + let coords = vec4( + batch, + row / outWidth, + row % outWidth, + col); + ` : ` + let coords = vec4( + batch, + row, + col / outWidth, + col % outWidth); + `; + const xHeight = isChannelsLast ? "i32(uniforms.x_shape[1])" : "i32(uniforms.x_shape[2])"; + const xWidth = isChannelsLast ? "i32(uniforms.x_shape[2])" : "i32(uniforms.x_shape[3])"; + const row = isChannelsLast ? "row" : "col"; + const col = isChannelsLast ? "col" : "row"; + const readXSnippet = ` + let inChannels = i32(uniforms.w_shape[2]); + let outWidth = ${isChannelsLast ? "i32(uniforms.result_shape[2])" : "i32(uniforms.result_shape[3])"}; + let outRow = ${row} / outWidth; + let outCol = ${row} % outWidth; + + let WRow = ${col} / (i32(uniforms.w_shape[1]) * inChannels); + let WCol = ${col} / inChannels % i32(uniforms.w_shape[1]); + let xRow = outRow * uniforms.stride[0] + uniforms.dilation[0] * WRow - uniforms.pad[0]; + let xCol = outCol * uniforms.stride[1] + uniforms.dilation[1] * WCol - uniforms.pad[1]; + let xCh = ${col} % inChannels; + var resData = ${typeSnippet(innerElementSizeX, dataType)}(0.0); + // The bounds checking is always needed since we use it to pad zero for + // the 'same' padding type. + if (xRow >= 0 && xRow < ${xHeight} && xCol >= 0 && xCol < ${xWidth}) { + ${coordASnippet} + let xIndex = getIndexFromCoords4D(coord, vec4(uniforms.x_shape)); + ${getXSnippet(innerElementSizeX)} + } + return resData;`; + const sampleX = isChannelsLast ? fitAOuter && fitInner ? ` + let col = colIn * ${innerElementSizeX}; + ${readXSnippet}` : ` + let col = colIn * ${innerElementSizeX}; + if (row < uniforms.dim_a_outer && col < uniforms.dim_inner) { + ${readXSnippet} + } + return ${typeSnippet(innerElementSizeX, dataType)}(0.0);` : fitInner && fitBOuter ? ` + let col = colIn * ${innerElementSizeX}; + ${readXSnippet}` : ` + let col = colIn * ${innerElementSizeX}; + if (row < uniforms.dim_inner && col < uniforms.dim_b_outer) { + ${readXSnippet} + } + return ${typeSnippet(innerElementSizeX, dataType)}(0.0);`; + const sampleW = isChannelsLast ? fitInner && fitBOuter ? getWSnippet(innerElementSizeW) : ` + let col = colIn * ${innerElementSizeW}; + if (row < uniforms.dim_inner && col < uniforms.dim_b_outer) { + ${getWSnippet(innerElementSizeW)} + } + return ${typeSnippet(innerElementSizeW, dataType)}(0.0);` : ` + let col = colIn * ${innerElementSizeW}; + if (row < uniforms.dim_inner && col < uniforms.dim_a_outer) { + ${getWSnippet(innerElementSizeW)} + } + return ${typeSnippet(innerElementSizeW, dataType)}(0.0);`; + const resType = typeSnippet(innerElementSize, dataType); + const aType = isChannelsLast ? typeSnippet(innerElementSizeX, dataType) : typeSnippet(innerElementSizeW, dataType); + const bType = isChannelsLast ? typeSnippet(innerElementSizeW, dataType) : typeSnippet(innerElementSizeX, dataType); + const applyActivation = getActivationSnippet2(attributes, resType, dataType); + const userCode = ` + fn mm_readA(batch: i32, row : i32, colIn : i32) -> ${aType} { + ${isChannelsLast ? sampleX : sampleW} + } + + fn mm_readB(batch: i32, row : i32, colIn : i32) -> ${bType} { + ${isChannelsLast ? sampleW : sampleX} + } + + fn mm_write(batch: i32, row : i32, colIn : i32, valueIn : ${resType}) { + let col = colIn * ${innerElementSize}; + if (row < uniforms.dim_a_outer && col < uniforms.dim_b_outer) + { + var value = valueIn; + let outWidth = ${isChannelsLast ? "i32(uniforms.result_shape[2])" : "i32(uniforms.result_shape[3])"}; + ${coordResSnippet} + ${biasSnippet(addBias)} + ${applyActivation} + setOutputAtCoords(coords[0], coords[1], coords[2], coords[3], value); + } + }`; + return userCode; + }; + createConv2DMatMulProgramInfo = (inputs, attributes, outputShape, dimAOuter, dimBOuter, dimInner, hasBias, sequentialAccessByThreads, squeezeOutputShapeFunction) => { + const isChannelsLast = attributes.format === "NHWC"; + const inChannels = isChannelsLast ? inputs[0].dims[3] : inputs[0].dims[1]; + const batchSize = outputShape[0]; + const outWidth = isChannelsLast ? outputShape[2] : outputShape[3]; + const outHeight = isChannelsLast ? outputShape[1] : outputShape[2]; + const outChannels = isChannelsLast ? outputShape[3] : outputShape[1]; + const isVec4 = isChannelsLast && (inChannels % 4 === 0 || inChannels % 3 === 0) && outChannels % 4 === 0; + const dispatchX = isChannelsLast ? outChannels : outWidth * outHeight; + const dispatchY = isChannelsLast ? outWidth * outHeight : outChannels; + const workGroupSize = [8, 8, 1]; + const elementsPerThread = dimAOuter <= 8 ? [4, 1, 1] : [4, 4, 1]; + const dispatch = [ + Math.ceil(dispatchX / workGroupSize[0] / elementsPerThread[0]), + Math.ceil(dispatchY / workGroupSize[1] / elementsPerThread[1]), + Math.ceil(batchSize / workGroupSize[2] / elementsPerThread[2]) + ]; + LOG_DEBUG("verbose", () => `[conv2d_mm_webgpu] dispatch = ${dispatch}`); + const innerElementSize = isVec4 ? isChannelsLast && inChannels % 4 !== 0 ? 3 : 4 : 1; + const tileAOuter = workGroupSize[1] * elementsPerThread[1]; + const tileBOuter = workGroupSize[0] * elementsPerThread[0]; + const tileInner = Math.max(workGroupSize[0] * innerElementSize, workGroupSize[1]); + const fitAOuter = dimAOuter % tileAOuter === 0; + const fitBOuter = dimBOuter % tileBOuter === 0; + const fitInner = dimInner % tileInner === 0; + const elementsSize = isVec4 ? [innerElementSize, 4, 4] : [1, 1, 1]; + const programUniforms = [ + { type: 6 /* int32 */, data: dimAOuter }, + { type: 6 /* int32 */, data: dimBOuter }, + { type: 6 /* int32 */, data: dimInner }, + { type: 6 /* int32 */, data: [attributes.pads[0], attributes.pads[1]] }, + { type: 6 /* int32 */, data: attributes.strides }, + { type: 6 /* int32 */, data: attributes.dilations } + ]; + appendActivationUniformsData(attributes, programUniforms); + programUniforms.push(...createTensorShapeVariables(inputs[0].dims, inputs[1].dims)); + const inputDependencies = ["rank", "rank"]; + if (hasBias) { + programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); + inputDependencies.push("rank"); + } + programUniforms.push(...createTensorShapeVariables(outputShape)); + const getShaderSource = (shaderHelper) => { + const uniforms = [ + { name: "dim_a_outer", type: "i32" }, + { name: "dim_b_outer", type: "i32" }, + { name: "dim_inner", type: "i32" }, + { name: "pad", type: "i32", length: 2 }, + { name: "stride", type: "i32", length: 2 }, + { name: "dilation", type: "i32", length: 2 } + ]; + appendActivationUniforms(attributes, uniforms); + const components = isVec4 ? 4 : 1; + const t = tensorTypeToWsglStorageType(inputs[0].dataType); + let declareFunctions = ` + fn setOutputAtIndex(flatIndex : i32, value : ${isVec4 ? `vec4<${t}>` : t}) { + result[flatIndex] = ${isVec4 ? `vec4<${t}>` : t}(value); + } + fn setOutputAtCoords(d0 : i32, d1 : i32, d2 : i32, d3 : i32, value : ${isVec4 ? `vec4<${t}>` : t}) { + let flatIndex = getOutputIndexFromCoords(vec4(d0, d1, d2, d3)); + setOutputAtIndex(flatIndex ${isVec4 ? "/ 4" : ""}, value); + }`; + const x = inputVariable( + "x", + inputs[0].dataType, + inputs[0].dims.length, + innerElementSize === 3 ? 1 : innerElementSize + ); + const w = inputVariable("w", inputs[1].dataType, inputs[1].dims.length, components); + const inputVariables = [x, w]; + const output = outputVariable("result", inputs[0].dataType, outputShape.length, components); + if (hasBias) { + const bias = inputVariable("bias", inputs[2].dataType, inputs[2].dims.length, components); + inputVariables.push(bias); + declareFunctions += ` + fn getBiasByOutputCoords(coords : vec4) -> ${isVec4 ? `vec4<${t}>` : t} { + return bias[coords.${isChannelsLast ? "w" : "y"}${isVec4 ? "/ 4" : ""}]; + }`; + } + return ` + ${utilFunctions("uniforms.result_strides")} + //struct Uniforms { xShape : vec4, wShape : vec4, outShape : vec4, + // outShapeStrides: vec3, filterDims : vec2, pad : vec2, stride : vec2, + // dilation : vec2, dimAOuter : i32, dimBOuter : i32, dimInner : i32 }; + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} + ${declareFunctions} + ${conv2dCommonSnippet( + isChannelsLast, + fitAOuter, + fitBOuter, + fitInner, + hasBias, + attributes, + elementsSize[0], + elementsSize[1], + elementsSize[2], + t + )} + ${isVec4 ? makeMatMulPackedVec4Source(elementsPerThread, workGroupSize, t, void 0, !isChannelsLast, tileInner) : makeMatMulPackedSource( + elementsPerThread, + workGroupSize, + t, + void 0, + !isChannelsLast, + tileInner, + false, + void 0, + sequentialAccessByThreads + )}`; + }; + return { + name: "Conv2DMatMul", + shaderCache: { + hint: `${attributes.cacheKey};${innerElementSize};${isVec4};${fitAOuter};${fitBOuter};${fitInner};${tileAOuter};${tileBOuter};${tileInner}`, + inputDependencies + }, + getRunData: () => ({ + outputs: [ + { + dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, + dataType: inputs[0].dataType + } + ], + dispatchGroup: { x: dispatch[0], y: dispatch[1], z: dispatch[2] }, + programUniforms + }), + getShaderSource + }; + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/3rd-party/conv3d_naive_webgpu.ts + var arrayProduct, parse3TupleParam, getEffectiveFilterSize, computeDefaultPad, computeOutputShape4D, get3DPadAndOutInfo, computeConv3DInfo, createConv3DNaiveProgramInfo; + var init_conv3d_naive_webgpu = __esm({ + "web/lib/wasm/jsep/webgpu/ops/3rd-party/conv3d_naive_webgpu.ts"() { + "use strict"; + init_wasm_common(); + init_log(); + init_util2(); + init_common(); + init_fuse_utils2(); + init_activation_util(); + arrayProduct = (arr) => { + let product = 1; + for (let i = 0; i < arr.length; i++) { + product *= arr[i]; + } + return product; + }; + parse3TupleParam = (param) => typeof param === "number" ? [param, param, param] : param; + getEffectiveFilterSize = (filterSize, dilation) => { + if (dilation <= 1) { + return filterSize; + } + return filterSize + (filterSize - 1) * (dilation - 1); + }; + computeDefaultPad = (inputShape, fieldSize, stride, dilation = 1) => { + const effectiveFieldSize = getEffectiveFilterSize(fieldSize, dilation); + return Math.floor((inputShape[0] * (stride - 1) - stride + effectiveFieldSize) / 2); + }; + computeOutputShape4D = (inShape, filterShape, outChannels, strides, zeroPad) => { + if (zeroPad == null) { + zeroPad = computeDefaultPad(inShape, filterShape[0], strides[0]); + } + const outShape = [0, 0, 0, outChannels]; + for (let index = 0; index < 3; index++) { + if (inShape[index] + 2 * zeroPad >= filterShape[index]) { + outShape[index] = Math.trunc((inShape[index] - filterShape[index] + 2 * zeroPad) / strides[index] + 1); + } + } + return outShape; + }; + get3DPadAndOutInfo = (pad2, inDepth, inHeight, inWidth, strideDepth, strideHeight, strideWidth, filterDepth, filterHeight, filterWidth) => { + let padInfo; + let outDepth; + let outHeight; + let outWidth; + if (pad2 === "VALID") { + pad2 = 0; + } + if (typeof pad2 === "number") { + padInfo = { top: pad2, bottom: pad2, left: pad2, right: pad2, front: pad2, back: pad2 }; + const outShape = computeOutputShape4D( + [inDepth, inHeight, inWidth, 1], + [filterDepth, filterHeight, filterWidth], + 1, + [strideDepth, strideHeight, strideWidth], + pad2 + ); + outDepth = outShape[0]; + outHeight = outShape[1]; + outWidth = outShape[2]; + } else if (Array.isArray(pad2)) { + if (!pad2.every((val, _, arr) => val === arr[0])) { + throw Error(`Unsupported padding parameter: ${pad2}`); + } + padInfo = { top: pad2[0], bottom: pad2[1], left: pad2[2], right: pad2[3], front: pad2[4], back: pad2[5] }; + const outShape = computeOutputShape4D( + [inDepth, inHeight, inWidth, 1], + [filterDepth, filterHeight, filterWidth], + 1, + [strideDepth, strideHeight, strideWidth], + pad2[0] + ); + outDepth = outShape[0]; + outHeight = outShape[1]; + outWidth = outShape[2]; + } else if (pad2 === "SAME_UPPER") { + outDepth = Math.ceil(inDepth / strideDepth); + outHeight = Math.ceil(inHeight / strideHeight); + outWidth = Math.ceil(inWidth / strideWidth); + const padAlongDepth = (outDepth - 1) * strideDepth + filterDepth - inDepth; + const padAlongHeight = (outHeight - 1) * strideHeight + filterHeight - inHeight; + const padAlongWidth = (outWidth - 1) * strideWidth + filterWidth - inWidth; + const front = Math.floor(padAlongDepth / 2); + const back = padAlongDepth - front; + const top = Math.floor(padAlongHeight / 2); + const bottom = padAlongHeight - top; + const left = Math.floor(padAlongWidth / 2); + const right = padAlongWidth - left; + padInfo = { top, bottom, left, right, front, back }; + } else { + throw Error(`Unknown padding parameter: ${pad2}`); + } + return { padInfo, outDepth, outHeight, outWidth }; + }; + computeConv3DInfo = (inShape, filterShape, strides, dilations, pad2, depthwise = false, dataFormat = "channelsLast") => { + let batchSize, inDepth, inHeight, inWidth, inChannels; + if (dataFormat === "channelsLast") { + [batchSize, inDepth, inHeight, inWidth, inChannels] = inShape; + } else if (dataFormat === "channelsFirst") { + [batchSize, inChannels, inDepth, inHeight, inWidth] = inShape; + } else { + throw new Error(`Unknown dataFormat ${dataFormat}`); + } + const [filterChannels, , filterDepth, filterHeight, filterWidth] = filterShape; + const [strideDepth, strideHeight, strideWidth] = parse3TupleParam(strides); + const [dilationDepth, dilationHeight, dilationWidth] = parse3TupleParam(dilations); + const effectiveFilterDepth = getEffectiveFilterSize(filterDepth, dilationDepth); + const effectiveFilterHeight = getEffectiveFilterSize(filterHeight, dilationHeight); + const effectiveFilterWidth = getEffectiveFilterSize(filterWidth, dilationWidth); + const { padInfo, outDepth, outHeight, outWidth } = get3DPadAndOutInfo( + pad2, + inDepth, + inHeight, + inWidth, + strideDepth, + strideHeight, + strideWidth, + effectiveFilterDepth, + effectiveFilterHeight, + effectiveFilterWidth + ); + const outChannels = depthwise ? filterChannels * inChannels : filterChannels; + let outShape = [0, 0, 0, 0, 0]; + if (dataFormat === "channelsFirst") { + outShape = [batchSize, outChannels, outDepth, outHeight, outWidth]; + } else if (dataFormat === "channelsLast") { + outShape = [batchSize, outDepth, outHeight, outWidth, outChannels]; + } + return { + batchSize, + dataFormat, + inDepth, + inHeight, + inWidth, + inChannels, + outDepth, + outHeight, + outWidth, + outChannels, + padInfo, + strideDepth, + strideHeight, + strideWidth, + filterDepth, + filterHeight, + filterWidth, + effectiveFilterDepth, + effectiveFilterHeight, + effectiveFilterWidth, + dilationDepth, + dilationHeight, + dilationWidth, + inShape, + outShape, + filterShape + }; + }; + createConv3DNaiveProgramInfo = (inputs, attributes, outputShape, filterDims, pads, dataFormat) => { + const isChannelLast = dataFormat === "channelsLast"; + const inChannels = isChannelLast ? inputs[0].dims[3] : inputs[0].dims[1]; + const isVec4 = false; + const workGroupSize = [64, 1, 1]; + const dispatchLayout = { x: outputShape.map((_, i) => i) }; + const dispatch = [Math.ceil(arrayProduct(dispatchLayout.x.map((d) => outputShape[d])) / workGroupSize[0]), 1, 1]; + LOG_DEBUG("verbose", () => `[conv3d_naive_webgpu] dispatch = ${dispatch}`); + const innerElementSize = isVec4 ? isChannelLast && inChannels % 4 !== 0 ? 3 : 4 : 1; + const outputSize = ShapeUtil2.size(outputShape); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: filterDims }, + { type: 12 /* uint32 */, data: pads }, + { type: 12 /* uint32 */, data: attributes.strides }, + { type: 12 /* uint32 */, data: attributes.dilations } + ]; + appendActivationUniformsData(attributes, programUniforms); + programUniforms.push(...createTensorShapeVariables(inputs[0].dims, inputs[1].dims)); + const inputDependencies = ["rank", "rank"]; + const hasBias = inputs.length === 3; + if (hasBias) { + programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); + inputDependencies.push("rank"); + } + programUniforms.push(...createTensorShapeVariables(outputShape)); + const getShaderSource = (shaderHelper) => { + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "filter_dims", type: "u32", length: filterDims.length }, + { name: "pads", type: "u32", length: pads.length }, + { name: "strides", type: "u32", length: attributes.strides.length }, + { name: "dilations", type: "u32", length: attributes.dilations.length } + ]; + appendActivationUniforms(attributes, uniforms); + const components = isVec4 ? 4 : 1; + const t = tensorTypeToWsglStorageType(inputs[0].dataType); + const x = inputVariable( + "x", + inputs[0].dataType, + inputs[0].dims.length, + innerElementSize === 3 ? 1 : innerElementSize + ); + const w = inputVariable("W", inputs[1].dataType, inputs[1].dims.length, components); + const inputVariables = [x, w]; + const output = outputVariable("result", inputs[0].dataType, outputShape.length, components); + let declareFunctions = ""; + if (hasBias) { + const bias = inputVariable("bias", inputs[2].dataType, inputs[2].dims.length, components); + inputVariables.push(bias); + declareFunctions += ` + fn getBiasByOutputCoords(coords : array) -> ${isVec4 ? `vec4<${t}>` : t} { + return bias[${isChannelLast ? getElementAt("coords", 4, 5) : getElementAt("coords", 1, 5)}${isVec4 ? "/ 4" : ""}]; + }`; + } + const resType = typeSnippet(innerElementSize, t); + const applyActivation = getActivationSnippet2(attributes, resType, t); + return ` + ${declareFunctions} + fn getX(d0 : u32, d1 : u32, d2 : u32, d3 : u32, d4 : u32) -> f32 { + let aIndices = array(d0, d1, d2, d3, d4); + return ${x.getByIndices("aIndices")}; + } + fn getW(d0 : u32, d1 : u32, d2 : u32, d3 : u32, d4 : u32) -> f32 { + let aIndices = array(d0, d1, d2, d3, d4); + return ${w.getByIndices("aIndices")}; + } + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let coords = ${output.offsetToIndices("global_idx")}; + let batch = ${getElementAt("coords", 0, x.rank)}; + let d2 = ${isChannelLast ? getElementAt("coords", x.rank - 1, x.rank) : getElementAt("coords", 1, x.rank)}; + let xFRCCorner = vec3(${isChannelLast ? getElementAt("coords", 1, x.rank) : getElementAt("coords", 2, x.rank)}, + ${isChannelLast ? getElementAt("coords", 2, x.rank) : getElementAt("coords", 3, x.rank)}, + ${isChannelLast ? getElementAt("coords", 3, x.rank) : getElementAt("coords", 4, x.rank)}) * uniforms.strides - uniforms.pads; + let xFCorner = xFRCCorner.x; + let xRCorner = xFRCCorner.y; + let xCCorner = xFRCCorner.z; + let xShapeY = ${isChannelLast ? getElementAt("uniforms.x_shape", 1, x.rank) : getElementAt("uniforms.x_shape", 2, x.rank)}; + let xShapeZ = ${isChannelLast ? getElementAt("uniforms.x_shape", 2, x.rank) : getElementAt("uniforms.x_shape", 3, x.rank)}; + let xShapeW = ${isChannelLast ? getElementAt("uniforms.x_shape", 3, x.rank) : getElementAt("uniforms.x_shape", 4, x.rank)}; + let xShapeU = ${isChannelLast ? getElementAt("uniforms.x_shape", 4, x.rank) : getElementAt("uniforms.x_shape", 1, x.rank)}; + let inputDepthNearestVec4 = (xShapeU / 4) * 4; + let inputDepthVec4Remainder = xShapeU % 4; + + var value = 0.0; + for (var wF = 0u; wF < uniforms.filter_dims[0]; wF++) { + let xF = xFCorner + wF * uniforms.dilations[0]; + if (xF < 0 || xF >= xShapeY) { + continue; + } + + for (var wR = 0u; wR < uniforms.filter_dims[1]; wR++) { + let xR = xRCorner + wR * uniforms.dilations[1]; + if (xR < 0 || xR >= xShapeZ) { + continue; + } + + for (var wC = 0u; wC < uniforms.filter_dims[2]; wC++) { + let xC = xCCorner + wC * uniforms.dilations[2]; + if (xC < 0 || xC >= xShapeW) { + continue; + } + + for (var d1 = 0u; d1 < inputDepthNearestVec4; d1 += 4) { + ${isChannelLast ? `let xValues = vec4( + getX(batch, xF, xR, xC, d1), + getX(batch, xF, xR, xC, d1 + 1), + getX(batch, xF, xR, xC, d1 + 2), + getX(batch, xF, xR, xC, d1 + 3)); + ` : `let xValues = vec4( + getX(batch, d1, xF, xR, xC), + getX(batch, d1 + 1, xF, xR, xC), + getX(batch, d1 + 2, xF, xR, xC), + getX(batch, d1 + 3, xF, xR, xC)); + `} + let wValues = vec4( + getW(d2, d1, wF, wR, wC), + getW(d2, d1 + 1, wF, wR, wC), + getW(d2, d1 + 2, wF, wR, wC), + getW(d2, d1 + 3, wF, wR, wC)); + value += dot(xValues, wValues); + } + if (inputDepthVec4Remainder == 1) { + ${isChannelLast ? `value += getX(batch, xF, xR, xC, inputDepthNearestVec4) + * getW(d2, inputDepthNearestVec4, wF, wR, wC);` : `value += getX(batch, inputDepthNearestVec4, xF, xR, xC) + * getW(d2, inputDepthNearestVec4, wF, wR, wC);`} + } else if (inputDepthVec4Remainder == 2) { + ${isChannelLast ? `let xValues = vec2( + getX(batch, xF, xR, xC, inputDepthNearestVec4), + getX(batch, xF, xR, xC, inputDepthNearestVec4 + 1)); + ` : `let xValues = vec2( + getX(batch, inputDepthNearestVec4, xF, xR, xC), + getX(batch, inputDepthNearestVec4 + 1, xF, xR, xC)); + `} + let wValues = vec2( + getW(d2, inputDepthNearestVec4, wF, wR, wC), + getW(d2, inputDepthNearestVec4 + 1, wF, wR, wC)); + value += dot(xValues, wValues); + } else if (inputDepthVec4Remainder == 3) { + ${isChannelLast ? `let xValues = vec3( + getX(batch, xF, xR, xC, inputDepthNearestVec4), + getX(batch, xF, xR, xC, inputDepthNearestVec4 + 1), + getX(batch, xF, xR, xC, inputDepthNearestVec4 + 2)); + ` : `let xValues = vec3( + getX(batch, inputDepthNearestVec4, xF, xR, xC), + getX(batch, inputDepthNearestVec4 + 1, xF, xR, xC), + getX(batch, inputDepthNearestVec4 + 2, xF, xR, xC)); + `} + let wValues = vec3( + getW(d2, inputDepthNearestVec4, wF, wR, wC), + getW(d2, inputDepthNearestVec4 + 1, wF, wR, wC), + getW(d2, inputDepthNearestVec4 + 2, wF, wR, wC)); + value += dot(xValues, wValues); + } + } + } + } + ${hasBias ? "value = value + getBiasByOutputCoords(coords)" : ""}; + ${applyActivation} + result[global_idx] = f32(value); + }`; + }; + return { + name: "Conv3DNaive", + shaderCache: { hint: `${attributes.cacheKey};${isChannelLast};${innerElementSize};${hasBias}`, inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: dispatch[0], y: dispatch[1], z: dispatch[2] }, + programUniforms + }), + getShaderSource + }; + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/conv-grouped.ts + var createGroupedConvProgramInfo, createGroupedConvVectorizeProgramInfo; + var init_conv_grouped2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/conv-grouped.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + init_fuse_utils2(); + createGroupedConvProgramInfo = (inputs, attributes, outputShape, squeezeOutputShapeFunction) => { + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += b[output_channel];" : ""; + const xShape = inputs[0].dims; + const wShape = inputs[1].dims; + const isChannelLast = attributes.format === "NHWC"; + const outputChannels = isChannelLast ? outputShape[3] : outputShape[1]; + const outputChannelsPerGroup = outputChannels / attributes.group; + const components = isChannelLast && outputChannelsPerGroup >= 4 ? getMaxComponents(outputChannels) : 1; + const outputSize = ShapeUtil2.size(outputShape) / components; + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: attributes.dilations }, + { type: 12 /* uint32 */, data: [attributes.strides[0], attributes.strides[1]] }, + { type: 12 /* uint32 */, data: [attributes.pads[0], attributes.pads[1]] }, + { type: 12 /* uint32 */, data: outputChannelsPerGroup } + ]; + appendActivationUniformsData(attributes, programUniforms); + programUniforms.push( + ...createTensorShapeVariables(xShape, [wShape[0], wShape[1], wShape[2], wShape[3] / components]) + ); + const inputDependencies = hasBias ? ["rank", "rank", "rank"] : ["rank", "rank"]; + programUniforms.push( + ...createTensorShapeVariables([outputShape[0], outputShape[1], outputShape[2], outputShape[3] / components]) + ); + const getShaderSource = (shaderHelper) => { + const output = outputVariable("output", inputs[0].dataType, outputShape.length, components); + const baseType = tensorTypeToWsglStorageType(output.type.tensor); + const applyActivation = getActivationSnippet2(attributes, output.type.value, baseType); + const x = inputVariable("x", inputs[0].dataType, xShape.length); + const w = inputVariable("w", inputs[1].dataType, wShape.length, components); + const inputVars = [x, w]; + if (hasBias) { + inputVars.push(inputVariable("b", inputs[2].dataType, inputs[2].dims, components)); + } + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "dilations", type: "u32", length: attributes.dilations.length }, + { name: "strides", type: "u32", length: 2 }, + { name: "pads", type: "u32", length: 2 }, + { name: "output_channels_per_group", type: "u32" } + ]; + appendActivationUniforms(attributes, uniforms); + const calculateResult = isChannelLast ? ` + for (var wHeight: u32 = 0u; wHeight < uniforms.w_shape[0]; wHeight++) { + let xHeight = xRCCorner.x + wHeight * uniforms.dilations[0]; + + if (xHeight < 0u || xHeight >= uniforms.x_shape[1]) { + continue; + } + + for (var wWidth: u32 = 0u; wWidth < uniforms.w_shape[1]; wWidth++) { + let xWidth = xRCCorner.y + wWidth * uniforms.dilations[1]; + if (xWidth < 0u || xWidth >= uniforms.x_shape[2]) { + continue; + } + + for (var wInChannel: u32 = 0u; wInChannel < uniforms.w_shape[2]; wInChannel++) { + let input_channel = in_channel_offset + wInChannel; + let xVal = ${x.get("batch", "xHeight", "xWidth", "input_channel")}; + let wVal = ${w.get("wHeight", "wWidth", "wInChannel", "output_channel")}; + value += xVal * wVal; + } + } + } + ` : ` + for (var wInChannel: u32 = 0u; wInChannel < uniforms.w_shape[1]; wInChannel++) { + let input_channel = in_channel_offset + wInChannel; + for (var wHeight: u32 = 0u; wHeight < uniforms.w_shape[2]; wHeight++) { + let xHeight = xRCCorner.x + wHeight * uniforms.dilations[0]; + + if (xHeight < 0u || xHeight >= uniforms.x_shape[2]) { + continue; + } + + for (var wWidth: u32 = 0u; wWidth < uniforms.w_shape[3]; wWidth++) { + let xWidth = xRCCorner.y + wWidth * uniforms.dilations[1]; + if (xWidth < 0u || xWidth >= uniforms.x_shape[3]) { + continue; + } + + let xVal = ${x.get("batch", "input_channel", "xHeight", "xWidth")}; + let wVal = ${w.get("output_channel", "wInChannel", "wHeight", "wWidth")}; + value += xVal * wVal; + } + } + } + `; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVars, output)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + + let outputIndices = ${output.offsetToIndices("global_idx")}; + let batch: u32 = outputIndices[0]; + let output_channel: u32 = outputIndices[${isChannelLast ? 3 : 1}]; + let xRCCorner: vec2 = vec2(outputIndices[${isChannelLast ? 1 : 2}], outputIndices[${isChannelLast ? 2 : 3}]) * uniforms.strides - uniforms.pads; + let group_id: u32 = output_channel * ${components} / uniforms.output_channels_per_group; + var in_channel_offset = group_id * uniforms.w_shape[${isChannelLast ? 2 : 1}]; + + var value: ${output.type.value} = ${output.type.value}(0); + ${calculateResult} + ${processBias} + ${applyActivation} + ${output.setByOffset("global_idx", "value")} + }`; + }; + return { + name: "GroupedConv", + shaderCache: { hint: `${attributes.cacheKey}_${components}`, inputDependencies }, + getRunData: () => ({ + outputs: [ + { + dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, + dataType: inputs[0].dataType + } + ], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + createGroupedConvVectorizeProgramInfo = (inputs, attributes, outputShape, squeezeOutputShapeFunction) => { + const hasBias = inputs.length > 2; + const components = getMaxComponents(outputShape[3]); + const outputNumber = getMaxComponents(outputShape[2]); + const outputSize = ShapeUtil2.size(outputShape) / components / outputNumber; + const xShape = [inputs[0].dims[0], inputs[0].dims[1], inputs[0].dims[2], inputs[0].dims[3] / components]; + const wShape = [inputs[1].dims[0], inputs[1].dims[1], inputs[1].dims[2], inputs[1].dims[3] / components]; + const outputShapeInShader = [outputShape[0], outputShape[1], outputShape[2], outputShape[3] / components]; + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 6 /* int32 */, data: [attributes.strides[0], attributes.strides[1]] }, + { type: 6 /* int32 */, data: [attributes.pads[0], attributes.pads[1]] } + ]; + appendActivationUniformsData(attributes, programUniforms); + programUniforms.push(...createTensorShapeVariables(xShape, wShape, outputShapeInShader)); + const xNumber = (outputNumber - 1) * attributes.strides[1] + wShape[1]; + const getShaderSource = (shaderHelper) => { + const output = outputVariable("output", inputs[0].dataType, outputShapeInShader.length, components); + const baseType = tensorTypeToWsglStorageType(output.type.tensor); + const applyActivation = getActivationSnippet2(attributes, output.type.value, baseType); + const x = inputVariable("x", inputs[0].dataType, xShape.length, components); + const w = inputVariable("w", inputs[1].dataType, wShape.length, components); + const inputVars = [x, w]; + if (hasBias) { + inputVars.push(inputVariable("b", inputs[2].dataType, inputs[2].dims, components)); + } + const processBias = hasBias ? "value += b[output_channel];" : ""; + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "strides", type: "i32", length: 2 }, + { name: "pads", type: "i32", length: 2 } + ]; + appendActivationUniforms(attributes, uniforms); + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVars, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let width0 = uniforms.output_shape[3]; + let output_channel = global_idx % width0; + var index1 = global_idx / width0; + let width1 = uniforms.output_shape[2] / ${outputNumber}u; + let col = (index1 % width1) * ${outputNumber}u; + index1 = index1 / width1; + let row = index1 % uniforms.output_shape[1]; + let batch = index1 / uniforms.output_shape[1]; + + let x_corner = vec2(i32(row), i32(col)) * uniforms.strides - uniforms.pads; + + var x_vals: array<${x.type.value}, ${xNumber}>; + var values: array<${output.type.value}, ${outputNumber}>; + let input_channel = output_channel; + // Use constant instead of uniform can give better performance for w's height/width. + for (var w_height: u32 = 0u; w_height < ${wShape[0]}; w_height++) { + let x_height = x_corner.x + i32(w_height); + if (x_height >= 0 && u32(x_height) < uniforms.x_shape[1]) { + for (var i = 0; i < ${xNumber}; i++) { + let x_width = x_corner.y + i; + if (x_width >= 0 && u32(x_width) < uniforms.x_shape[2]) { + x_vals[i] = ${x.get("batch", "u32(x_height)", "u32(x_width)", "input_channel")}; + } else { + x_vals[i] = ${x.type.value}(0); + } + } + for (var w_width: u32 = 0u; w_width < ${wShape[1]}; w_width++) { + let w_val = ${w.get("w_height", "w_width", "0", "output_channel")}; + for (var i = 0u; i < ${outputNumber}u; i++) { + values[i] = fma(x_vals[i * u32(uniforms.strides[1]) + w_width], w_val, values[i]); + } + } + } + } + + for (var i = 0u; i < ${outputNumber}u; i++) { + var value = values[i]; + ${processBias} + ${applyActivation} + ${output.set("batch", "row", "col + i", "output_channel", "value")}; + } + }`; + }; + return { + name: "GroupedConv-Vectorize", + shaderCache: { + hint: `${attributes.cacheKey};${components};${outputNumber};${xNumber};${wShape[0]};${wShape[1]}`, + inputDependencies: hasBias ? ["rank", "rank", "type"] : ["rank", "rank"] + }, + getRunData: () => ({ + outputs: [ + { + dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, + dataType: inputs[0].dataType + } + ], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/conv.ts + var calculateOutputShape2, weightTransposeAttribute, validateInputs33, getAdjustedConvAttributes2, parseConvAttributes2, conv2d2, conv1d, conv3d, conv2; + var init_conv2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/conv.ts"() { + "use strict"; + init_util2(); + init_conv2d_mm_webgpu(); + init_conv3d_naive_webgpu(); + init_matmul_packed_webgpu(); + init_conv_grouped2(); + init_fuse_utils2(); + init_matmul_shaders(); + init_transpose2(); + calculateOutputShape2 = (inputShape, kernelShape, dilations, adjustPads, strides, isChannelLast) => { + const batchSize = inputShape[0]; + const inputSpatialShape = inputShape.slice(isChannelLast ? 1 : 2, isChannelLast ? 3 : 4); + 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 outputShape = inputSpatialShapeWithPad.map( + (v, i) => Math.floor((v - dilatedKernelShape[i] + strides[i]) / strides[i]) + ); + outputShape.splice(0, 0, batchSize); + outputShape.splice(isChannelLast ? 3 : 1, 0, outChannels); + return outputShape; + }; + weightTransposeAttribute = [2, 3, 1, 0]; + validateInputs33 = (inputs, attributes) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Conv requires 2 or 3 inputs"); + } + if (inputs[0].dims.length > 5) { + throw new Error("greater than 5D is not supported"); + } + if (inputs[0].dims.length !== inputs[1].dims.length) { + throw new Error("filter does not have same dimension as input"); + } + const dataChannel = inputs[0].dims[attributes.format === "NHWC" ? inputs[0].dims.length - 1 : 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"); + } + }; + getAdjustedConvAttributes2 = (attributes, inputs) => { + const kernelShape = attributes.kernelShape.slice(); + if (kernelShape.length < inputs[1].dims.length - 2) { + kernelShape.push(...Array(inputs[1].dims.length - 2 - kernelShape.length).fill(0)); + } + for (let i = 2; i < inputs[1].dims.length; ++i) { + if (kernelShape[i - 2] === 0) { + kernelShape[i - 2] = inputs[1].dims[i]; + } + } + const pads = attributes.pads.slice(); + PoolConvUtil2.adjustPadsBasedOnAutoPad( + inputs[0].dims, + attributes.strides, + attributes.dilations, + kernelShape, + pads, + attributes.format === "NHWC", + attributes.autoPad + ); + const newAttributes = Object.assign({}, attributes); + Object.assign(newAttributes, { kernelShape, pads }); + return newAttributes; + }; + parseConvAttributes2 = (attributes) => { + const activationAttributes = parseInternalActivationAttributes2(attributes); + const format = attributes.format; + const autoPad = ["NOTSET", "VALID", "SAME_UPPER", "SAME_LOWER"][attributes.auto_pad]; + const dilations = attributes.dilations; + const group = attributes.group; + const kernelShape = attributes.kernel_shape; + const pads = attributes.pads; + const strides = attributes.strides; + const wIsConst = attributes.w_is_const(); + return { + autoPad, + format, + dilations, + group, + kernelShape, + pads, + strides, + wIsConst, + ...activationAttributes, + cacheKey: `${attributes.format};${activationAttributes.activation};` + }; + }; + conv2d2 = (context, inputs, attributes, squeezeOutputShapeFunction) => { + const isChannelsLast = attributes.format === "NHWC"; + const outputShape = calculateOutputShape2( + inputs[0].dims, + inputs[1].dims, + attributes.dilations, + attributes.pads, + attributes.strides, + isChannelsLast + ); + if (attributes.group !== 1) { + const convInputs2 = [inputs[0]]; + if (isChannelsLast) { + const transposedWeight2 = context.kernelCustomData.wT ?? context.compute(createTransposeProgramInfo2(inputs[1], weightTransposeAttribute), { + inputs: [1], + outputs: [attributes.wIsConst ? -2 : -1] + })[0]; + if (attributes.wIsConst && !context.kernelCustomData.wT) { + context.kernelCustomData.wT = transposedWeight2; + } + convInputs2.push(transposedWeight2); + } else { + convInputs2.push(inputs[1]); + } + if (inputs.length === 3) { + convInputs2.push(inputs[2]); + } + const enableGroupedConvVectorize = !context.adapterInfo.isArchitecture("ampere"); + if (enableGroupedConvVectorize && isChannelsLast && inputs[1].dims[0] === attributes.group && inputs[1].dims[1] === 1 && attributes.dilations[0] === 1 && attributes.dilations[1] === 1) { + context.compute( + createGroupedConvVectorizeProgramInfo(convInputs2, attributes, outputShape, squeezeOutputShapeFunction), + { inputs: convInputs2 } + ); + } else { + context.compute(createGroupedConvProgramInfo(convInputs2, attributes, outputShape, squeezeOutputShapeFunction), { + inputs: convInputs2 + }); + } + return; + } + const hasBias = inputs.length === 3; + const inputHeight = inputs[0].dims[isChannelsLast ? 1 : 2]; + const inputWidth = inputs[0].dims[isChannelsLast ? 2 : 3]; + const inputChannels = inputs[0].dims[isChannelsLast ? 3 : 1]; + const weightHeight = inputs[1].dims[2]; + const weightWidth = inputs[1].dims[3]; + const outHeight = outputShape[isChannelsLast ? 1 : 2]; + const outWidth = outputShape[isChannelsLast ? 2 : 3]; + const outChannels = outputShape[isChannelsLast ? 3 : 1]; + const sameSize = isChannelsLast && weightHeight === inputHeight && weightWidth === inputWidth && attributes.pads[0] === 0 && attributes.pads[1] === 0; + if (sameSize || weightHeight === 1 && weightWidth === 1 && attributes.dilations[0] === 1 && attributes.dilations[1] === 1 && attributes.strides[0] === 1 && attributes.strides[1] === 1 && attributes.pads[0] === 0 && attributes.pads[1] === 0) { + const batch = outputShape[0]; + let xReshaped, wReshaped, matmulOutputShape; + const matmulInputs = []; + if (isChannelsLast) { + const transposedWeight2 = context.kernelCustomData.wT ?? context.compute(createTransposeProgramInfo2(inputs[1], weightTransposeAttribute), { + inputs: [1], + outputs: [attributes.wIsConst ? -2 : -1] + })[0]; + if (attributes.wIsConst && !context.kernelCustomData.wT) { + context.kernelCustomData.wT = transposedWeight2; + } + if (sameSize) { + const sharedDim = inputHeight * inputWidth * inputChannels; + xReshaped = inputs[0].reshape([1, batch, sharedDim]); + wReshaped = transposedWeight2.reshape([1, sharedDim, outChannels]); + matmulOutputShape = [1, batch, outChannels]; + } else { + xReshaped = inputs[0].reshape([batch, inputHeight * inputWidth, inputChannels]); + wReshaped = transposedWeight2.reshape([1, inputChannels, outChannels]); + matmulOutputShape = [batch, outHeight * outWidth, outChannels]; + } + matmulInputs.push(xReshaped); + matmulInputs.push(wReshaped); + } else { + xReshaped = inputs[0].reshape([batch, inputChannels, inputHeight * inputWidth]); + wReshaped = inputs[1].reshape([1, outChannels, inputChannels]); + matmulOutputShape = [batch, outChannels, outHeight * outWidth]; + matmulInputs.push(wReshaped); + matmulInputs.push(xReshaped); + } + if (hasBias) { + matmulInputs.push(inputs[2]); + } + const N = matmulOutputShape[2]; + const K = matmulInputs[0].dims[matmulInputs[0].dims.length - 1]; + if (N < 8 && K < 8) { + context.compute( + createNaiveMatmulProgramInfo( + matmulInputs, + attributes, + outputShape, + matmulOutputShape, + isChannelsLast, + squeezeOutputShapeFunction + ), + { inputs: matmulInputs } + ); + } else { + context.compute( + createMatmulProgramInfo2( + matmulInputs, + attributes, + outputShape, + matmulOutputShape, + isChannelsLast, + squeezeOutputShapeFunction + ), + { inputs: matmulInputs } + ); + } + return; + } + const sequentialAccessByThreads = ( + /* backend.adapterInfo.isIntel() */ + true + ); + const transposedWeight = context.kernelCustomData.wT ?? context.compute(createTransposeProgramInfo2(inputs[1], weightTransposeAttribute), { + inputs: [1], + outputs: [attributes.wIsConst ? -2 : -1] + })[0]; + if (attributes.wIsConst && !context.kernelCustomData.wT) { + context.kernelCustomData.wT = transposedWeight; + } + const convInputs = [inputs[0], transposedWeight]; + if (hasBias) { + convInputs.push(inputs[2]); + } + const dimAOuter = isChannelsLast ? outHeight * outWidth : outChannels; + const dimBOuter = isChannelsLast ? outChannels : outHeight * outWidth; + const dimInner = weightHeight * weightWidth * inputChannels; + context.compute( + createConv2DMatMulProgramInfo( + convInputs, + attributes, + outputShape, + dimAOuter, + dimBOuter, + dimInner, + hasBias, + sequentialAccessByThreads, + squeezeOutputShapeFunction + ), + { inputs: convInputs } + ); + }; + conv1d = (context, attributes) => { + const isChannelLast = attributes.format === "NHWC"; + const inputs = [ + context.inputs[0].reshape( + isChannelLast ? ( + // [N, W, C] -> [N, H=1, W, C] + [context.inputs[0].dims[0], 1, context.inputs[0].dims[1], context.inputs[0].dims[2]] + ) : ( + // [N, C, W] -> [N, C, H=1, W] + [context.inputs[0].dims[0], context.inputs[0].dims[1], 1, context.inputs[0].dims[2]] + ) + ), + //[FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, kW] -> [FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, kH=1, kW] + context.inputs[1].reshape([context.inputs[1].dims[0], context.inputs[1].dims[1], 1, context.inputs[1].dims[2]]) + ]; + if (context.inputs.length === 3) { + inputs.push(context.inputs[2]); + } + const pads = [0, attributes.pads[0], 0, attributes.pads[1]]; + const strides = [1].concat(attributes.strides); + const dilations = [1].concat(attributes.dilations); + const kernelShape = [1].concat(attributes.kernelShape); + const adjustedAttributes = getAdjustedConvAttributes2( + { ...attributes, pads, strides, dilations, kernelShape }, + inputs + ); + conv2d2( + context, + inputs, + adjustedAttributes, + (outputShape) => isChannelLast ? [outputShape[0], outputShape[2], outputShape[3]] : [outputShape[0], outputShape[1], outputShape[3]] + ); + }; + conv3d = (context, inputs, attributes) => { + const format = attributes.format === "NHWC" ? "channelsLast" : "channelsFirst"; + const adjustedAttributes = getAdjustedConvAttributes2(attributes, inputs); + const pads = attributes.autoPad === "NOTSET" ? attributes.pads : attributes.autoPad; + const convInfo = computeConv3DInfo( + inputs[0].dims, + inputs[1].dims, + attributes.strides, + attributes.dilations, + pads, + false, + format + ); + context.compute( + createConv3DNaiveProgramInfo( + inputs, + adjustedAttributes, + convInfo.outShape, + [convInfo.filterDepth, convInfo.filterHeight, convInfo.filterWidth], + [convInfo.padInfo.front, convInfo.padInfo.top, convInfo.padInfo.left], + format + ) + ); + }; + conv2 = (context, attributes) => { + validateInputs33(context.inputs, attributes); + if (context.inputs[0].dims.length === 3) { + conv1d(context, attributes); + } else if (context.inputs[0].dims.length === 5) { + conv3d(context, context.inputs, attributes); + } else { + const adjustedAttributes = getAdjustedConvAttributes2(attributes, context.inputs); + conv2d2(context, context.inputs, adjustedAttributes); + } + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/3rd-party/conv_backprop_webgpu.ts + var createConvTranspose2DProgramInfo; + var init_conv_backprop_webgpu = __esm({ + "web/lib/wasm/jsep/webgpu/ops/3rd-party/conv_backprop_webgpu.ts"() { + "use strict"; + init_wasm_common(); + init_log(); + init_util2(); + init_common(); + createConvTranspose2DProgramInfo = (inputs, attributes, squeezeOutputShapeFunction) => { + const hasBias = inputs.length > 2; + const outputShape = attributes.outputShape; + const isChannelsLast = attributes.format === "NHWC"; + const group = attributes.group; + const wShape = inputs[1].dims; + const inputChannelsPerGroup = wShape[2] / group; + const outputChannelsPerGroup = wShape[3]; + const aComponents = isChannelsLast ? getMaxComponents(inputChannelsPerGroup) : 1; + const packInputAs4 = isChannelsLast && outputChannelsPerGroup === 1 && inputChannelsPerGroup >= 4; + const inputChannelsPerGroupInt = packInputAs4 ? Math.floor(inputChannelsPerGroup / 4) * 4 : Math.floor(inputChannelsPerGroup / aComponents) * aComponents; + const inputChannelsRemainder = inputChannelsPerGroup - inputChannelsPerGroupInt; + const components = isChannelsLast ? getMaxComponents(outputChannelsPerGroup) : 1; + const bComponents = isChannelsLast ? outputChannelsPerGroup === 1 ? aComponents : components : 1; + const outputSize = ShapeUtil2.size(outputShape) / components; + const dispatch = [Math.ceil(outputSize / 64), 1, 1]; + LOG_DEBUG("verbose", () => `[conv2d_backprop_webgpu] dispatch = ${dispatch}`); + const inputDependencies = ["rank", "rank"]; + const strides = [attributes.strides[0], attributes.strides[1]]; + const filterDims = [attributes.kernelShape[isChannelsLast ? 1 : 2], attributes.kernelShape[isChannelsLast ? 2 : 3]]; + const dilations = [attributes.dilations[0], attributes.dilations[1]]; + const effectiveFilterDims = [ + filterDims[0] + (attributes.dilations[0] <= 1 ? 0 : (attributes.kernelShape[isChannelsLast ? 1 : 2] - 1) * (attributes.dilations[0] - 1)), + filterDims[1] + (attributes.dilations[1] <= 1 ? 0 : (attributes.kernelShape[isChannelsLast ? 2 : 3] - 1) * (attributes.dilations[1] - 1)) + ]; + const pads = [ + effectiveFilterDims[0] - 1 - Math.floor((attributes.pads[0] + attributes.pads[2]) / 2), + effectiveFilterDims[1] - 1 - Math.floor((attributes.pads[1] + attributes.pads[3]) / 2) + ]; + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: strides }, + { type: 12 /* uint32 */, data: filterDims }, + { type: 12 /* uint32 */, data: dilations }, + { type: 12 /* uint32 */, data: effectiveFilterDims }, + { type: 6 /* int32 */, data: pads }, + { type: 12 /* uint32 */, data: inputChannelsPerGroupInt }, + { type: 12 /* uint32 */, data: inputChannelsPerGroup }, + { type: 12 /* uint32 */, data: outputChannelsPerGroup }, + ...createTensorShapeVariables(inputs[0].dims, inputs[1].dims) + ]; + if (hasBias) { + programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); + inputDependencies.push("rank"); + } + programUniforms.push(...createTensorShapeVariables(outputShape)); + const getShaderSource = (shaderHelper) => { + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "strides", type: "u32", length: strides.length }, + { name: "filter_dims", type: "u32", length: filterDims.length }, + { name: "dilations", type: "u32", length: filterDims.length }, + { name: "effective_filter_dims", type: "u32", length: effectiveFilterDims.length }, + { name: "pads", type: "i32", length: pads.length }, + { name: "input_channels_per_group_int", type: "u32" }, + { name: "input_channels_per_group", type: "u32" }, + { name: "output_channels_per_group", type: "u32" } + ]; + const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); + const rowDim = isChannelsLast ? 1 : 2; + const colDim = isChannelsLast ? 2 : 3; + const channelDim = isChannelsLast ? 3 : 1; + const w = inputVariable("W", inputs[1].dataType, inputs[1].dims.length, bComponents); + const dy = inputVariable("Dy", inputs[0].dataType, inputs[0].dims.length, aComponents); + const inputVariables = [dy, w]; + if (hasBias) { + inputVariables.push(inputVariable("bias", inputs[2].dataType, [outputShape[channelDim]].length, components)); + } + const output = outputVariable("result", inputs[0].dataType, outputShape.length, components); + const calculateResult = () => { + let calcStr = ""; + if (packInputAs4) { + if (aComponents === 4) { + calcStr += ` + let xValue = ${dy.getByOffset("x_offset")}; + let wValue = ${w.getByOffset("w_offset")}; + dotProd = dotProd + dot(xValue, wValue); + x_offset += 1u; + w_offset += 1u;`; + } else if (aComponents === 2) { + calcStr += ` + dotProd = dotProd + dot(vec4<${dataType}>(${dy.getByOffset("x_offset")}, ${dy.getByOffset("x_offset + 1u")}), vec4<${dataType}>(${w.getByOffset("w_offset")}, ${w.getByOffset("w_offset + 1u")})); + x_offset += 2u; + w_offset += 2u;`; + } else if (aComponents === 1) { + calcStr += ` + dotProd = dotProd + dot(vec4<${dataType}>(${dy.getByOffset("x_offset")}, ${dy.getByOffset("x_offset + 1u")}, ${dy.getByOffset("x_offset + 2u")}, ${dy.getByOffset("x_offset + 3u")}), vec4<${dataType}>(${w.getByOffset("w_offset")}, ${w.getByOffset("w_offset + 1u")}, ${w.getByOffset("w_offset + 2u")}, ${w.getByOffset("w_offset + 3u")})); + x_offset += 4u; + w_offset += 4u;`; + } + } else { + calcStr += ` + let xValue = ${isChannelsLast ? dy.getByOffset( + `${dy.indicesToOffset(`${dy.type.indices}(batch, idyR, idyC, inputChannel)`)} / ${aComponents}` + ) : dy.get("batch", "inputChannel", "idyR", "idyC")}; + `; + if (aComponents === 1) { + calcStr += ` + let w_offset = ${w.indicesToOffset(`${w.type.indices}(u32(wRPerm), u32(wCPerm), inputChannel, wOutChannel)`)}; + let wValue = ${w.getByOffset(`w_offset / ${bComponents}`)}; + dotProd = dotProd + xValue * wValue;`; + } else { + for (let c = 0; c < aComponents; c++) { + calcStr += ` + let wValue${c} = ${w.getByOffset(`${w.indicesToOffset(`${w.type.indices}(u32(wRPerm), u32(wCPerm), inputChannel + ${c}, wOutChannel)`)} / ${bComponents}`)}; + dotProd = dotProd + xValue[${c}] * wValue${c};`; + } + } + } + return calcStr; + }; + const calculateRemainder = () => { + if (inputChannelsRemainder === 0) { + return ""; + } + if (!packInputAs4) { + throw new Error(`packInputAs4 ${packInputAs4} is not true.`); + } + let calcStr = ""; + if (aComponents === 1) { + calcStr += "dotProd = dotProd"; + for (let i = 0; i < inputChannelsRemainder; i++) { + calcStr += ` + + ${dy.getByOffset(`x_offset + ${i}`)} * ${w.getByOffset(`w_offset + ${i}`)}`; + } + calcStr += ";"; + } else if (aComponents === 2) { + if (inputChannelsRemainder !== 2) { + throw new Error(`Invalid inputChannelsRemainder ${inputChannelsRemainder}.`); + } + calcStr += ` + let xValue = ${dy.getByOffset("x_offset")}; + let wValue = ${w.getByOffset("w_offset")}; + dotProd = dotProd + dot(xValue, wValue);`; + } + return calcStr; + }; + const codeSnippet = ` + let outputIndices = ${output.offsetToIndices(`global_idx * ${components}`)}; + let batch = ${output.indicesGet("outputIndices", 0)}; + let d1 = ${output.indicesGet("outputIndices", channelDim)}; + let r = ${output.indicesGet("outputIndices", rowDim)}; + let c = ${output.indicesGet("outputIndices", colDim)}; + let dyCorner = vec2(i32(r), i32(c)) - uniforms.pads; + let dyRCorner = dyCorner.x; + let dyCCorner = dyCorner.y; + let groupId = d1 / uniforms.output_channels_per_group; + let wOutChannel = d1 - groupId * uniforms.output_channels_per_group; + // Convolve dy(?, ?, d2) with w(:, :, d1, d2) to compute dx(xR, xC, d1). + // ? = to be determined. : = across all values in that axis. + var dotProd = ${output.type.value}(0.0); + var wR: u32 = 0; + if (uniforms.dilations.x == 1) { + // Minimum wR >= 0 that satisfies (dyRCorner + wR) % (uniforms.strides.x) == 0 + wR = u32(((dyRCorner + i32(uniforms.strides.x) - 1) / i32(uniforms.strides.x)) * i32(uniforms.strides.x) - dyRCorner); + } + for (; wR < uniforms.effective_filter_dims.x; wR = wR + 1) { + if (wR % uniforms.dilations.x != 0) { + continue; + } + let dyR = (${dataType}(dyRCorner) + ${dataType}(wR)) / ${dataType}(uniforms.strides[0]); + let wRPerm = uniforms.filter_dims.x - 1 - wR / uniforms.dilations.x; + if (dyR < 0.0 || dyR >= ${dataType}(uniforms.Dy_shape[${rowDim}]) || fract(dyR) > 0.0 || + wRPerm < 0) { + continue; + } + let idyR: u32 = u32(dyR); + var wC: u32 = 0; + if (uniforms.dilations.y == 1) { + // Minimum wC >= 0 that satisfies (dyCCorner + wC) % (uniforms.strides.y) == 0 + wC = u32(((dyCCorner + i32(uniforms.strides.y) - 1) / i32(uniforms.strides.y)) * i32(uniforms.strides.y) - dyCCorner); + } + for (; wC < uniforms.effective_filter_dims.y; wC = wC + 1) { + if (wC % uniforms.dilations.y != 0) { + continue; + } + let dyC = (${dataType}(dyCCorner) + ${dataType}(wC)) / ${dataType}(uniforms.strides.y); + let wCPerm = uniforms.filter_dims.y - 1 - wC / uniforms.dilations.y; + if (dyC < 0.0 || dyC >= ${dataType}(uniforms.Dy_shape[${colDim}]) || + fract(dyC) > 0.0 || wCPerm < 0) { + continue; + } + let idyC: u32 = u32(dyC); + var inputChannel = groupId * uniforms.input_channels_per_group; + ${packInputAs4 ? ` + var x_offset = ${dy.indicesToOffset(`${dy.type.indices}(batch, idyR, idyC, inputChannel)`)} / ${aComponents}; + var w_offset = ${w.indicesToOffset(`${w.type.indices}(wRPerm, wCPerm, inputChannel, wOutChannel)`)} / ${bComponents}; + ` : ""} + for (var d2: u32 = 0; d2 < uniforms.input_channels_per_group_int; d2 = d2 + ${packInputAs4 ? 4 : aComponents}) { + ${calculateResult()} + inputChannel = inputChannel + ${packInputAs4 ? 4 : aComponents}; + } + ${calculateRemainder()} + wC = wC + uniforms.strides.y - 1; + } + wR = wR + uniforms.strides[0] - 1; + } + let value = dotProd${hasBias ? ` + bias[d1 / ${components}]` : ""}; + ${output.setByOffset("global_idx", "value")}; + `; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")}; + ${codeSnippet}}`; + }; + return { + name: "ConvTranspose2D", + shaderCache: { + hint: `${attributes.cacheKey};${aComponents}${bComponents}${components}${packInputAs4}${inputChannelsRemainder}`, + inputDependencies + }, + getRunData: () => ({ + dispatchGroup: { x: dispatch[0], y: dispatch[1], z: dispatch[2] }, + outputs: [ + { + dims: squeezeOutputShapeFunction ? squeezeOutputShapeFunction(outputShape) : outputShape, + dataType: inputs[0].dataType + } + ], + programUniforms + }), + getShaderSource + }; + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts + var computeTotalPad2, distributePadding2, calculateOutputShapeAndPads2, getAdjustedConvTransposeAttributes2, parseConvTransposeAttributes2, validateInputs34, convTranspose2d2, convTranspose1d, convTranspose2; + var init_conv_transpose2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/conv-transpose.ts"() { + "use strict"; + init_conv_backprop_webgpu(); + init_fuse_utils2(); + init_transpose2(); + computeTotalPad2 = (inDim, stride, adj, kernel, dilation, outSize) => (inDim - 1) * stride + adj + (kernel - 1) * dilation + 1 - outSize; + distributePadding2 = (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; + } + }; + calculateOutputShapeAndPads2 = (inputShape, kernelShape, dilations, autoPad, group, pads, strides, isChannelLast, outputPadding, outputShape) => { + const spatialRank = inputShape.length - 2; + const updateOutputShape = outputShape.length === 0; + if (outputPadding.length < spatialRank) { + outputPadding.push(...Array(spatialRank - outputPadding.length).fill(0)); + } + const batchSize = inputShape[0]; + const outChannels = kernelShape[isChannelLast ? 3 : 1] * group; + for (let i = 0, j = inputShape.length - spatialRank - (isChannelLast ? 1 : 0); i < spatialRank; ++i, ++j) { + const inSize = inputShape[j]; + const outSize = updateOutputShape ? inSize * strides[i] : outputShape[i]; + const totalPad = computeTotalPad2(inSize, strides[i], pads[i], kernelShape[j], dilations[i], outSize); + distributePadding2(totalPad, autoPad, pads, i, i + spatialRank); + if (updateOutputShape) { + outputShape.push( + strides[i] * (inSize - 1) + outputPadding[i] + (kernelShape[j] - 1) * dilations[i] + 1 - pads[i] - pads[i + spatialRank] + ); + } + } + outputShape.splice(0, 0, batchSize); + outputShape.splice(isChannelLast ? 3 : 1, 0, outChannels); + }; + getAdjustedConvTransposeAttributes2 = (attributes, inputs) => { + const kernelShape = attributes.kernelShape.slice(); + if (attributes.kernelShape.length === 0 || attributes.kernelShape.reduce((a, b) => a * b, 1) === 0) { + kernelShape.length = 0; + for (let i = 2; i < inputs[1].dims.length; ++i) { + kernelShape.push(inputs[1].dims[i]); + } + } + const isChannelsLast = attributes.format === "NHWC"; + kernelShape.splice(0, 0, inputs[1].dims[0]); + kernelShape.splice(isChannelsLast ? 3 : 1, 0, inputs[1].dims[1]); + const pads = attributes.pads.slice(); + const outputShape = attributes.outputShape.slice(); + const outputPadding = attributes.outputPadding.slice(); + const inputShape = inputs[0].dims; + let dilations = attributes.dilations.slice(); + if (dilations.reduce((a, b) => a + b, 0) === 0) { + const spatialRank = inputs[0].dims.length - 2; + dilations = new Array(spatialRank).fill(1); + } + let strides = attributes.strides.slice(); + if (strides.reduce((a, b) => a + b, 0) === 0) { + const spatialRank = inputs[0].dims.length - 2; + strides = new Array(spatialRank).fill(1); + } + calculateOutputShapeAndPads2( + inputShape, + kernelShape, + dilations, + attributes.autoPad, + attributes.group, + pads, + strides, + isChannelsLast, + outputPadding, + outputShape + ); + const newAttributes = Object.assign({}, attributes); + Object.assign(newAttributes, { kernelShape, pads, outputPadding, outputShape, dilations, strides }); + return newAttributes; + }; + parseConvTransposeAttributes2 = (attributes) => { + const activationAttributes = parseInternalActivationAttributes2(attributes); + const format = attributes.format; + const autoPad = ["NOTSET", "VALID", "SAME_UPPER", "SAME_LOWER"][typeof attributes.autoPad == "undefined" ? 0 : attributes.autoPad]; + const dilations = attributes.dilations; + const group = attributes.group; + const kernelShape = attributes.kernelShape; + const pads = attributes.pads; + const strides = attributes.strides; + const wIsConst = attributes.wIsConst(); + const outputPadding = attributes.outputPadding; + const outputShape = attributes.outputShape; + return { + autoPad, + format, + dilations, + group, + kernelShape, + outputPadding, + outputShape, + pads, + strides, + wIsConst, + ...activationAttributes, + cacheKey: `${attributes.format};${activationAttributes.activation};` + }; + }; + validateInputs34 = (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[0].dims.length !== 3) { + throw new Error("currently only support 2-dimensional conv"); + } + if (inputs[0].dims.length !== inputs[1].dims.length) { + throw new Error("filter does not have same dimension as input"); + } + const dataChannel = inputs[0].dims[attributes.format === "NHWC" ? inputs[0].dims.length - 1 : 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; + const dilationsSet = attributes.dilations.reduce((a, b) => a + b, 0) > 0; + if (dilationsSet && attributes.dilations.length !== spatialRank) { + throw new Error(`dilations should be ${spatialRank}D`); + } + const stridesSet = attributes.strides.reduce((a, b) => a + b, 0) > 0; + if (stridesSet && attributes.strides.length !== spatialRank) { + throw new Error(`strides should be ${spatialRank}D`); + } + const padsSet = attributes.pads.reduce((a, b) => a + b, 0) > 0; + if (padsSet && attributes.pads.length !== spatialRank * 2) { + throw new Error(`pads should be ${spatialRank * 2}D`); + } + if (attributes.outputPadding.length !== spatialRank && attributes.outputPadding.length !== 0) { + throw new Error(`output_padding should be ${spatialRank}D`); + } + const kernelShapeSet = attributes.kernelShape.reduce((a, b) => a + b, 0) > 0; + if (kernelShapeSet && 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"); + } + }; + convTranspose2d2 = (context, inputs, attributes, squeezeOutputShapeFunction) => { + const transposedWeight = context.kernelCustomData.wT ?? context.compute(createTransposeProgramInfo2(inputs[1], [2, 3, 0, 1]), { + inputs: [1], + outputs: [attributes.wIsConst ? -2 : -1] + })[0]; + if (attributes.wIsConst && !context.kernelCustomData.wT) { + context.kernelCustomData.wT = transposedWeight; + } + const convTransposeInputs = [inputs[0], transposedWeight]; + if (inputs.length === 3) { + convTransposeInputs.push(inputs[2]); + } + context.compute(createConvTranspose2DProgramInfo(convTransposeInputs, attributes, squeezeOutputShapeFunction), { + inputs: convTransposeInputs + }); + }; + convTranspose1d = (context, attributes) => { + const isChannelLast = attributes.format === "NHWC"; + const inputs = [ + context.inputs[0].reshape( + isChannelLast ? ( + // [N, W, C] -> [N, H=1, W, C] + [context.inputs[0].dims[0], 1, context.inputs[0].dims[1], context.inputs[0].dims[2]] + ) : ( + // [N, C, W] -> [N, C, H=1, W] + [context.inputs[0].dims[0], context.inputs[0].dims[1], 1, context.inputs[0].dims[2]] + ) + ), + //[FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, kW] -> [FILTER_OUT_CHANNEL, FILTER_IN_CHANNEL, kH=1, kW] + context.inputs[1].reshape([context.inputs[1].dims[0], context.inputs[1].dims[1], 1, context.inputs[1].dims[2]]) + ]; + if (context.inputs.length === 3) { + inputs.push(context.inputs[2]); + } + let kernelShape = attributes.kernelShape; + if (kernelShape.length === 0 || kernelShape[0] === 0) { + kernelShape = [context.inputs[1].dims[2]]; + } + let dilations = attributes.dilations; + if (dilations.length === 0 || dilations[0] === 0) { + dilations = [1]; + } + let strides = attributes.strides; + if (strides.length === 0 || strides[0] === 0) { + strides = [1]; + } + let pads = attributes.pads; + if (pads.length === 0) { + pads = [0, 0]; + } + pads = [0, pads[0], 0, pads[1]]; + strides = [1].concat(strides); + dilations = [1].concat(dilations); + kernelShape = [1].concat(kernelShape); + let outputPadding = attributes.outputPadding; + outputPadding = [0].concat(outputPadding); + const adjustedAttributes = getAdjustedConvTransposeAttributes2( + { ...attributes, pads, strides, dilations, kernelShape, outputPadding }, + inputs + ); + convTranspose2d2( + context, + inputs, + adjustedAttributes, + (outputShape) => isChannelLast ? [outputShape[0], outputShape[2], outputShape[3]] : [outputShape[0], outputShape[1], outputShape[3]] + ); + }; + convTranspose2 = (context, attributes) => { + validateInputs34(context.inputs, attributes); + if (context.inputs[0].dims.length === 3) { + convTranspose1d(context, attributes); + } else { + const adjustedAttributes = getAdjustedConvTransposeAttributes2(attributes, context.inputs); + convTranspose2d2(context, context.inputs, adjustedAttributes); + } + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/cumsum.ts + var createCumsumProgramInfo, cumsum, parseCumSumAttributes; + var init_cumsum = __esm({ + "web/lib/wasm/jsep/webgpu/ops/cumsum.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + createCumsumProgramInfo = (inputType, inputShape, axisInput, attributes) => { + const outputSize = ShapeUtil2.size(inputShape); + const rank = inputShape.length; + const input = inputVariable("input", inputType, rank); + const output = outputVariable("output", inputType, rank); + const axisValue = axisInput.dataType === 6 /* int32 */ ? axisInput.getInt32Array()[0] : Number(axisInput.getBigInt64Array()[0]); + const axis = ShapeUtil2.normalizeAxis(axisValue, rank); + const getShaderSource = (shaderHelper) => { + const index = ` i32(${input.indicesGet("inputIndices", "uniforms.axis")}) `; + const max = getElementAt("uniforms.input_shape", "uniforms.axis", rank); + const lowerLimit = attributes.reverse ? index + (attributes.exclusive ? " + 1" : "") : "0"; + const upperLimit = attributes.reverse ? max : index + (attributes.exclusive ? "" : " + 1"); + return ` + ${shaderHelper.registerUniform("outputSize", "u32").registerUniform("axis", "u32").declareVariables(input, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + var inputIndices = ${output.offsetToIndices("global_idx")}; + var sum = ${output.type.value}(0); + let first : i32 = ${lowerLimit}; + let last : i32 = ${upperLimit}; + for (var i : i32 = first; i < last; i++) { + ${input.indicesSet("inputIndices", "uniforms.axis", "u32(i)")}; + sum = sum + ${input.getByIndices("inputIndices")}; + } + ${output.setByOffset("global_idx", "sum")}; + }`; + }; + return { + name: "CumSum", + shaderCache: { hint: attributes.cacheKey, inputDependencies: ["rank"] }, + getRunData: () => ({ + outputs: [{ dims: inputShape, dataType: inputType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms: [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: axis }, + ...createTensorShapeVariables(inputShape, inputShape) + ] + }), + getShaderSource + }; + }; + cumsum = (context, attributes) => { + const inputShape = context.inputs[0].dims; + const inputType = context.inputs[0].dataType; + const axis = context.inputs[1]; + context.compute(createCumsumProgramInfo(inputType, inputShape, axis, attributes), { inputs: [0] }); + }; + parseCumSumAttributes = (attributes) => { + const exclusive = attributes.exclusive === 1; + const reverse = attributes.reverse === 1; + return createAttributeWithCacheKey2({ exclusive, reverse }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/depth-to-space.ts + var validateInputs35, permFunctionBody2, createDepthToSpaceProgramInfo, depthToSpace2, parseDepthToSpaceAttributes2; + var init_depth_to_space2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/depth-to-space.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs35 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("DepthToSpace requires 1 input."); + } + if (inputs[0].dims.length !== 4) { + throw new Error("DepthToSpace requires 4D input."); + } + }; + permFunctionBody2 = (perm, rank, input, output) => { + const reverseFunc = []; + reverseFunc.push(`fn perm(i: ${output.type.indices}) -> ${input.type.indices} { + var a: ${input.type.indices};`); + for (let i = 0; i < rank; ++i) { + reverseFunc.push(input.indicesSet("a", perm[i], `i[${i}]`)); + } + reverseFunc.push("return a;}"); + return reverseFunc.join("\n"); + }; + createDepthToSpaceProgramInfo = (inputTensor, attributes) => { + let n, h, w, c; + let shape2; + let perm; + const isChannelLast = attributes.format === "NHWC"; + const blocksize = attributes.blocksize; + const isDCRmode = attributes.mode === "DCR"; + if (isChannelLast) { + [n, h, w, c] = inputTensor.dims; + shape2 = isDCRmode ? [n, h, w, blocksize, blocksize, c / blocksize ** 2] : [n, h, w, c / blocksize ** 2, blocksize, blocksize]; + perm = isDCRmode ? [0, 1, 3, 2, 4, 5] : [0, 1, 4, 2, 5, 3]; + } else { + [n, h, w, c] = [inputTensor.dims[0], inputTensor.dims[2], inputTensor.dims[3], inputTensor.dims[1]]; + shape2 = isDCRmode ? [n, blocksize, blocksize, c / blocksize ** 2, h, w] : [n, c / blocksize ** 2, blocksize, blocksize, h, w]; + perm = isDCRmode ? [0, 3, 4, 1, 5, 2] : [0, 1, 4, 2, 5, 3]; + } + const reshapedInputTensor = inputTensor.reshape(shape2); + const reshapedInputRank = reshapedInputTensor.dims.length; + const inputDataType = inputTensor.dataType; + const reshapedInput = inputVariable("a", inputDataType, reshapedInputRank); + const permedOutput = outputVariable("output", inputDataType, reshapedInputRank); + const getShaderSource = (shaderHelper) => ` + ${shaderHelper.registerUniform("output_size", "u32").declareVariables(reshapedInput, permedOutput)} + + ${permFunctionBody2(perm, reshapedInputRank, reshapedInput, permedOutput)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + + let indices = ${permedOutput.offsetToIndices("global_idx")}; + let aIndices = perm(indices); + + ${permedOutput.setByOffset("global_idx", reshapedInput.getByIndices("aIndices"))} + }`; + return { + name: "DepthToSpace", + shaderCache: { + hint: `${inputTensor.dims};${attributes.blocksize};${attributes.mode}`, + inputDependencies: ["rank"] + }, + getRunData: (inputs) => { + const outputShape = isChannelLast ? [n, h * blocksize, w * blocksize, c / blocksize ** 2] : [n, c / blocksize ** 2, h * blocksize, w * blocksize]; + const outputSize = ShapeUtil2.size(outputShape); + const shapeBeforePerm = reshapedInputTensor.dims; + const shapeAfterPerm = ShapeUtil2.sortBasedOnPerm(shapeBeforePerm, perm); + return { + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms: [ + { type: 12 /* uint32 */, data: outputSize }, + ...createTensorShapeVariables(shapeBeforePerm, shapeAfterPerm) + ] + }; + }, + getShaderSource + }; + }; + depthToSpace2 = (context, attributes) => { + validateInputs35(context.inputs); + context.compute(createDepthToSpaceProgramInfo(context.inputs[0], attributes)); + }; + parseDepthToSpaceAttributes2 = (attributes) => createAttributeWithCacheKey2({ + blocksize: attributes.blocksize, + mode: attributes.mode, + format: attributes.format + }); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/einsum.ts + var symbolPattern, termPattern, termPatternOnly, lhsPattern, lhsPatternOnly, EinsumTerm, EinsumEquation, appendMax, createEinsumProgramInfo, einsum, parseEinsumAttributes; + var init_einsum = __esm({ + "web/lib/wasm/jsep/webgpu/ops/einsum.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + symbolPattern = "[a-zA-Z]|\\.\\.\\."; + termPattern = "(" + symbolPattern + ")+"; + termPatternOnly = "^" + termPattern + "$"; + lhsPattern = "(" + termPattern + ",)*" + termPattern; + lhsPatternOnly = "^" + lhsPattern + "$"; + EinsumTerm = class { + constructor(inputIndex = -1) { + this.symbolToIndices = /* @__PURE__ */ new Map(); + this.inputIndex = inputIndex; + } + // Add a symbol to the term + addSymbol(symbol, index) { + let value = this.symbolToIndices.get(symbol); + if (value === void 0) { + value = [index]; + } else { + value.push(index); + } + this.symbolToIndices.set(symbol, value); + } + // -1 for output and 0, 1, 2, ... for inputs + }; + EinsumEquation = class { + constructor(inputs, equation) { + this.equation = equation; + this.hasEllipsis = false; + this.symbolToInfo = /* @__PURE__ */ new Map(); + this.lhs = new Array(); + this.outputDims = []; + let [lhs, rhs] = equation.includes("->") ? equation.split("->", 2) : [equation, ""]; + if (!lhs.match(RegExp(lhsPatternOnly))) { + throw new Error("Invalid LHS term"); + } + const inputTerms = lhs.split(","); + inputTerms.forEach((inputTerm, index) => { + const dims = inputs[index].dims.slice(); + if (!inputTerm.match(RegExp(termPatternOnly))) { + throw new Error("Invalid LHS term"); + } + const einsumTerm = this.processTerm(inputTerm, true, dims, index); + this.lhs.push(einsumTerm); + }); + if (rhs === "") { + rhs += [...this.symbolToInfo.entries()].filter(([sym, info]) => info.count === 1 || sym === "...").map(([sym]) => sym).join(""); + } else { + if (!rhs.match(RegExp(termPattern))) { + throw new Error("Invalid RHS"); + } + } + const rhsSymbols = rhs.match(RegExp(symbolPattern, "g")); + rhsSymbols?.forEach((symbol) => { + if (symbol === "...") { + this.outputDims = this.outputDims.concat(this.ellipsisDims); + } else { + const info = this.symbolToInfo.get(symbol); + if (info === void 0) { + throw new Error("Invalid RHS symbol"); + } + this.outputDims.push(info.dimValue); + } + }); + this.rhs = this.processTerm(rhs, false, this.outputDims); + } + // End of EinsumEqation constructor + // Add a symbol to the equation + addSymbol(symbol, dimValue, inputIndex) { + let info = this.symbolToInfo.get(symbol); + if (info !== void 0) { + if (info.dimValue !== dimValue && info.count !== 1) { + throw new Error("Dimension mismatch"); + } else { + info.count++; + info.inputIndices.push(inputIndex); + } + } else { + info = { count: 1, dimValue, inputIndices: [inputIndex] }; + } + this.symbolToInfo.set(symbol, info); + } + // Process one input/output term + processTerm(term, isInput, dims, index = -1) { + const rank = dims.length; + let ellipsis = false; + let ellipsisDims = []; + let nextDim = 0; + if (!term.match(RegExp(termPatternOnly)) && !isInput && term !== "") { + throw new Error("Invalid LHS term"); + } + const indexSymbols = term.match(RegExp(symbolPattern, "g")); + const einsumTerm = new EinsumTerm(index); + indexSymbols?.forEach((symbol, i) => { + if (symbol === "...") { + if (ellipsis) { + throw new Error("Only one ellipsis is allowed per input term"); + } + ellipsis = true; + const ellipsisDimLength = rank - indexSymbols.length + 1; + if (ellipsisDimLength < 0) { + throw new Error("Ellipsis out of bounds"); + } + ellipsisDims = dims.slice(nextDim, nextDim + ellipsisDimLength); + if (this.hasEllipsis) { + if (this.ellipsisDims.length !== ellipsisDims.length || this.ellipsisDims.toString() !== ellipsisDims.toString()) { + throw new Error("Ellipsis dimensions mismatch"); + } + } else if (isInput) { + this.hasEllipsis = true; + this.ellipsisDims = ellipsisDims; + } else { + throw new Error("Ellipsis must be specified in the LHS"); + } + for (let j = 0; j < ellipsisDims.length; j++) { + const symbol2 = String.fromCharCode("0".charCodeAt(0) + j); + einsumTerm.addSymbol(symbol2, i + j); + this.addSymbol(symbol2, dims[nextDim++], index); + } + } else { + einsumTerm.addSymbol(symbol, i + (this.hasEllipsis ? this.ellipsisDims.length - 1 : 0)); + this.addSymbol(symbol, dims[nextDim++], index); + } + }); + return einsumTerm; + } + // Output dimensions of the equation + }; + appendMax = (name2) => name2 + "_max"; + createEinsumProgramInfo = (inputShapes, dataType, einsumEquation, outputShape) => { + const ranks = inputShapes.map((dims) => dims.length); + const inputVars = ranks.map((rank, index) => inputVariable(`input${index}`, dataType, rank)); + const outputSize = ShapeUtil2.size(outputShape); + const output = outputVariable("output", dataType, outputShape.length); + const uniformsSymbols = [...einsumEquation.symbolToInfo.keys()].filter( + (symbol) => !einsumEquation.rhs.symbolToIndices.has(symbol) + ); + const getShaderSource = (shaderHelper) => { + const idxCopy = []; + const initProd = "var prod = 1.0;"; + const initSum = "var sum = 0.0;"; + const updateSum = "sum += prod;"; + const reduceOpsSetIndices = []; + const reduceOpsLoopHeaders = []; + const reduceOpsLoopFooters = []; + const reduceOpCompute = []; + const isReduceOpsWithoutLoop = einsumEquation.symbolToInfo.size === einsumEquation.rhs.symbolToIndices.size; + einsumEquation.symbolToInfo.forEach((info, symbol) => { + if (einsumEquation.rhs.symbolToIndices.has(symbol)) { + const outputIndex = einsumEquation.rhs.symbolToIndices.get(symbol)?.[0]; + if (outputIndex !== void 0) { + einsumEquation.lhs.forEach((term, i) => { + if (info.inputIndices.includes(i)) { + const indices = term.symbolToIndices.get(symbol); + if (indices === void 0) { + throw new Error("Invalid symbol error"); + } + indices.forEach((index) => { + idxCopy.push( + `${inputVars[i].indicesSet( + `input${i}Indices`, + index, + output.indicesGet("outputIndices", outputIndex) + )}` + ); + }); + } + }); + } + } else { + einsumEquation.lhs.forEach((term, i) => { + if (info.inputIndices.includes(i)) { + const indices = term.symbolToIndices.get(symbol); + if (indices === void 0) { + throw new Error("Invalid symbol error"); + } + indices.forEach((index) => { + reduceOpsSetIndices.push(`${inputVars[i].indicesSet(`input${i}Indices`, index, `${symbol}`)}`); + }); + reduceOpCompute.push(`prod *= ${inputVars[i].getByIndices(`input${i}Indices`)};`); + } + }); + reduceOpsLoopHeaders.push( + `for(var ${symbol}: u32 = 0; ${symbol} < uniforms.${appendMax(symbol)}; ${symbol}++) {` + ); + reduceOpsLoopFooters.push("}"); + } + }); + const reduceOps2 = isReduceOpsWithoutLoop ? [ + ...idxCopy, + `let sum = ${inputVars.map((inputVar, i) => inputVar.getByIndices(`input${i}Indices`)).join(" * ")};` + ] : [ + ...idxCopy, + initSum, + ...reduceOpsLoopHeaders, + ...reduceOpsSetIndices, + initProd, + ...reduceOpCompute, + updateSum, + ...reduceOpsLoopFooters + ]; + return ` + ${shaderHelper.registerUniforms(uniformsSymbols.map((symbol) => ({ name: `${appendMax(symbol)}`, type: "u32" }))).registerUniform("outputSize", "u32").declareVariables(...inputVars, output)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + var outputIndices = ${output.offsetToIndices("global_idx")}; + ${inputVars.map((_var, i) => `var input${i}Indices: ${inputVars[i].type.indices};`).join("\n")} + ${reduceOps2.join("\n")}; + ${output.setByOffset("global_idx", "sum")}; + }`; + }; + return { + name: "Einsum", + shaderCache: { hint: einsumEquation.equation, inputDependencies: inputShapes.map(() => "rank") }, + getRunData: () => { + const programUniformsInit = uniformsSymbols.filter((symbol) => einsumEquation.symbolToInfo.has(symbol)).map((symbol) => ({ type: 12 /* uint32 */, data: einsumEquation.symbolToInfo.get(symbol)?.dimValue || 0 })); + programUniformsInit.push({ type: 12 /* uint32 */, data: outputSize }); + const programUniforms = inputShapes.map((dims, _) => [...createTensorShapeVariables(dims)]).reduce((acc, inputProgramUniforms) => acc.concat(inputProgramUniforms), programUniformsInit); + programUniforms.push(...createTensorShapeVariables(outputShape)); + return { + outputs: [{ dims: outputShape, dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }; + }, + getShaderSource + }; + }; + einsum = (context, attributes) => { + const einsumEquation = new EinsumEquation(context.inputs, attributes.equation); + const outputShape = einsumEquation.outputDims; + const inputShapes = context.inputs.map((input, _) => input.dims); + context.compute(createEinsumProgramInfo(inputShapes, context.inputs[0].dataType, einsumEquation, outputShape)); + }; + parseEinsumAttributes = (attributes) => { + const equation = attributes.equation.replace(/\s+/g, ""); + return createAttributeWithCacheKey2({ equation }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/expand.ts + var validateInputs36, getAdjustedShape, calculateOutputShape3, createExpandProgramInfo, expand; + var init_expand = __esm({ + "web/lib/wasm/jsep/webgpu/ops/expand.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + validateInputs36 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Expand requires 2 input."); + } + const inputShape = inputs[0].dims; + const shape2 = Array.from(inputs[1].getBigInt64Array(), Number); + let shapeIndex = shape2.length < inputShape.length ? 0 : shape2.length - inputShape.length; + let inputShapeIndex = inputShape.length < shape2.length ? 0 : inputShape.length - shape2.length; + for (; shapeIndex < shape2.length && inputShapeIndex < inputShape.length; ++shapeIndex, ++inputShapeIndex) { + if (shape2[shapeIndex] !== inputShape[inputShapeIndex] && shape2[shapeIndex] !== 1 && inputShape[inputShapeIndex] !== 1) { + throw new Error("Expand requires shape to be broadcastable to input"); + } + } + }; + getAdjustedShape = (shape1, shape2) => { + const diff = shape1.length - shape2.length; + const shape3 = []; + for (let i = 0; i < diff; ++i) { + shape3.push(shape1[i]); + } + for (let i = 0; i < shape2.length; ++i) { + shape3.push(shape2[i] === 1 ? shape1[i + diff] : shape2[i]); + } + return shape3; + }; + calculateOutputShape3 = (inputShape, shape2) => inputShape.length > shape2.length ? getAdjustedShape(inputShape, shape2) : getAdjustedShape(shape2, inputShape); + createExpandProgramInfo = (inputs) => { + const inputShape = inputs[0].dims; + const shape2 = Array.from(inputs[1].getBigInt64Array(), Number); + const outputShape = calculateOutputShape3(inputShape, shape2); + const dataType = inputs[0].dataType; + const isBoolOrScalar = dataType === 9 /* bool */ || ShapeUtil2.size(inputShape) === 1; + const iComponents = dataType === 9 /* bool */ ? 4 : inputShape.length > 0 && inputShape[inputShape.length - 1] % 4 === 0 ? 4 : 1; + const components = isBoolOrScalar ? 4 : outputShape.length > 0 && outputShape[outputShape.length - 1] % 4 === 0 ? 4 : 1; + const outputSize = Math.ceil(ShapeUtil2.size(outputShape) / components); + const getShaderSource = (shaderHelper) => { + const input = inputVariable("input", dataType, inputShape.length, iComponents); + const output = outputVariable("output", dataType, outputShape.length, components); + let assignment; + if (dataType === 9 /* bool */) { + const singleAssignment = (resStr, x, typeCast = "") => ` + let outputIndices${x} = ${output.offsetToIndices(`outputOffset + ${x}u`)}; + let offset${x} = ${input.broadcastedIndicesToOffset(`outputIndices${x}`, output)}; + let index${x} = offset${x} / 4u; + let component${x} = offset${x} % 4u; + ${resStr}[${x}] = ${typeCast}(${input.getByOffset(`index${x}`)}[component${x}]); + `; + assignment = ` + let outputOffset = global_idx * ${components}; + var data = vec4(0); + ${singleAssignment("data", 0, "u32")} + ${singleAssignment("data", 1, "u32")} + ${singleAssignment("data", 2, "u32")} + ${singleAssignment("data", 3, "u32")} + ${output.setByOffset("global_idx", "data")} + }`; + } else { + assignment = ` + let outputIndices = ${output.offsetToIndices(`global_idx * ${components}`)}; + let inputOffset = ${input.broadcastedIndicesToOffset("outputIndices", output)}; + let data = ${output.type.value}(${input.getByOffset(`inputOffset / ${iComponents}`)}); + ${output.setByOffset("global_idx", "data")} + }`; + } + return ` + ${shaderHelper.registerUniform("vec_size", "u32").declareVariables(input, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.vec_size")} + ${assignment}`; + }; + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + ...createTensorShapeVariables(inputShape, outputShape) + ]; + return { + name: "Expand", + shaderCache: { hint: `${outputShape.length};${iComponents}${components}`, inputDependencies: ["rank"] }, + getShaderSource, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }) + }; + }; + expand = (context) => { + validateInputs36(context.inputs); + context.compute(createExpandProgramInfo(context.inputs), { inputs: [0] }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/fast-gelu.ts + var createFastGeluProgramInfo, fastGelu2; + var init_fast_gelu = __esm({ + "web/lib/wasm/jsep/webgpu/ops/fast-gelu.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + init_unary_op2(); + createFastGeluProgramInfo = (inputTensors) => { + const dataType = inputTensors[0].dataType; + const outputSize = ShapeUtil2.size(inputTensors[0].dims); + const biasLength = ShapeUtil2.size(inputTensors[1].dims); + const useVec4 = biasLength % 4 === 0; + const getShaderSource = (shaderHelper) => { + const x = inputVariable("x", dataType, [1], 4); + const bias = inputVariable("bias", dataType, [1], 4); + const y = outputVariable("y", dataType, [1], 4); + const uniforms = [ + { name: "output_vec_size", type: "u32" }, + { name: "bias_size", type: "u32" } + ]; + const singleElementBias = (i) => ` + let bias${i}_offset: u32 = (global_idx * 4 + ${i}) % uniforms.bias_size; + let bias${i} = ${bias.getByOffset(`bias${i}_offset / 4`)}[bias${i}_offset % 4];`; + const biasGetExpression = useVec4 ? ` + let bias = ${bias.getByOffset("global_idx % (uniforms.bias_size / 4)")};` : `${singleElementBias(0)}${singleElementBias(1)}${singleElementBias(2)}${singleElementBias(3)} + let bias = ${x.type.value}(bias0, bias1, bias2, bias3);`; + return `${shaderHelper.registerUniforms(uniforms).declareVariables(x, bias, y)} + + ${fastGeluImpl(tensorTypeToWsglValueType(dataType))} + + ${shaderHelper.mainStart(WORKGROUP_SIZE)} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_vec_size")} + + let x = ${x.getByOffset("global_idx")}; + ${biasGetExpression} + let x_in = x + bias; + ${y.setByOffset("global_idx", fastGeluExpression("x_in"))} + }`; + }; + return { + name: "FastGeluWithBias", + shaderCache: { hint: `${useVec4}`, inputDependencies: ["type", "type"] }, + getShaderSource, + getRunData: (inputs) => ({ + outputs: [{ dims: inputs[0].dims, dataType: inputs[0].dataType }], + programUniforms: [ + { type: 12 /* uint32 */, data: Math.ceil(outputSize / 4) }, + { type: 12 /* uint32 */, data: biasLength } + ], + dispatchGroup: { x: Math.ceil(outputSize / WORKGROUP_SIZE / 4) } + }) + }; + }; + fastGelu2 = (context) => { + if (context.inputs.length < 2 || ShapeUtil2.size(context.inputs[1].dims) === 0) { + fastGelu(context); + } else { + context.compute(createFastGeluProgramInfo(context.inputs)); + } + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/gather.ts + var validateInputs37, createGatherProgramInfo2, parseGatherAttributes2, gather2; + var init_gather2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/gather.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs37 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Gather requires 2 inputs."); + } + }; + createGatherProgramInfo2 = (inputs, attributes) => { + const inputShape = inputs[0].dims; + const indicesShape = inputs[1].dims; + const inputRank = inputShape.length; + const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputRank); + const outputShape = inputShape.slice(0); + outputShape.splice(axis, 1, ...indicesShape); + const axisDimLimit = inputShape[axis]; + const components = inputs[0].dataType === 9 /* bool */ ? 4 : 1; + const outputSize = Math.ceil(ShapeUtil2.size(outputShape) / components); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 6 /* int32 */, data: axisDimLimit }, + { type: 12 /* uint32 */, data: axis }, + ...createTensorShapeVariables(inputs[0].dims, inputs[1].dims, outputShape) + ]; + const getShaderSource = (shaderHelper) => { + const data = inputVariable("data", inputs[0].dataType, inputs[0].dims.length, components); + const indices = inputVariable("inputIndices", inputs[1].dataType, inputs[1].dims.length); + const output = outputVariable("output", inputs[0].dataType, outputShape.length, components); + const calcDataIndices = (x) => { + const indicesRank = indicesShape.length; + let calcStr = `var indicesIndices${x} = ${indices.type.indices}(0);`; + for (let i = 0; i < indicesRank; i++) { + calcStr += `${indicesRank > 1 ? `indicesIndices${x}[${i}]` : `indicesIndices${x}`} = ${outputShape.length > 1 ? `outputIndices${x}[uniforms.axis + ${i}]` : `outputIndices${x}`};`; + } + calcStr += ` + var idx${x} = ${indices.getByIndices(`indicesIndices${x}`)}; + if (idx${x} < 0) { + idx${x} = idx${x} + uniforms.axisDimLimit; + } + var dataIndices${x} : ${data.type.indices}; + `; + for (let i = 0, j = 0; i < inputRank; i++) { + if (i === axis) { + calcStr += `${inputRank > 1 ? `dataIndices${x}[${i}]` : `dataIndices${x}`} = u32(idx${x});`; + j += indicesRank; + } else { + calcStr += `${inputRank > 1 ? `dataIndices${x}[${i}]` : `dataIndices${x}`} = ${outputShape.length > 1 ? `outputIndices${x}[${j}]` : `outputIndices${x}`};`; + j++; + } + } + return calcStr; + }; + let assignment; + if (inputs[0].dataType === 9 /* bool */) { + const singleAssignment = (resStr, x, typeCast = "") => ` + let outputIndices${x} = ${output.offsetToIndices(`outputOffset + ${x}u`)}; + ${calcDataIndices(x)}; + let offset${x} = ${data.indicesToOffset(`dataIndices${x}`)}; + let index${x} = offset${x} / 4u; + let component${x} = offset${x} % 4u; + ${resStr}[${x}] = ${typeCast}(${data.getByOffset(`index${x}`)}[component${x}]); + `; + assignment = ` + let outputOffset = global_idx * ${components}; + var value = vec4(0); + ${singleAssignment("value", 0, "u32")} + ${singleAssignment("value", 1, "u32")} + ${singleAssignment("value", 2, "u32")} + ${singleAssignment("value", 3, "u32")} + ${output.setByOffset("global_idx", "value")} + `; + } else { + assignment = ` + let outputIndices = ${output.offsetToIndices("global_idx")}; + ${calcDataIndices("")}; + let value = ${data.getByIndices("dataIndices")}; + ${output.setByOffset("global_idx", "value")}; + `; + } + return ` + ${shaderHelper.registerUniform("outputSize", "u32").registerUniform("axisDimLimit", "i32").registerUniform("axis", "u32").declareVariables(data, indices, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + ${assignment} + }`; + }; + return { + name: "Gather", + shaderCache: { hint: attributes.cacheKey, inputDependencies: ["rank", "rank"] }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + parseGatherAttributes2 = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis }); + gather2 = (context, attributes) => { + const inputs = context.inputs; + validateInputs37(inputs); + context.compute(createGatherProgramInfo2(context.inputs, attributes)); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/gather-nd.ts + var computeSliceOffsets, gatherND, parseGatherNDAttributes; + var init_gather_nd = __esm({ + "web/lib/wasm/jsep/webgpu/ops/gather-nd.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + computeSliceOffsets = (context, indicesData, sizesFromSliceDimsData, batchDims, inputDims, numSlices, numSlicesPerBatch, inputBatchStride, numSliceDims) => { + const programUniforms = [ + { type: 12 /* uint32 */, data: numSlices }, + { type: 12 /* uint32 */, data: batchDims }, + { type: 12 /* uint32 */, data: inputDims }, + { type: 12 /* uint32 */, data: sizesFromSliceDimsData }, + { type: 12 /* uint32 */, data: numSlicesPerBatch }, + { type: 12 /* uint32 */, data: inputBatchStride }, + { type: 12 /* uint32 */, data: numSliceDims } + ]; + const outputShape = [numSlices]; + programUniforms.push(...createTensorShapeVariables(indicesData.dims, outputShape)); + const getShaderSource = (shaderHelper) => { + const indices = inputVariable("indices_data", indicesData.dataType, indicesData.dims.length); + const output = outputVariable("input_slice_offsets_data", 12 /* uint32 */, 1, 1); + const variables = [indices, output]; + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "batch_dims", type: "u32" }, + { name: "input_dims", type: "u32", length: inputDims.length }, + { name: "sizes_from_slice_dims_data", type: "u32", length: sizesFromSliceDimsData.length }, + { name: "num_slices_per_batch", type: "u32" }, + { name: "input_batch_stride", type: "u32" }, + { name: "num_slice_dims", type: "u32" } + ]; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(...variables)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let batch_idx = global_idx / uniforms.num_slices_per_batch; + let base_offset = batch_idx * uniforms.input_batch_stride; + + let slice_indices_base_offset = global_idx * uniforms.num_slice_dims; + var relative_slice_offset = 0; + for (var dim_idx = 0u; dim_idx < uniforms.num_slice_dims; dim_idx ++) { + var index = i32(indices_data[dim_idx + slice_indices_base_offset].x); + let input_dim_idx = uniforms.batch_dims + dim_idx; + if (index < 0) { + ${inputDims.length === 1 ? "index += i32(uniforms.input_dims);" : "index += i32(uniforms.input_dims[input_dim_idx]);"} + } + ${sizesFromSliceDimsData.length === 1 ? "relative_slice_offset += index * i32(uniforms.sizes_from_slice_dims_data);" : "relative_slice_offset += index * i32(uniforms.sizes_from_slice_dims_data[dim_idx]);"} + } + + input_slice_offsets_data[global_idx] = base_offset + u32(relative_slice_offset); + }`; + }; + return context.compute( + { + name: "computeSliceOffsets", + shaderCache: { hint: `${inputDims.length}_${sizesFromSliceDimsData.length}`, inputDependencies: ["rank"] }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: context.inputs[1].dataType }], + dispatchGroup: { x: Math.ceil(numSlices / 64) }, + programUniforms + }), + getShaderSource + }, + { inputs: [indicesData], outputs: [-1] } + )[0]; + }; + gatherND = (context, attributes) => { + const inputs = context.inputs; + const inputShape = inputs[0].dims; + const inputType = inputs[0].dataType; + const indicesShape = inputs[1].dims; + const numSliceDims = indicesShape[indicesShape.length - 1]; + const numSlices = ShapeUtil2.sizeToDimension(indicesShape, indicesShape.length - 1); + const sliceSize = ShapeUtil2.sizeFromDimension(inputShape, attributes.batchDims + numSliceDims); + const numBatches = ShapeUtil2.sizeToDimension(inputShape, attributes.batchDims); + const inputBatchStride = ShapeUtil2.sizeFromDimension(inputShape, attributes.batchDims); + const numSlicesPerBatch = numSlices / numBatches; + const sizesFromSliceDims = new Array(numSliceDims); + let runningProduct = sliceSize; + for (let i = 0; i < numSliceDims; ++i) { + sizesFromSliceDims[numSliceDims - 1 - i] = runningProduct; + runningProduct *= inputShape[attributes.batchDims + numSliceDims - 1 - i]; + } + const inputSliceOffsets = computeSliceOffsets( + context, + inputs[1], + sizesFromSliceDims, + attributes.batchDims, + inputShape, + numSlices, + numSlicesPerBatch, + inputBatchStride, + numSliceDims + ); + const lastIndicesDimension = attributes.batchDims + numSliceDims; + if (lastIndicesDimension > inputShape.length) { + throw new Error("last dimension of indices must not be larger than rank of input tensor"); + } + const outputShape = indicesShape.slice(0, -1).concat(inputShape.slice(lastIndicesDimension)); + const outputSize = ShapeUtil2.size(outputShape); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: sliceSize }, + ...createTensorShapeVariables(inputs[0].dims, inputSliceOffsets.dims, outputShape) + ]; + const getShaderSource = (shaderHelper) => { + const input = inputVariable("data", inputs[0].dataType, inputs[0].dims.length); + const indices = inputVariable("slice_offsets", 12 /* uint32 */, inputSliceOffsets.dims.length); + const output = outputVariable("output", inputs[0].dataType, outputShape.length); + return ` + ${shaderHelper.registerUniform("output_size", "u32").registerUniform("slice_size", "u32").declareVariables(input, indices, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let slice_offset = slice_offsets[global_idx / uniforms.slice_size]; + output[global_idx] = data[u32(slice_offset) + global_idx % uniforms.slice_size]; + }`; + }; + context.compute( + { + name: "GatherND", + shaderCache: { hint: attributes.cacheKey, inputDependencies: ["rank", "rank"] }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }, + { inputs: [inputs[0], inputSliceOffsets] } + ); + }; + parseGatherNDAttributes = (attributes) => { + const batchDims = attributes.batch_dims; + return { + batchDims, + cacheKey: "" + }; + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/gather-block-quantized.ts + var validateInputs38, createGatherBlockQuantizedProgramInfo, gatherBlockQuantized, parseGatherBlockQuantizedAttributes; + var init_gather_block_quantized = __esm({ + "web/lib/wasm/jsep/webgpu/ops/gather-block-quantized.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs38 = (inputs, attributes) => { + if (inputs.length < 3 || inputs.length > 4) { + throw new Error("GatherBlockQuantized requires 3 or 4 inputs."); + } + const quantizeAxis = ShapeUtil2.normalizeAxis(attributes.quantizeAxis, inputs[0].dims.length); + const blockSize = attributes.blockSize; + const data = inputs[0]; + const scales = inputs[2]; + const zeroPoint = inputs.length === 4 ? inputs[3] : void 0; + if (scales.dims.length !== data.dims.length || !data.dims.map((d, i) => i === quantizeAxis ? Math.ceil(d / blockSize) === scales.dims[i] : d === scales.dims[i]).reduce((a, b) => a && b, true)) { + throw new Error( + "Scales must have the same rank as the input tensor and the dims should match except on gatherAxis." + ); + } + if (zeroPoint) { + if (zeroPoint.dataType !== data.dataType) { + throw new Error("Zero point must have the same data type as the input tensor."); + } + if (zeroPoint.dims.length !== scales.dims.length || !zeroPoint.dims.map((d, i) => d === scales.dims[i]).reduce((a, b) => a && b, true)) { + throw new Error( + "Zero point must have the same rank as the input tensor and the dims should match except on quantizeAxis." + ); + } + } + }; + createGatherBlockQuantizedProgramInfo = (inputs, attributes) => { + const inputShape = inputs[0].dims; + const indicesShape = inputs[1].dims; + const inputRank = inputShape.length; + const gatherAxis = ShapeUtil2.normalizeAxis(attributes.gatherAxis, inputRank); + const quantizeAxis = ShapeUtil2.normalizeAxis(attributes.quantizeAxis, inputRank); + const outputShape = inputShape.slice(0); + outputShape.splice(gatherAxis, 1, ...indicesShape); + const outputSize = ShapeUtil2.size(outputShape); + const outputType = inputs[2].dataType; + const inputType = inputs[0].dataType; + const isSigned = inputType === 22 /* int4 */; + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: quantizeAxis }, + { type: 12 /* uint32 */, data: gatherAxis }, + { type: 12 /* uint32 */, data: attributes.blockSize }, + ...createTensorShapeVariables(...inputs.map((input, _) => input.dims), outputShape) + ]; + const getShaderSource = (shaderHelper) => { + const data = inputVariable("data", inputs[0].dataType, inputs[0].dims.length); + const indices = inputVariable("inputIndices", inputs[1].dataType, inputs[1].dims.length); + const scales = inputVariable("scales", inputs[2].dataType, inputs[2].dims.length); + const zeroPoint = inputs.length > 3 ? inputVariable("zeroPoint", inputs[3].dataType, inputs[3].dims.length) : void 0; + const output = outputVariable("output", outputType, outputShape.length); + const inputVariables = [data, indices, scales]; + if (zeroPoint) { + inputVariables.push(zeroPoint); + } + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "quantize_axis", type: "u32" }, + { name: "gather_axis", type: "u32" }, + { name: "block_size", type: "u32" } + ]; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} + ${shaderHelper.mainStart()} + let output_indices = ${output.offsetToIndices("global_idx")}; + var indices_indices = ${indices.type.indices}(0); + ${(() => { + if (indicesShape.length > 1) { + return ` + for (var i: u32 = 0; i < ${indicesShape.length}; i++) { + let index = ${output.indicesGet("output_indices", "uniforms.gather_axis + i")}; + ${indices.indicesSet("indices_indices", "i", "index")}; + }`; + } else { + return `indices_indices = ${output.indicesGet("output_indices", "uniforms.gather_axis")};`; + } + })()}; + var data_indices = ${data.type.indices}(0); + for (var i: u32 = 0; i < uniforms.gather_axis; i++) { + let index = ${output.indicesGet("output_indices", "i")}; + ${data.indicesSet("data_indices", "i", "index")}; + } + var index_from_indices = ${indices.getByIndices("indices_indices")}; + if (index_from_indices < 0) { + index_from_indices += ${inputShape[gatherAxis]}; + } + ${data.indicesSet("data_indices", "uniforms.gather_axis", "u32(index_from_indices)")}; + for (var i = uniforms.gather_axis + 1; i < ${outputShape.length}; i++) { + let index = ${output.indicesGet("output_indices", `i + ${indicesShape.length} - 1`)}; + ${data.indicesSet("data_indices", "i", "index")}; + } + let data_offset = ${data.indicesToOffset("data_indices")}; + let data_index = data_offset % 8; + // Convert 4-bit packed data to 8-bit packed data. + let packed_4bit_quantized_data = ${data.getByOffset("data_offset / 8")}; + let packed_8bit_quantized_data = (packed_4bit_quantized_data >> (4 * (data_index % 2))) & 0x0f0f0f0f; + let quantized_data_vec = ${isSigned ? "unpack4xI8" : "unpack4xU8"}(u32(packed_8bit_quantized_data)); + let quantized_data = quantized_data_vec[data_index / 2]; + var scale_indices = data_indices; + let quantize_axis_index = ${scales.indicesGet("data_indices", "uniforms.quantize_axis")} / uniforms.block_size; + ${scales.indicesSet("scale_indices", "uniforms.quantize_axis", "quantize_axis_index")}; + var scale = ${scales.getByIndices("scale_indices")}; + ${(() => { + if (!zeroPoint) { + return "var zero_point = 0"; + } else { + return ` + let zero_point_indices = scale_indices; + let zero_point_offset = ${zeroPoint.indicesToOffset("zero_point_indices")}; + let zero_point_index = zero_point_offset % 8; + let packed_4bit_zero_points = ${zeroPoint.getByOffset("zero_point_offset / 8")}; + let packed_8bit_zero_points = (packed_4bit_zero_points >> (4 * (zero_point_index % 2))) & 0x0f0f0f0f; + let zero_point_vec = ${isSigned ? "unpack4xI8" : "unpack4xU8"}(u32(packed_8bit_zero_points)); + let zero_point = zero_point_vec[zero_point_index / 2];`; + } + })()}; + let dequantized_data = ${tensorTypeToWsglValueType(outputType)}(quantized_data - zero_point) * scale; + ${output.setByOffset("global_idx", "dequantized_data")}; + }`; + }; + return { + name: "GatherBlockQuantized", + shaderCache: { + hint: `${attributes.cacheKey};${inputs.filter((_, i) => i !== 1).map((input) => input.dims.join("_")).join(";")}`, + inputDependencies: Array.from({ length: inputs.length }, (_v, _i) => "rank") + }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: outputType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + gatherBlockQuantized = (context, attributes) => { + const inputs = context.inputs; + validateInputs38(inputs, attributes); + context.compute(createGatherBlockQuantizedProgramInfo(context.inputs, attributes)); + }; + parseGatherBlockQuantizedAttributes = (attributes) => createAttributeWithCacheKey2({ + blockSize: attributes.blockSize, + gatherAxis: attributes.gatherAxis, + quantizeAxis: attributes.quantizeAxis + }); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/gather-elements.ts + var validateInputs39, createGatherElementsProgramInfo, parseGatherElementsAttributes, gatherElements; + var init_gather_elements = __esm({ + "web/lib/wasm/jsep/webgpu/ops/gather-elements.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs39 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("GatherElements requires 2 inputs."); + } + if (inputs[0].dims.length < 1) { + throw new Error("GatherElements requires that the data input be rank >= 1."); + } + if (inputs[0].dims.length !== inputs[1].dims.length) { + throw new Error(`GatherElements requires that the data input and + indices input tensors be of same rank.`); + } + }; + createGatherElementsProgramInfo = (inputs, attributes) => { + const inputShape = inputs[0].dims; + const inputOutputDataType = inputs[0].dataType; + const inputRank = inputShape.length; + const indicesShape = inputs[1].dims; + const indicesDataType = inputs[1].dataType; + const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputRank); + const axisDimLimit = inputShape[axis]; + const outputShape = indicesShape.slice(0); + const outputSize = ShapeUtil2.size(outputShape); + const input = inputVariable("input", inputOutputDataType, inputRank); + const indices = inputVariable("indicesInput", indicesDataType, indicesShape.length); + const output = outputVariable("output", inputOutputDataType, outputShape.length); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 6 /* int32 */, data: axisDimLimit }, + { type: 12 /* uint32 */, data: axis } + ]; + programUniforms.push(...createTensorShapeVariables(inputShape, indicesShape, outputShape)); + const inputDependencies = ["rank", "rank"]; + const getShaderSource = (shaderHelper) => ` + ${shaderHelper.registerUniform("outputSize", "u32").registerUniform("axisDimLimit", "i32").registerUniform("axis", "u32").declareVariables(input, indices, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + + let outputIndices = ${output.offsetToIndices("global_idx")}; + + var idx = ${indices.getByOffset("global_idx")}; + if (idx < 0) { + idx = idx + uniforms.axisDimLimit; + } + var inputIndices = ${input.type.indices}(outputIndices); + ${input.indicesSet("inputIndices", "uniforms.axis", "u32(idx)")}; + let value = ${input.getByIndices("inputIndices")}; + + ${output.setByOffset("global_idx", "value")}; + }`; + return { + name: "GatherElements", + shaderCache: { inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + parseGatherElementsAttributes = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis }); + gatherElements = (context, attributes) => { + const inputs = context.inputs; + validateInputs39(inputs); + context.compute(createGatherElementsProgramInfo(context.inputs, attributes)); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/gemm.ts + var validateInputs40, createGemmProgramInfo2, parseGemmAttributes2, gemm2; + var init_gemm2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/gemm.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + validateInputs40 = (inputs) => { + if (!inputs) { + throw new Error("Input is missing"); + } + if (inputs.length < 2 || inputs.length > 3) { + throw new Error("Invaid input number."); + } + if (inputs.length === 3 && inputs[2].dims.length > 2) { + throw new Error("Invalid input shape of C"); + } + if (inputs[0].dataType !== inputs[1].dataType || inputs.length === 3 && inputs[0].dataType !== inputs[2].dataType) { + throw new Error("Input types are mismatched"); + } + }; + createGemmProgramInfo2 = (inputs, attributes) => { + const aShape = inputs[0].dims.slice(); + const bShape = inputs[1].dims.slice(); + const [M, N, K] = GemmUtil2.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"); + } + const tileSize = 16; + const numTileN = Math.ceil(N / tileSize); + const numTileM = Math.ceil(M / tileSize); + const useShared = true; + const outputSize = ShapeUtil2.size(outputShape); + const programUniforms = [ + { type: 12 /* uint32 */, data: useShared ? numTileN : outputSize }, + { type: 12 /* uint32 */, data: M }, + { type: 12 /* uint32 */, data: N }, + { type: 12 /* uint32 */, data: K }, + { type: 1 /* float */, data: attributes.alpha }, + { type: 1 /* float */, data: attributes.beta } + ]; + const inputDependencies = ["type", "type"]; + if (inputs.length === 3) { + programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); + inputDependencies.push("rank"); + } + programUniforms.push(...createTensorShapeVariables(outputShape)); + const getShaderSource = (shaderHelper) => { + let line = ""; + if (attributes.transA && attributes.transB) { + line = "value += a[k * uniforms.M + m] * b[n * uniforms.K + k];"; + } else if (attributes.transA && !attributes.transB) { + line = "value += a[k * uniforms.M + m] * b[k * uniforms.N + n];"; + } else if (!attributes.transA && attributes.transB) { + line = "value += a[m * uniforms.K + k] * b[n * uniforms.K + k];"; + } else if (!attributes.transA && !attributes.transB) { + line = "value += a[m * uniforms.K + k] * b[k * uniforms.N + n];"; + } + const calculateAlpha = attributes.alpha === 1 ? "" : "value *= uniforms.alpha;"; + const a = inputVariable("a", inputs[0].dataType, inputs[0].dims); + const b = inputVariable("b", inputs[1].dataType, inputs[1].dims); + const dataType = a.type.value; + let c = null; + const variables = [a, b]; + if (inputs.length === 3) { + c = inputVariable("c", inputs[2].dataType, inputs[2].dims.length); + variables.push(c); + } + const output = outputVariable("output", inputs[0].dataType, outputShape.length); + variables.push(output); + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "M", type: "u32" }, + { name: "N", type: "u32" }, + { name: "K", type: "u32" }, + { name: "alpha", type: "f32" }, + { name: "beta", type: "f32" } + ]; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(...variables)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + + let m = global_idx / uniforms.N; + let n = global_idx % uniforms.N; + + var value = ${dataType}(0); + for (var k: u32 = 0u; k < uniforms.K; k++) { + ${line} + } + + ${calculateAlpha} + ${(() => { + if (c != null) { + return `let cOffset = ${c.broadcastedIndicesToOffset("vec2(m, n)", output)}; value += ${dataType}(uniforms.beta) * ${c.getByOffset("cOffset")};`; + } + return ""; + })()} + output[global_idx] = value; + }`; + }; + const getShaderSourceShared = (shaderHelper) => { + const a = inputVariable("a", inputs[0].dataType, inputs[0].dims); + const b = inputVariable("b", inputs[1].dataType, inputs[1].dims); + let c = null; + const variables = [a, b]; + if (inputs.length === 3) { + c = inputVariable("c", inputs[2].dataType, inputs[2].dims.length); + variables.push(c); + } + const output = outputVariable("output", inputs[0].dataType, outputShape.length); + variables.push(output); + const uniforms = [ + { name: "num_tile_n", type: "u32" }, + { name: "M", type: "u32" }, + { name: "N", type: "u32" }, + { name: "K", type: "u32" }, + { name: "alpha", type: "f32" }, + { name: "beta", type: "f32" } + ]; + let calcResult = ""; + let fillWorkgroupMemory = ""; + if (attributes.transA && attributes.transB) { + fillWorkgroupMemory = ` + var col = tile_row_start + local_id.x; + var row = k_start + local_id.y; + if (col < uniforms.M && row < uniforms.K) { + tile_a[local_id.y][local_id.x] = a[row * uniforms.M + col]; + } else { + tile_a[local_id.y][local_id.x] = ${a.type.value}(0); + } + + col = k_start + local_id.x; + row = tile_col_start + local_id.y; + if (col < uniforms.K && row < uniforms.N) { + tile_b[local_id.y][local_id.x] = b[row * uniforms.K + col]; + } else { + tile_b[local_id.y][local_id.x] = ${b.type.value}(0); + } + `; + calcResult = `value += tile_a[k][local_id.y] * tile_b[local_id.x][k];`; + } else if (attributes.transA && !attributes.transB) { + fillWorkgroupMemory = ` + var col = tile_row_start + local_id.x; + var row = k_start + local_id.y; + if (col < uniforms.M && row < uniforms.K) { + tile_a[local_id.y][local_id.x] = a[row * uniforms.M + col]; + } else { + tile_a[local_id.y][local_id.x] = ${a.type.value}(0); + } + + col = tile_col_start + local_id.x; + row = k_start + local_id.y; + if (col < uniforms.N && row < uniforms.K) { + tile_b[local_id.y][local_id.x] = b[row * uniforms.N + col]; + } else { + tile_b[local_id.y][local_id.x] = ${b.type.value}(0); + } + `; + calcResult = `value += tile_a[k][local_id.y] * tile_b[k][local_id.x];`; + } else if (!attributes.transA && attributes.transB) { + fillWorkgroupMemory = ` + var col = k_start + local_id.x; + var row = tile_row_start + local_id.y; + if (col < uniforms.K && row < uniforms.M) { + tile_a[local_id.y][local_id.x] = a[row * uniforms.K + col]; + } else { + tile_a[local_id.y][local_id.x] = ${a.type.value}(0); + } + + col = k_start + local_id.x; + row = tile_col_start + local_id.y; + if (col < uniforms.K && row < uniforms.N) { + tile_b[local_id.y][local_id.x] = b[row * uniforms.K + col]; + } else { + tile_b[local_id.y][local_id.x] = ${b.type.value}(0); + } + `; + calcResult = `value += tile_a[local_id.y][k] * tile_b[local_id.x][k];`; + } else if (!attributes.transA && !attributes.transB) { + fillWorkgroupMemory = ` + var col = k_start + local_id.x; + var row = tile_row_start + local_id.y; + if (col < uniforms.K && row < uniforms.M) { + tile_a[local_id.y][local_id.x] = a[row * uniforms.K + col]; + } else { + tile_a[local_id.y][local_id.x] = ${a.type.value}(0); + } + + col = tile_col_start + local_id.x; + row = k_start + local_id.y; + if (col < uniforms.N && row < uniforms.K) { + tile_b[local_id.y][local_id.x] = b[row * uniforms.N + col]; + } else { + tile_b[local_id.y][local_id.x] = ${b.type.value}(0); + } + `; + calcResult = `value += tile_a[local_id.y][k] * tile_b[k][local_id.x];`; + } + const calculateAlpha = attributes.alpha === 1 ? "" : "value *= uniforms.alpha;"; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(...variables)} + var tile_a: array, ${tileSize}>; + var tile_b: array, ${tileSize}>; + ${shaderHelper.mainStart([tileSize, tileSize, 1])} + let tile_col_start = (workgroup_index % uniforms.num_tile_n) * ${tileSize}; + let tile_row_start = (workgroup_index / uniforms.num_tile_n) * ${tileSize}; + let num_tiles = (uniforms.K - 1) / ${tileSize} + 1; + var k_start = 0u; + var value = ${output.type.value}(0); + for (var t: u32 = 0u; t < num_tiles; t++) { + ${fillWorkgroupMemory} + k_start = k_start + ${tileSize}; + workgroupBarrier(); + + for (var k: u32 = 0u; k < ${tileSize}; k++) { + ${calcResult} + } + workgroupBarrier(); + } + + ${calculateAlpha} + let m = tile_row_start + local_id.y; + let n = tile_col_start + local_id.x; + ${(() => { + if (c != null) { + return `let cOffset = ${c.broadcastedIndicesToOffset("vec2(m, n)", output)}; value += ${output.type.value}(uniforms.beta) * ${c.getByOffset("cOffset")};`; + } + return ""; + })()} + if (m < uniforms.M && n < uniforms.N) { + output[m * uniforms.N + n] = value; + } + }`; + }; + if (useShared) { + return { + name: "GemmShared", + shaderCache: { hint: `${attributes.cacheKey}`, inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: numTileN * numTileM }, + programUniforms + }), + getShaderSource: getShaderSourceShared + }; + } + return { + name: "Gemm", + shaderCache: { hint: `${attributes.cacheKey}`, inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + parseGemmAttributes2 = (attributes) => { + const transA = attributes.transA; + const transB = attributes.transB; + const alpha = attributes.alpha; + const beta = attributes.beta; + return { + transA, + transB, + alpha, + beta, + cacheKey: `${attributes.transA};${attributes.transB};${attributes.alpha === 1}` + }; + }; + gemm2 = (context, attributes) => { + validateInputs40(context.inputs); + context.compute(createGemmProgramInfo2(context.inputs, attributes)); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/grid-sample.ts + var idxN, idxC, idxH, idxW, validateInputs41, gsGetCubicCoeffs, gsBicubicInterpolate, gsDenormalize, gsReflect, pixelAtGrid, computePixel, createGridSampleProgramInfo, gridSample, parseGridSampleAttributes; + var init_grid_sample = __esm({ + "web/lib/wasm/jsep/webgpu/ops/grid-sample.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + [idxN, idxC, idxH, idxW] = [0, 1, 2, 3]; + validateInputs41 = (inputs) => { + if (inputs[0].dims.length !== 4) { + throw new Error("only 4-D tensor is supported."); + } + if (inputs[0].dims.length !== inputs[1].dims.length) { + throw new Error("input dimensions must be equal to grid dimensions"); + } + if (inputs[0].dims.length - 2 !== inputs[1].dims[inputs[1].dims.length - 1]) { + throw new Error(`last dimension of grid must be equal to ${inputs[0].dims.length - 2}`); + } + if (inputs[0].dims[0] !== inputs[1].dims[0]) { + throw new Error("grid batch size must match input batch size"); + } + }; + gsGetCubicCoeffs = ` + fn gs_get_cubic_coeffs(x: f32) -> vec4 { + let cubic_alpha = -0.75f; + let x_abs = abs(x); + var coeffs: vec4; + coeffs[0] = (((cubic_alpha * (x_abs + 1) - 5 * cubic_alpha) * (x_abs + 1) + 8 * cubic_alpha) * (x_abs + 1) - 4 * cubic_alpha); + coeffs[1] = (((cubic_alpha + 2) * x_abs - (cubic_alpha + 3)) * x_abs * x_abs + 1); + coeffs[2] = (((cubic_alpha + 2) * (1 - x_abs) - (cubic_alpha + 3)) * (1 - x_abs) * (1 - x_abs) + 1); + coeffs[3] = (((cubic_alpha * (2 - x_abs) - 5 * cubic_alpha) * (2 - x_abs) + 8 * cubic_alpha) * (2 - x_abs) - 4 * cubic_alpha); + return coeffs; + } +`; + gsBicubicInterpolate = (dataType) => ` + fn gs_bicubic_interpolate(p: mat4x4<${dataType}>, x: f32, y: f32) -> ${dataType} { + var v: vec4; + var coeffs = gs_get_cubic_coeffs(x); + for (var i = 0; i < 4; i++) { + v[i] = coeffs[0] * p[i][0] + coeffs[1] * p[i][1] + coeffs[2] * p[i][2] + coeffs[3] * p[i][3]; + } + coeffs = gs_get_cubic_coeffs(y); + let pixel = ${dataType}(coeffs[0] * v[0] + coeffs[1] * v[1] + coeffs[2] * v[2] + coeffs[3] * v[3]); + return pixel; + } +`; + gsDenormalize = (attributes) => ` + fn gs_denormalize(n: f32, length: i32) -> f32 { + ${attributes.alignCorners === 0 ? ` + // alignCorners: false => [-1, 1] to [-0.5, length - 0.5] + return ((n + 1.0) * f32(length) - 1.0) / 2.0; + ` : ` + // alignCorners: true => [-1, 1] to [0, length - 1] + return (n + 1.0) / 2.0 * (f32(length - 1)); + `} + } +`; + gsReflect = (attributes) => ` + ${attributes.paddingMode === "reflection" ? ` + fn gs_reflect(x: i32, x_min: f32, x_max: f32) -> u32 { + var dx = 0.0; + var fx = f32(x); + let range = x_max - x_min; + if (fx < x_min) { + dx = x_min - fx; + let n = u32(dx / range); + let r = dx - f32(n) * range; + if (n % 2 == 0) { + fx = x_min + r; + } else { + fx = x_max - r; + } + } else if (fx > x_max) { + dx = fx - x_max; + let n = u32(dx / range); + let r = dx - f32(n) * range; + if (n % 2 == 0) { + fx = x_max - r; + } else { + fx = x_min + r; + } + } + return u32(fx); + }` : ""} +`; + pixelAtGrid = (input, dataType, attributes) => ` + fn pixel_at_grid(r: i32, c: i32, H: i32, W: i32, batch: u32, channel: u32, border: vec4) -> ${dataType} { + var pixel = ${dataType}(0); + var indices = vec4(0); + indices[${idxN}] = batch; + indices[${idxC}] = channel;` + (() => { + switch (attributes.paddingMode) { + case "zeros": + return ` + if (r >= 0 && r < H && c >=0 && c < W) { + indices[${idxH}] = u32(r); + indices[${idxW}] = u32(c); + } else { + return ${dataType}(0); + } + `; + case "border": + return ` + indices[${idxH}] = u32(clamp(r, 0, H - 1)); + indices[${idxW}] = u32(clamp(c, 0, W - 1)); + `; + case "reflection": + return ` + indices[${idxH}] = gs_reflect(r, border[1], border[3]); + indices[${idxW}] = gs_reflect(c, border[0], border[2]); + `; + default: + throw new Error(`padding mode ${attributes.paddingMode} is not supported`); + } + })() + ` + return ${input.getByIndices("indices")}; + } +`; + computePixel = (output, dataType, attributes) => (() => { + switch (attributes.mode) { + case "nearest": + return ` + let result = pixel_at_grid(i32(round(y)), i32(round(x)), H_in, W_in, indices[${idxN}], indices[${idxC}], border); + `; + case "bilinear": + return ` + let x1 = i32(floor(x)); + let y1 = i32(floor(y)); + let x2 = x1 + 1; + let y2 = y1 + 1; + + let p11 = pixel_at_grid(y1, x1, H_in, W_in, indices[${idxN}], indices[${idxC}], border); + let p12 = pixel_at_grid(y1, x2, H_in, W_in, indices[${idxN}], indices[${idxC}], border); + let p21 = pixel_at_grid(y2, x1, H_in, W_in, indices[${idxN}], indices[${idxC}], border); + let p22 = pixel_at_grid(y2, x2, H_in, W_in, indices[${idxN}], indices[${idxC}], border); + + let dx2 = ${dataType}(f32(x2) - x); + let dx1 = ${dataType}(x - f32(x1)); + let dy2 = ${dataType}(f32(y2) - y); + let dy1 = ${dataType}(y - f32(y1)); + let result = dy2 * (dx2 * p11 + dx1 * p12) + dy1 * (dx2 * p21 + dx1 * p22); + `; + case "bicubic": + return ` + let x0 = i32(floor(x)) - 1; + let y0 = i32(floor(y)) - 1; + var p: mat4x4<${dataType}>; + for (var h = 0; h < 4; h++) { + for (var w = 0; w < 4; w++) { + p[h][w] = pixel_at_grid(h + y0, w + x0, H_in, W_in, indices[${idxN}], indices[${idxC}], border); + } + } + + let dx = x - f32(x0 + 1); + let dy = y - f32(y0 + 1); + let result = gs_bicubic_interpolate(p, dx, dy); + `; + default: + throw new Error(`mode ${attributes.mode} is not supported`); + } + })() + `${output.setByOffset("global_idx", "result")}`; + createGridSampleProgramInfo = (inputs, attributes) => { + const x = inputVariable("x", inputs[0].dataType, inputs[0].dims.length); + const gridShape = [inputs[1].dims[0], inputs[1].dims[1], inputs[1].dims[2]]; + const grid = inputVariable("grid", inputs[1].dataType, gridShape.length, 2); + let outputShape = [inputs[0].dims[0], inputs[0].dims[1], inputs[1].dims[1], inputs[1].dims[2]]; + if (attributes.format === "NHWC") { + outputShape = [inputs[0].dims[0], inputs[1].dims[1], inputs[1].dims[2], inputs[0].dims[3]]; + [idxN, idxC, idxH, idxW] = [0, 3, 1, 2]; + } + const output = outputVariable("output", inputs[0].dataType, outputShape.length); + const dataType = x.type.value; + const outputSize = ShapeUtil2.size(outputShape); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + ...createTensorShapeVariables(inputs[0].dims, gridShape, outputShape) + ]; + const getShaderSource = (shaderHelper) => ` + ${shaderHelper.registerUniform("output_size", "u32").declareVariables(x, grid, output)} + ${gsGetCubicCoeffs} + ${gsBicubicInterpolate(dataType)} + ${gsDenormalize(attributes)} + ${gsReflect(attributes)} + ${pixelAtGrid(x, dataType, attributes)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let H_in = i32(uniforms.x_shape[${idxH}]); + let W_in = i32(uniforms.x_shape[${idxW}]); + + ${attributes.alignCorners === 0 ? ` + let x_min = -0.5; + let x_max = f32(W_in) - 0.5; + let y_min = -0.5; + let y_max = f32(H_in) - 0.5; + ` : ` + let x_min = 0.0; + let x_max = f32(W_in) - 1.0; + let y_min = 0.0; + let y_max = f32(H_in) - 1.0; + `}; + let border = vec4(x_min, y_min, x_max, y_max); + + let indices = ${output.offsetToIndices("global_idx")}; + var grid_indices = vec3(indices[${idxN}], indices[${idxH}], indices[${idxW}]); + let nxy = ${grid.getByIndices("grid_indices")}; + var x = gs_denormalize(f32(nxy[0]), W_in); + var y = gs_denormalize(f32(nxy[1]), H_in); + + ${computePixel(output, dataType, attributes)} + }`; + return { + name: "GridSample", + shaderCache: { hint: `${attributes.cacheKey}`, inputDependencies: ["type", "type"] }, + getRunData: (inputs2) => { + const outputSize2 = ShapeUtil2.size(outputShape); + return { + outputs: [{ dims: outputShape, dataType: inputs2[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize2 / 64 + /* workgroup size */ + ) }, + programUniforms + }; + }, + getShaderSource + }; + }; + gridSample = (context, attributes) => { + validateInputs41(context.inputs); + context.compute(createGridSampleProgramInfo(context.inputs, attributes)); + }; + parseGridSampleAttributes = (attributes) => createAttributeWithCacheKey2({ + alignCorners: attributes.align_corners, + mode: attributes.mode, + paddingMode: attributes.padding_mode, + format: attributes.format + }); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/multihead-attention.ts + var getInput, validateInputs42, parseMultiHeadAttentionAttributes, weightTransposeAttribute2, addBiasTranspose, maybeTransposeToBNSHAndAddBias, multiHeadAttention; + var init_multihead_attention = __esm({ + "web/lib/wasm/jsep/webgpu/ops/multihead-attention.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_types2(); + init_attention(); + init_common(); + init_transpose2(); + getInput = (inputs, i) => inputs.length > i && inputs[i].dims.length > 0 ? inputs[i] : void 0; + validateInputs42 = (inputs, attributes) => { + const query = inputs[0]; + const key = getInput(inputs, 1); + const value = getInput(inputs, 2); + const bias = getInput(inputs, 3); + const keyPaddingMask = getInput(inputs, 4); + const attentionBias = getInput(inputs, 5); + const pastKey = getInput(inputs, 6); + const pastValue = getInput(inputs, 7); + if (query.dims.length !== 3 && query.dims.length !== 5) { + throw new Error("Input query is expected to have 3 or 5 dimensions"); + } + const batchSize = query.dims[0]; + const sequenceLength = query.dims[1]; + const hiddenSize = query.dims.length === 3 ? query.dims[2] : attributes.numHeads * query.dims[4]; + let kvSequenceLength = sequenceLength; + let pastSequenceLength = 0; + let maxSequenceLength = 0; + const headSize = Math.floor(hiddenSize / attributes.numHeads); + if (pastKey && pastValue && ShapeUtil2.size(pastKey.dims) && ShapeUtil2.size(pastValue.dims)) { + if (pastKey.dims.length !== 4) { + throw new Error('Input "past_key" is expected to have 4 dimensions'); + } + if (pastKey.dims[0] !== batchSize || pastKey.dims[1] !== attributes.numHeads || pastKey.dims[3] !== headSize) { + throw new Error('Input "past_key" shape (batch_size, num_heads, past_sequence_length, head_size)'); + } + if (pastValue.dims[0] !== batchSize || pastValue.dims[1] !== attributes.numHeads || pastValue.dims[3] !== headSize) { + throw new Error('Input "past_value" shape (batch_size, num_heads, past_sequence_length, head_size)'); + } + if (pastKey.dims[2] !== pastValue.dims[2]) { + throw new Error('Input "past_key" and "past_value" shall have same dim 2 (past_sequence_length)'); + } + if (pastValue.dims.length !== 4) { + throw new Error('Input "past_value" is expected to have 4 dimensions'); + } + pastSequenceLength = pastKey.dims[2]; + maxSequenceLength = pastKey.dims[2]; + } else if (pastKey && ShapeUtil2.size(pastKey.dims) || pastValue && ShapeUtil2.size(pastValue.dims)) { + throw new Error('Input "past_key" and "past_value" shall be both present or both absent'); + } + let qkvFormat; + if (key && ShapeUtil2.size(key.dims) > 0) { + if (query.dims.length !== 3) { + throw new Error('Input "query" is expected to have 3 dimensions when key is given'); + } + if (key.dims.length < 3 || key.dims.length > 5) { + throw new Error('Input "key" is expected to have 3, 4, or 5 dimensions'); + } + if (query.dims[0] !== key.dims[0]) { + throw new Error('Input "query" and "key" shall have same dim 0 (batch size)'); + } + if (key.dims.length === 3) { + if (key.dims[2] !== query.dims[2]) { + throw new Error('Input "query" and "key" shall have same dim 2 (hidden_size)'); + } + qkvFormat = 2 /* qkvBSNH */; + kvSequenceLength = key.dims[1]; + } else if (key.dims.length === 5) { + if (key.dims[2] !== attributes.numHeads || key.dims[3] !== 2 || key.dims[4] !== headSize) { + throw new Error('Expect "key" shape (batch_size, kv_sequence_length, num_heads, 2, head_size) for packed kv'); + } + if (value) { + throw new Error('Expect "value" be none when "key" has packed kv format.'); + } + qkvFormat = 5 /* qKvBSNHxBSN2H */; + kvSequenceLength = key.dims[1]; + } else { + if (key.dims[1] !== attributes.numHeads || key.dims[3] !== headSize) { + throw new Error('Expect "key" shape (batch_size, num_heads, kv_sequence_length, head_size) for past_key'); + } + qkvFormat = 0 /* unknown */; + kvSequenceLength = key.dims[2]; + } + } else { + if (query.dims.length !== 5) { + throw new Error('Input "query" is expected to have 5 dimensions when key is empty'); + } + if (query.dims[2] !== attributes.numHeads || query.dims[3] !== 3) { + throw new Error('Expect "query" shape (batch_size, kv_sequence_length, num_heads, 3, head_size) for packed kv'); + } + qkvFormat = 3 /* qkvBSN3H */; + } + if (bias && ShapeUtil2.size(bias.dims) > 0) { + if (bias.dims.length !== 1) { + throw new Error('Input "bias" is expected to have 1 dimension'); + } + if (key) { + if (key.dims.length === 5 && key.dims[3] === 2) { + throw new Error("bias is not allowed for packed kv."); + } + } + } + const totalSequenceLength = pastSequenceLength + kvSequenceLength; + let maskType = 0 /* none */; + if (keyPaddingMask && ShapeUtil2.size(keyPaddingMask.dims) > 0) { + maskType = 8 /* maskUnknown */; + const maskDims = keyPaddingMask.dims; + if (maskDims.length === 1) { + if (maskDims[0] === batchSize) { + maskType = 1 /* mask1dKeySeqLen */; + } else if (maskDims[0] === 3 * batchSize + 2) { + maskType = 3 /* mask1DKeySeqLenStart */; + } + } else if (maskDims.length === 2 && maskDims[0] === batchSize && maskDims[1] === totalSequenceLength) { + maskType = 5 /* mask2dKeyPadding */; + } + if (maskType === 8 /* maskUnknown */) { + throw new Error('Input "key_padding_mask" shape shall be (batch_size) or (batch_size, total_sequence_length)'); + } + throw new Error("Mask not supported"); + } + let passPastInKv = false; + let vHiddenSize = hiddenSize; + if (value && ShapeUtil2.size(value.dims) > 0) { + if (value.dims.length !== 3 && value.dims.length !== 4) { + throw new Error('Input "value" is expected to have 3 or 4 dimensions'); + } + if (query.dims[0] !== value.dims[0]) { + throw new Error('Input "query" and "value" shall have same dim 0 (batch_size)'); + } + if (value.dims.length === 3) { + if (kvSequenceLength !== value.dims[1]) { + throw new Error('Input "key" and "value" shall have the same dim 1 (kv_sequence_length)'); + } + vHiddenSize = value.dims[2]; + } else { + if (kvSequenceLength !== value.dims[2]) { + throw new Error('Input "key" and "value" shall have the same dim 2 (kv_sequence_length)'); + } + vHiddenSize = value.dims[1] * value.dims[3]; + passPastInKv = true; + } + } + const broadcastResPosBias = false; + if (keyPaddingMask && ShapeUtil2.size(keyPaddingMask.dims) > 0) { + throw new Error("Key padding mask is not supported"); + } + if (attentionBias && ShapeUtil2.size(attentionBias.dims) > 0) { + if (attentionBias.dims.length !== 4) { + throw new Error('Input "attention_bias" is expected to have 4 dimensions'); + } + if (attentionBias.dims[0] !== batchSize || attentionBias.dims[1] !== attributes.numHeads || attentionBias.dims[2] !== sequenceLength || attentionBias.dims[3] !== totalSequenceLength) { + throw new Error('Expect "attention_bias" shape (batch_size, num_heads, sequence_length, total_sequence_length)'); + } + } + return { + batchSize, + sequenceLength, + pastSequenceLength, + kvSequenceLength, + totalSequenceLength, + maxSequenceLength, + inputHiddenSize: 0, + hiddenSize, + vHiddenSize, + headSize, + vHeadSize: Math.floor(vHiddenSize / attributes.numHeads), + numHeads: attributes.numHeads, + isUnidirectional: false, + pastPresentShareBuffer: false, + maskFilterValue: attributes.maskFilterValue, + maskType, + scale: attributes.scale, + broadcastResPosBias, + passPastInKv, + qkvFormat + }; + }; + parseMultiHeadAttentionAttributes = (attributes) => createAttributeWithCacheKey2({ ...attributes }); + weightTransposeAttribute2 = createAttributeWithCacheKey2({ perm: [0, 2, 1, 3] }); + addBiasTranspose = (context, qkv, bias, batchSize, sequenceLength, hiddenSize, biasOffset) => { + const outputShape = [batchSize, sequenceLength, hiddenSize]; + const outputSize = ShapeUtil2.size(outputShape); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: biasOffset }, + { type: 12 /* uint32 */, data: hiddenSize } + ]; + const getShaderSource = (shaderHelper) => { + const output = outputVariable("qkv_with_bias", qkv.dataType, outputShape); + const qkvInput = inputVariable("qkv", qkv.dataType, outputShape); + const biasInput = inputVariable("bias", bias.dataType, outputShape); + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "bias_offset", type: "u32" }, + { name: "hidden_size", type: "u32" } + ]; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(qkvInput, biasInput, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let bias_offset_idx = (global_idx % uniforms.hidden_size) + uniforms.bias_offset; + + qkv_with_bias[global_idx] = qkv[global_idx] + bias[bias_offset_idx]; + }`; + }; + return context.compute( + { + name: "MultiHeadAttentionAddBias", + shaderCache: { inputDependencies: ["type", "type"] }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: qkv.dataType, gpuDataType: 0 /* default */ }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }, + { inputs: [qkv, bias], outputs: [-1] } + )[0]; + }; + maybeTransposeToBNSHAndAddBias = (context, batchSize, numHeads, sequenceLength, headSize, input, bias, biasOffset) => { + let reshapedInput = input; + if (!(bias && ShapeUtil2.size(bias.dims) > 0)) { + if (input.dims.length === 3) { + reshapedInput = input.reshape([batchSize, sequenceLength, numHeads, headSize]); + } + if (numHeads === 1 || sequenceLength === 1) { + return reshapedInput; + } + return context.compute(createTransposeProgramInfo2(reshapedInput, weightTransposeAttribute2.perm), { + inputs: [reshapedInput], + outputs: [-1] + })[0]; + } else { + if (sequenceLength === 1) { + throw new Error("AddBiasReshape is not implemented. Please export your model with packed QKV or KV"); + } else { + reshapedInput = addBiasTranspose( + context, + input, + bias, + batchSize, + sequenceLength, + numHeads * headSize, + biasOffset + ); + reshapedInput = reshapedInput.reshape([batchSize, sequenceLength, numHeads, headSize]); + if (numHeads === 1 || sequenceLength === 1) { + return reshapedInput; + } + return context.compute(createTransposeProgramInfo2(reshapedInput, weightTransposeAttribute2.perm), { + inputs: [reshapedInput], + outputs: [-1] + })[0]; + } + } + }; + multiHeadAttention = (context, attributes) => { + const params = validateInputs42(context.inputs, attributes); + const query = context.inputs[0]; + const key = getInput(context.inputs, 1); + const value = getInput(context.inputs, 2); + const bias = getInput(context.inputs, 3); + const keyPaddingMask = getInput(context.inputs, 4); + const attentionBias = getInput(context.inputs, 5); + const pastKey = getInput(context.inputs, 6); + const pastValue = getInput(context.inputs, 7); + if (query.dims.length === 5) { + throw new Error("Packed QKV is not implemented"); + } + if (key?.dims.length === 5) { + throw new Error("Packed KV is not implemented"); + } + const kvBNSH = key && value && key.dims.length === 4 && value.dims.length === 4; + const Q = maybeTransposeToBNSHAndAddBias( + context, + params.batchSize, + params.numHeads, + params.sequenceLength, + params.headSize, + query, + bias, + 0 + ); + if (kvBNSH) { + return applyAttention(context, Q, key, value, keyPaddingMask, void 0, pastKey, pastValue, attentionBias, params); + } + if (!key || !value) { + throw new Error("key and value must be provided"); + } + const K = maybeTransposeToBNSHAndAddBias( + context, + params.batchSize, + params.numHeads, + params.kvSequenceLength, + params.headSize, + key, + bias, + params.hiddenSize + ); + const V = maybeTransposeToBNSHAndAddBias( + context, + params.batchSize, + params.numHeads, + params.kvSequenceLength, + params.vHeadSize, + value, + bias, + 2 * params.hiddenSize + ); + applyAttention(context, Q, K, V, keyPaddingMask, void 0, pastKey, pastValue, attentionBias, params); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/split.ts + var validateInputs43, createSplitAttributesFromInputs, calculateOutputIndexImpl, writeBufferDataImpl, createSplitProgramInfo2, split2, parseSplitAttributes2; + var init_split2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/split.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs43 = (inputs) => { + if (!inputs || inputs.length < 1) { + throw new Error("too few inputs"); + } + }; + createSplitAttributesFromInputs = (inputs, attributes) => { + const splitSizes = []; + let numOutputs = attributes.numOutputs; + if (inputs[1].dims[0] > 0) { + inputs[1].getBigInt64Array().forEach((v) => splitSizes.push(Number(v))); + numOutputs = splitSizes.length; + } + return createAttributeWithCacheKey2({ numOutputs, axis: attributes.axis, splitSizes }); + }; + calculateOutputIndexImpl = (numberOfTensors) => ` +fn calculateOutputIndex(index: u32) -> u32 { + for (var i: u32 = 0u; i < ${numberOfTensors}u; i += 1u ) { + if (index < ${getElementAt("uniforms.size_in_split_axis", "i", numberOfTensors)}) { + return i; + } + } + return ${numberOfTensors}u; +}`; + writeBufferDataImpl = (outputs) => { + const numberOfTensors = outputs.length; + const codeLines = []; + for (let i = 0; i < numberOfTensors; ++i) { + const returnSnippet = outputs[i].setByIndices("indices", "input[global_idx]"); + if (numberOfTensors === 1) { + codeLines.push(returnSnippet); + } else if (i === 0) { + codeLines.push(`if (output_number == ${i}u) { ${returnSnippet} }`); + } else if (i === numberOfTensors - 1) { + codeLines.push(`else { ${returnSnippet} }`); + } else { + codeLines.push(`else if (output_number == ${i}) { ${returnSnippet} }`); + } + } + return ` + fn writeBufferData(output_number: u32, indices: ${outputs[0].type.indices}, global_idx: u32) { + ${codeLines.join("\n")} + }`; + }; + createSplitProgramInfo2 = (inputs, attributes) => { + const inputShape = inputs[0].dims; + const inputSize = ShapeUtil2.size(inputShape); + const dataType = inputs[0].dataType; + const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputShape.length); + const outputs = new Array(attributes.numOutputs); + const input = inputVariable("input", dataType, inputShape.length); + const sizeInSplitAxis = new Array(attributes.numOutputs); + const outputsTensorInfo = []; + const outputShapes = []; + let previousSum = 0; + const programUniforms = [{ type: 12 /* uint32 */, data: inputSize }]; + for (let i = 0; i < attributes.numOutputs; i++) { + previousSum += attributes.splitSizes[i]; + sizeInSplitAxis[i] = previousSum; + const outputShape = inputShape.slice(); + outputShape[axis] = attributes.splitSizes[i]; + outputShapes.push(outputShape); + outputs[i] = outputVariable(`output${i}`, dataType, outputShape.length); + outputsTensorInfo.push({ dims: outputShapes[i], dataType: inputs[0].dataType }); + } + programUniforms.push( + { type: 12 /* uint32 */, data: sizeInSplitAxis }, + ...createTensorShapeVariables(inputShape, ...outputShapes) + ); + const getShaderSource = (shaderHelper) => ` + ${shaderHelper.registerUniform("input_size", "u32").registerUniform("size_in_split_axis", "u32", sizeInSplitAxis.length).declareVariables(input, ...outputs)} + ${calculateOutputIndexImpl(sizeInSplitAxis.length)} + ${writeBufferDataImpl(outputs)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.input_size")} + + var indices = ${input.offsetToIndices("global_idx")}; + var index = ${input.indicesGet("indices", axis)}; + let output_number = calculateOutputIndex(index); + if (output_number != 0) { + index -= ${getElementAt("uniforms.size_in_split_axis", "output_number - 1u", sizeInSplitAxis.length)}; + ${input.indicesSet("indices", axis, "index")}; + } + writeBufferData(output_number, indices, global_idx); + }`; + return { + name: "Split", + shaderCache: { hint: attributes.cacheKey, inputDependencies: ["rank"] }, + getShaderSource, + getRunData: () => ({ + outputs: outputsTensorInfo, + dispatchGroup: { x: Math.ceil( + inputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }) + }; + }; + split2 = (context, attributes) => { + validateInputs43(context.inputs); + const updatedAttributes = context.inputs.length === 1 ? attributes : createSplitAttributesFromInputs(context.inputs, attributes); + context.compute(createSplitProgramInfo2(context.inputs, updatedAttributes), { inputs: [0] }); + }; + parseSplitAttributes2 = (attributes) => { + const axis = attributes.axis; + const splitSizes = attributes.splitSizes; + const numOutputs = attributes.numOutputs < 0 ? splitSizes.length : attributes.numOutputs; + if (numOutputs !== splitSizes.length) { + throw new Error("numOutputs and splitSizes lengh must be equal"); + } + return createAttributeWithCacheKey2({ axis, numOutputs, splitSizes }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/rotary-embedding.ts + var validateInputs44, createRotaryEmbeddingProgramInfo, rotaryEmbedding; + var init_rotary_embedding = __esm({ + "web/lib/wasm/jsep/webgpu/ops/rotary-embedding.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs44 = (inputs, attributes) => { + const [input, positionIds, cosCache, sinCache] = inputs; + const { numHeads, rotaryEmbeddingDim } = attributes; + if (input.dims.length !== 3 && input.dims.length !== 4) { + throw new Error(`Input 'x' is expected to have 3 or 4 dimensions, got ${input.dims.length}`); + } + if (!ShapeUtil2.areEqual(positionIds.dims, []) && !ShapeUtil2.areEqual(positionIds.dims, [1]) && positionIds.dims.length !== 2) { + throw new Error(`Input 'position_ids' is expected to have 0, 1, or 2 dimensions, got ${positionIds.dims.length}`); + } + if (cosCache.dims.length !== 2) { + throw new Error(`Input 'cos_cache' is expected to have 2 dimensions, got ${cosCache.dims.length}`); + } + if (sinCache.dims.length !== 2) { + throw new Error(`Input 'sin_cache' is expected to have 2 dimensions, got ${sinCache.dims.length}`); + } + if (!ShapeUtil2.areEqual(cosCache.dims, sinCache.dims)) { + throw new Error("Inputs 'cos_cache' and 'sin_cache' are expected to have the same shape"); + } + if (rotaryEmbeddingDim > 0 && numHeads === 0) { + throw new Error("num_heads must be provided if rotary_embedding_dim is specified"); + } + const batchSize = input.dims[0]; + const sequenceLength = input.dims[input.dims.length - 2]; + const maxSequenceLength = cosCache.dims[0]; + const hiddenSize = ShapeUtil2.sizeFromDimension(input.dims, 1) / sequenceLength; + const headSize = rotaryEmbeddingDim === 0 ? cosCache.dims[1] * 2 : hiddenSize / numHeads; + if (rotaryEmbeddingDim > headSize) { + throw new Error("rotary_embedding_dim must be less than or equal to head_size"); + } + if (positionIds.dims.length === 2) { + if (batchSize !== positionIds.dims[0]) { + throw new Error(`Input 'position_ids' dimension 0 should be of size batch_size, got ${positionIds.dims[0]}`); + } + if (sequenceLength !== positionIds.dims[1]) { + throw new Error(`Input 'position_ids' dimension 1 should be of size sequence_length, got ${positionIds.dims[1]}`); + } + } + if (headSize / 2 !== cosCache.dims[1] && rotaryEmbeddingDim / 2 !== cosCache.dims[1]) { + throw new Error( + `Input 'cos_cache' dimension 1 should be same as head_size / 2 or rotary_embedding_dim / 2, got ${cosCache.dims[1]}` + ); + } + if (sequenceLength > maxSequenceLength) { + throw new Error("Updating cos_cache and sin_cache in RotaryEmbedding is not currently supported"); + } + }; + createRotaryEmbeddingProgramInfo = (inputs, attributes) => { + const { interleaved, numHeads, rotaryEmbeddingDim, scale } = attributes; + const batchSize = inputs[0].dims[0]; + const batchStride = ShapeUtil2.sizeFromDimension(inputs[0].dims, 1); + const sequenceLength = inputs[0].dims[inputs[0].dims.length - 2]; + const hiddenSize = batchStride / sequenceLength; + const halfRotaryEmbeddingDim = inputs[2].dims[1]; + const headSize = rotaryEmbeddingDim === 0 ? halfRotaryEmbeddingDim * 2 : hiddenSize / numHeads; + const globalShape = new Array( + batchSize, + sequenceLength, + hiddenSize / headSize, + headSize - halfRotaryEmbeddingDim + ); + const globalStrides = ShapeUtil2.computeStrides(globalShape); + const programUniforms = [ + { type: 1 /* float */, data: scale }, + { type: 12 /* uint32 */, data: globalShape }, + { type: 12 /* uint32 */, data: globalStrides }, + // strides for addressing the input/output tensor, in permutated order to align with the unfolded global index, + // i.e. BSNH + ...inputs[0].dims.length === 3 ? new Array({ type: 12 /* uint32 */, data: [batchStride, hiddenSize, headSize, 1] }) : [], + ...inputs[0].dims.length === 4 ? new Array({ + type: 12 /* uint32 */, + data: [batchStride, headSize, sequenceLength * headSize, 1] + }) : [], + ...createTensorShapeVariables(inputs[0].dims, inputs[1].dims, inputs[2].dims, inputs[3].dims, inputs[0].dims) + ]; + const getShaderSource = (shaderHelper) => { + const input = inputVariable("input", inputs[0].dataType, inputs[0].dims.length); + const positionIds = inputVariable("position_ids", inputs[1].dataType, inputs[1].dims.length); + const cosCache = inputVariable("cos_cache", inputs[2].dataType, inputs[2].dims.length); + const sinCache = inputVariable("sin_cache", inputs[3].dataType, inputs[3].dims.length); + const output = outputVariable("output", inputs[0].dataType, inputs[0].dims.length); + shaderHelper.registerUniforms([ + { name: "scale", type: "f32" }, + { name: "global_shape", type: "u32", length: globalShape.length }, + { name: "global_strides", type: "u32", length: globalStrides.length }, + { name: "input_output_strides", type: "u32", length: globalStrides.length } + ]); + return ` + ${shaderHelper.declareVariables(input, positionIds, cosCache, sinCache, output)} + + ${shaderHelper.mainStart(WORKGROUP_SIZE)} + let half_rotary_emb_dim = uniforms.${cosCache.name}_shape[1]; + let bsnh = global_idx / uniforms.global_strides % uniforms.global_shape; + let size = uniforms.global_shape[0] * uniforms.global_strides[0]; + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("size")} + + if (bsnh[3] < half_rotary_emb_dim) { + let position_ids_idx = + ${positionIds.broadcastedIndicesToOffset("bsnh.xy", outputVariable("", positionIds.type.tensor, 2))}; + let position_id = + u32(${positionIds.getByOffset("position_ids_idx")}) + select(0, bsnh[1], position_ids_idx == 0); + let i = dot(bsnh, uniforms.input_output_strides) + select(0, bsnh[3], ${interleaved}); + let j = i + select(half_rotary_emb_dim, 1, ${interleaved}); + let re = ${input.getByOffset("i")} * ${cosCache.get("position_id", "bsnh[3]")} - + ${input.getByOffset("j")} * ${sinCache.get("position_id", "bsnh[3]")}; + ${output.setByOffset("i", "re")} + let im = ${input.getByOffset("i")} * ${sinCache.get("position_id", "bsnh[3]")} + + ${input.getByOffset("j")} * ${cosCache.get("position_id", "bsnh[3]")}; + ${output.setByOffset("j", "im")} + } else { + let k = dot(bsnh, uniforms.input_output_strides) + half_rotary_emb_dim; + ${output.setByOffset("k", input.getByOffset("k"))} + } + }`; + }; + return { + name: "RotaryEmbedding", + shaderCache: { + hint: createAttributeWithCacheKey2({ + interleaved + }).cacheKey, + inputDependencies: ["rank", "rank", "rank", "rank"] + }, + getShaderSource, + getRunData: () => ({ + outputs: [{ dims: inputs[0].dims, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil(ShapeUtil2.size(globalShape) / WORKGROUP_SIZE) }, + programUniforms + }) + }; + }; + rotaryEmbedding = (context, attributes) => { + validateInputs44(context.inputs, attributes); + context.compute(createRotaryEmbeddingProgramInfo(context.inputs, attributes)); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/group-query-attention.ts + var validateInputs45, weightTransposeAttribute3, maybeTransposeToBNSH, generatePositionIdsProgramInfo, groupQueryAttention; + var init_group_query_attention = __esm({ + "web/lib/wasm/jsep/webgpu/ops/group-query-attention.ts"() { + "use strict"; + init_attribute_with_cache_key2(); + init_wasm_common(); + init_attention(); + init_multihead_attention(); + init_split2(); + init_transpose2(); + init_rotary_embedding(); + init_common(); + validateInputs45 = (inputs, attributes) => { + if (attributes.doRotary && inputs.length <= 7) { + throw new Error("cos_cache and sin_cache inputs are required if do_rotary is specified"); + } + const query = inputs[0]; + const key = inputs[1]; + const value = inputs[2]; + const pastKey = inputs[3]; + const pastValue = inputs[4]; + if (attributes.doRotary !== 0 && inputs.length <= 7) { + throw new Error("cos_cast and sin_cache are expected if do_rotary attribute is non-zero"); + } + if (attributes.localWindowSize !== -1) { + throw new Error("Local attention is not supported"); + } + if (attributes.softcap !== 0) { + throw new Error("Softcap is not supported"); + } + if (attributes.rotaryInterleaved !== 0) { + throw new Error("Rotary interleaved is not supported"); + } + if (attributes.smoothSoftmax) { + throw new Error("Smooth softmax is not supported"); + } + if (query.dims.length !== 3 && query.dims.length !== 5) { + throw new Error("Input query is expected to have 3 or 5 dimensions"); + } + const dmmhaPacking = false; + const batchSize = query.dims[0]; + const sequenceLength = query.dims[1]; + let hiddenSize = query.dims.length === 3 ? dmmhaPacking ? query.dims[2] / 3 : query.dims[2] : attributes.numHeads * query.dims[4]; + let kvSequenceLength = sequenceLength; + let pastSequenceLength = 0; + const packedQKV = !key || key.dims.length === 0; + const headSize = !packedQKV ? Math.floor(hiddenSize / attributes.numHeads) : Math.floor(hiddenSize / (attributes.numHeads + 2 * attributes.kvNumHeads)); + if (packedQKV) { + hiddenSize = headSize * attributes.numHeads; + } + const hasPastKey = pastKey && pastKey.dims.length !== 0; + const hasPastValue = pastValue && pastValue.dims.length !== 0; + const isPastkvBSNH = hasPastKey && pastKey.dims.length === 4 && pastKey.dims[0] === batchSize && pastKey.dims[1] !== attributes.kvNumHeads && pastKey.dims[2] === attributes.kvNumHeads && pastKey.dims[3] === headSize; + if (isPastkvBSNH) { + throw new Error("BSNH pastKey/pastValue is not supported"); + } + if (hasPastKey && hasPastValue) { + if (pastKey.dims.length !== 4) { + throw new Error('Input "past_key" is expected to have 4 dimensions'); + } + if (pastValue.dims.length !== 4) { + throw new Error('Input "past_value" is expected to have 4 dimensions'); + } + pastSequenceLength = pastKey.dims[2]; + } else if (hasPastKey || hasPastValue) { + throw new Error('Input "past_key" and "past_value" shall be both present or both absent'); + } + let qkvFormat = 1 /* qkvBNSH */; + if (key && key.dims.length > 0) { + if (query.dims.length !== 3) { + throw new Error('Input "query" is expected to have 3 dimensions when key is given'); + } + if (key.dims.length < 3 || key.dims.length > 5) { + throw new Error('Input "key" is expected to have 3, 4, or 5 dimensions'); + } + if (query.dims[0] !== key.dims[0]) { + throw new Error('Input "query" and "key" shall have same dim 0 (batch size)'); + } + if (key.dims.length === 3) { + if (query.dims[2] % key.dims[2] !== 0) { + throw new Error('Dimension 2 of "query" should be a multiple of "key"'); + } + kvSequenceLength = key.dims[1]; + } else if (key.dims.length === 5) { + if (key.dims[2] !== attributes.numHeads || key.dims[3] !== 2 || key.dims[4] !== headSize) { + throw new Error('Expect "key" shape (batch_size, kv_sequence_length, num_heads, 2, head_size) for packed kv'); + } + if (value) { + throw new Error('Expect "value" be none when "key" has packed kv format.'); + } + kvSequenceLength = key.dims[1]; + } else { + if (key.dims[1] !== attributes.numHeads || key.dims[3] !== headSize) { + throw new Error('Expect "key" shape (batch_size, num_heads, kv_sequence_length, head_size) for past_key'); + } + kvSequenceLength = key.dims[2]; + } + } else { + if (query.dims.length !== 3 && query.dims.length !== 5) { + throw new Error('Input "query" is expected to have 3 or 5 dimensions when key is empty'); + } + if (query.dims.length === 5 && (query.dims[2] !== attributes.numHeads || query.dims[3] !== 3)) { + throw new Error('Expect "query" shape (batch_size, kv_sequence_length, num_heads, 3, head_size) for packed kv'); + } + qkvFormat = 3 /* qkvBSN3H */; + } + const maskType = 0 /* none */; + let passPastInKv = false; + let vHiddenSize = attributes.kvNumHeads ? headSize * attributes.kvNumHeads : hiddenSize; + if (value && value.dims.length > 0) { + if (value.dims.length !== 3 && value.dims.length !== 4) { + throw new Error('Input "value" is expected to have 3 or 4 dimensions'); + } + if (query.dims[0] !== value.dims[0]) { + throw new Error('Input "query" and "value" shall have same dim 0 (batch_size)'); + } + if (value.dims.length === 3) { + if (kvSequenceLength !== value.dims[1]) { + throw new Error('Input "key" and "value" shall have the same dim 1 (kv_sequence_length)'); + } + vHiddenSize = value.dims[2]; + } else { + if (kvSequenceLength !== value.dims[2]) { + throw new Error('Input "past_key" and "past_value" shall have the same dim 2 (kv_sequence_length)'); + } + vHiddenSize = value.dims[1] * value.dims[3]; + passPastInKv = true; + } + } + const seqlLens = inputs.length > 4 ? inputs[5] : void 0; + if (seqlLens && seqlLens.dims.length !== 1 && seqlLens.dims[0] !== batchSize) { + throw new Error('Input "seqlens" is expected to have 1 dimension and the same dim 0 as batch_size'); + } + const totalSequenceLength = -1; + const maxSequenceLength = -1; + const broadcastResPosBias = false; + return { + batchSize, + sequenceLength, + pastSequenceLength, + kvSequenceLength, + totalSequenceLength, + maxSequenceLength, + inputHiddenSize: 0, + hiddenSize, + vHiddenSize, + headSize, + vHeadSize: Math.floor(vHiddenSize / attributes.kvNumHeads), + numHeads: attributes.numHeads, + kvNumHeads: attributes.kvNumHeads, + nReps: attributes.numHeads / attributes.kvNumHeads, + pastPresentShareBuffer: false, + maskType, + scale: attributes.scale, + broadcastResPosBias, + passPastInKv, + qkvFormat + }; + }; + weightTransposeAttribute3 = createAttributeWithCacheKey2({ perm: [0, 2, 1, 3] }); + maybeTransposeToBNSH = (context, input, params) => { + let reshapedInput = input; + const numHeads = params.kvNumHeads; + if (input.dims.length === 3 && params.kvSequenceLength !== 0) { + reshapedInput = input.reshape([params.batchSize, params.kvSequenceLength, numHeads, params.headSize]); + reshapedInput = context.compute(createTransposeProgramInfo2(reshapedInput, weightTransposeAttribute3.perm), { + inputs: [reshapedInput], + outputs: [-1] + })[0]; + } + return reshapedInput; + }; + generatePositionIdsProgramInfo = (batchSize, sequenceLength, seqLens, totalSeqLen) => { + const outputDataType = 7 /* int64 */; + const inputDependencies = ["type", "type"]; + const outputShape = [batchSize * sequenceLength]; + const outputSize = batchSize * sequenceLength; + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: sequenceLength }, + { type: 12 /* uint32 */, data: batchSize } + ]; + const getShaderSource = (shaderHelper) => { + const seqLensInputHelper = inputVariable("seq_lens", seqLens.dataType, seqLens.dims); + const totalSeqLenInputHelper = inputVariable("total_seq_lens", totalSeqLen.dataType, totalSeqLen.dims); + const positionIdsHelper = outputVariable("pos_ids", outputDataType, outputShape); + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "sequence_length", type: "u32" }, + { name: "batch_size", type: "u32" } + ]; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(seqLensInputHelper, totalSeqLenInputHelper, positionIdsHelper)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let total_sequence_length = u32(${totalSeqLenInputHelper.getByOffset("0")}); + let is_subsequent_prompt = uniforms.sequence_length > 1 && uniforms.sequence_length != total_sequence_length; + let is_first_prompt = !is_subsequent_prompt && uniforms.sequence_length == total_sequence_length; + let batch_idx = global_idx / uniforms.sequence_length; + let sequence_idx = i32(global_idx % uniforms.sequence_length); + var pos_id: i32 = 0; + let seqlen = ${seqLensInputHelper.getByOffset("batch_idx")}; + let total_seqlen = seqlen + 1; + if (is_first_prompt) { + if (sequence_idx < total_seqlen) { + pos_id = sequence_idx; + } else { + pos_id = 1; + } + ${positionIdsHelper.setByOffset("global_idx", "pos_id")} + } else if (is_subsequent_prompt) { + let past_seqlen = total_seqlen - i32(uniforms.sequence_length); + if (past_seqlen + sequence_idx < total_seqlen) { + pos_id = past_seqlen + sequence_idx; + } else { + pos_id = 1; + } + ${positionIdsHelper.setByOffset("global_idx", "pos_id")} + } else if (global_idx < uniforms.batch_size) { + ${positionIdsHelper.setByOffset("global_idx", "seqlen")} + }; + } + `; + }; + return { + name: "GeneratePositionIds", + shaderCache: { hint: `${batchSize};${sequenceLength}`, inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: outputDataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + groupQueryAttention = (context, attributes) => { + const params = validateInputs45(context.inputs, attributes); + if (context.inputs[0].dims.length === 5) { + throw new Error("Packed QKV is not implemented"); + } + if (context.inputs[1]?.dims.length === 5) { + throw new Error("Packed KV is not implemented"); + } + const q = context.inputs[0]; + const k = context.inputs[1] && context.inputs[1].dims.length > 0 ? context.inputs[1] : void 0; + const v = context.inputs[2] && context.inputs[2].dims.length > 0 ? context.inputs[2] : void 0; + const pastKey = context.inputs[3] && context.inputs[3].dims.length !== 0 ? context.inputs[3] : void 0; + const pastValue = context.inputs[4] && context.inputs[4].dims.length !== 0 ? context.inputs[4] : void 0; + const seqLens = context.inputs.length > 4 ? context.inputs[5] : void 0; + const totalSequenceLengthInput = context.inputs.length > 5 ? context.inputs[6] : void 0; + const kvNumHeads = params.kvNumHeads ? params.kvNumHeads : params.numHeads; + const splitAttributes = createAttributeWithCacheKey2({ + axis: 2, + numOutputs: 3, + splitSizes: [params.numHeads * params.headSize, kvNumHeads * params.headSize, kvNumHeads * params.headSize] + }); + const [query, key, value] = !k && !v ? context.compute(createSplitProgramInfo2([q], splitAttributes), { inputs: [q], outputs: [-1, -1, -1] }) : [q, k, v]; + let qRotary; + let kRotary; + if (attributes.doRotary) { + const posIds = context.compute( + generatePositionIdsProgramInfo(params.batchSize, params.sequenceLength, seqLens, totalSequenceLengthInput), + { inputs: [seqLens, totalSequenceLengthInput], outputs: [-1] } + )[0]; + const cosCache = context.inputs[7]; + const sinCache = context.inputs[8]; + const qRotaryEmbeddingAttributes = createAttributeWithCacheKey2({ + interleaved: attributes.rotaryInterleaved !== 0, + numHeads: params.numHeads, + rotaryEmbeddingDim: 0, + scale: attributes.scale + }); + const inputs = [query, posIds, cosCache, sinCache]; + const outputs = [-1]; + qRotary = context.compute(createRotaryEmbeddingProgramInfo(inputs, qRotaryEmbeddingAttributes), { + inputs, + outputs + })[0]; + inputs.splice(0, 1, key); + const kRotaryEmbeddingAttributes = createAttributeWithCacheKey2({ + interleaved: attributes.rotaryInterleaved !== 0, + numHeads: params.kvNumHeads, + rotaryEmbeddingDim: 0, + scale: attributes.scale + }); + kRotary = context.compute(createRotaryEmbeddingProgramInfo(inputs, kRotaryEmbeddingAttributes), { + inputs, + outputs + })[0]; + } + const Q = maybeTransposeToBNSHAndAddBias( + context, + params.batchSize, + params.numHeads, + params.sequenceLength, + params.headSize, + attributes.doRotary ? qRotary : query, + void 0, + 0 + ); + const K = maybeTransposeToBNSH(context, attributes.doRotary ? kRotary : key, params); + const V = maybeTransposeToBNSH(context, value, params); + applyAttention( + context, + Q, + K, + V, + void 0, + void 0, + pastKey, + pastValue, + void 0, + params, + seqLens, + totalSequenceLengthInput + ); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/instance-norm.ts + var computeChannelScaleShift, createInstanceNormProgramInfo, createInstanceNormNHWCProgramInfo, instanceNorm; + var init_instance_norm = __esm({ + "web/lib/wasm/jsep/webgpu/ops/instance-norm.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_transpose2(); + init_common(); + computeChannelScaleShift = (context, input, scale, bias, n, h, c, epsilon) => { + const components = getMaxComponents(h); + const f32Type = components === 1 ? "f32" : `vec${components}f`; + const wgType = components === 1 ? "vec2f" : `mat2x${components}f`; + const unitsOfWork = n * c; + let workgroupSize = 64; + if (unitsOfWork === 1) { + workgroupSize = 256; + } + const inputShape = [n, c, h / components]; + const outputShape = [n, c, 2]; + const inputDependencies = ["rank", "type", "type"]; + const programUniforms = []; + programUniforms.push(...createTensorShapeVariables(inputShape, outputShape)); + const getShaderSource = (shaderHelper) => { + const x = inputVariable("x", input.dataType, 3, components); + const s = inputVariable("scale", scale.dataType, scale.dims); + const b = inputVariable("bias", bias.dataType, bias.dims); + const output = outputVariable("output", 1 /* float */, 3, 2); + const variables = [x, s, b, output]; + return ` + var workgroup_shared : array<${wgType}, ${workgroupSize}>; + const workgroup_size = ${workgroupSize}u; + ${shaderHelper.declareVariables(...variables)} + ${shaderHelper.mainStart(workgroupSize)} + let batch = workgroup_index / uniforms.x_shape[1]; + let channel = workgroup_index % uniforms.x_shape[1]; + let hight = uniforms.x_shape[2]; + // initialize workgroup memory + var sum = ${f32Type}(0); + var squared_sum = ${f32Type}(0); + for (var h = local_idx; h < hight; h += workgroup_size) { + let value = ${f32Type}(${x.get("batch", "channel", "h")}); + sum += value; + squared_sum += value * value; + } + workgroup_shared[local_idx] = ${wgType}(sum, squared_sum); + workgroupBarrier(); + + for (var currSize = workgroup_size >> 1; currSize > 0; currSize = currSize >> 1) { + if (local_idx < currSize) { + workgroup_shared[local_idx] = workgroup_shared[local_idx] + workgroup_shared[local_idx + currSize]; + } + workgroupBarrier(); + } + if (local_idx == 0) { + let sum_final = ${sumVector("workgroup_shared[0][0]", components)} / f32(hight * ${components}); + let squared_sum_final = ${sumVector("workgroup_shared[0][1]", components)} / f32(hight * ${components}); + + let inv_std_dev = inverseSqrt(squared_sum_final - sum_final * sum_final + f32(${epsilon})); + let channel_scale = inv_std_dev * f32(scale[channel]); + let channel_shift = f32(bias[channel]) - sum_final * channel_scale; + output[workgroup_index] = vec2f(channel_scale, channel_shift); + } + }`; + }; + return context.compute( + { + name: "InstanceNormComputeChannelScaleShift", + // TODO: use epsilon as uniform. Currently epsilon as uniform fails test_instancenorm_epsilon. + shaderCache: { hint: `${components};${epsilon};${workgroupSize}`, inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: 1 /* float */ }], + dispatchGroup: { x: unitsOfWork }, + programUniforms + }), + getShaderSource + }, + { inputs: [input, scale, bias], outputs: [-1] } + )[0]; + }; + createInstanceNormProgramInfo = (context, inputs, attributes) => { + const xShape = inputs[0].dims; + const outputShape = xShape; + const axis = 2; + const N = xShape[0]; + const C = xShape[1]; + const H = ShapeUtil2.sizeFromDimension(xShape, axis); + const components = getMaxComponents(H); + const outputSize = ShapeUtil2.size(outputShape) / components; + const channelScaleShift = computeChannelScaleShift( + context, + inputs[0], + inputs[1], + inputs[2], + N, + H, + C, + attributes.epsilon + ); + const inputShape = [N, C, H / components]; + const scaleShape = [N, C]; + const inputDependencies = ["type", "none"]; + const getShaderSource = (shaderHelper) => { + const x = inputVariable("x", inputs[0].dataType, inputShape.length, components); + const scale = inputVariable("scale_shift", 1 /* float */, scaleShape.length, 2); + const output = outputVariable("output", inputs[0].dataType, inputShape.length, components); + const variables = [x, scale, output]; + return ` + ${shaderHelper.registerUniform("output_size", "u32").declareVariables(...variables)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let outputIndices = ${output.offsetToIndices("global_idx")}; + let batch = outputIndices[0]; + let channel = outputIndices[1]; + let scale_shift = ${scale.getByIndices("vec2(batch, channel)")}; + let value = ${x.getByOffset("global_idx")} * ${output.type.value}(scale_shift.x) + ${output.type.value}(scale_shift.y); + ${output.setByOffset("global_idx", "value")}; + }`; + }; + context.compute( + { + name: "InstanceNormalization", + shaderCache: { hint: `${components}`, inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms: [ + { type: 12 /* uint32 */, data: outputSize }, + ...createTensorShapeVariables(inputShape, scaleShape, inputShape) + ] + }), + getShaderSource + }, + { inputs: [inputs[0], channelScaleShift] } + ); + }; + createInstanceNormNHWCProgramInfo = (context, inputs, attributes) => { + const xShape = inputs[0].dims; + const outputShape = xShape; + const N = xShape[0]; + const C = xShape[xShape.length - 1]; + const H = ShapeUtil2.sizeFromDimension(xShape, 1) / C; + const components = getMaxComponents(C); + const outputSize = ShapeUtil2.size(outputShape) / components; + const programUniforms = [ + { type: 12 /* uint32 */, data: H }, + { type: 12 /* uint32 */, data: Math.floor(C / components) } + ]; + const inputDependencies = ["type", "type"]; + let needTranspose = false; + const transposedXPerm = [0, xShape.length - 1]; + for (let i = 0; i < xShape.length - 2; i++) { + needTranspose = needTranspose || xShape[i + 1] !== 1; + transposedXPerm.push(i + 1); + } + needTranspose = needTranspose && xShape[xShape.length - 1] !== 1; + const transposedX = needTranspose ? context.compute(createTransposeProgramInfo2(context.inputs[0], transposedXPerm), { + inputs: [context.inputs[0]], + outputs: [-1] + })[0] : context.inputs[0].reshape(Array.from({ length: xShape.length }, (_, i) => xShape[transposedXPerm[i]])); + const channelScaleShift = computeChannelScaleShift( + context, + transposedX, + inputs[1], + inputs[2], + N, + H, + C, + attributes.epsilon + ); + const getShaderSource = (shaderHelper) => { + const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); + const scaleType = components === 1 ? "vec2f" : `mat${components}x2f`; + const scaleData = (num) => { + const index = num === 0 ? "x" : "y"; + const f32Type = components === 1 ? "f32" : `vec${components}f`; + switch (components) { + case 1: + return `${dataType}(${f32Type}(scale.${index}))`; + case 2: + return `vec2<${dataType}>(${f32Type}(scale[0].${index}, scale[1].${index}))`; + case 4: + return `vec4<${dataType}>(${f32Type}(scale[0].${index}, scale[1].${index}, scale[2].${index}, scale[3].${index}))`; + default: + throw new Error(`Not supported compoents ${components}`); + } + }; + const inputHelper = inputVariable("input", inputs[0].dataType, inputs[0].dims, components); + const outputHelper = outputVariable("output", inputs[0].dataType, outputShape, components); + return ` + @group(0) @binding(0) var input : array<${inputHelper.type.storage}>; + @group(0) @binding(1) var scale_input : array<${scaleType}>; + @group(0) @binding(2) var output : array<${outputHelper.type.storage}>; + struct Uniforms {H: u32, C : u32}; + @group(0) @binding(3) var uniforms: Uniforms; + + ${shaderHelper.mainStart()} + let current_image_number = global_idx / (uniforms.C * uniforms.H); + let current_channel_number = global_idx % uniforms.C; + + let scale_offset = current_image_number * uniforms.C + current_channel_number; + let scale = scale_input[scale_offset]; + output[global_idx] = fma(input[global_idx], ${scaleData(0)}, ${scaleData(1)}); + }`; + }; + context.compute( + { + name: "InstanceNormalizationNHWC", + shaderCache: { hint: `${components}`, inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }, + { inputs: [inputs[0], channelScaleShift] } + ); + }; + instanceNorm = (context, attributes) => { + if (attributes.format === "NHWC") { + createInstanceNormNHWCProgramInfo(context, context.inputs, attributes); + } else { + createInstanceNormProgramInfo(context, context.inputs, attributes); + } + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/layer-norm.ts + var validateInputs46, createLayerNormProgramInfo, layerNorm; + var init_layer_norm = __esm({ + "web/lib/wasm/jsep/webgpu/ops/layer-norm.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + validateInputs46 = (inputs) => { + if (!inputs || inputs.length < 2) { + throw new Error("layerNorm requires at least 2 inputs."); + } + }; + createLayerNormProgramInfo = (inputs, attributes, outputCount) => { + const simplified = attributes.simplified; + const xShape = inputs[0].dims; + const scale = inputs[1]; + const bias = !simplified && inputs[2]; + const outputShape = xShape; + const axis = ShapeUtil2.normalizeAxis(attributes.axis, xShape.length); + const normCount = ShapeUtil2.sizeToDimension(xShape, axis); + const normSize = ShapeUtil2.sizeFromDimension(xShape, axis); + const scaleSize = ShapeUtil2.size(scale.dims); + const biasSize = bias ? ShapeUtil2.size(bias.dims) : 0; + if (scaleSize !== normSize || bias && biasSize !== normSize) { + throw new Error(`Size of X.shape()[axis:] == ${normSize}. + Size of scale and bias (if provided) must match this. + Got scale size of ${scaleSize} and bias size of ${biasSize}`); + } + const meanInvStdDevDim = []; + for (let i = 0; i < xShape.length; ++i) { + if (i < axis) { + meanInvStdDevDim.push(xShape[i]); + } else { + meanInvStdDevDim.push(1); + } + } + const components = getMaxComponents(normSize); + const inputDependencies = ["type", "type"]; + const programUniforms = [ + { type: 12 /* uint32 */, data: normCount }, + { type: 1 /* float */, data: normSize }, + { type: 12 /* uint32 */, data: Math.floor(normSize / components) }, + { type: 1 /* float */, data: attributes.epsilon } + ]; + if (bias) { + inputDependencies.push("type"); + } + const hasMeanDataOutput = outputCount > 1; + const hasInvStdOutput = outputCount > 2; + const getShaderSource = (shaderHelper) => { + const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); + const variables = [ + inputVariable("x", inputs[0].dataType, inputs[0].dims, components), + inputVariable("scale", scale.dataType, scale.dims, components) + ]; + if (bias) { + variables.push(inputVariable("bias", bias.dataType, bias.dims, components)); + } + variables.push(outputVariable("output", inputs[0].dataType, outputShape, components)); + if (hasMeanDataOutput) { + variables.push(outputVariable("mean_data_output", 1 /* float */, meanInvStdDevDim)); + } + if (hasInvStdOutput) { + variables.push(outputVariable("inv_std_output", 1 /* float */, meanInvStdDevDim)); + } + const uniforms = [ + { name: "norm_count", type: "u32" }, + { name: "norm_size", type: "f32" }, + { name: "norm_size_vectorized", type: "u32" }, + { name: "epsilon", type: "f32" } + ]; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(...variables)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.norm_count")} + let offset = global_idx * uniforms.norm_size_vectorized; + var mean_vector = ${fillVector("f32", components)}; + var mean_square_vector = ${fillVector("f32", components)}; + + for (var h: u32 = 0u; h < uniforms.norm_size_vectorized; h++) { + let value = ${castToF32(dataType, components, "x[h + offset]")}; + mean_vector += value; + mean_square_vector += value * value; + } + let mean = ${sumVector("mean_vector", components)} / uniforms.norm_size; + let inv_std_dev = inverseSqrt(${sumVector("mean_square_vector", components)} / uniforms.norm_size ${simplified ? "" : "- mean * mean"} + uniforms.epsilon); + + for (var j: u32 = 0; j < uniforms.norm_size_vectorized; j++) { + let f32input = ${castToF32(dataType, components, "x[j + offset]")}; + let f32scale = ${castToF32(dataType, components, "scale[j]")}; + output[j + offset] = ${variables[0].type.value}((f32input ${simplified ? "" : "- mean"}) * inv_std_dev * f32scale + ${bias ? `+ ${castToF32(dataType, components, "bias[j]")}` : ""} + ); + } + + ${hasMeanDataOutput ? "mean_data_output[global_idx] = mean" : ""}; + ${hasInvStdOutput ? "inv_std_output[global_idx] = inv_std_dev" : ""}; + }`; + }; + const outputs = [{ dims: outputShape, dataType: inputs[0].dataType }]; + if (hasMeanDataOutput) { + outputs.push({ dims: meanInvStdDevDim, dataType: 1 /* float */ }); + } + if (hasInvStdOutput) { + outputs.push({ dims: meanInvStdDevDim, dataType: 1 /* float */ }); + } + return { + name: "LayerNormalization", + shaderCache: { hint: `${components};${outputCount};${simplified}`, inputDependencies }, + getRunData: () => ({ + outputs, + dispatchGroup: { x: Math.ceil( + normCount / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + layerNorm = (context, attributes) => { + validateInputs46(context.inputs); + context.compute(createLayerNormProgramInfo(context.inputs, attributes, context.outputCount)); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/matmul.ts + var validateInputs47, matMul2; + var init_matmul2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/matmul.ts"() { + "use strict"; + init_util2(); + init_matmul_shaders(); + init_matmul_packed_webgpu(); + validateInputs47 = (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."); + } + }; + matMul2 = (context) => { + validateInputs47(context.inputs); + const outputShape = BroadcastUtil2.calcShape(context.inputs[0].dims, context.inputs[1].dims, true); + if (!outputShape) { + throw new Error("Can't use matmul on the given tensors"); + } + const N = outputShape[outputShape.length - 1]; + const K = context.inputs[0].dims[context.inputs[0].dims.length - 1]; + if (N < 8 && K < 8) { + context.compute(createNaiveMatmulProgramInfo(context.inputs, { activation: "" }, outputShape)); + } else { + const M = outputShape[outputShape.length - 2]; + const batchA = ShapeUtil2.size(context.inputs[0].dims.slice(0, -2)); + const batchB = ShapeUtil2.size(context.inputs[1].dims.slice(0, -2)); + if (batchA !== 1 && M === 1 && batchB === 1) { + const reshapedA = context.inputs[0].reshape([1, batchA, K]); + const reshapedB = context.inputs[1].reshape([1, K, N]); + const matmulOutputShape = [1, batchA, N]; + const matmulInputs = [reshapedA, reshapedB]; + context.compute(createMatmulProgramInfo2(matmulInputs, { activation: "" }, outputShape, matmulOutputShape), { + inputs: matmulInputs + }); + } else { + context.compute(createMatmulProgramInfo2(context.inputs, { activation: "" }, outputShape)); + } + } + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/matmulnbits.ts + var validateInputs48, createMatMulNBitsProgramInfo, createMatMulNBitsBlockSize32ProgramInfo, matMulNBits, parseMatMulNBitsAttributes; + var init_matmulnbits = __esm({ + "web/lib/wasm/jsep/webgpu/ops/matmulnbits.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs48 = (inputs, attributes) => { + if (inputs.length < 3 || inputs.length > 4) { + throw new Error("MatMulNBits requires 3 or 4 inputs"); + } + const a = inputs[0]; + const aRank = a.dims.length; + if (a.dims[aRank - 1] !== attributes.k) { + throw new Error("The last dim of input shape does not match the k value"); + } + const nBlocksPerCol = Math.floor((attributes.k + attributes.blockSize - 1) / attributes.blockSize); + const blobSize = attributes.blockSize / 8 * attributes.bits; + const b = inputs[1]; + if (!ShapeUtil2.areEqual(b.dims, [attributes.n, nBlocksPerCol, blobSize])) { + throw new Error("The second inputs must be 3D tensor with shape N X nBlocksPerCol X blobSize"); + } + const scales = inputs[2]; + const scalesShape = scales.dims; + if (ShapeUtil2.size(scalesShape) !== attributes.n * nBlocksPerCol) { + throw new Error("scales input size error."); + } + if (inputs.length === 4) { + const zeroPoints = inputs[3]; + const zeroPointsShape = zeroPoints.dims; + const expectedZeroPointsSize = attributes.bits > 4 ? attributes.n * nBlocksPerCol : attributes.n * Math.floor((nBlocksPerCol + 1) / 2); + if (ShapeUtil2.size(zeroPointsShape) !== expectedZeroPointsSize) { + throw new Error("zeroPoints input size error."); + } + } + }; + createMatMulNBitsProgramInfo = (inputs, attributes) => { + const inputShape = inputs[0].dims; + const aRank = inputShape.length; + const dimAOuter = inputShape[aRank - 2]; + const dimInner = attributes.k; + const dimBOuter = attributes.n; + const batchDims = inputShape.slice(0, aRank - 2); + const batchSize = ShapeUtil2.size(batchDims); + const blobSize = inputs[1].dims[2]; + const blobSizeInWords = blobSize / 4; + const dataType = inputs[0].dataType; + const aComponents = getMaxComponents(attributes.k); + const bComponents = getMaxComponents(blobSizeInWords); + const components = getMaxComponents(dimBOuter); + const outputShape = batchDims.concat([dimAOuter, dimBOuter]); + const outputNumber = dimAOuter > 1 && dimBOuter / components % 2 === 0 ? 2 : 1; + const dispatchSize = ShapeUtil2.size(outputShape) / components / outputNumber; + const workgroupSize = 64; + const programUniforms = []; + const inputShapeTemp = [batchSize, dimAOuter, dimInner / aComponents]; + const bShape = ShapeUtil2.convertShape(inputs[1].dims).slice(); + bShape.splice(-1, 1, blobSizeInWords / bComponents); + programUniforms.push(...createTensorShapeVariables(inputShapeTemp)); + programUniforms.push(...createTensorShapeVariables(bShape)); + programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); + if (inputs.length === 4) { + programUniforms.push(...createTensorShapeVariables(ShapeUtil2.convertShape(inputs[3].dims))); + } + const outputShapeTemp = [batchSize, dimAOuter, dimBOuter / components]; + programUniforms.push(...createTensorShapeVariables(outputShapeTemp)); + const getShaderSource = (shaderHelper) => { + const inputRank = inputShapeTemp.length; + const a = inputVariable("a", inputs[0].dataType, inputRank, aComponents); + const b = inputVariable("b", 12 /* uint32 */, bShape.length, bComponents); + const scales = inputVariable("scales", inputs[2].dataType, inputs[2].dims.length); + const inputVariables = [a, b, scales]; + const zeroPoints = inputs.length === 4 ? inputVariable("zero_points", 12 /* uint32 */, inputs[3].dims.length) : void 0; + if (zeroPoints) { + inputVariables.push(zeroPoints); + } + const outputRank = outputShapeTemp.length; + const output = outputVariable("output", inputs[0].dataType, outputRank, components); + const dataType2 = tensorTypeToWsglStorageType(inputs[0].dataType); + const qDqDataType = (() => { + switch (aComponents) { + case 1: + return `array<${dataType2}, 8>`; + case 2: + return `mat4x2<${dataType2}>`; + case 4: + return `mat2x4<${dataType2}>`; + default: + throw new Error(`${aComponents}-component is not supported.`); + } + })(); + const processOneWord = () => { + let calcStr = ` + // reuse a data + var input_offset = ${a.indicesToOffset(`${a.type.indices}(batch, row, word_offset)`)}; + var a_data: ${qDqDataType}; + for (var j: u32 = 0; j < ${8 / aComponents}; j++) { + a_data[j] = ${a.getByOffset("input_offset")}; + input_offset++; + } + `; + for (let c = 0; c < components * outputNumber; c++) { + calcStr += ` + b_value = ${bComponents === 1 ? `b${c}_data` : `b${c}_data[i]`}; + b_value_lower = unpack4xU8(b_value & b_mask); + b_value_upper = unpack4xU8((b_value >> 4) & b_mask); + b_quantized_values = ${qDqDataType}(${Array.from( + { length: 4 }, + (_, i) => `${dataType2}(b_value_lower[${i}]), ${dataType2}(b_value_upper[${i}])` + ).join(", ")}); + b_dequantized_values = ${(() => { + if (aComponents === 1) { + return `${qDqDataType}(${Array.from( + { length: 8 }, + (_, i) => `(b_quantized_values[${i}] - ${zeroPoints ? `zero_point${c}` : "zero_point"}) * scale${c}` + ).join(", ")});`; + } else { + return `(b_quantized_values - ${qDqDataType}(${Array(8).fill(`${zeroPoints ? `zero_point${c}` : "zero_point"}`).join(",")})) * scale${c};`; + } + })()}; + workgroup_shared[local_id.x * ${outputNumber} + ${Math.floor(c / components)}]${components > 1 ? `[${c % components}]` : ""} += ${Array.from( + { length: 8 / aComponents }, + (_, i) => `${aComponents === 1 ? `a_data[${i}] * b_dequantized_values[${i}]` : `dot(a_data[${i}], b_dequantized_values[${i}])`}` + ).join(" + ")}; + `; + } + return calcStr; + }; + const prepareScaleAndZeroPoint = () => { + let calcStr = ` + var col_index = col * ${components}; + ${zeroPoints ? ` + let zero_point_bytes_per_col = (nBlocksPerCol + 1) / 2; + var zero_point_byte_count: u32; + var zero_point_word_index: u32; + var zero_point_byte_offset: u32; + let zero_point_nibble_offset: u32 = block & 0x1u; + var zero_point_bits_offset: u32; + var zero_point_word: u32;` : ` + // The default zero point is 8 for unsigned 4-bit quantization. + let zero_point = ${dataType2}(${8});`} + `; + for (let c = 0; c < components * outputNumber; c++) { + calcStr += ` + let scale${c} = ${scales.getByOffset(`col_index * nBlocksPerCol + block`)}; + ${zeroPoints ? ` + zero_point_byte_count = col_index * zero_point_bytes_per_col + (block >> 0x1u); + zero_point_word_index = zero_point_byte_count >> 0x2u; + zero_point_byte_offset = zero_point_byte_count & 0x3u; + zero_point_bits_offset = (zero_point_byte_offset << 3) + (zero_point_nibble_offset << 2); + zero_point_word = ${zeroPoints.getByOffset("zero_point_word_index")} >> zero_point_bits_offset; + let zero_point${c} = ${dataType2}((zero_point_word) & 0xFu);` : ""} + col_index += 1;`; + } + return calcStr; + }; + const prepareBData = () => { + let calcStr = `col_index = col * ${components};`; + for (let c = 0; c < components * outputNumber; c++) { + calcStr += ` + let b${c}_data = ${b.getByIndices(`${b.type.indices}(col_index, block, word)`)}; + col_index += 1;`; + } + calcStr += ` + var b_value: u32; + let b_mask: u32 = 0x0F0F0F0Fu; + var b_value_lower: vec4; + var b_value_upper: vec4; + var b_quantized_values: ${qDqDataType}; + var b_dequantized_values: ${qDqDataType};`; + return calcStr; + }; + return ` + var workgroup_shared: array<${output.type.value}, ${outputNumber * workgroupSize}>; + ${shaderHelper.declareVariables(...inputVariables, output)} + ${shaderHelper.mainStart([workgroupSize, 1, 1])} + let output_indices = ${output.offsetToIndices(`(global_idx / ${workgroupSize}) * ${outputNumber}`)}; + let col = output_indices[2]; + let row = output_indices[1]; + let batch = output_indices[0]; + let nBlocksPerCol = uniforms.b_shape[1]; + + for (var block = local_id.x; block < nBlocksPerCol; block += ${workgroupSize}) { + //process one block + var word_offset: u32 = block * ${attributes.blockSize / aComponents}; + ${prepareScaleAndZeroPoint()} + for (var word: u32 = 0; word < ${blobSizeInWords}; word += ${bComponents}) { + ${prepareBData()} + for (var i: u32 = 0; i < ${bComponents}; i++) { + ${processOneWord()} + word_offset += ${8 / aComponents}; + } + } + } + workgroupBarrier(); + + if (local_id.x < ${outputNumber}) { + var output_value: ${output.type.value} = ${output.type.value}(0); + var workgroup_shared_offset: u32 = local_id.x; + for (var b: u32 = 0u; b < ${workgroupSize}u; b++) { + output_value += workgroup_shared[workgroup_shared_offset]; + workgroup_shared_offset += ${outputNumber}; + } + ${output.setByIndices(`${output.type.indices}(batch, row, col + local_id.x)`, "output_value")}; + } + }`; + }; + return { + name: "MatMulNBits", + shaderCache: { + hint: `${attributes.blockSize};${attributes.bits};${aComponents};${bComponents};${components};${outputNumber};${workgroupSize}`, + inputDependencies: Array(inputs.length).fill("rank") + }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType }], + dispatchGroup: { x: dispatchSize }, + programUniforms + }), + getShaderSource + }; + }; + createMatMulNBitsBlockSize32ProgramInfo = (inputs, attributes) => { + const inputShape = inputs[0].dims; + const aRank = inputShape.length; + const dimAOuter = inputShape[aRank - 2]; + const dimInner = attributes.k; + const dimBOuter = attributes.n; + const batchDims = inputShape.slice(0, aRank - 2); + const batchSize = ShapeUtil2.size(batchDims); + const blobSize = inputs[1].dims[2]; + const blobSizeInWords = blobSize / 4; + const dataType = inputs[0].dataType; + const aComponents = getMaxComponents(attributes.k); + const bComponents = getMaxComponents(blobSizeInWords); + const outputShape = batchDims.concat([dimAOuter, dimBOuter]); + const workgroupSize = 128; + const workgroupY = dimBOuter % 8 === 0 ? 8 : dimBOuter % 4 === 0 ? 4 : 1; + const workgroupX = workgroupSize / workgroupY; + const tileSize = workgroupX * bComponents * 8; + const aLengthPerTile = tileSize / aComponents; + const blocksPerTile = tileSize / attributes.blockSize; + const dispatchSize = ShapeUtil2.size(outputShape) / workgroupY; + const programUniforms = []; + const inputShapeTemp = [batchSize, dimAOuter, dimInner / aComponents]; + const bShape = ShapeUtil2.convertShape(inputs[1].dims).slice(); + bShape.splice(-1, 1, blobSizeInWords / bComponents); + programUniforms.push(...createTensorShapeVariables(inputShapeTemp)); + programUniforms.push(...createTensorShapeVariables(bShape)); + programUniforms.push(...createTensorShapeVariables(inputs[2].dims)); + if (inputs.length === 4) { + programUniforms.push(...createTensorShapeVariables(ShapeUtil2.convertShape(inputs[3].dims))); + } + const outputShapeTemp = [batchSize, dimAOuter, dimBOuter]; + programUniforms.push(...createTensorShapeVariables(outputShapeTemp)); + const getShaderSource = (shaderHelper) => { + const inputRank = inputShapeTemp.length; + const a = inputVariable("a", inputs[0].dataType, inputRank, aComponents); + const b = inputVariable("b", 12 /* uint32 */, bShape.length, bComponents); + const scales = inputVariable("scales", inputs[2].dataType, inputs[2].dims.length); + const inputVariables = [a, b, scales]; + const zeroPoints = inputs.length === 4 ? inputVariable("zero_points", 12 /* uint32 */, inputs[3].dims.length) : void 0; + if (zeroPoints) { + inputVariables.push(zeroPoints); + } + const outputRank = outputShapeTemp.length; + const output = outputVariable("output", inputs[0].dataType, outputRank); + const dataType2 = tensorTypeToWsglStorageType(inputs[0].dataType); + const readA = () => { + switch (aComponents) { + case 1: + return ` + let a_data0 = vec4<${dataType2}>(sub_a[word_offset], sub_a[word_offset + 1], sub_a[word_offset + 2], sub_a[word_offset + 3]); + let a_data1 = vec4<${dataType2}>(sub_a[word_offset + 4], sub_a[word_offset + 5], sub_a[word_offset + 6], sub_a[word_offset + 7]);`; + case 2: + return ` + let a_data0 = vec4<${dataType2}>(sub_a[word_offset], sub_a[word_offset + 1]); + let a_data1 = vec4<${dataType2}>(sub_a[word_offset + 2], sub_a[word_offset + 3]);`; + case 4: + return ` + let a_data0 = sub_a[word_offset]; + let a_data1 = sub_a[word_offset + 1];`; + default: + throw new Error(`${aComponents}-component is not supported.`); + } + }; + return ` + var sub_a: array<${a.type.value}, ${aLengthPerTile}>; + var inter_results: array, ${workgroupY}>; + ${shaderHelper.declareVariables(...inputVariables, output)} + ${shaderHelper.mainStart([workgroupX, workgroupY, 1])} + let output_indices = ${output.offsetToIndices(`workgroup_index * ${workgroupY}`)}; + let col = output_indices[2]; + let row = output_indices[1]; + let batch = output_indices[0]; + let n_blocks_per_col = uniforms.b_shape[1]; + let num_tiles = (n_blocks_per_col - 1) / ${blocksPerTile} + 1; + + // Loop over shared dimension. + for (var tile: u32 = 0; tile < num_tiles; tile += 1) { + let a_col_start = tile * ${aLengthPerTile}; + // load one tile A data into shared memory. + for (var a_offset = local_idx; a_offset < ${aLengthPerTile}; a_offset += ${workgroupSize}) + { + let a_col = a_col_start + a_offset; + if (a_col < uniforms.a_shape[2]) + { + sub_a[a_offset] = ${a.getByIndices(`${a.type.indices}(batch, row, a_col)`)}; + } else { + sub_a[a_offset] = ${a.type.value}(0); + } + } + workgroupBarrier(); + + // each thread process one block + let b_row = col + local_id.y; + let block = tile * ${blocksPerTile} + local_id.x; + ${zeroPoints ? ` + let zero_point_bytes_per_col = (n_blocks_per_col + 1) / 2; + let zero_point_byte_count = b_row * zero_point_bytes_per_col + (block >> 0x1u); + let zero_point_word_index = zero_point_byte_count >> 0x2u; + let zero_point_byte_offset = zero_point_byte_count & 0x3u; + let zero_point_nibble_offset: u32 = block & 0x1u; + let zero_point_bits_offset = (zero_point_byte_offset << 3) + (zero_point_nibble_offset << 2); + let zero_point_word = ${zeroPoints.getByOffset("zero_point_word_index")} >> zero_point_bits_offset; + let zero_point = ${dataType2}((zero_point_word) & 0xFu);` : ` + // The default zero point is 8 for unsigned 4-bit quantization. + let zero_point = ${dataType2}(${8});`} + let scale = ${scales.getByOffset(`b_row * n_blocks_per_col + block`)}; + let b_data = ${b.getByIndices(`${b.type.indices}(b_row, block, 0)`)}; + var word_offset = local_id.x * ${attributes.blockSize / aComponents}; + for (var i: u32 = 0; i < ${bComponents}; i++) { + ${readA()} + let b_value = ${bComponents === 1 ? `b_data` : `b_data[i]`}; + let b_value_lower = unpack4xU8(b_value & 0x0F0F0F0Fu); + let b_value_upper = unpack4xU8((b_value >> 4) & 0x0F0F0F0Fu); + let b_quantized_values = mat2x4<${dataType2}>(${Array.from( + { length: 4 }, + (_, i) => `${dataType2}(b_value_lower[${i}]), ${dataType2}(b_value_upper[${i}])` + ).join(", ")}); + let b_dequantized_values = (b_quantized_values - mat2x4<${dataType2}>(${Array(8).fill("zero_point").join(",")})) * scale; + inter_results[local_id.y][local_id.x] += ${Array.from( + { length: 2 }, + (_, i) => `${`dot(a_data${i}, b_dequantized_values[${i}])`}` + ).join(" + ")}; + word_offset += ${8 / aComponents}; + } + workgroupBarrier(); + } + + if (local_idx < ${workgroupY}) { + var output_value: ${output.type.value} = ${output.type.value}(0); + for (var b = 0u; b < ${workgroupX}; b++) { + output_value += inter_results[local_idx][b]; + } + if (col + local_idx < uniforms.output_shape[2]) + { + ${output.setByIndices(`${output.type.indices}(batch, row, col + local_idx)`, "output_value")} + } + } + }`; + }; + return { + name: "BlockwiseMatMulNBits32", + shaderCache: { + hint: `${attributes.blockSize};${aComponents};${bComponents};${workgroupX};${workgroupY}`, + inputDependencies: Array(inputs.length).fill("rank") + }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType }], + dispatchGroup: { x: dispatchSize }, + programUniforms + }), + getShaderSource + }; + }; + matMulNBits = (context, attributes) => { + validateInputs48(context.inputs, attributes); + if (attributes.blockSize === 32 && context.adapterInfo.isVendor("intel") && context.adapterInfo.isArchitecture("gen-12lp")) { + context.compute(createMatMulNBitsBlockSize32ProgramInfo(context.inputs, attributes)); + } else { + context.compute(createMatMulNBitsProgramInfo(context.inputs, attributes)); + } + }; + parseMatMulNBitsAttributes = (attributes) => createAttributeWithCacheKey2(attributes); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/pad.ts + var validateInputs49, getPadConstant2, getPadReflect2, getPadEdge2, getPadWrap, getPadSnippet, createPadProgramInfo2, createPadAttributesFromInputs, pad; + var init_pad2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/pad.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + validateInputs49 = (inputs) => { + if (!inputs || inputs.length < 1) { + throw new Error("Too few inputs"); + } + if (inputs[0].dataType !== 1 /* float */ && inputs[0].dataType !== 10 /* float16 */) { + throw new Error("Input type must be float or float16."); + } + if (inputs.length >= 2) { + let validPads = inputs[0].dims.length * 2 === inputs[1].dims[0]; + if (inputs.length === 4) { + validPads = inputs[3].dims[0] * 2 === inputs[1].dims[0]; + } + if (!validPads) { + throw new Error("The pads should be a 1D tensor of shape [2 * input_rank] or [2 * num_axes]."); + } + } + }; + getPadConstant2 = (output, inputRank, padsLength) => { + let block = ""; + for (let i = inputRank - 1; i >= 0; --i) { + block += ` + k = i32(${output.indicesGet("indices", i)}) - ${getElementAt("uniforms.pads", i, padsLength)}; + if (k < 0) { + break; + } + if (k >= i32(${getElementAt("uniforms.x_shape", i, inputRank)})) { + break; + } + offset += k * i32(${getElementAt("uniforms.x_strides", i, inputRank)}); + `; + } + return ` + value = ${output.type.value}(uniforms.constant_value); + for (var i = 0; i < 1; i++) { + var offset = 0; + var k = 0; + ${block} + value = x[offset]; + } + `; + }; + getPadReflect2 = (output, inputRank, padsLength) => { + let block = ""; + for (let i = inputRank - 1; i >= 0; --i) { + block += ` + k = i32(${output.indicesGet("indices", i)}) - ${getElementAt("uniforms.pads", i, padsLength)}; + if (k < 0) { + k = -k; + } + { + let _2n_1 = 2 * (i32(${getElementAt("uniforms.x_shape", i, inputRank)}) - 1); + k = k % _2n_1; + if(k >= i32(${getElementAt("uniforms.x_shape", i, inputRank)})) { + k = _2n_1 - k; + } + } + offset += k * i32(${getElementAt("uniforms.x_strides", i, inputRank)}); + `; + } + return ` + var offset = 0; + var k = 0; + ${block} + value = x[offset]; + `; + }; + getPadEdge2 = (output, inputRank, padsLength) => { + let block = ""; + for (let i = inputRank - 1; i >= 0; --i) { + block += ` + k = i32(${output.indicesGet("indices", i)}) - ${getElementAt("uniforms.pads", i, padsLength)}; + if (k < 0) { + k = 0; + } + if (k >= i32(${getElementAt("uniforms.x_shape", i, inputRank)})) { + k = i32(${getElementAt("uniforms.x_shape", i, inputRank)}) - 1; + } + offset += k * i32(${getElementAt("uniforms.x_strides", i, inputRank)}); + `; + } + return ` + var offset = 0; + var k = 0; + ${block} + value = x[offset]; + `; + }; + getPadWrap = (output, inputRank, padsLength) => { + let block = ""; + for (let i = inputRank - 1; i >= 0; --i) { + block += ` + k = i32(${output.indicesGet("indices", i)}) - ${getElementAt("uniforms.pads", i, padsLength)}; + if (k < 0) { + k += i32(${getElementAt("uniforms.x_shape", i, inputRank)}]); + } + if (k >= i32(${getElementAt("uniforms.x_shape", i, inputRank)})) { + k -= i32(${getElementAt("uniforms.x_shape", i, inputRank)}); + } + offset += k * i32(${getElementAt("uniforms.x_strides", i, inputRank)}); + `; + } + return ` + var offset = 0; + var k = 0; + ${block} + value = x[offset]; + `; + }; + getPadSnippet = (output, inputRank, attributes) => { + switch (attributes.mode) { + case 0: + return getPadConstant2(output, inputRank, attributes.pads.length); + case 1: + return getPadReflect2(output, inputRank, attributes.pads.length); + case 2: + return getPadEdge2(output, inputRank, attributes.pads.length); + case 3: + return getPadWrap(output, inputRank, attributes.pads.length); + default: + throw new Error("Invalid mode"); + } + }; + createPadProgramInfo2 = (inputs, attributes) => { + const outputShape = ShapeUtil2.padShape(inputs[0].dims.slice(), attributes.pads); + const inputDims = inputs[0].dims; + const outputSize = ShapeUtil2.size(outputShape); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 6 /* int32 */, data: attributes.pads } + ]; + const isValueFromInput = inputs.length >= 3 && inputs[2].data; + if (attributes.mode === 0) { + programUniforms.push({ type: isValueFromInput ? inputs[2].dataType : 1 /* float */, data: attributes.value }); + } + programUniforms.push(...createTensorShapeVariables(inputs[0].dims, outputShape)); + const inputDependencies = ["rank"]; + const getShaderSource = (shaderHelper) => { + const output = outputVariable("output", inputs[0].dataType, outputShape.length); + const input = inputVariable("x", inputs[0].dataType, inputDims.length); + const dataType = input.type.value; + const padSnippet = getPadSnippet(output, inputDims.length, attributes); + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "pads", type: "i32", length: attributes.pads.length } + ]; + if (attributes.mode === 0) { + uniforms.push({ name: "constant_value", type: isValueFromInput ? dataType : "f32" }); + } + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(input, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + + let indices = ${output.offsetToIndices("global_idx")}; + + var value = ${dataType}(0); + ${padSnippet} + output[global_idx] = value; + }`; + }; + return { + name: "Pad", + shaderCache: { hint: `${attributes.mode}${isValueFromInput}`, inputDependencies }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + ShapeUtil2.size(outputShape) / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + createPadAttributesFromInputs = (inputs, attributes) => { + if (inputs.length > 1) { + const bigInt64Pads = inputs[1].getBigInt64Array(); + const value = inputs.length >= 3 && inputs[2].data ? inputs[2].dataType === 10 /* float16 */ ? inputs[2].getUint16Array()[0] : inputs[2].getFloat32Array()[0] : 0; + const inputRank = inputs[0].dims.length; + const updatePads = new Int32Array(2 * inputRank).fill(0); + if (inputs.length >= 4) { + const axes = inputs[3].getBigInt64Array(); + for (let i = 0; i < axes.length; i++) { + updatePads[Number(axes[i])] = Number(bigInt64Pads[i]); + updatePads[Number(axes[i]) + inputRank] = Number(bigInt64Pads[i + axes.length]); + } + } else { + bigInt64Pads.forEach((v, i) => updatePads[Number(i)] = Number(v)); + } + const pads = []; + updatePads.forEach((v) => pads.push(v)); + return { mode: attributes.mode, value, pads }; + } else { + return attributes; + } + }; + pad = (context, attributes) => { + validateInputs49(context.inputs); + const updatedAttributes = createPadAttributesFromInputs(context.inputs, attributes); + context.compute(createPadProgramInfo2(context.inputs, updatedAttributes), { inputs: [0] }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/pool.ts + var validateInputs50, getAdjustedPoolAttributesAndOutputShape2, getUniformAndPadInfo, generatePoolingCode2, createShaderKeyFromAttributes, createAveragePoolShaderKeyFromAttributes, createMaxPoolShaderKeyFromAttributes, parsePoolCommonAttributes, createAveragePoolProgramInfo2, parseAveragePoolAttributes2, averagePool2, globalPoolAttributes, parseGlobalAveragePoolAttributes2, globalAveragePool2, createMaxPoolProgramInfo2, maxPool2, parseMaxPoolAttributes2, parseGlobalMaxPoolAttributes, globalMaxPool2; + var init_pool2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/pool.ts"() { + "use strict"; + init_esm(); + init_wasm_common(); + init_util2(); + init_common(); + validateInputs50 = (inputs) => { + if (env2.webgpu.validateInputContent && (!inputs || inputs.length !== 1)) { + throw new Error("Pool ops requires 1 input."); + } + }; + getAdjustedPoolAttributesAndOutputShape2 = (input, attributes, isGlobalOperator) => { + const isChannelsLast = attributes.format === "NHWC"; + const inputShapeAsChannelFirst = input.dims.slice(); + if (isChannelsLast) { + inputShapeAsChannelFirst.splice(1, 0, inputShapeAsChannelFirst.pop()); + } + 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(); + PoolConvUtil2.adjustPoolAttributes(isGlobalOperator, inputShapeAsChannelFirst, kernelShape, strides, dilations, pads); + const outputShapeAsChannelFirst = PoolConvUtil2.computePoolOutputShape( + isGlobalOperator, + inputShapeAsChannelFirst, + 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 }); + } + const outputShapeAsChannelLast = outputShapeAsChannelFirst.slice(); + outputShapeAsChannelLast.push(outputShapeAsChannelLast.splice(1, 1)[0]); + return [newAttributes, isChannelsLast ? outputShapeAsChannelLast : outputShapeAsChannelFirst]; + }; + getUniformAndPadInfo = (outputShape, attributes) => { + const isChannelsLast = attributes.format === "NHWC"; + const outputSize = ShapeUtil2.size(outputShape); + const kernelSize = ShapeUtil2.size(attributes.kernelShape); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: kernelSize } + ]; + const uniforms = [ + { name: "outputSize", type: "u32" }, + { name: "kernelSize", type: "u32" } + ]; + 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 pwStartEndNotZero = !!(pwStart + pwEnd); + programUniforms.push( + { type: 12 /* uint32 */, data: kw }, + { type: 12 /* uint32 */, data: sw }, + { type: 12 /* uint32 */, data: pwStart }, + { type: 12 /* uint32 */, data: pwEnd } + ); + uniforms.push( + { name: "kw", type: "u32" }, + { name: "sw", type: "u32" }, + { name: "pwStart", type: "u32" }, + { name: "pwEnd", type: "u32" } + ); + let phStartEndNotZero = false; + 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]; + phStartEndNotZero = !!(phStart + phEnd); + programUniforms.push( + { type: 12 /* uint32 */, data: kh }, + { type: 12 /* uint32 */, data: sh }, + { type: 12 /* uint32 */, data: phStart }, + { type: 12 /* uint32 */, data: phEnd } + ); + uniforms.push( + { name: "kh", type: "u32" }, + { name: "sh", type: "u32" }, + { name: "phStart", type: "u32" }, + { name: "phEnd", type: "u32" } + ); + } + return [programUniforms, uniforms, true, pwStartEndNotZero, phStartEndNotZero]; + } else { + if (isChannelsLast) { + throw new Error("Pooling with kernelShape.length > 2 is not supported for NHWC format."); + } + const kernelStrides = ShapeUtil2.computeStrides(attributes.kernelShape); + programUniforms.push( + { type: 12 /* uint32 */, data: kernelStrides }, + { type: 12 /* uint32 */, data: attributes.pads }, + { type: 12 /* uint32 */, data: attributes.strides } + ); + uniforms.push( + { name: "kernelStrides", type: "u32", length: kernelStrides.length }, + { name: "pads", type: "u32", length: attributes.pads.length }, + { name: "strides", type: "u32", length: attributes.strides.length } + ); + const hasPads = attributes.pads.reduce((sum2, cur) => sum2 + cur); + return [programUniforms, uniforms, !!hasPads, false, false]; + } + }; + generatePoolingCode2 = (shaderHelper, x, rank, outputShapeRank, attributes, op1, op2, start, uniforms, hasPads, pwStartEndNotZero, phStartEndNotZero) => { + const isChannelsLast = attributes.format === "NHWC"; + const dataType = x.type.value; + const output = outputVariable("output", x.type.tensor, outputShapeRank); + if (attributes.kernelShape.length <= 2) { + let codeW = ""; + let codeH = ""; + let codeHEnd = ""; + const dimIdxW = rank - (isChannelsLast ? 2 : 1); + if (pwStartEndNotZero) { + codeW = ` + for (var i: u32 = 0u; i < uniforms.kw; i++) { + xIndices[${dimIdxW}] = indices[${dimIdxW}] * uniforms.sw - uniforms.pwStart + i; + if (xIndices[${dimIdxW}] < 0 || xIndices[${dimIdxW}] + >= uniforms.x_shape[${dimIdxW}]) { + pad++; + continue; + } + let x_val = x[${x.indicesToOffset("xIndices")}]; + ${op1} + }`; + } else { + codeW = ` + for (var i: u32 = 0u; i < uniforms.kw; i++) { + xIndices[${dimIdxW}] = indices[${dimIdxW}] * uniforms.sw - uniforms.pwStart + i; + let x_val = x[${x.indicesToOffset("xIndices")}]; + ${op1} + }`; + } + if (attributes.kernelShape.length === 2) { + const dimIdxH = rank - (isChannelsLast ? 3 : 2); + if (phStartEndNotZero) { + codeH = ` + for (var j: u32 = 0u; j < uniforms.kh; j++) { + xIndices[${dimIdxH}] = indices[${dimIdxH}] * uniforms.sh - uniforms.phStart + j; + if (xIndices[${dimIdxH}] < 0 || xIndices[${dimIdxH}] >= uniforms.x_shape[${dimIdxH}]) { + pad += i32(uniforms.kw); + continue; + } + `; + } else { + codeH = ` + for (var j: u32 = 0u; j < uniforms.kh; j++) { + xIndices[${dimIdxH}] = indices[${dimIdxH}] * uniforms.sh - uniforms.phStart + j; + `; + } + codeHEnd = ` + } + `; + } + const poolingCode = ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(x, output)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + + let indices = ${output.offsetToIndices("global_idx")}; + var xIndices = ${output.offsetToIndices("global_idx")}; + + var value = ${dataType}(${start}); + var pad = 0; + ${codeH} + ${codeW} + ${codeHEnd} + ${op2} + + output[global_idx] = value; + }`; + return poolingCode; + } else { + if (isChannelsLast) { + throw new Error("Pooling with kernelShape.length > 2 is not supported for NHWC format."); + } + const stridesRank = attributes.kernelShape.length; + const padsRank = attributes.pads.length; + let padCode = ""; + if (hasPads) { + padCode = ` + if (xIndices[j] >= uniforms.x_shape[j]) { + pad++; + isPad = true; + break; + } + } + if (!isPad) { + let x_val = x[${x.indicesToOffset("xIndices")}]; + ${op1} + }`; + } else { + padCode = ` + } + let x_val = x[${x.indicesToOffset("xIndices")}]; + ${op1} + `; + } + const poolingCode = ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(x, output)} + + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + let indices = ${output.offsetToIndices("global_idx")}; + var xIndices = ${output.offsetToIndices("global_idx")}; + + var offsets: array; + + var value = ${dataType}(${start}); + var pad = 0; + var isPad = false; + + for (var i: u32 = 0u; i < uniforms.kernelSize; i++) { + var offset = i; + for (var j = 0u; j < ${stridesRank - 1}u; j++) { + offsets[j] = offset / ${getElementAt("uniforms.kernelStrides", "j", stridesRank)}; + offset -= offsets[j] * ${getElementAt("uniforms.kernelStrides", "j", stridesRank)}; + } + offsets[${stridesRank - 1}] = offset; + + isPad = false; + for (var j = ${rank - stridesRank}u; j < ${rank}u; j++) { + xIndices[j] = indices[j] * ${getElementAt( + "uniforms.strides", + `j - ${rank - stridesRank}u`, + stridesRank + )} + + offsets[j - ${rank - stridesRank}u] - ${getElementAt("uniforms.pads", "j - 2u", padsRank)}; + ${padCode} + } + ${op2} + + output[global_idx] = value; + }`; + return poolingCode; + } + }; + createShaderKeyFromAttributes = (attributes) => `${attributes.format};${attributes.ceilMode};${attributes.autoPad};${attributes.kernelShape.length}`; + createAveragePoolShaderKeyFromAttributes = (attributes) => `${createShaderKeyFromAttributes(attributes)};${attributes.countIncludePad}`; + createMaxPoolShaderKeyFromAttributes = (attributes) => `${createShaderKeyFromAttributes(attributes)};${attributes.storageOrder};${attributes.dilations}`; + parsePoolCommonAttributes = (attributes) => ({ + format: attributes.format, + autoPad: ["NOTSET", "VALID", "SAME_UPPER", "SAME_LOWER"][attributes.auto_pad], + ceilMode: attributes.ceil_mode, + kernelShape: attributes.kernel_shape, + strides: attributes.strides, + pads: attributes.pads + }); + createAveragePoolProgramInfo2 = (name2, input, isGlobalOperator, attributes) => { + const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape2( + input, + attributes, + isGlobalOperator + ); + const x = inputVariable("x", input.dataType, input.dims.length); + const dataType = x.type.value; + const op1 = "value += x_val;"; + let op2 = ""; + if (adjustedAttributes.countIncludePad) { + op2 += `value /= ${dataType}(uniforms.kernelSize);`; + } else { + op2 += `value /= ${dataType}(i32(uniforms.kernelSize) - pad);`; + } + const [programUniforms, uniforms, hasPads, pwStartEndNotZero, phStartEndNotZero] = getUniformAndPadInfo( + outputShape, + adjustedAttributes + ); + programUniforms.push(...createTensorShapeVariables(input.dims, outputShape)); + const inputDependencies = ["rank"]; + return { + name: name2, + shaderCache: { + hint: `${attributes.cacheKey};${hasPads};${pwStartEndNotZero};${phStartEndNotZero}`, + inputDependencies + }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: input.dataType }], + dispatchGroup: { x: Math.ceil( + ShapeUtil2.size(outputShape) / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource: (shaderHelper) => generatePoolingCode2( + shaderHelper, + x, + input.dims.length, + outputShape.length, + adjustedAttributes, + op1, + op2, + 0, + uniforms, + hasPads, + pwStartEndNotZero, + phStartEndNotZero + ) + }; + }; + parseAveragePoolAttributes2 = (attributes) => { + const countIncludePad = attributes.count_include_pad === 0 ? false : true; + const attr = parsePoolCommonAttributes(attributes); + if (attr.ceilMode !== 0) { + throw new Error("using ceil() in shape computation is not yet supported for AveragePool"); + } + const averagePoolAttributes = { countIncludePad, ...attr, cacheKey: "" }; + return { ...averagePoolAttributes, cacheKey: createAveragePoolShaderKeyFromAttributes(averagePoolAttributes) }; + }; + averagePool2 = (context, attributes) => { + validateInputs50(context.inputs); + context.compute(createAveragePoolProgramInfo2("AveragePool", context.inputs[0], false, attributes)); + }; + globalPoolAttributes = { + autoPad: "", + ceilMode: 0, + countIncludePad: false, + kernelShape: [], + strides: [], + pads: [], + storageOrder: 0, + dilations: [] + }; + parseGlobalAveragePoolAttributes2 = (attributes) => { + const format = attributes.format; + return { format, ...globalPoolAttributes, cacheKey: format }; + }; + globalAveragePool2 = (context, attributes) => { + validateInputs50(context.inputs); + context.compute(createAveragePoolProgramInfo2("GlobalAveragePool", context.inputs[0], true, attributes)); + }; + createMaxPoolProgramInfo2 = (name2, input, isGlobalOperator, attributes) => { + const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape2( + input, + attributes, + isGlobalOperator + ); + const op1 = ` + value = max(x_val, value); + `; + const op2 = ""; + const x = inputVariable("x", input.dataType, input.dims.length); + const inputDependencies = ["rank"]; + const [programUniforms, uniforms, hasPads, pwStartEndNotZero, phStartEndNotZero] = getUniformAndPadInfo( + outputShape, + adjustedAttributes + ); + programUniforms.push(...createTensorShapeVariables(input.dims, outputShape)); + return { + name: name2, + shaderCache: { + hint: `${attributes.cacheKey};${hasPads};${pwStartEndNotZero};${phStartEndNotZero}`, + inputDependencies + }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: input.dataType }], + dispatchGroup: { x: Math.ceil( + ShapeUtil2.size(outputShape) / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource: (shaderHelper) => generatePoolingCode2( + shaderHelper, + x, + input.dims.length, + outputShape.length, + adjustedAttributes, + op1, + op2, + input.dataType === 10 /* float16 */ ? -65504 : -1e5, + uniforms, + hasPads, + pwStartEndNotZero, + phStartEndNotZero + ) + }; + }; + maxPool2 = (context, attributes) => { + validateInputs50(context.inputs); + context.compute(createMaxPoolProgramInfo2("MaxPool", context.inputs[0], false, attributes)); + }; + parseMaxPoolAttributes2 = (attributes) => { + const storageOrder = attributes.storage_order; + const dilations = attributes.dilations; + const attr = parsePoolCommonAttributes(attributes); + if (storageOrder !== 0) { + throw new Error("column major storage order is not yet supported for MaxPool"); + } + if (attr.ceilMode !== 0) { + throw new Error("using ceil() in shape computation is not yet supported for MaxPool"); + } + const maxPoolAttributes = { storageOrder, dilations, ...attr, cacheKey: "" }; + return { ...maxPoolAttributes, cacheKey: createMaxPoolShaderKeyFromAttributes(maxPoolAttributes) }; + }; + parseGlobalMaxPoolAttributes = (attributes) => { + const format = attributes.format; + return { format, ...globalPoolAttributes, cacheKey: format }; + }; + globalMaxPool2 = (context, attributes) => { + validateInputs50(context.inputs); + context.compute(createMaxPoolProgramInfo2("GlobalMaxPool", context.inputs[0], true, attributes)); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/quantize-linear.ts + var validateInputs51, createDequantizeLinearProgramInfo, dequantizeLinear, parseDequantizeLinearAttributes; + var init_quantize_linear = __esm({ + "web/lib/wasm/jsep/webgpu/ops/quantize-linear.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs51 = (inputs, attributes) => { + if (inputs.length < 2 || inputs.length > 3) { + throw new Error("DequantizeLinear requires 2 or 3 inputs."); + } + if (inputs.length === 3 && inputs[1].dims === inputs[2].dims) { + throw new Error("x-scale and x-zero-point must have the same shape."); + } + if (inputs.length === 3 && inputs[0].dataType !== inputs[2].dataType) { + throw new Error("x and x-zero-point must have the same data type."); + } + if (inputs[0].dataType === 6 /* int32 */ && inputs.length > 2) { + throw new Error("In the case of dequantizing int32 there is no zero point."); + } + if (inputs[1].dims.length !== 0 && inputs[1].dims.length !== 1 && inputs[1].dims.length !== inputs[0].dims.length) { + throw new Error("scale input must be a scalar, a 1D tensor, or have the same rank as the input tensor."); + } + if (inputs.length > 2) { + if (inputs[0].dataType !== inputs[2].dataType) { + throw new Error("x and x-zero-point must have the same data type."); + } + if (inputs[1].dims.length !== inputs[2].dims.length) { + throw new Error("scale and zero-point inputs must have the same rank."); + } + if (!inputs[1].dims.map((d, i) => d === inputs[2].dims[i]).reduce((a, b) => a && b, true)) { + throw new Error("scale and zero-point inputs must have the same shape."); + } + } + if (attributes.blockSize > 0) { + if (inputs[1].dims.length === 0 || inputs[1].dims.length === 1 && inputs[1].dims[0] === 1) { + throw new Error("blockSize must be set only for block quantization."); + } + if (!inputs[1].dims.map((d, i) => i === attributes.axis || d === inputs[0].dims[i]).reduce((a, b) => a && b, true)) { + throw new Error("For block qunatization, scale input shape to match the input shape except for the axis"); + } + if (inputs[1].dims.length !== inputs[0].dims.length) { + throw new Error("For block qunatization the scale input rank must be the same as the x rank."); + } + const dI = inputs[0].dims[attributes.axis]; + const si = inputs[1].dims[attributes.axis]; + if (attributes.blockSize < Math.ceil(dI / si) || attributes.blockSize > Math.ceil(dI / (si - 1) - 1)) { + throw new Error("blockSize must be with in the range [ceil(dI / Si), ceil(dI / (Si - 1) - 1)]."); + } + } + }; + createDequantizeLinearProgramInfo = (inputs, attributes) => { + const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputs[0].dims.length); + const inputType = inputs[0].dataType; + const isSigned = inputType === 3 /* int8 */; + const outputShape = inputs[0].dims; + const dataType = inputs[1].dataType; + const outputSize = ShapeUtil2.size(outputShape); + const isPacked = inputType === 3 /* int8 */ || inputType === 2 /* uint8 */; + const inputShape = isPacked ? [Math.ceil(ShapeUtil2.size(inputs[0].dims) / 4)] : inputs[0].dims; + const scaleShape = inputs[1].dims; + const zeroPointInput = inputs.length > 2 ? inputs[2] : void 0; + const zeroPointShape = zeroPointInput ? isPacked ? [Math.ceil(ShapeUtil2.size(zeroPointInput.dims) / 4)] : zeroPointInput.dims : void 0; + const perLayerQuantization = scaleShape.length === 0 || scaleShape.length === 1 && scaleShape[0] === 1; + const perAxisQuantization = perLayerQuantization === false && scaleShape.length === 1; + const maxComponents = getMaxComponents(outputSize); + const useComponents = perLayerQuantization && (!isPacked || maxComponents === 4); + const components = useComponents ? maxComponents : 1; + const inputComponent = useComponents && !isPacked ? maxComponents : 1; + const input = inputVariable("input", isPacked ? 12 /* uint32 */ : inputType, inputShape.length, inputComponent); + const scale = inputVariable("scale", dataType, scaleShape.length); + const zeroPoint = zeroPointInput ? inputVariable("zero_point", isPacked ? 12 /* uint32 */ : inputType, zeroPointShape.length) : void 0; + const output = outputVariable("output", dataType, outputShape.length, components); + const inputVariables = [input, scale]; + if (zeroPoint) { + inputVariables.push(zeroPoint); + } + const inputShapes = [inputShape, scaleShape]; + if (zeroPointInput) { + inputShapes.push(zeroPointShape); + } + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize / components }, + { type: 12 /* uint32 */, data: axis }, + { type: 12 /* uint32 */, data: attributes.blockSize }, + ...createTensorShapeVariables(...inputShapes, outputShape) + ]; + const getShaderSource = (shaderHelper) => { + const uniforms = [ + { name: "output_size", type: "u32" }, + { name: "axis", type: "u32" }, + { name: "block_size", type: "u32" } + ]; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(...inputVariables, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let output_indices = ${output.offsetToIndices("global_idx")}; + + // Set input x + ${(() => { + if (isPacked) { + return ` + let input = ${input.getByOffset("global_idx / 4")}; + let x_vec = ${isSigned ? "unpack4xI8(input)" : "unpack4xU8(input)"}; + let x_value = ${components === 1 ? "x_vec[global_idx % 4]" : "x_vec"};`; + } else { + return `let x_value = ${input.getByOffset("global_idx")};`; + } + })()}; + + // Set scale input + ${(() => { + if (perLayerQuantization) { + return `let scale_value= ${scale.getByOffset("0")}`; + } else if (perAxisQuantization) { + return ` + let scale_index = ${output.indicesGet("output_indices", "uniforms.axis")}; + let scale_value= ${scale.getByOffset("scale_index")};`; + } else { + return ` + var scale_indices: ${scale.type.indices} = output_indices; + let index = ${scale.indicesGet("scale_indices", "uniforms.axis")} / uniforms.block_size; + ${scale.indicesSet("scale_indices", "uniforms.axis", "index")}; + let scale_value= ${scale.getByIndices("scale_indices")};`; + } + })()}; + + // Set zero-point input + ${(() => { + if (zeroPoint) { + if (perLayerQuantization) { + if (isPacked) { + return ` + let zero_point_input = ${zeroPoint.getByOffset("0")}; + let zero_point_vec = ${isSigned ? "unpack4xI8(zero_point_input)" : "unpack4xU8(zero_point_input)"}; + let zero_point_value= zero_point_vec[0]`; + } else { + return `let zero_point_value = ${zeroPoint.getByOffset("0")}`; + } + } else if (perAxisQuantization) { + if (isPacked) { + return ` + let zero_point_index = ${output.indicesGet("output_indices", "uniforms.axis")}; + let zero_point_input = ${zeroPoint.getByOffset("zero_point_index / 4")}; + let zero_point_vec = ${isSigned ? "unpack4xI8(zero_point_input)" : "unpack4xU8(zero_point_input)"}; + let zero_point_value = zero_point_vec[zero_point_index % 4]`; + } else { + return ` + let zero_point_index = ${output.indicesGet("output_indices", "uniforms.axis")}; + let zero_point_value = ${zeroPoint.getByOffset("zero_point_index")};`; + } + } else { + if (isPacked) { + return ` + let zero_point_offset = ${scale.indicesToOffset("scale_indices")}; + let zero_point_input = ${zeroPoint.getByOffset("zero_point_offset / 4")}; + let zero_point_vec = ${isSigned ? "unpack4xI8(zero_point_input)" : "unpack4xU8(zero_point_input)"}; + let zero_point_value = zero_point_vec[zero_point_offset % 4];`; + } else { + return `let zero_point_value = ${zeroPoint.getByIndices("scale_indices")};`; + } + } + } else { + return `let zero_point_value = ${isPacked ? isSigned ? "i32" : "u32" : input.type.value}(0);`; + } + })()}; + // Compute and write output + ${output.setByOffset("global_idx", `${output.type.value}(x_value - zero_point_value) * scale_value`)}; + }`; + }; + return { + name: "DequantizeLinear", + shaderCache: { + hint: attributes.cacheKey, + inputDependencies: zeroPoint ? ["rank", "rank", "rank"] : ["rank", "rank"] + }, + getShaderSource, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType }], + dispatchGroup: { x: Math.ceil(outputSize / components / 64), y: 1, z: 1 }, + programUniforms + }) + }; + }; + dequantizeLinear = (context, attributes) => { + validateInputs51(context.inputs, attributes); + context.compute(createDequantizeLinearProgramInfo(context.inputs, attributes)); + }; + parseDequantizeLinearAttributes = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis, blockSize: attributes.blockSize }); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/range.ts + var validateInputsContent, createRangeProgramInfo, range; + var init_range = __esm({ + "web/lib/wasm/jsep/webgpu/ops/range.ts"() { + "use strict"; + init_esm(); + init_wasm_common(); + init_common(); + validateInputsContent = (start, limit, delta) => { + const sameStartLimit = start === limit; + const increasingRangeNegativeStep = start < limit && delta < 0; + const decreasingRangePositiveStep = start > limit && delta > 0; + if (sameStartLimit || increasingRangeNegativeStep || decreasingRangePositiveStep) { + throw new Error("Range these inputs' contents are invalid."); + } + }; + createRangeProgramInfo = (start, limit, delta, dataType) => { + const numElements = Math.abs(Math.ceil((limit - start) / delta)); + const outputShape = [numElements]; + const outputSize = numElements; + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: dataType, data: start }, + { type: dataType, data: delta }, + ...createTensorShapeVariables(outputShape) + ]; + const getShaderSource = (shaderHelper) => { + const output = outputVariable("output", dataType, outputShape.length); + const wgslType = output.type.value; + const uniforms = [ + { name: "outputSize", type: "u32" }, + { name: "start", type: wgslType }, + { name: "delta", type: wgslType } + ]; + return ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + output[global_idx] = uniforms.start + ${wgslType}(global_idx) * uniforms.delta; + }`; + }; + return { + name: "Range", + shaderCache: { hint: `${dataType}` }, + getShaderSource, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }) + }; + }; + range = (context) => { + let start = 0; + let limit = 0; + let delta = 0; + if (context.inputs[0].dataType === 6 /* int32 */) { + start = context.inputs[0].getInt32Array()[0]; + limit = context.inputs[1].getInt32Array()[0]; + delta = context.inputs[2].getInt32Array()[0]; + } else if (context.inputs[0].dataType === 1 /* float */) { + start = context.inputs[0].getFloat32Array()[0]; + limit = context.inputs[1].getFloat32Array()[0]; + delta = context.inputs[2].getFloat32Array()[0]; + } + if (env2.webgpu.validateInputContent) { + validateInputsContent(start, limit, delta); + } + context.compute(createRangeProgramInfo(start, limit, delta, context.inputs[0].dataType), { inputs: [] }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/scatter-nd.ts + var atomicReductionSnippet, createScatterNDProgramInfo, parseScatterNDAttributes, scatterND; + var init_scatter_nd = __esm({ + "web/lib/wasm/jsep/webgpu/ops/scatter-nd.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + atomicReductionSnippet = (reduction, ptr, v, type) => { + if (reduction !== "none" && type !== "i32" && type !== "u32" && type !== "f32") { + throw new Error(`Input ${type} is not supported with reduction ${reduction}.`); + } + const floatStart = `{ + var oldValue = 0; + loop { + let newValueF32 =`; + const floatEnd = `; + let newValue = bitcast(newValueF32); + let res = atomicCompareExchangeWeak(&${ptr}, oldValue, newValue); + if res.exchanged { + break; + } + oldValue = res.old_value; + } + }`; + switch (reduction) { + case "none": + return `${ptr}=${v};`; + case "add": + if (type === "i32" || type === "u32") { + return `atomicAdd(&${ptr}, bitcast<${type}>(${v}));`; + } else { + return ` + ${floatStart}bitcast<${type}>(oldValue) + (${v})${floatEnd}`; + } + case "max": + if (type === "i32" || type === "u32") { + return `atomicMax(&${ptr}, bitcast<${type}>(${v}));`; + } else { + return ` + ${floatStart}max(bitcast(oldValue), (${v}))${floatEnd}`; + } + case "min": + if (type === "i32" || type === "u32") { + return `atomicMin(&${ptr}, bitcast<${type}>(${v}));`; + } else { + return `${floatStart}min(bitcast<${type}>(oldValue), (${v}))${floatEnd}`; + } + case "mul": + return `${floatStart}(bitcast<${type}>(oldValue) * (${v}))${floatEnd}`; + default: + throw new Error(`Reduction ${reduction} is not supported.`); + } + }; + createScatterNDProgramInfo = (inputs, attributes) => { + const inputShape = inputs[0].dims; + const indicesShape = inputs[1].dims; + const outputShape = inputShape; + const components = 1; + const outputSize = Math.ceil(ShapeUtil2.sizeToDimension(indicesShape, indicesShape.length - 1) / components); + const lastIndexDimension = indicesShape[indicesShape.length - 1]; + const numUpdatesElements = ShapeUtil2.sizeFromDimension(inputShape, lastIndexDimension); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: lastIndexDimension }, + { type: 12 /* uint32 */, data: numUpdatesElements }, + ...createTensorShapeVariables(inputs[1].dims, inputs[2].dims, outputShape) + ]; + const getShaderSource = (shaderHelper) => { + const indices = inputVariable("indices", inputs[1].dataType, inputs[1].dims.length); + const updates = inputVariable("updates", inputs[2].dataType, inputs[2].dims.length, components); + const output = attributes.reduction !== "none" && attributes.reduction !== "" ? atomicOutputVariable("output", inputs[0].dataType, outputShape.length) : outputVariable("output", inputs[0].dataType, outputShape.length, components); + return ` + ${shaderHelper.registerUniform("output_size", "u32").registerUniform("last_index_dimension", "u32").registerUniform("num_updates_elements", "u32").declareVariables(indices, updates, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + var data_offset = 0u; + let indices_start = uniforms.last_index_dimension * global_idx; + let indices_end = indices_start + uniforms.last_index_dimension; + for (var i = indices_start; i < indices_end; i++) { + var index = i32(indices[i].x); + ${inputs[0].dims.length === 1 ? ` + let element_count_dim = uniforms.output_strides; + let dim_value = uniforms.output_shape;` : ` + let element_count_dim = uniforms.output_strides[i - indices_start]; + let dim_value = uniforms.output_shape[i - indices_start];`} + if (index >= 0) { + if (index >= i32(dim_value)) { + index = i32(dim_value - 1); + } + } else { + if (index < -i32(dim_value)) { + index = 0; + } else { + index += i32(dim_value); + } + } + data_offset += u32((u32(index) * element_count_dim)); + } + + for (var i = 0u; i < uniforms.num_updates_elements; i++) { + let value = updates[uniforms.num_updates_elements * global_idx + i]; + ${atomicReductionSnippet( + attributes.reduction, + "output[data_offset + i]", + "value", + output.type.value + )} + } + + }`; + }; + return { + name: "ScatterND", + shaderCache: { + hint: `${attributes.cacheKey}_${attributes.reduction}`, + inputDependencies: ["rank", "rank"] + }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }), + getShaderSource + }; + }; + parseScatterNDAttributes = (attributes) => createAttributeWithCacheKey2({ reduction: attributes.reduction }); + scatterND = (context, attributes) => { + context.compute(createScatterNDProgramInfo(context.inputs, attributes), { + inputs: [context.inputs[1], context.inputs[2]], + outputs: [] + }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/resize.ts + var validateScales, updateScales, validateInputs52, getSafeIntegerDivision, getOriginalCoordinateFromResizedCoordinate, getNearestPixelFromOriginal, updateRoI, initOutputShape, adjustOutputShape, calculateOriginalIndicesFromOutputIndices, calculateInputIndicesFromOutputIndices, checkInputIndices, setChannelAndBatchIndices, bilinearInterpolation, bicubicInterpolation, trilinearInterpolation, createResizeProgramInfo, getOpsetVersionFromCustomDataBuffer, resize2, parseResizeAttributes; + var init_resize = __esm({ + "web/lib/wasm/jsep/webgpu/ops/resize.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateScales = (scales, attributes) => { + scales.every( + (value) => value > 0 || (() => { + throw new Error("Resize requires scales input values to be positive"); + }) + ); + if (scales.length > 0) { + if (attributes.mode === "linear") { + if (!(scales.length === 2 || scales.length === 3 || scales.length === 4 && scales[0] === 1 && scales[1] === 1 || scales.length === 4 && scales[0] === 1 && scales[3] === 1 || scales.length === 5 && scales[0] === 1 && scales[1] === 1)) { + throw new Error( + `For linear mode, Resize requires scales to be 2D, 3D, 4D with either two outermost or one innermost and + one outermost scale values equal to 1, or 5D with two outermost scale values equal to 1` + ); + } + } else if (attributes.mode === "cubic") { + if (!(scales.length === 2 || scales.length === 4 && scales[0] === 1 && scales[1] === 1 || scales.length === 4 && scales[0] === 1 && scales[3] === 1)) { + throw new Error("Resize requires scales input size to be 2 or 4 for cubic mode"); + } + } + } + }; + updateScales = (scales, axes, rank) => { + axes.every( + (value) => value >= 0 && value < rank || (() => { + throw new Error("Resize requires axes input values to be positive and less than rank"); + }) + ); + const newScales = new Array(rank).fill(1); + axes.forEach((value, index) => newScales[value] = scales[index]); + return newScales; + }; + validateInputs52 = (inputs, attributes, opsetVersion, scales, sizes, roi) => { + const [roiInputIndex, scalesInputIndex, sizesInputIndex] = opsetVersion > 10 ? [1, 2, 3] : [-1, inputs.length > 1 ? 1 : -1, -1]; + const rank = inputs[0].dims.length; + if (roiInputIndex > 0 && inputs.length > roiInputIndex && inputs[roiInputIndex].dims.length > 0) { + inputs[roiInputIndex].getFloat32Array().forEach((value) => roi.push(value)); + } else if (attributes.coordinateTransformMode === "tf_crop_and_resize") { + throw new Error("Resize requires RoI input to be specified when coordinateTransformMode is tfCropAndResize"); + } + if (scalesInputIndex > 0 && inputs.length > scalesInputIndex && inputs[scalesInputIndex].dims.length === 1 && inputs[scalesInputIndex].dims[0] > 0) { + inputs[scalesInputIndex].getFloat32Array().forEach((value) => scales.push(value)); + if (scales.length !== 0 && scales.length !== rank && opsetVersion >= 18 && scales.length !== attributes.axes.length) { + throw new Error("Resize requires scales input size to be same as input rank or axes size for opset 18 and up"); + } + validateScales(scales, attributes); + if (attributes.axes.length > 0) { + updateScales(scales, attributes.axes, rank).forEach((value, index) => scales[index] = value); + } + } + if (sizesInputIndex > 0 && inputs.length > sizesInputIndex && inputs[sizesInputIndex].dims.length === 1 && inputs[sizesInputIndex].dims[0] > 0) { + inputs[sizesInputIndex].getBigInt64Array().forEach((value) => sizes.push(Number(value))); + if (sizes.length !== 0 && sizes.length !== rank && opsetVersion >= 18 && sizes.length !== attributes.axes.length) { + throw new Error("Resize requires sizes input size to be same as input rank or axes size for opset 18 and up"); + } + } + if (attributes.axes.length > 0) { + if (scales.length !== 0 && scales.length !== attributes.axes.length) { + throw new Error('Resize requires "scales" input size to be of axes rank when axes attributes is specified'); + } + if (sizes.length !== 0 && sizes.length !== attributes.axes.length) { + throw new Error('Resize requires "sizes" input size to be of rank axes rank when axes attributes is specified'); + } + } + if (typeof scales !== "undefined" && typeof sizes !== "undefined" && scales.length > 0 && sizes.length > rank) { + throw new Error("Resize requires only of scales or sizes to be specified"); + } + }; + getSafeIntegerDivision = (a, b, c, dType) => ` + // The whole part and the fractional part are calculated separately due to inaccuracy of floating + // point division. As an example, f32(21) / f32(7) may evaluate to 2.99... instead of 3, causing an + // offset-by-one error later in floor(). + let big = (${a}) * (${b}); + let whole = ${dType}(big / (${c})); + let fract = ${dType}(big % (${c})) / ${dType}(${c}); + return whole + fract; +`; + getOriginalCoordinateFromResizedCoordinate = (coordinateTransferMode, dType) => `fn getOriginalCoordinateFromResizedCoordinate(xResized: u32, xScale: f32, lengthResized: u32, + lengthOriginal: u32, roiStart: f32, roiEnd: f32) -> ${dType} { ` + (() => { + switch (coordinateTransferMode) { + case "asymmetric": + return ` + if (xScale < 1.0 || floor(xScale) != xScale) { + return ${dType}(xResized) / ${dType}(xScale); + } else { + ${getSafeIntegerDivision("xResized", "lengthOriginal", "lengthResized", dType)} + } + `; + case "pytorch_half_pixel": + return `if (lengthResized > 1) { + return (${dType}(xResized) + 0.5) / ${dType}(xScale) - 0.5; + } else { + return 0.0; + }`; + case "tf_half_pixel_for_nn": + return `return (${dType}(xResized) + 0.5) / ${dType}(xScale);`; + case "align_corners": + return `if (lengthResized == 1) { + return 0.0; + } else { + ${getSafeIntegerDivision("xResized", "lengthOriginal - 1", "lengthResized - 1", dType)} + }`; + case "tf_crop_and_resize": + return `if (lengthResized > 1) { + return ${dType}(roiStart) * ${dType}(lengthOriginal - 1) + + (${dType}(xResized) * ${dType}(roiEnd - roiStart) * ${dType}(lengthOriginal - 1)) / + ${dType}(lengthResized - 1); + } else { + return 0.5 * ${dType}(roiStart + roiEnd) * ${dType}(lengthOriginal - 1); + }`; + case "half_pixel_symmetric": + return `const outputWidth = ${dType}xScale * ${dType}(lengthResized); + const adjustment = ${dType}(lengthResized) / outputWidth; + const center = ${dType}(lengthOriginal) / 2; + const offset = center * (1 - adjustment); + return offset + ((${dType}(xResized) + 0.5) / ${dType}(xScale)) - 0.5;`; + case "half_pixel": + return `return ((${dType}(xResized) + 0.5) / ${dType}(xScale)) - 0.5;`; + default: + throw new Error(`Coordinate transform mode ${coordinateTransferMode} is not supported`); + } + })() + "}"; + getNearestPixelFromOriginal = (nearestMode, opsetVersion, dType) => `fn getNearestPixelFromOriginal(xOriginal: ${dType}, isDownSample: bool) -> ${dType} {` + (() => { + switch (nearestMode) { + case "round_prefer_ceil": + return "if (fract(xOriginal) == 0.5) { return ceil(xOriginal); } else { return round(xOriginal); }"; + case "floor": + return "return floor(xOriginal);"; + case "ceil": + return "return ceil(xOriginal);"; + case "round_prefer_floor": + return "if (fract(xOriginal) == 0.5) { return floor(xOriginal); } else { return round(xOriginal); }"; + case "simple": + default: + if (opsetVersion < 11) { + return "if (isDownSample) { return ceil(xOriginal); } else { return xOriginal; }"; + } + throw new Error(`Nearest mode ${nearestMode} is not supported`); + } + })() + "}"; + updateRoI = (roi, axes, rank) => { + const roiTmp = new Array(rank).fill(0).concat(new Array(rank).fill(1)); + const roiLocal = roi.length === 0 ? roiTmp : roi.slice(); + if (axes.length > 0) { + axes.forEach((v, i) => { + roiTmp[v] = roiLocal[i]; + roiTmp[i + rank] = roiLocal[axes.length + i]; + }); + return roiTmp; + } + return roiLocal; + }; + initOutputShape = (inputShape, scales, sizes, axes) => { + let outputShape = []; + if (sizes.length > 0) { + if (axes.length > 0) { + inputShape.forEach((v) => outputShape.push(v)); + if (Math.max(...axes) > inputShape.length) { + throw new Error("axes is out of bound"); + } + axes.forEach((v, i) => outputShape[v] = sizes[i]); + } else { + sizes.forEach((v) => outputShape.push(v)); + } + } else { + if (scales.length === 0) { + throw new Error("Resize requires either scales or sizes."); + } else { + outputShape = inputShape.map((value, index) => Math.round(value * scales[index])); + } + } + return outputShape; + }; + adjustOutputShape = (inputShape, scales, attributes) => { + const scaleInPolicy = (() => { + switch (attributes.keepAspectRatioPolicy) { + case "not_larger": + return attributes.axes.length > 0 ? Math.min(...attributes.axes.map((i) => scales[i]), Number.MAX_VALUE) : Math.min(...scales, Number.MAX_VALUE); + case "not_smaller": + return attributes.axes.length > 0 ? Math.max(...attributes.axes.map((i) => scales[i]), Number.MIN_VALUE) : Math.max(...scales, Number.MIN_VALUE); + default: + throw new Error(`Keep aspect ratio policy ${attributes.keepAspectRatioPolicy} is not supported`); + } + })(); + scales.fill(1, 0, scales.length); + const adjustedOutputShape = inputShape.slice(); + if (attributes.axes.length > 0) { + attributes.axes.forEach((v) => scales[v] = scaleInPolicy); + attributes.axes.forEach((v) => adjustedOutputShape[v] = Math.round(inputShape[v] * scales[v])); + } else { + scales.fill(scaleInPolicy, 0, scales.length); + adjustedOutputShape.forEach((v, i) => adjustedOutputShape[i] = Math.round(v * scales[i])); + } + return adjustedOutputShape; + }; + calculateOriginalIndicesFromOutputIndices = (output, inputShape, outputShape, scalesLength, roiLength) => ` + fn calculateOriginalIndicesFromOutputIndices(output_indices: ${output.type.indices}) -> array<${output.type.value}, ${outputShape.length}> { + var original_indices: array<${output.type.value}, ${outputShape.length}>; + for (var i:u32 = 0; i < ${outputShape.length}; i++) { + var output_index = ${output.indicesGet("output_indices", "i")}; + var scale = ${getElementAt("uniforms.scales", "i", scalesLength)}; + var roi_low = ${getElementAt("uniforms.roi", "i", roiLength)}; + var roi_hi = ${getElementAt("uniforms.roi", `i + ${inputShape.length}`, roiLength)}; + if (scale == 1.0) { + original_indices[i] = ${output.type.value}(output_index); + } else { + var input_shape_i = ${getElementAt("uniforms.input_shape", "i", inputShape.length)}; + var output_shape_i = ${getElementAt("uniforms.output_shape", "i", outputShape.length)}; + original_indices[i] = getOriginalCoordinateFromResizedCoordinate(output_index, scale, output_shape_i, + input_shape_i, roi_low, roi_hi); + } + } + return original_indices; + }`; + calculateInputIndicesFromOutputIndices = (input, output, inputShape, outputShape, scalesLength, roiLength, useExtrapolation) => ` + fn calculateInputIndicesFromOutputIndices(output_indices: ${output.type.indices}) -> ${input.type.indices} { + var input_indices: ${input.type.indices}; + for (var i:u32 = 0; i < ${outputShape.length}; i++) { + var output_index = ${output.indicesGet("output_indices", "i")}; + var input_index: u32; + var scale = ${getElementAt("uniforms.scales", "i", scalesLength)}; + if (scale == 1.0) { + input_index = output_index; + } else { + var roi_low = ${getElementAt("uniforms.roi", "i", roiLength)}; + var roi_hi = ${getElementAt("uniforms.roi", `i + ${inputShape.length}`, roiLength)}; + var input_shape_i = ${getElementAt("uniforms.input_shape", "i", inputShape.length)}; + var output_shape_i = ${getElementAt("uniforms.output_shape", "i", outputShape.length)}; + var original_idx = getOriginalCoordinateFromResizedCoordinate(output_index, scale, output_shape_i, + input_shape_i, roi_low, roi_hi); + if (!${useExtrapolation} || (original_idx >= 0 && original_idx < ${output.type.value}(input_shape_i))) { + if (original_idx < 0) { + input_index = 0; + } else if (original_idx > ${output.type.value}(input_shape_i - 1)) { + input_index = input_shape_i - 1; + } else { + input_index = u32(getNearestPixelFromOriginal(original_idx, scale < 1)); + } + } else { + input_index = u32(original_idx); + } + } + ${input.indicesSet("input_indices", "i", "input_index")} + } + return input_indices; + }`; + checkInputIndices = (input, inputShape) => ` + fn checkInputIndices(input_indices: ${input.type.indices}) -> bool { + for (var i:u32 = 0; i < ${inputShape.length}; i++) { + var input_index = ${input.indicesGet("input_indices", "i")}; + if (input_index < 0 || input_index >= ${getElementAt("uniforms.input_shape", "i", inputShape.length)}) { + return false; + } + } + return true; + }`; + setChannelAndBatchIndices = (input, channelIdx, batchIdx, spacialDims) => input.rank > spacialDims ? ` + ${input.indicesSet("input_indices", channelIdx, "channel")}; + ${input.indicesSet("input_indices", batchIdx, "batch")}; +` : ""; + bilinearInterpolation = (input, output, inputShape, useExtrapolation, extrapolationValue) => { + const isNchw = true; + const [batchIdx, heightIdx, widthIdx, channelIdx] = inputShape.length === 2 ? [-1, 0, 1, -1] : isNchw ? [0, 2, 3, 1] : [0, 1, 2, 3]; + const dType = input.type.value; + return ` + fn getInputValue(batch: u32, channel: u32, row: u32, col: u32) -> ${dType} { + var input_indices: ${input.type.indices}; + ${input.indicesSet("input_indices", heightIdx, `max(0, min(row, ${inputShape[heightIdx]} - 1))`)}; + ${input.indicesSet("input_indices", widthIdx, `max(0, min(col, ${inputShape[widthIdx]} - 1))`)}; + ${setChannelAndBatchIndices(input, channelIdx, batchIdx, 2)} + return ${input.getByIndices("input_indices")}; + } + + fn bilinearInterpolation(output_indices: ${output.type.indices}) -> ${dType} { + var originalIndices = calculateOriginalIndicesFromOutputIndices(output_indices); + var row:${dType} = originalIndices[${heightIdx}]; + var col:${dType} = originalIndices[${widthIdx}]; + ${useExtrapolation ? `if (row < 0 || row > (${inputShape[heightIdx]} - 1) || col < 0 || col > (${inputShape[widthIdx]} - 1)) { + return ${extrapolationValue}; + }` : ""}; + row = max(0, min(row, ${inputShape[heightIdx]} - 1)); + col = max(0, min(col, ${inputShape[widthIdx]} - 1)); + var row1: u32 = u32(row); + var col1: u32 = u32(col); + var row2: u32 = u32(row + 1); + var col2: u32 = u32(col + 1); + var channel: u32 = ${inputShape.length > 2 ? `u32(originalIndices[${channelIdx}])` : "0"}; + var batch: u32 = ${inputShape.length > 2 ? `u32(originalIndices[${batchIdx}])` : "0"}; + var x11: ${dType} = getInputValue(batch, channel, row1, col1); + var x12: ${dType} = getInputValue(batch, channel, row1, col2); + var x21: ${dType} = getInputValue(batch, channel, row2, col1); + var x22: ${dType} = getInputValue(batch, channel, row2, col2); + var dx1: ${dType} = abs(row - ${dType}(row1)); + var dx2: ${dType} = abs(${dType}(row2) - row); + var dy1: ${dType} = abs(col - ${dType}(col1)); + var dy2: ${dType} = abs(${dType}(col2) - col); + if (row1 == row2) { + dx1 = 0.5; + dx2 = 0.5; + } + if (col1 == col2) { + dy1 = 0.5; + dy2 = 0.5; + } + return (x11 * dx2 * dy2 + x12 * dx2 * dy1 + x21 * dx1 * dy2 + x22 * dx1 * dy1); + }`; + }; + bicubicInterpolation = (input, output, inputShape, outputShape, scales, roi, cubicCoeffA, useExtrapolation, extrapolationValue, excludeOutside) => { + const is2D = inputShape.length === 2; + const isNchw = true; + const [heightIdx, widthIdx] = is2D ? [0, 1] : isNchw ? [2, 3] : [1, 2]; + const dType = input.type.value; + const createCubicInterpolationFunction = (idx) => { + const direction = idx === heightIdx ? "row" : "col"; + return ` + fn ${direction}CubicInterpolation(input_indices: ${input.type.indices}, output_indices: ${output.type.indices}) -> ${dType} { + var output_index = ${output.indicesGet("output_indices", idx)}; + var originalIdx: ${dType} = getOriginalCoordinateFromResizedCoordinate(output_index, ${scales[idx]}, + ${outputShape[idx]}, ${inputShape[idx]}, ${roi[idx]}, ${roi[idx]} + ${inputShape.length}); + var fractOriginalIdx: ${dType} = originalIdx - floor(originalIdx); + var coefs = getCubicInterpolationCoefs(fractOriginalIdx); + + if (${useExtrapolation} && (originalIdx < 0 || originalIdx > (${inputShape[idx]} - 1))) { + return ${extrapolationValue}; + } + var data: array<${dType}, 4> = array<${dType}, 4>(0.0, 0.0, 0.0, 0.0); + for (var i: i32 = -1; i < 3; i++) { + var ${direction}: ${dType} = originalIdx + ${dType}(i); + if (${direction} < 0 || ${direction} >= ${inputShape[idx]}) { + ${(() => { + if (excludeOutside) { + return `coefs[i + 1] = 0.0; + continue;`; + } else if (useExtrapolation) { + return `return ${extrapolationValue};`; + } else { + return `${direction} = max(0, min(${direction}, ${inputShape[idx]} - 1));`; + } + })()}; + } + var input_indices_copy: ${input.type.indices} = input_indices; + ${input.indicesSet("input_indices_copy", idx, `u32(${direction})`)}; + data[i + 1] = ${idx === heightIdx ? input.getByIndices("input_indices_copy") : "rowCubicInterpolation(input_indices_copy, output_indices)"}; + } + return cubicInterpolation1D(data, coefs); + }`; + }; + return ` + ${createCubicInterpolationFunction(heightIdx)}; + ${createCubicInterpolationFunction(widthIdx)}; + fn getCubicInterpolationCoefs(s: ${dType}) -> array<${dType}, 4> { + var absS = abs(s); + var coeffs: array<${dType}, 4> = array<${dType}, 4>(0.0, 0.0, 0.0, 0.0); + var oneMinusAbsS: ${dType} = 1.0 - absS; + var twoMinusAbsS: ${dType} = 2.0 - absS; + var onePlusAbsS: ${dType} = 1.0 + absS; + coeffs[0] = ((${cubicCoeffA} * onePlusAbsS - 5 * ${cubicCoeffA}) * onePlusAbsS + 8 * ${cubicCoeffA}) * onePlusAbsS - 4 * ${cubicCoeffA}; + coeffs[1] = ((${cubicCoeffA} + 2) * absS - (${cubicCoeffA} + 3)) * absS * absS + 1; + coeffs[2] = ((${cubicCoeffA} + 2) * oneMinusAbsS - (${cubicCoeffA} + 3)) * oneMinusAbsS * oneMinusAbsS + 1; + coeffs[3] = ((${cubicCoeffA} * twoMinusAbsS - 5 * ${cubicCoeffA}) * twoMinusAbsS + 8 * ${cubicCoeffA}) * twoMinusAbsS - 4 * ${cubicCoeffA}; + return coeffs; + } + + fn cubicInterpolation1D(x: array<${dType}, 4>, coefs: array<${dType}, 4>) -> ${dType} { + var coefsSum: ${dType} = coefs[0] + coefs[1] + coefs[2] + coefs[3]; + return (x[0] * coefs[0] + x[1] * coefs[1]+ x[2] * coefs[2]+ x[3] * coefs[3]) / coefsSum; + } + + fn bicubicInterpolation(output_indices: ${output.type.indices}) -> ${dType} { + var input_indices: ${input.type.indices} = output_indices; + return colCubicInterpolation(input_indices, output_indices); + } + `; + }; + trilinearInterpolation = (input, output, inputShape, useExtrapolation, extrapolationValue) => { + const isNchw = true; + const [batchIdx, depthIdx, heightIdx, widthIdx, channelIdx] = inputShape.length === 3 ? [-1, 0, 1, 2, -1] : isNchw ? [0, 2, 3, 4, 1] : [0, 1, 2, 3, 4]; + const dType = input.type.value; + return ` + fn getInputValue(batch: u32, channel: u32, depth:u32, height: u32, width: u32) -> ${dType} { + var input_indices: ${input.type.indices}; + ${input.indicesSet("input_indices", depthIdx, `max(0, min(depth, ${inputShape[depthIdx]} - 1))`)}; + ${input.indicesSet("input_indices", heightIdx, `max(0, min(height, ${inputShape[heightIdx]} - 1))`)}; + ${input.indicesSet("input_indices", widthIdx, `max(0, min(width, ${inputShape[widthIdx]} - 1))`)}; + ${setChannelAndBatchIndices(input, channelIdx, batchIdx, 3)} + return ${input.getByIndices("input_indices")}; + } + + fn trilinearInterpolation(output_indices: ${output.type.indices}) -> ${dType} { + var originalIndices = calculateOriginalIndicesFromOutputIndices(output_indices); + var depth:${dType} = originalIndices[${depthIdx}]; + var height:${dType} = originalIndices[${heightIdx}]; + var width:${dType} = originalIndices[${widthIdx}]; + ${useExtrapolation ? `if (depth < 0 || depth > (${inputShape[depthIdx]} - 1) || height < 0 || height > (${inputShape[heightIdx]} - 1) || width < 0 || (width > ${inputShape[widthIdx]} - 1)) { + return ${extrapolationValue}; + }` : ""}; + + depth = max(0, min(depth, ${inputShape[depthIdx]} - 1)); + height = max(0, min(height, ${inputShape[heightIdx]} - 1)); + width = max(0, min(width, ${inputShape[widthIdx]} - 1)); + var depth1: u32 = u32(depth); + var height1: u32 = u32(height); + var width1: u32 = u32(width); + var depth2: u32 = u32(depth + 1); + var height2: u32 = u32(height + 1); + var width2: u32 = u32(width + 1); + var channel: u32 = ${inputShape.length > 3 ? `u32(originalIndices[${channelIdx}])` : "0"}; + var batch: u32 = ${inputShape.length > 3 ? `u32(originalIndices[${batchIdx}])` : "0"}; + + var x111: ${dType} = getInputValue(batch, channel, depth1, height1, width1); + var x112: ${dType} = getInputValue(batch, channel, depth1, height1, width2); + var x121: ${dType} = getInputValue(batch, channel, depth1, height2, width1); + var x122: ${dType} = getInputValue(batch, channel, depth1, height2, width2); + var x211: ${dType} = getInputValue(batch, channel, depth2, height1, width1); + var x212: ${dType} = getInputValue(batch, channel, depth2, height1, width2); + var x221: ${dType} = getInputValue(batch, channel, depth2, height2, width1); + var x222: ${dType} = getInputValue(batch, channel, depth2, height2, width2); + var dx1: ${dType} = abs(depth - ${dType}(depth1)); + var dx2: ${dType} = abs(${dType}(depth2) - depth); + var dy1: ${dType} = abs(height - ${dType}(height1)); + var dy2: ${dType} = abs(${dType}(height2) - height); + var dz1: ${dType} = abs(width - ${dType}(width1)); + var dz2: ${dType} = abs(${dType}(width2) - width); + if (depth1 == depth2) { + dx1 = 0.5; + dx2 = 0.5; + } + if (height1 == height2) { + dy1 = 0.5; + dy2 = 0.5; + } + if (width1 == width2) { + dz1 = 0.5; + dz2 = 0.5; + } + return (x111 * dx2 * dy2 * dz2 + x112 * dx2 * dy2 * dz1 + x121 * dx2 * dy1 *dz2 + x122 * dx2 * dy1 * dz1 + + x211 * dx1 * dy2 * dz2 + x212 * dx1 * dy2 * dz1 + x221 * dx1 * dy1 *dz2 + x222 * dx1 * dy1 * dz1); + }`; + }; + createResizeProgramInfo = (inputTensor, attributes, opsetVersion, scalesInput, sizes, roiInput) => { + const inputShape = inputTensor.dims; + const roi = updateRoI(roiInput, attributes.axes, inputShape.length); + let outputShape = initOutputShape(inputShape, scalesInput, sizes, attributes.axes); + let scales = scalesInput.slice(); + if (scalesInput.length === 0) { + scales = inputShape.map((value, index) => value === 0 ? 1 : outputShape[index] / value); + if (attributes.keepAspectRatioPolicy !== "stretch") { + outputShape = adjustOutputShape(inputShape, scales, attributes); + } + } + const output = outputVariable("output", inputTensor.dataType, outputShape.length); + const input = inputVariable("input", inputTensor.dataType, inputShape.length); + const outputSize = ShapeUtil2.size(outputShape); + const noScale = inputShape.length === outputShape.length && inputShape.every((d, i) => d === outputShape[i]); + const useExtrapolation = attributes.coordinateTransformMode === "tf_crop_and_resize"; + const extrapolationValue = attributes.extrapolationValue; + const dataType = input.type.value; + const getShaderSource = (shaderHelper) => ` + ${noScale ? "" : ` + ${getOriginalCoordinateFromResizedCoordinate(attributes.coordinateTransformMode, dataType)}; + ${(() => { + switch (attributes.mode) { + case "nearest": + return ` + ${checkInputIndices(input, inputShape)}; + ${getNearestPixelFromOriginal(attributes.nearestMode, opsetVersion, dataType)}; + ${calculateInputIndicesFromOutputIndices( + input, + output, + inputShape, + outputShape, + scales.length, + roi.length, + useExtrapolation + )}; + `; + case "linear": + return ` + ${calculateOriginalIndicesFromOutputIndices(output, inputShape, outputShape, scales.length, roi.length)}; + ${(() => { + if (inputShape.length === 2 || inputShape.length === 4) { + return `${bilinearInterpolation(input, output, inputShape, useExtrapolation, extrapolationValue)}`; + } else if (inputShape.length === 3 || inputShape.length === 5) { + return `${trilinearInterpolation(input, output, inputShape, useExtrapolation, extrapolationValue)}`; + } else { + throw Error("Linear mode only supports input dims 2, 3, 4 and 5 are supported in linear mode."); + } + })()}; + `; + case "cubic": + return ` + ${(() => { + if (inputShape.length === 2 || inputShape.length === 4) { + return `${bicubicInterpolation( + input, + output, + inputShape, + outputShape, + scales, + roi, + attributes.cubicCoeffA, + useExtrapolation, + attributes.extrapolationValue, + attributes.excludeOutside + )}`; + } else { + throw Error("Cubic mode only supports input dims 2 and 4 are supported in linear mode."); + } + })()}; + `; + default: + throw Error("Invalid resize mode"); + } + })()}; + `} + ${shaderHelper.registerUniform("output_size", "u32").registerUniform("scales", "f32", scales.length).registerUniform("roi", "f32", roi.length).declareVariables(input, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + ${noScale ? "output[global_idx] = input[global_idx];" : ` + let output_indices = ${output.offsetToIndices("global_idx")}; + var input_indices: ${input.type.indices}; + ${(() => { + switch (attributes.mode) { + case "nearest": + return `input_indices = calculateInputIndicesFromOutputIndices(output_indices); + if (checkInputIndices(input_indices)) { + output[global_idx] = ${input.getByIndices("input_indices")}; + } else { + output[global_idx] = ${attributes.extrapolationValue}; + }`; + case "linear": + return `output[global_idx] = ${inputShape.length === 2 || inputShape.length === 4 ? "bilinearInterpolation" : "trilinearInterpolation"}(output_indices);`; + case "cubic": + return "output[global_idx] = bicubicInterpolation(output_indices);"; + default: + throw Error(`Unsupported resize mode: ${attributes.mode}`); + } + })()}; +`} + }`; + return { + name: "Resize", + shaderCache: { + hint: `${attributes.cacheKey}|${opsetVersion}|${scales.length > 0 ? attributes.mode === "cubic" ? scales : scales.length : ""}|${sizes.length > 0 ? sizes : ""}|${roi.length > 0 ? roi : ""}|${noScale}|${attributes.mode === "nearest" ? inputShape.length : inputShape}`, + inputDependencies: ["rank"] + }, + getShaderSource, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputTensor.dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms: [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 1 /* float */, data: scales }, + { type: 1 /* float */, data: roi }, + ...createTensorShapeVariables(inputShape, outputShape) + ] + }) + }; + }; + getOpsetVersionFromCustomDataBuffer = (context) => { + const customDataBuffer = context.customDataBuffer; + const customDataBuffer32 = new Uint32Array(customDataBuffer, customDataBuffer.byteOffset, 1); + const opsetVersion = customDataBuffer32[0]; + return opsetVersion; + }; + resize2 = (context, attributes) => { + const scales = []; + const sizes = []; + const roi = []; + const opsetVersion = getOpsetVersionFromCustomDataBuffer(context); + if (attributes.antialias !== 0) { + throw Error("Only default value (0) for Antialias attribute is supported"); + } + validateInputs52(context.inputs, attributes, opsetVersion, scales, sizes, roi); + context.compute(createResizeProgramInfo(context.inputs[0], attributes, opsetVersion, scales, sizes, roi), { + inputs: [0] + }); + }; + parseResizeAttributes = (attributes) => { + const antialias = attributes.antialias; + const axes = attributes.axes; + const coordinateTransformMode = attributes.coordinateTransformMode; + const cubicCoeffA = attributes.cubicCoeffA; + const excludeOutside = attributes.excludeOutside !== 0; + const extrapolationValue = attributes.extrapolationValue; + const keepAspectRatioPolicy = attributes.keepAspectRatioPolicy; + const mode = attributes.mode; + const nearestMode = attributes.nearestMode === "" ? "simple" : attributes.nearestMode; + return createAttributeWithCacheKey2({ + antialias, + axes, + coordinateTransformMode, + cubicCoeffA, + excludeOutside, + extrapolationValue, + keepAspectRatioPolicy, + mode, + nearestMode + }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/skip-layer-norm.ts + var validateInputs53, createSkipLayerNormProgramInfo, skipLayerNorm; + var init_skip_layer_norm = __esm({ + "web/lib/wasm/jsep/webgpu/ops/skip-layer-norm.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + validateInputs53 = (inputs) => { + if (!inputs || inputs.length < 3) { + throw new Error("layerNorm requires at least 3 inputs."); + } + const input = inputs[0]; + const skip = inputs[1]; + const gamma = inputs[2]; + if (input.dataType !== skip.dataType || input.dataType !== gamma.dataType) { + throw new Error("All inputs must have the same data type"); + } + if (input.dims.length !== 3 && input.dims.length !== 2) { + throw new Error("Input must be 2D or 3D"); + } + if (skip.dims.length !== 3 && skip.dims.length !== 2) { + throw new Error("Skip must be 2D or 3D"); + } + const hiddenSize = input.dims[input.dims.length - 1]; + const sequenceLength = input.dims[input.dims.length - 2]; + if (skip.dims[skip.dims.length - 1] !== hiddenSize) { + throw new Error("Skip must have the same hidden size as input"); + } + if (skip.dims[skip.dims.length - 2] !== sequenceLength) { + throw new Error("Skip must have the same sequence length as input"); + } + if (gamma.dims.length !== 1) { + throw new Error("Gamma must be 1D"); + } + if (gamma.dims[gamma.dims.length - 1] !== hiddenSize) { + throw new Error("Gamma must have the same hidden size as input"); + } + if (inputs.length > 3) { + const beta = inputs[3]; + if (beta.dims.length !== 1) { + throw new Error("Beta must be 1D"); + } + if (beta.dims[beta.dims.length - 1] !== hiddenSize) { + throw new Error("Beta must have the same hidden size as input"); + } + } + if (inputs.length > 4) { + const bias = inputs[4]; + if (bias.dims.length !== 1) { + throw new Error("Bias must be 1D"); + } + if (bias.dims[bias.dims.length - 1] !== hiddenSize) { + throw new Error("Bias must have the same hidden size as input"); + } + } + }; + createSkipLayerNormProgramInfo = (inputs, attributes, outputCount, isTraining) => { + const simplified = attributes.simplified; + const inputShape = inputs[0].dims; + const inputSize = ShapeUtil2.size(inputShape); + const outputShape = inputShape; + const outputSize = inputSize; + const hiddenSize = inputShape.slice(-1)[0]; + const meanInvStdDevDim = isTraining ? inputShape.slice(0, -1).concat(1) : []; + const hasBetaInput = !simplified && inputs.length > 3; + const hasBiasInput = inputs.length > 4; + const hasMeanOutput = isTraining && outputCount > 1; + const hasInvStdDevOutput = isTraining && outputCount > 2; + const hasInputSkipBiasSumOutput = outputCount > 3; + const workgroupSize = 64; + const components = getMaxComponents(hiddenSize); + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: components }, + { type: 12 /* uint32 */, data: hiddenSize }, + { type: 1 /* float */, data: attributes.epsilon } + ]; + const getShaderSource = (shaderHelper) => { + const uniformsArray = [ + { name: "output_size", type: "u32" }, + { name: "components", type: "u32" }, + { name: "hidden_size", type: "u32" }, + { name: "epsilon", type: "f32" } + ]; + const variables = [ + inputVariable("x", inputs[0].dataType, inputs[0].dims, components), + inputVariable("skip", inputs[1].dataType, inputs[1].dims, components), + inputVariable("gamma", inputs[2].dataType, inputs[2].dims, components) + ]; + if (hasBetaInput) { + variables.push(inputVariable("beta", inputs[3].dataType, inputs[3].dims, components)); + } + if (hasBiasInput) { + variables.push(inputVariable("bias", inputs[4].dataType, inputs[4].dims, components)); + } + variables.push(outputVariable("output", inputs[0].dataType, outputShape, components)); + if (hasMeanOutput) { + variables.push(outputVariable("mean_output", 1 /* float */, meanInvStdDevDim)); + } + if (hasInvStdDevOutput) { + variables.push(outputVariable("inv_std_output", 1 /* float */, meanInvStdDevDim)); + } + if (hasInputSkipBiasSumOutput) { + variables.push(outputVariable("input_skip_bias_sum", inputs[0].dataType, outputShape, components)); + } + const dataType = tensorTypeToWsglStorageType(inputs[0].dataType); + const vecDataType = tensorTypeToWsglStorageType(1 /* float */, components); + return ` + + ${shaderHelper.registerUniforms(uniformsArray).declareVariables(...variables)} + var sum_shared : array<${vecDataType}, ${workgroupSize}>; + var sum_squared_shared : array<${vecDataType}, ${workgroupSize}>; + + ${shaderHelper.mainStart([workgroupSize, 1, 1])} + let ix = local_id.x; + let iy = global_id.x / ${workgroupSize}; + + let hidden_size_vectorized: u32 = uniforms.hidden_size / uniforms.components; + var stride = hidden_size_vectorized / ${workgroupSize}; + let offset = ix * stride + iy * hidden_size_vectorized; + let offset1d = stride * ix; + if (ix == ${workgroupSize - 1}) { + stride = hidden_size_vectorized - stride * ix; + } + for (var i: u32 = 0; i < stride; i++) { + let skip_value = skip[offset + i]; + let bias_value = ${hasBiasInput ? "bias[offset1d + i]" : dataType + "(0.0)"}; + let input_value = x[offset + i]; + let value = input_value + skip_value + bias_value; + ${hasInputSkipBiasSumOutput ? "input_skip_bias_sum[offset + i] = value;" : ""} + output[offset + i] = value; + let f32_value = ${castToF32(dataType, components, "value")}; + sum_shared[ix] += f32_value; + sum_squared_shared[ix] += f32_value * f32_value; + } + workgroupBarrier(); + + var reduce_size : u32 = ${workgroupSize}; + for (var curr_size = reduce_size >> 1; curr_size > 0; curr_size = reduce_size >> 1) { + reduce_size = curr_size + (reduce_size & 1); + if (ix < curr_size) { + sum_shared[ix] += sum_shared[ix + reduce_size]; + sum_squared_shared[ix] += sum_squared_shared[ix + reduce_size]; + } + workgroupBarrier(); + } + + let sum = sum_shared[0]; + let square_sum = sum_squared_shared[0]; + let mean = ${sumVector("sum", components)} / f32(uniforms.hidden_size); + let inv_std_dev = inverseSqrt(${sumVector("square_sum", components)} / f32(uniforms.hidden_size) ${simplified ? "" : "- mean * mean"} + uniforms.epsilon); + ${hasMeanOutput ? "mean_output[global_idx] = mean;" : ""} + ${hasInvStdDevOutput ? "inv_std_output[global_idx] = inv_std_dev;" : ""} + + for (var i: u32 = 0; i < stride; i++) { + output[offset + i] = (output[offset + i] ${simplified ? "" : `- ${dataType}(mean)`}) * + ${dataType}(inv_std_dev) * gamma[offset1d + i] + ${hasBetaInput ? "+ beta[offset1d + i]" : ""}; + } + }`; + }; + const outputs = [{ dims: outputShape, dataType: inputs[0].dataType }]; + if (outputCount > 1) { + outputs.push({ dims: meanInvStdDevDim, dataType: 1 /* float */ }); + } + if (outputCount > 2) { + outputs.push({ dims: meanInvStdDevDim, dataType: 1 /* float */ }); + } + if (outputCount > 3) { + outputs.push({ dims: inputShape, dataType: inputs[0].dataType }); + } + return { + name: "SkipLayerNormalization", + shaderCache: { + hint: `${components};${hasMeanOutput};${hasInvStdDevOutput};${hasInputSkipBiasSumOutput}`, + inputDependencies: inputs.map((_input, _index) => "type") + }, + getShaderSource, + getRunData: () => ({ + outputs, + dispatchGroup: { + x: Math.ceil(outputSize / hiddenSize) + }, + programUniforms + }) + }; + }; + skipLayerNorm = (context, attributes) => { + const isTraining = false; + validateInputs53(context.inputs); + const outputs = [0]; + if (context.outputCount > 1) { + outputs.push(isTraining ? 1 : -3); + } + if (context.outputCount > 2) { + outputs.push(isTraining ? 2 : -3); + } + if (context.outputCount > 3) { + outputs.push(3); + } + context.compute(createSkipLayerNormProgramInfo(context.inputs, attributes, context.outputCount, isTraining), { + outputs + }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/slice.ts + var validateInputs54, readInput, createSliceAttributesFromInputs, fixStartEndValues, calculateInputIndicesImpl, createSliceProgramInfo2, slice2, parseSliceAttributes2; + var init_slice2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/slice.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_common(); + validateInputs54 = (inputs, attributes) => { + if (!inputs || inputs.length < 1) { + throw new Error("too few inputs"); + } + if (attributes.axes.length !== 0) { + if (attributes.axes.length !== attributes.starts.length || attributes.axes.length !== attributes.ends.length) { + throw new Error("axes, starts and ends must have the same length"); + } + } else if (attributes.starts.length !== attributes.ends.length) { + throw new Error("starts and ends must have the same length"); + } + inputs.slice(1).forEach((_, idx) => { + if (inputs[idx + 1].dataType !== 6 /* int32 */ && inputs[idx + 1].dataType !== 7 /* int64 */) { + throw new Error(`Input ${idx} must be an array of int32 or int64`); + } + }); + }; + readInput = (inputs, idx) => { + const input = []; + if (inputs.length > idx) { + if (inputs[idx].dataType === 7 /* int64 */) { + inputs[idx].getBigInt64Array().forEach((v) => input.push(Number(v))); + } else if (inputs[idx].dataType === 6 /* int32 */) { + inputs[idx].getInt32Array().forEach((v) => input.push(Number(v))); + } else { + throw new Error(`Input ${idx} must be an array of int32 or int64`); + } + } + return input; + }; + createSliceAttributesFromInputs = (inputs, attributes) => { + if (inputs.length > 1) { + const starts = readInput(inputs, 1); + const ends = readInput(inputs, 2); + let axes = readInput(inputs, 3); + if (axes.length === 0) { + axes = [...Array(inputs[0].dims.length).keys()]; + } + return createAttributeWithCacheKey2({ starts, ends, axes }); + } else { + return attributes; + } + }; + fixStartEndValues = (value, index, inputShape, axes, steps) => { + let newValue = value; + if (value < 0) { + newValue += inputShape[axes[index]]; + } + if (steps[index] < 0) { + return Math.max(0, Math.min(newValue, inputShape[axes[index]] - 1)); + } else { + return Math.max(0, Math.min(newValue, inputShape[axes[index]])); + } + }; + calculateInputIndicesImpl = (input, output, inputShape) => `fn calculateInputIndices(output_indices: ${output.type.indices}) -> ${input.type.indices} { + var input_indices: ${input.type.indices}; + var carry = 0u; + for (var i = ${inputShape.length}; i >= 0; i--) { + let input_shape_i = ${getElementAt("uniforms.input_shape", "i", inputShape.length)}; + let steps_i = ${getElementAt("uniforms.steps", "i", inputShape.length)}; + let signs_i = ${getElementAt("uniforms.signs", "i", inputShape.length)}; + let starts_i = ${getElementAt("uniforms.starts", "i", inputShape.length)}; + var output_index = ${output.indicesGet("output_indices", "i")}; + var input_index = output_index * steps_i + starts_i + carry; + carry = input_index / input_shape_i; + input_index = input_index % input_shape_i; + if (signs_i < 0) { + input_index = input_shape_i - input_index - 1u + starts_i; + } + ${input.indicesSet("input_indices", "i", "input_index")}; + } + return input_indices; + }`; + createSliceProgramInfo2 = (inputs, attributes) => { + const inputShape = inputs[0].dims; + const inputSize = ShapeUtil2.size(inputShape); + const axes = attributes.axes.length > 0 ? ShapeUtil2.normalizeAxes(attributes.axes, inputShape.length) : [...Array(inputShape.length).keys()]; + let steps = readInput(inputs, 4); + steps.forEach( + (step) => step !== 0 || (() => { + throw new Error("step cannot be 0"); + }) + ); + if (steps.length === 0) { + steps = Array(axes.length).fill(1); + } + const starts = attributes.starts.map((start, i) => fixStartEndValues(start, i, inputShape, axes, steps)); + const ends = attributes.ends.map((end, i) => fixStartEndValues(end, i, inputShape, axes, steps)); + if (axes.length !== starts.length || axes.length !== ends.length) { + throw new Error("start, ends and axes should have the same number of elements"); + } + if (axes.length !== inputShape.length) { + for (let i = 0; i < inputShape.length; ++i) { + if (!axes.includes(i)) { + starts.splice(i, 0, 0); + ends.splice(i, 0, inputShape[i]); + steps.splice(i, 0, 1); + } + } + } + const signs = steps.map((step) => Math.sign(step)); + steps.forEach((step, i, array) => { + if (step < 0) { + const numSteps = (ends[i] - starts[i]) / step; + const newEnd = starts[i]; + const newStart = newEnd + numSteps * steps[i]; + starts[i] = newStart; + ends[i] = newEnd; + array[i] = -step; + } + }); + const outputShape = inputShape.slice(0); + axes.forEach((axis, _) => { + outputShape[axis] = Math.ceil((ends[axis] - starts[axis]) / steps[axis]); + }); + const outputTensorInfo = { dims: outputShape, dataType: inputs[0].dataType }; + const output = outputVariable("output", inputs[0].dataType, outputShape.length); + const input = inputVariable("input", inputs[0].dataType, inputs[0].dims.length); + const outputSize = ShapeUtil2.size(outputShape); + const uniforms = [ + { name: "outputSize", type: "u32" }, + { name: "starts", type: "u32", length: starts.length }, + { name: "signs", type: "i32", length: signs.length }, + { name: "steps", type: "u32", length: steps.length } + ]; + const programUniforms = [ + { type: 12 /* uint32 */, data: outputSize }, + { type: 12 /* uint32 */, data: starts }, + { type: 6 /* int32 */, data: signs }, + { type: 12 /* uint32 */, data: steps }, + ...createTensorShapeVariables(inputs[0].dims, outputShape) + ]; + const getShaderSource = (shaderHelper) => ` + ${shaderHelper.registerUniforms(uniforms).declareVariables(input, output)} + ${calculateInputIndicesImpl(input, output, inputShape)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.outputSize")} + let output_indices = ${output.offsetToIndices("global_idx")}; + let input_indices = calculateInputIndices(output_indices); + ${output.setByOffset("global_idx", input.getByIndices("input_indices"))} + }`; + return { + name: "Slice", + shaderCache: { hint: `${signs.length}_${starts.length}_${steps.length}`, inputDependencies: ["rank"] }, + getShaderSource, + getRunData: () => ({ + outputs: [outputTensorInfo], + dispatchGroup: { x: Math.ceil( + inputSize / 64 + /* workgroup size */ + ) }, + programUniforms + }) + }; + }; + slice2 = (context, attributes) => { + validateInputs54(context.inputs, attributes); + const updatedAttributes = createSliceAttributesFromInputs(context.inputs, attributes); + context.compute(createSliceProgramInfo2(context.inputs, updatedAttributes), { inputs: [0] }); + }; + parseSliceAttributes2 = (attributes) => { + const starts = attributes.starts; + const ends = attributes.ends; + const axes = attributes.axes; + return createAttributeWithCacheKey2({ starts, ends, axes }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/softmax.ts + var validateInputs55, createSoftmaxProgramInfo, softmax2, parseSoftmaxAttributes2; + var init_softmax2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/softmax.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_attribute_with_cache_key2(); + init_transpose2(); + init_common(); + validateInputs55 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Softmax op requires 1 input."); + } + }; + createSoftmaxProgramInfo = (context, attributes) => { + const input = context.inputs[0]; + const inputShape = input.dims; + const outputSize = ShapeUtil2.size(inputShape); + const inputRank = inputShape.length; + const axis = ShapeUtil2.normalizeAxis(attributes.axis, inputRank); + const isTransposeRequired = axis < inputShape.length - 1; + let transposedInput; + let perm = []; + if (isTransposeRequired) { + perm = Array.from({ length: inputRank }, (_, i) => i); + perm[axis] = inputRank - 1; + perm[inputRank - 1] = axis; + transposedInput = context.compute(createTransposeProgramInfo2(input, perm), { + inputs: [input], + outputs: [-1] + })[0]; + } else { + transposedInput = input; + } + const transposedInputShape = transposedInput.dims; + const cols = transposedInputShape[inputRank - 1]; + const rows = outputSize / cols; + const components = getMaxComponents(cols); + const packedCols = cols / components; + let WG = 64; + if (rows === 1) { + WG = 256; + } + const maxVector = (name2, components2) => { + if (components2 === 4) { + return `max(max(${name2}.x, ${name2}.y), max(${name2}.z, ${name2}.w))`; + } else if (components2 === 2) { + return `max(${name2}.x, ${name2}.y)`; + } else if (components2 === 3) { + return `max(max(${name2}.x, ${name2}.y), ${name2}.z)`; + } + return name2; + }; + const x = inputVariable("x", transposedInput.dataType, transposedInput.dims, components); + const output = outputVariable("result", transposedInput.dataType, transposedInput.dims, components); + const valueType = x.type.value; + const threadMaxDecl = tensorTypeToWsglStorageType(transposedInput.dataType) === "f32" ? `var threadMax = ${valueType}(-3.402823e+38f);` : `var threadMax = ${valueType}(-65504.0h);`; + const getShaderSource = (shaderHelper) => ` + var rowMaxShared : ${valueType}; + var rowSumShared : ${valueType}; + var threadShared : array<${valueType}, ${WG}>; + + fn getValue(row: i32, col: i32, row_stride: i32) -> ${valueType} { + let index = row * row_stride + col; + return x[index]; + } + + fn setValue(row: i32, col: i32, row_stride: i32, value: ${valueType}) { + let index = row * row_stride + col; + result[index] = value; + } + ${shaderHelper.registerUniform("packedCols", "i32").declareVariables(x, output)} + ${shaderHelper.mainStart(WG)} + let gindex = i32(global_idx); + let lindex = i32(local_idx); + const wg = ${WG}; + let row = gindex / wg; + let cols = uniforms.packedCols; + let row_stride : i32 = uniforms.packedCols; + + // find the rows max + ${threadMaxDecl} + for (var col = lindex; col < cols; col += wg) { + let value = getValue(row, col, row_stride); + threadMax = max(threadMax, value); + } + if (lindex < cols) { + threadShared[lindex] = threadMax; + } + workgroupBarrier(); + + var reduceSize = min(cols, wg); + for (var currSize = reduceSize >> 1; currSize > 0; currSize = reduceSize >> 1) { + reduceSize = currSize + (reduceSize & 1); + if (lindex < currSize) { + threadShared[lindex] = max(threadShared[lindex], threadShared[lindex + reduceSize]); + } + workgroupBarrier(); + } + if (lindex == 0) { + rowMaxShared = ${valueType}(${maxVector("threadShared[0]", components)}); + } + workgroupBarrier(); + + // find the rows sum + var threadSum = ${valueType}(0.0); + for (var col = lindex; col < cols; col += wg) { + let subExp = exp(getValue(row, col, row_stride) - rowMaxShared); + threadSum += subExp; + } + threadShared[lindex] = threadSum; + workgroupBarrier(); + + for (var currSize = wg >> 1; currSize > 0; currSize = currSize >> 1) { + if (lindex < currSize) { + threadShared[lindex] = threadShared[lindex] + threadShared[lindex + currSize]; + } + workgroupBarrier(); + } + if (lindex == 0) { + rowSumShared = ${valueType}(${sumVector("threadShared[0]", components)}); + } + workgroupBarrier(); + + // calculate final value for each element in the row + for (var col = lindex; col < cols; col += wg) { + let value = exp(getValue(row, col, row_stride) - rowMaxShared) / rowSumShared; + setValue(row, col, row_stride, value); + } + }`; + const result = context.compute( + { + name: "Softmax", + // Note that in JSEP, WG size is not included in cache by default, but WebGPU EP it is. + shaderCache: { hint: `${components};${WG}`, inputDependencies: ["type"] }, + getRunData: () => ({ + outputs: [{ dims: transposedInputShape, dataType: transposedInput.dataType }], + dispatchGroup: { x: rows }, + programUniforms: [{ type: 6 /* int32 */, data: packedCols }] + }), + getShaderSource + }, + { + inputs: [transposedInput], + outputs: [isTransposeRequired ? -1 : 0] + } + )[0]; + if (isTransposeRequired) { + context.compute(createTransposeProgramInfo2(result, perm), { + inputs: [result] + }); + } + }; + softmax2 = (context, attributes) => { + validateInputs55(context.inputs); + createSoftmaxProgramInfo(context, attributes); + }; + parseSoftmaxAttributes2 = (attributes) => createAttributeWithCacheKey2({ axis: attributes.axis }); + } + }); + + // web/lib/wasm/jsep/webgpu/ops/tile.ts + var getRepeats, validateInputs56, getOutputShape3, createTileProgramInfo2, tile2; + var init_tile2 = __esm({ + "web/lib/wasm/jsep/webgpu/ops/tile.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + getRepeats = (repeatsTensorView) => Array.from(repeatsTensorView.getBigInt64Array(), Number); + validateInputs56 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Tile requires 2 inputs."); + } + if (inputs[0].dataType !== 1 /* float */ && inputs[0].dataType !== 10 /* float16 */ && inputs[0].dataType !== 6 /* int32 */ && inputs[0].dataType !== 12 /* uint32 */) { + throw new Error("Tile only support float, float16, int32, and uint32 data types"); + } + if (inputs[1].dataType !== 7 /* int64 */) { + throw new Error("Tile `repeats` input should be of int64 data type"); + } + if (inputs[1].dims.length !== 1) { + throw new Error("Tile `repeats` input should be 1-D"); + } + const repeats = getRepeats(inputs[1]); + if (repeats.length !== inputs[0].dims.length) { + throw new Error("Tile `repeats` input should have same number of elements as rank of input data tensor"); + } + }; + getOutputShape3 = (inputShape, repeats) => { + const outputShape = []; + for (let i = 0; i < inputShape.length; ++i) { + outputShape.push(inputShape[i] * repeats[i]); + } + return outputShape; + }; + createTileProgramInfo2 = (inputs, shape2) => { + const inputShape = inputs[0].dims; + const repeats = shape2 == null ? getRepeats(inputs[1]) : shape2; + const outputShape = getOutputShape3(inputShape, repeats); + const outputSize = ShapeUtil2.size(outputShape); + const dataType = inputs[0].dataType; + const input = inputVariable("input", dataType, inputShape.length); + const output = outputVariable("output", dataType, outputShape.length); + const getShaderSource = (shaderHelper) => ` + const inputShape = ${input.indices(...inputShape)}; + ${shaderHelper.registerUniform("output_size", "u32").declareVariables(input, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.output_size")} + let output_indices = ${output.offsetToIndices("global_idx")}; + var input_indices: ${input.type.indices}; + for (var i = 0; i < ${inputShape.length}; i++) { + let input_dim_i = ${input.indicesGet("uniforms.input_shape", "i")}; + let input_dim_value = ${output.indicesGet("output_indices", "i")} % input_dim_i; + + ${input.indicesSet("input_indices", "i", "input_dim_value")} + } + ${output.setByOffset("global_idx", input.getByIndices("input_indices"))} + }`; + return { + name: "Tile", + shaderCache: { hint: `${repeats}`, inputDependencies: ["rank"] }, + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: inputs[0].dataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 + /* workgroup size */ + ) }, + programUniforms: [ + { type: 12 /* uint32 */, data: outputSize }, + ...createTensorShapeVariables(inputs[0].dims, outputShape) + ] + }), + getShaderSource + }; + }; + tile2 = (context) => { + validateInputs56(context.inputs); + context.compute(createTileProgramInfo2(context.inputs), { inputs: [0] }); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/ops/where.ts + var createWhereOpProgramShader, createWhereOpProgramInfo, where; + var init_where = __esm({ + "web/lib/wasm/jsep/webgpu/ops/where.ts"() { + "use strict"; + init_wasm_common(); + init_util2(); + init_common(); + createWhereOpProgramShader = (shaderHelper, inputs, dimsOutput, isBroadcast, typeOutput) => { + const output = outputVariable("output_data", typeOutput, dimsOutput.length, 4); + const a = inputVariable("a_data", inputs[1].dataType, inputs[1].dims.length, 4); + const b = inputVariable("b_data", inputs[2].dataType, inputs[2].dims.length, 4); + const c = inputVariable("c_data", inputs[0].dataType, inputs[0].dims.length, 4); + let assignment; + const expression = (a2, b2, c2) => `select(${b2}, ${a2}, ${c2})`; + if (!isBroadcast) { + assignment = output.setByOffset( + "global_idx", + expression(a.getByOffset("global_idx"), b.getByOffset("global_idx"), c.getByOffset("global_idx")) + ); + } else { + const singleAssignment = (resStr, x, typeCast = "") => { + const expressionA = `a_data[index_a${x}][component_a${x}]`; + const expressionB = `b_data[index_b${x}][component_b${x}]`; + const expressionC = `bool(c_data[index_c${x}] & (0xffu << (component_c${x} * 8)))`; + return ` + let output_indices${x} = ${output.offsetToIndices(`global_idx * 4u + ${x}u`)}; + let offset_a${x} = ${a.broadcastedIndicesToOffset(`output_indices${x}`, output)}; + let offset_b${x} = ${b.broadcastedIndicesToOffset(`output_indices${x}`, output)}; + let offset_c${x} = ${c.broadcastedIndicesToOffset(`output_indices${x}`, output)}; + let index_a${x} = offset_a${x} / 4u; + let index_b${x} = offset_b${x} / 4u; + let index_c${x} = offset_c${x} / 4u; + let component_a${x} = offset_a${x} % 4u; + let component_b${x} = offset_b${x} % 4u; + let component_c${x} = offset_c${x} % 4u; + ${resStr}[${x}] = ${typeCast}(${expression(expressionA, expressionB, expressionC)}); + `; + }; + if (typeOutput === 9 /* bool */) { + assignment = ` + var data = vec4(0); + ${singleAssignment("data", 0, "u32")} + ${singleAssignment("data", 1, "u32")} + ${singleAssignment("data", 2, "u32")} + ${singleAssignment("data", 3, "u32")} + output_data[global_idx] = dot(vec4(0x1, 0x100, 0x10000, 0x1000000), vec4(data));`; + } else { + assignment = ` + ${singleAssignment("output_data[global_idx]", 0)} + ${singleAssignment("output_data[global_idx]", 1)} + ${singleAssignment("output_data[global_idx]", 2)} + ${singleAssignment("output_data[global_idx]", 3)} + `; + } + } + return ` + ${shaderHelper.registerUniform("vec_size", "u32").declareVariables(c, a, b, output)} + ${shaderHelper.mainStart()} + ${shaderHelper.guardAgainstOutOfBoundsWorkgroupSizes("uniforms.vec_size")} + ${assignment} + }`; + }; + createWhereOpProgramInfo = (inputs) => { + const dimsA = inputs[1].dims; + const dimsB = inputs[2].dims; + const dimsC = inputs[0].dims; + const outputDataType = inputs[1].dataType; + const isBroadcast = !(ShapeUtil2.areEqual(dimsA, dimsB) && ShapeUtil2.areEqual(dimsB, dimsC)); + let outputShape = dimsA; + let outputSize = ShapeUtil2.size(dimsA); + if (isBroadcast) { + const calculatedShape = BroadcastUtil2.calcShape(BroadcastUtil2.calcShape(dimsA, dimsB, false), dimsC, false); + if (!calculatedShape) { + throw new Error("Can't perform where op on the given tensors"); + } + outputShape = calculatedShape; + outputSize = ShapeUtil2.size(outputShape); + } + const vecSize = Math.ceil(outputSize / 4); + return { + name: "Where", + shaderCache: { inputDependencies: ["rank", "rank", "rank"] }, + getShaderSource: (shaderHelper) => createWhereOpProgramShader(shaderHelper, inputs, outputShape, isBroadcast, outputDataType), + getRunData: () => ({ + outputs: [{ dims: outputShape, dataType: outputDataType }], + dispatchGroup: { x: Math.ceil( + outputSize / 64 / 4 + /* vec size */ + ) }, + programUniforms: [ + { type: 12 /* uint32 */, data: vecSize }, + ...createTensorShapeVariables(dimsC, dimsA, dimsB, outputShape) + ] + }) + }; + }; + where = (context) => { + context.compute(createWhereOpProgramInfo(context.inputs)); + }; + } + }); + + // web/lib/wasm/jsep/webgpu/op-resolve-rules.ts + var WEBGPU_OP_RESOLVE_RULES; + var init_op_resolve_rules2 = __esm({ + "web/lib/wasm/jsep/webgpu/op-resolve-rules.ts"() { + "use strict"; + init_argminmax(); + init_attention(); + init_batch_norm(); + init_bias_add(); + init_bias_split_gelu(); + init_binary_op2(); + init_concat2(); + init_conv2(); + init_conv_transpose2(); + init_cumsum(); + init_depth_to_space2(); + init_einsum(); + init_expand(); + init_fast_gelu(); + init_gather2(); + init_gather_nd(); + init_gather_block_quantized(); + init_gather_elements(); + init_gemm2(); + init_grid_sample(); + init_group_query_attention(); + init_instance_norm(); + init_layer_norm(); + init_matmul2(); + init_matmulnbits(); + init_multihead_attention(); + init_pad2(); + init_pool2(); + init_quantize_linear(); + init_range(); + init_scatter_nd(); + init_reduce2(); + init_resize(); + init_rotary_embedding(); + init_skip_layer_norm(); + init_slice2(); + init_softmax2(); + init_split2(); + init_tile2(); + init_transpose2(); + init_unary_op2(); + init_where(); + WEBGPU_OP_RESOLVE_RULES = /* @__PURE__ */ new Map([ + ["Abs", [abs2]], + ["Acos", [acos2]], + ["Acosh", [acosh]], + ["Add", [add3]], + ["ArgMax", [argMax, parseArgMinMaxAttributes]], + ["ArgMin", [argMin, parseArgMinMaxAttributes]], + ["Asin", [asin2]], + ["Asinh", [asinh]], + ["Atan", [atan2]], + ["Atanh", [atanh]], + ["Attention", [attention]], + // TODO: support new attributes for AveragePool-10 + ["AveragePool", [averagePool2, parseAveragePoolAttributes2]], + ["BatchNormalization", [batchNorm]], + ["BiasAdd", [biasAdd]], + ["BiasSplitGelu", [biasSplitGelu]], + ["Cast", [cast2, parseCastAttributes2]], + ["Ceil", [ceil2]], + ["Clip", [clip2]], + ["Concat", [concat2, parseConcatAttributes2]], + ["Conv", [conv2, parseConvAttributes2]], + ["ConvTranspose", [convTranspose2, parseConvTransposeAttributes2]], + ["Cos", [cos2]], + ["Cosh", [cosh]], + ["CumSum", [cumsum, parseCumSumAttributes]], + ["DepthToSpace", [depthToSpace2, parseDepthToSpaceAttributes2]], + ["DequantizeLinear", [dequantizeLinear, parseDequantizeLinearAttributes]], + ["Div", [div2]], + ["Einsum", [einsum, parseEinsumAttributes]], + ["Elu", [elu2, parseAlphaAttributes]], + ["Equal", [equal2]], + ["Erf", [erf]], + ["Exp", [exp2]], + ["Expand", [expand]], + ["FastGelu", [fastGelu2]], + ["Floor", [floor2]], + ["FusedConv", [conv2, parseConvAttributes2]], + ["Gather", [gather2, parseGatherAttributes2]], + ["GatherElements", [gatherElements, parseGatherElementsAttributes]], + ["GatherBlockQuantized", [gatherBlockQuantized, parseGatherBlockQuantizedAttributes]], + ["GatherND", [gatherND, parseGatherNDAttributes]], + ["Gelu", [gelu]], + ["Gemm", [gemm2, parseGemmAttributes2]], + ["GlobalAveragePool", [globalAveragePool2, parseGlobalAveragePoolAttributes2]], + ["GlobalMaxPool", [globalMaxPool2, parseGlobalMaxPoolAttributes]], + ["Greater", [greater2]], + ["GreaterOrEqual", [greaterOrEqual]], + ["GridSample", [gridSample, parseGridSampleAttributes]], + ["GroupQueryAttention", [groupQueryAttention]], + ["HardSigmoid", [hardSigmoid, parseHardSigmoidAttributes]], + ["InstanceNormalization", [instanceNorm]], + ["LayerNormalization", [layerNorm]], + ["LeakyRelu", [leakyRelu2, parseAlphaAttributes]], + ["Less", [less2]], + ["LessOrEqual", [lessOrEqual]], + ["Log", [log3]], + ["MatMul", [matMul2]], + ["MatMulNBits", [matMulNBits, parseMatMulNBitsAttributes]], + // TODO: support new attributes for MaxPool-8 and MaxPool-10 + ["MaxPool", [maxPool2, parseMaxPoolAttributes2]], + ["Mul", [mul2]], + ["MultiHeadAttention", [multiHeadAttention, parseMultiHeadAttentionAttributes]], + ["Neg", [neg2]], + ["Not", [not3]], + ["Pad", [pad]], + ["Pow", [pow2]], + ["QuickGelu", [quickgelu, parseAlphaAttributes]], + ["Range", [range]], + ["Reciprocal", [reciprocal]], + ["ReduceMin", [reduceMin2]], + ["ReduceMean", [reduceMean2]], + ["ReduceMax", [reduceMax2]], + ["ReduceSum", [reduceSum2]], + ["ReduceProd", [reduceProd2]], + ["ReduceL1", [reduceL1]], + ["ReduceL2", [reduceL2]], + ["ReduceLogSum", [reduceLogSum2]], + ["ReduceLogSumExp", [reduceLogSumExp]], + ["ReduceSumSquare", [reduceSumSquare]], + ["Relu", [relu2]], + ["Resize", [resize2, parseResizeAttributes]], + ["RotaryEmbedding", [rotaryEmbedding]], + ["ScatterND", [scatterND, parseScatterNDAttributes]], + ["Sigmoid", [sigmoid2]], + ["Sin", [sin2]], + ["Sinh", [sinh]], + ["Slice", [slice2, parseSliceAttributes2]], + ["SkipLayerNormalization", [skipLayerNorm]], + ["Split", [split2, parseSplitAttributes2]], + ["Sqrt", [sqrt2]], + ["Softmax", [softmax2, parseSoftmaxAttributes2]], + ["Sub", [sub2]], + ["Tan", [tan2]], + ["Tanh", [tanh2]], + ["ThresholdedRelu", [thresholdedRelu, parseAlphaAttributes]], + ["Tile", [tile2]], + ["Transpose", [transpose2, parseTransposeAttributes2]], + ["Where", [where]] + ]); + } + }); + + // web/lib/wasm/jsep/webgpu/program-manager.ts + var ProgramManager2; + var init_program_manager2 = __esm({ + "web/lib/wasm/jsep/webgpu/program-manager.ts"() { + "use strict"; + init_esm(); + init_log(); + init_common(); + ProgramManager2 = class { + constructor(backend2) { + this.backend = backend2; + 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, outputs, dispatchGroup, uniformBufferBinding) { + TRACE_FUNC_BEGIN(buildArtifact.programInfo.name); + const device = this.backend.device; + const computePassEncoder = this.backend.getComputePassEncoder(); + this.backend.writeTimestamp(this.backend.pendingDispatchNumber * 2); + const entries = []; + for (const input of inputs) { + entries.push({ binding: entries.length, resource: { buffer: input.buffer } }); + } + for (const output of outputs) { + entries.push({ binding: entries.length, resource: { buffer: output.buffer } }); + } + if (uniformBufferBinding) { + entries.push({ binding: entries.length, resource: uniformBufferBinding }); + } + const bindGroup = device.createBindGroup({ + layout: buildArtifact.computePipeline.getBindGroupLayout(0), + entries, + label: buildArtifact.programInfo.name + }); + if (this.backend.sessionStatus === "capturing") { + const commandInfo = { + kernelId: this.backend.currentKernelId, + computePipeline: buildArtifact.computePipeline, + bindGroup, + dispatchGroup + }; + const sessionCommandList = this.backend.capturedCommandList.get(this.backend.currentSessionId); + sessionCommandList.push(commandInfo); + } + computePassEncoder.setPipeline(buildArtifact.computePipeline); + computePassEncoder.setBindGroup(0, bindGroup); + computePassEncoder.dispatchWorkgroups(...dispatchGroup); + this.backend.writeTimestamp(this.backend.pendingDispatchNumber * 2 + 1); + this.backend.pendingDispatchNumber++; + if (this.backend.pendingDispatchNumber >= this.backend.maxDispatchNumber || this.backend.queryType === "at-passes") { + this.backend.endComputePass(); + } + if (this.backend.pendingDispatchNumber >= this.backend.maxDispatchNumber) { + this.backend.flush(); + } + TRACE_FUNC_END(buildArtifact.programInfo.name); + } + dispose() { + } + build(programInfo, normalizedDispatchGroupSize) { + TRACE_FUNC_BEGIN(programInfo.name); + const device = this.backend.device; + const enableDirectives = []; + const extensionsInfo = [ + { feature: "shader-f16", extension: "f16" }, + { feature: "subgroups", extension: "subgroups" } + ]; + extensionsInfo.forEach((info) => { + if (device.features.has(info.feature)) { + enableDirectives.push(`enable ${info.extension};`); + } + }); + const shaderHelper = createShaderHelper(normalizedDispatchGroupSize, this.backend.device.limits); + const userCode = programInfo.getShaderSource(shaderHelper); + const code = `${enableDirectives.join("\n")} +${shaderHelper.additionalImplementations} +${userCode}`; + const shaderModule = device.createShaderModule({ code, label: programInfo.name }); + LOG_DEBUG("verbose", () => `[WebGPU] ${programInfo.name} shader code: ${code}`); + const computePipeline = device.createComputePipeline({ + compute: { module: shaderModule, entryPoint: "main" }, + layout: "auto", + label: programInfo.name + }); + TRACE_FUNC_END(programInfo.name); + return { programInfo, computePipeline, uniformVariablesInfo: shaderHelper.variablesInfo }; + } + normalizeDispatchGroupSize(dispatchGroup) { + const x = typeof dispatchGroup === "number" ? dispatchGroup : dispatchGroup.x; + const y = typeof dispatchGroup === "number" ? 1 : dispatchGroup.y || 1; + const z = typeof dispatchGroup === "number" ? 1 : dispatchGroup.z || 1; + const limitPerDimension = this.backend.device.limits.maxComputeWorkgroupsPerDimension; + if (x <= limitPerDimension && y <= limitPerDimension && z <= limitPerDimension) { + return [x, y, z]; + } + const size = x * y * z; + let dispatchAverage = Math.ceil(Math.sqrt(size)); + if (dispatchAverage > limitPerDimension) { + dispatchAverage = Math.ceil(Math.cbrt(size)); + if (dispatchAverage > limitPerDimension) { + throw new Error("Total dispatch size exceeds WebGPU maximum."); + } + return [dispatchAverage, dispatchAverage, dispatchAverage]; + } else { + return [dispatchAverage, dispatchAverage, 1]; + } + } + }; + } + }); + + // web/lib/wasm/jsep/backend-webgpu.ts + var backend_webgpu_exports = {}; + __export(backend_webgpu_exports, { + WebGpuBackend: () => WebGpuBackend + }); + var getProgramInputTensorInfoDependencyKey, getProgramInfoUniqueKey2, AdapterInfoImpl, WebGpuBackend; + var init_backend_webgpu = __esm({ + "web/lib/wasm/jsep/backend-webgpu.ts"() { + "use strict"; + init_esm(); + init_wasm_common(); + init_log(); + init_tensor_view(); + init_gpu_data_manager(); + init_op_resolve_rules2(); + init_program_manager2(); + getProgramInputTensorInfoDependencyKey = (inputTensors, inputDependencies) => { + if (inputDependencies.length !== inputTensors.length) { + throw new Error( + `inputDependencies length ${inputDependencies.length} is not equal to inputTensors length ${inputTensors.length}.` + ); + } + const inputInfos = []; + for (let i = 0; i < inputTensors.length; ++i) { + const type = inputTensors[i].dataType; + switch (inputDependencies[i]) { + case "none": { + inputInfos.push(""); + break; + } + case "type": { + inputInfos.push(`${type}`); + break; + } + case "rank": { + const rank = inputTensors[i].dims.length; + inputInfos.push(`${type};${rank}`); + break; + } + case "dims": { + const dims = inputTensors[i].dims.join(","); + inputInfos.push(`${type};${dims}`); + break; + } + default: + throw new Error(`unsupported input dependency: ${inputDependencies[i]}`); + } + } + return inputInfos.join("|"); + }; + getProgramInfoUniqueKey2 = (programInfo, inputTensors, is1DimensionDispatch) => { + let key = programInfo.name; + if (programInfo.shaderCache?.hint) { + key += "[" + programInfo.shaderCache.hint + "]"; + } + key += ":" + is1DimensionDispatch + `:${getProgramInputTensorInfoDependencyKey( + inputTensors, + programInfo.shaderCache?.inputDependencies ?? new Array(inputTensors.length).fill("dims") + )}`; + return key; + }; + AdapterInfoImpl = class { + constructor(adapterInfo) { + if (adapterInfo) { + this.architecture = adapterInfo.architecture; + this.vendor = adapterInfo.vendor; + } + } + isArchitecture(architecture) { + return this.architecture === architecture; + } + isVendor(vendor) { + return this.vendor === vendor; + } + }; + WebGpuBackend = class { + constructor() { + /** + * representing the session ID of which is currently being run. + * `null` means no session is being run. + * only valid when session.run is executed. + */ + this.currentSessionId = null; + /** + * representing the kernel ID of which is currently being computed (CPU code perspective). + * `null` means no kernel is being computed. + * only one kernel can be computed at a moment. + */ + this.currentKernelId = null; + this.commandEncoder = null; + this.computePassEncoder = null; + this.maxDispatchNumber = 16; + this.pendingDispatchNumber = 0; + // info of kernels pending submission for a single batch + this.pendingKernels = []; + // queryReadBuffer -> pendingKernels mapping for all the batches + this.pendingQueries = /* @__PURE__ */ new Map(); + this.sessionStatus = "default"; + /** + * a SessionID -> CommandInfo[] mapping. It's used to record all GPU commands for corresponding session. + */ + this.capturedCommandList = /* @__PURE__ */ new Map(); + /** + * a SessionID -> PendingKernelInfo[] mapping for profiling. + */ + this.capturedPendingKernels = /* @__PURE__ */ new Map(); + /** + * a SessionID -> a Map of (InputOutputIndex -> [ID, GPUBuffer]) mapping. + */ + this.sessionExternalDataMapping = /* @__PURE__ */ new Map(); + } + /** + * get the custom data of the current kernel + */ + get currentKernelCustomData() { + if (this.currentKernelId === null) { + throw new Error("currentKernelCustomData(): currentKernelId is null. (should not happen)"); + } + let data = this.kernelCustomData.get(this.currentKernelId); + if (!data) { + data = {}; + this.kernelCustomData.set(this.currentKernelId, data); + } + return data; + } + async initialize(env3, adapter) { + this.env = env3; + const requiredFeatures = []; + const deviceDescriptor = { + requiredLimits: { + maxComputeWorkgroupStorageSize: adapter.limits.maxComputeWorkgroupStorageSize, + maxComputeWorkgroupsPerDimension: adapter.limits.maxComputeWorkgroupsPerDimension, + maxStorageBufferBindingSize: adapter.limits.maxStorageBufferBindingSize, + maxBufferSize: adapter.limits.maxBufferSize, + maxComputeInvocationsPerWorkgroup: adapter.limits.maxComputeInvocationsPerWorkgroup, + maxComputeWorkgroupSizeX: adapter.limits.maxComputeWorkgroupSizeX, + maxComputeWorkgroupSizeY: adapter.limits.maxComputeWorkgroupSizeY, + maxComputeWorkgroupSizeZ: adapter.limits.maxComputeWorkgroupSizeZ + }, + requiredFeatures + }; + const requireFeatureIfAvailable = (feature) => adapter.features.has(feature) && requiredFeatures.push(feature) && true; + if (!requireFeatureIfAvailable("chromium-experimental-timestamp-query-inside-passes")) { + requireFeatureIfAvailable("timestamp-query"); + } + requireFeatureIfAvailable("shader-f16"); + requireFeatureIfAvailable("subgroups"); + this.device = await adapter.requestDevice(deviceDescriptor); + this.adapterInfo = new AdapterInfoImpl(adapter.info || await adapter.requestAdapterInfo()); + this.gpuDataManager = createGpuDataManager(this); + this.programManager = new ProgramManager2(this); + this.kernels = /* @__PURE__ */ new Map(); + this.kernelPersistentData = /* @__PURE__ */ new Map(); + this.kernelCustomData = /* @__PURE__ */ new Map(); + configureLogger(env3.logLevel, !!env3.debug); + this.device.onuncapturederror = (ev) => { + if (ev.error instanceof GPUValidationError) { + console.error(`An uncaught WebGPU validation error was raised: ${ev.error.message}`); + } + }; + Object.defineProperty(this.env.webgpu, "device", { + value: this.device, + writable: false, + enumerable: true, + configurable: false + }); + Object.defineProperty(this.env.webgpu, "adapter", { + value: adapter, + writable: false, + enumerable: true, + configurable: false + }); + this.setQueryType(); + } + dispose() { + if (typeof this.querySet !== "undefined") { + this.querySet.destroy(); + } + this.gpuDataManager.dispose(); + } + getCommandEncoder() { + if (!this.commandEncoder) { + this.commandEncoder = this.device.createCommandEncoder(); + } + return this.commandEncoder; + } + getComputePassEncoder() { + if (!this.computePassEncoder) { + const commandEncoder = this.getCommandEncoder(); + const computePassDescriptor = {}; + if (this.queryType === "at-passes") { + computePassDescriptor.timestampWrites = { + querySet: this.querySet, + beginningOfPassWriteIndex: this.pendingDispatchNumber * 2, + endOfPassWriteIndex: this.pendingDispatchNumber * 2 + 1 + }; + } + this.computePassEncoder = commandEncoder.beginComputePass(computePassDescriptor); + } + return this.computePassEncoder; + } + endComputePass() { + if (this.computePassEncoder) { + this.computePassEncoder.end(); + this.computePassEncoder = null; + } + } + flush() { + if (!this.commandEncoder) { + return; + } + TRACE_FUNC_BEGIN(); + this.endComputePass(); + let queryReadBuffer; + if (this.queryType !== "none") { + this.commandEncoder.resolveQuerySet( + this.querySet, + 0, + this.pendingDispatchNumber * 2, + this.queryResolveBuffer, + 0 + ); + queryReadBuffer = this.device.createBuffer( + // eslint-disable-next-line no-bitwise + { size: this.pendingDispatchNumber * 2 * 8, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST } + ); + this.pendingQueries.set(queryReadBuffer, this.pendingKernels); + this.pendingKernels = []; + this.commandEncoder.copyBufferToBuffer( + this.queryResolveBuffer, + 0, + queryReadBuffer, + 0, + this.pendingDispatchNumber * 2 * 8 + ); + } + this.device.queue.submit([this.commandEncoder.finish()]); + this.gpuDataManager.refreshPendingBuffers(); + this.commandEncoder = null; + this.pendingDispatchNumber = 0; + if (this.queryType !== "none") { + void queryReadBuffer.mapAsync(GPUMapMode.READ).then(() => { + const mappedData = new BigUint64Array(queryReadBuffer.getMappedRange()); + const pendingKernels = this.pendingQueries.get(queryReadBuffer); + for (let i = 0; i < mappedData.length / 2; i++) { + const pendingKernelInfo = pendingKernels[i]; + const kernelId = pendingKernelInfo.kernelId; + const kernelInfo = this.kernels.get(kernelId); + const kernelType = kernelInfo.kernelType; + const kernelName = kernelInfo.kernelName; + const programName = pendingKernelInfo.programName; + const inputTensorViews = pendingKernelInfo.inputTensorViews; + const outputTensorViews = pendingKernelInfo.outputTensorViews; + const startTimeU64 = mappedData[i * 2]; + const endTimeU64 = mappedData[i * 2 + 1]; + if (typeof this.queryTimeBase === "undefined") { + this.queryTimeBase = startTimeU64; + } + const startTime = Number(startTimeU64 - this.queryTimeBase); + const endTime = Number(endTimeU64 - this.queryTimeBase); + if (!Number.isSafeInteger(startTime) || !Number.isSafeInteger(endTime)) { + throw new RangeError("incorrect timestamp range"); + } + if (this.env.webgpu.profiling?.ondata) { + this.env.webgpu.profiling.ondata({ + version: 1, + inputsMetadata: inputTensorViews.map((value) => ({ + dims: value.dims, + dataType: tensorDataTypeEnumToString(value.dataType) + })), + outputsMetadata: outputTensorViews.map((value) => ({ + dims: value.dims, + dataType: tensorDataTypeEnumToString(value.dataType) + })), + kernelId, + kernelType, + kernelName, + programName, + startTime, + endTime + }); + } else { + let inputShapes = ""; + inputTensorViews.forEach((value, i2) => { + inputShapes += `input[${i2}]: [${value.dims}] | ${tensorDataTypeEnumToString(value.dataType)}, `; + }); + let outputShapes = ""; + outputTensorViews.forEach((value, i2) => { + outputShapes += `output[${i2}]: [${value.dims}] | ${tensorDataTypeEnumToString(value.dataType)}, `; + }); + console.log( + `[profiling] kernel "${kernelId}|${kernelType}|${kernelName}|${programName}" ${inputShapes}${outputShapes}execution time: ${endTime - startTime} ns` + ); + } + TRACE("GPU", `${programName}::${startTimeU64}::${endTimeU64}`); + } + queryReadBuffer.unmap(); + this.pendingQueries.delete(queryReadBuffer); + }); + } + TRACE_FUNC_END(); + } + /** + * run a WebGPU program. + * @param program a ProgramInfo instance + * @param inputTensorViews a TensorView array. each element represents a value already exists in GPU. + * @param outputIndices an indices array. each element can be either -1 (temporary data), -2 (persistent data) or an + * index to the kernel's output. + * @param createKernelOutput a callback function that create a value to kernel's output with the given index + * @param createIntermediateOutput a callback function that create a value as a intermediate value, either temporary + * or persistent (owned by the current kernel) + * @returns a TensorView array representing the result. + */ + run(program, inputTensorViews, outputIndices, createKernelOutput, createIntermediateOutput, outputCount) { + TRACE_FUNC_BEGIN(program.name); + const inputDatas = []; + for (let i = 0; i < inputTensorViews.length; ++i) { + const data = inputTensorViews[i].data; + if (data === 0) { + continue; + } + const gpuData = this.gpuDataManager.get(data); + if (!gpuData) { + throw new Error(`no GPU data for input: ${data}`); + } + inputDatas.push(gpuData); + } + const { outputs, dispatchGroup, programUniforms } = program.getRunData(inputTensorViews); + const validatedOutputIndices = outputIndices.length === 0 ? outputs.map((_, i) => i) : outputIndices; + if (validatedOutputIndices.length !== outputs.length) { + throw new Error(`Output size ${validatedOutputIndices.length} must be equal to ${outputs.length}.`); + } + const outputTensorViews = []; + const outputDatas = []; + for (let i = 0; i < outputs.length; ++i) { + if (!Number.isInteger(validatedOutputIndices[i]) || validatedOutputIndices[i] < -3 || validatedOutputIndices[i] >= outputCount) { + throw new Error(`Invalid output index: ${validatedOutputIndices[i]}`); + } + if (validatedOutputIndices[i] === -3) { + continue; + } + const isTemporary = validatedOutputIndices[i] === -1; + const isPersistent = validatedOutputIndices[i] === -2; + const tensorView = isTemporary || isPersistent ? createIntermediateOutput(outputs[i].dataType, outputs[i].dims) : createKernelOutput(validatedOutputIndices[i], outputs[i].dataType, outputs[i].dims); + outputTensorViews.push(tensorView); + if (tensorView.data === 0) { + continue; + } + const gpuData = this.gpuDataManager.get(tensorView.data); + if (!gpuData) { + throw new Error(`no GPU data for output: ${tensorView.data}`); + } + if (isTemporary) { + this.temporaryData.push(gpuData); + } + if (isPersistent) { + let persistentData = this.kernelPersistentData.get(this.currentKernelId); + if (!persistentData) { + persistentData = []; + this.kernelPersistentData.set(this.currentKernelId, persistentData); + } + persistentData.push(gpuData); + } + outputDatas.push(gpuData); + } + if (inputDatas.length !== inputTensorViews.length || outputDatas.length !== outputTensorViews.length) { + if (outputDatas.length === 0) { + TRACE_FUNC_END(program.name); + return outputTensorViews; + } + throw new Error( + `Program ${program.name} has zero-sized tensor(s) in inputs or outputs. This is not supported now.` + ); + } + let uniformBufferBinding; + if (programUniforms) { + let currentOffset = 0; + const offsets = []; + programUniforms.forEach((v) => { + const data = typeof v.data === "number" ? [v.data] : v.data; + if (data.length === 0) { + return; + } + const sizeOfElement = v.type === 10 /* float16 */ ? 2 : 4; + let sizeOfVecOrMat; + let baseAlignment; + if (v.type === 10 /* float16 */) { + baseAlignment = data.length > 4 ? 16 : data.length > 2 ? 8 : data.length * sizeOfElement; + sizeOfVecOrMat = data.length > 4 ? 16 : sizeOfElement * data.length; + } else { + baseAlignment = data.length <= 2 ? data.length * sizeOfElement : 16; + sizeOfVecOrMat = 16; + } + currentOffset = Math.ceil(currentOffset / baseAlignment) * baseAlignment; + offsets.push(currentOffset); + const elementPerVecOrMat = v.type === 10 /* float16 */ ? 8 : 4; + currentOffset += data.length > 4 ? Math.ceil(data.length / elementPerVecOrMat) * sizeOfVecOrMat : data.length * sizeOfElement; + }); + const maxAlignmentOfField = 16; + currentOffset = Math.ceil(currentOffset / maxAlignmentOfField) * maxAlignmentOfField; + const arrayBuffer = new ArrayBuffer(currentOffset); + programUniforms.forEach((v, i) => { + const offset = offsets[i]; + const data = typeof v.data === "number" ? [v.data] : v.data; + if (v.type === 6 /* int32 */) { + new Int32Array(arrayBuffer, offset, data.length).set(data); + } else if (v.type === 12 /* uint32 */) { + new Uint32Array(arrayBuffer, offset, data.length).set(data); + } else if (v.type === 10 /* float16 */) { + new Uint16Array(arrayBuffer, offset, data.length).set(data); + } else if (v.type === 1 /* float */) { + new Float32Array(arrayBuffer, offset, data.length).set(data); + } else { + throw new Error(`Unsupported uniform type: ${tensorDataTypeEnumToString(v.type)}`); + } + }); + const uniformBufferData = ( + // eslint-disable-next-line no-bitwise + this.gpuDataManager.create(currentOffset, GPUBufferUsage.COPY_DST | GPUBufferUsage.UNIFORM) + ); + this.device.queue.writeBuffer(uniformBufferData.buffer, 0, arrayBuffer, 0, currentOffset); + this.gpuDataManager.release(uniformBufferData.id); + uniformBufferBinding = { offset: 0, size: currentOffset, buffer: uniformBufferData.buffer }; + } + const normalizedDispatchGroup = this.programManager.normalizeDispatchGroupSize(dispatchGroup); + const is1DimensionDispatch = normalizedDispatchGroup[1] === 1 && normalizedDispatchGroup[2] === 1; + const key = getProgramInfoUniqueKey2(program, inputTensorViews, is1DimensionDispatch); + let artifact = this.programManager.getArtifact(key); + if (!artifact) { + artifact = this.programManager.build(program, normalizedDispatchGroup); + this.programManager.setArtifact(key, artifact); + LOG_DEBUG("info", () => `[artifact] key: ${key}, programName: ${program.name}`); + } + if (programUniforms && artifact.uniformVariablesInfo) { + if (programUniforms.length !== artifact.uniformVariablesInfo.length) { + throw new Error( + `Uniform variables count mismatch: expect ${artifact.uniformVariablesInfo.length}, got ${programUniforms.length} in program "${artifact.programInfo.name}".` + ); + } + for (let i = 0; i < programUniforms.length; i++) { + const uniform = programUniforms[i]; + const actualType = uniform.type; + const actualLength = typeof uniform.data === "number" ? 1 : uniform.data.length; + const [type, length] = artifact.uniformVariablesInfo[i]; + if (actualType !== type || actualLength !== length) { + throw new Error( + `Uniform variable ${i} mismatch: expect type ${type} with size ${length}, got type ${actualType} with size ${actualLength} in program "${artifact.programInfo.name}".` + ); + } + } + } + LOG_DEBUG( + "info", + () => `[ProgramManager] run "${program.name}" (key=${key}) with ${normalizedDispatchGroup[0]}x${normalizedDispatchGroup[1]}x${normalizedDispatchGroup[2]}` + ); + if (this.queryType !== "none" || this.sessionStatus === "capturing") { + const pendingKernelInfo = { + kernelId: this.currentKernelId, + programName: artifact.programInfo.name, + inputTensorViews, + outputTensorViews + }; + this.pendingKernels.push(pendingKernelInfo); + if (this.sessionStatus === "capturing") { + const sessionPendingKernels = this.capturedPendingKernels.get(this.currentSessionId); + sessionPendingKernels.push(pendingKernelInfo); + } + } + this.programManager.run(artifact, inputDatas, outputDatas, normalizedDispatchGroup, uniformBufferBinding); + TRACE_FUNC_END(program.name); + return outputTensorViews; + } + upload(gpuDataId, data) { + this.gpuDataManager.upload(gpuDataId, data); + } + memcpy(src, dst) { + this.gpuDataManager.memcpy(src, dst); + } + async download(gpuDataId, getTargetBuffer) { + await this.gpuDataManager.download(gpuDataId, getTargetBuffer); + } + alloc(size) { + return this.gpuDataManager.create(size).id; + } + free(ptr) { + return this.gpuDataManager.release(ptr); + } + createKernel(kernelType, kernelId, attribute, kernelName) { + const op = WEBGPU_OP_RESOLVE_RULES.get(kernelType); + if (!op) { + throw new Error(`kernel not implemented: ${kernelType}`); + } + const kernelInfo = { + kernelType, + kernelName, + kernelEntry: op[0], + attributes: [op[1], attribute] + }; + this.kernels.set(kernelId, kernelInfo); + } + releaseKernel(kernelId) { + const persistentData = this.kernelPersistentData.get(kernelId); + if (persistentData) { + for (const data of persistentData) { + this.gpuDataManager.release(data.id); + } + this.kernelPersistentData.delete(kernelId); + } + this.kernelCustomData.delete(kernelId); + this.kernels.delete(kernelId); + } + computeKernel(kernelId, context, errors) { + const kernel = this.kernels.get(kernelId); + if (!kernel) { + throw new Error(`kernel not created: ${kernelId}`); + } + const kernelType = kernel.kernelType; + const kernelName = kernel.kernelName; + const kernelEntry = kernel.kernelEntry; + const attributes = kernel.attributes; + if (this.currentKernelId !== null) { + throw new Error(`kernel "[${kernelType}] ${kernelName}" is not allowed to be called recursively`); + } + this.currentKernelId = kernelId; + if (attributes[0]) { + attributes[1] = attributes[0](attributes[1]); + attributes[0] = void 0; + } + LOG_DEBUG("info", () => `[WebGPU] Start to run kernel "[${kernelType}] ${kernelName}"...`); + const useErrorScope = this.env.debug; + this.temporaryData = []; + try { + if (useErrorScope) { + this.device.pushErrorScope("validation"); + } + kernelEntry(context, attributes[1]); + return 0; + } catch (e) { + errors.push(Promise.resolve(`[WebGPU] Kernel "[${kernelType}] ${kernelName}" failed. ${e}`)); + return 1; + } finally { + if (useErrorScope) { + errors.push( + this.device.popErrorScope().then( + (err) => err ? `GPU validation error for kernel "[${kernelType}] ${kernelName}": ${err.message}` : null + ) + ); + } + for (const data of this.temporaryData) { + this.gpuDataManager.release(data.id); + } + this.temporaryData = []; + this.currentKernelId = null; + } + } + // #region external buffer + registerBuffer(sessionId, index, buffer, size) { + let sessionInputOutputMapping = this.sessionExternalDataMapping.get(sessionId); + if (!sessionInputOutputMapping) { + sessionInputOutputMapping = /* @__PURE__ */ new Map(); + this.sessionExternalDataMapping.set(sessionId, sessionInputOutputMapping); + } + const previousBuffer = sessionInputOutputMapping.get(index); + const id = this.gpuDataManager.registerExternalBuffer(buffer, size, previousBuffer); + sessionInputOutputMapping.set(index, [id, buffer]); + return id; + } + unregisterBuffers(sessionId) { + const sessionInputOutputMapping = this.sessionExternalDataMapping.get(sessionId); + if (sessionInputOutputMapping) { + sessionInputOutputMapping.forEach((bufferInfo) => this.gpuDataManager.unregisterExternalBuffer(bufferInfo[0])); + this.sessionExternalDataMapping.delete(sessionId); + } + } + getBuffer(gpuDataId) { + const gpuData = this.gpuDataManager.get(gpuDataId); + if (!gpuData) { + throw new Error(`no GPU data for buffer: ${gpuDataId}`); + } + return gpuData.buffer; + } + createDownloader(gpuBuffer, size, type) { + return async () => { + const data = await downloadGpuData(this, gpuBuffer, size); + return createView2(data.buffer, type); + }; + } + // #endregion + writeTimestamp(index) { + if (this.queryType !== "inside-passes") { + return; + } + this.computePassEncoder.writeTimestamp(this.querySet, index); + } + setQueryType() { + this.queryType = "none"; + if (this.env.webgpu.profiling?.mode === "default" || (typeof this.env.trace === "undefined" ? this.env.wasm.trace : this.env.trace)) { + if (this.device.features.has("chromium-experimental-timestamp-query-inside-passes")) { + this.queryType = "inside-passes"; + } else if (this.device.features.has("timestamp-query")) { + this.queryType = "at-passes"; + } + if (this.queryType !== "none" && typeof this.querySet === "undefined") { + this.querySet = this.device.createQuerySet({ + type: "timestamp", + count: this.maxDispatchNumber * 2 + }); + this.queryResolveBuffer = this.device.createBuffer( + // eslint-disable-next-line no-bitwise + { size: this.maxDispatchNumber * 2 * 8, usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.QUERY_RESOLVE } + ); + } + } + } + captureBegin() { + LOG_DEBUG("info", "captureBegin"); + if (!this.capturedCommandList.get(this.currentSessionId)) { + this.capturedCommandList.set(this.currentSessionId, []); + } + if (!this.capturedPendingKernels.get(this.currentSessionId)) { + this.capturedPendingKernels.set(this.currentSessionId, []); + } + this.flush(); + this.sessionStatus = "capturing"; + } + captureEnd() { + LOG_DEBUG("info", "captureEnd"); + this.flush(); + this.sessionStatus = "default"; + } + replay() { + LOG_DEBUG("info", "replay"); + this.sessionStatus = "replaying"; + const sessionCommandList = this.capturedCommandList.get(this.currentSessionId); + const sessionPendingKernels = this.capturedPendingKernels.get(this.currentSessionId); + const length = sessionCommandList.length; + this.pendingKernels = []; + for (let i = 0; i < length; i++) { + const computePassEncoder = this.getComputePassEncoder(); + const command = sessionCommandList[i]; + this.writeTimestamp(this.pendingDispatchNumber * 2); + computePassEncoder.setPipeline(command.computePipeline); + computePassEncoder.setBindGroup(0, command.bindGroup); + computePassEncoder.dispatchWorkgroups(...command.dispatchGroup); + this.writeTimestamp(this.pendingDispatchNumber * 2 + 1); + this.pendingDispatchNumber++; + if (this.queryType !== "none") { + this.pendingKernels.push(sessionPendingKernels[i]); + } + if (this.pendingDispatchNumber >= this.maxDispatchNumber || this.queryType === "at-passes") { + this.endComputePass(); + } + if (this.pendingDispatchNumber >= this.maxDispatchNumber) { + this.flush(); + } + } + this.flush(); + this.sessionStatus = "default"; + } + onCreateSession() { + this.gpuDataManager.onCreateSession(); + } + onReleaseSession(sessionId) { + this.unregisterBuffers(sessionId); + if (this.capturedCommandList.has(sessionId)) { + this.capturedCommandList.delete(sessionId); + } + if (this.capturedPendingKernels.has(sessionId)) { + this.capturedPendingKernels.delete(sessionId); + } + this.gpuDataManager.onReleaseSession(sessionId); + } + onRunStart(sessionId) { + this.currentSessionId = sessionId; + this.setQueryType(); + } + }; + } + }); + + // web/lib/wasm/jsep/init.ts + var init_exports = {}; + __export(init_exports, { + init: () => init + }); + var TensorViewImpl, ComputeContextImpl, init; + var init_init = __esm({ + "web/lib/wasm/jsep/init.ts"() { + "use strict"; + init_wasm_common(); + init_log(); + init_util2(); + init_backend_webnn(); + TensorViewImpl = class _TensorViewImpl { + constructor(module2, dataType, data, dims) { + this.module = module2; + this.dataType = dataType; + this.data = data; + this.dims = dims; + } + getFloat32Array() { + if (this.dataType !== 1 /* float */) { + throw new Error("Invalid data type"); + } + const elementCount = ShapeUtil2.size(this.dims); + return elementCount === 0 ? new Float32Array() : new Float32Array(this.module.HEAP8.buffer, this.data, elementCount); + } + getBigInt64Array() { + if (this.dataType !== 7 /* int64 */) { + throw new Error("Invalid data type"); + } + const elementCount = ShapeUtil2.size(this.dims); + return elementCount === 0 ? new BigInt64Array() : new BigInt64Array(this.module.HEAP8.buffer, this.data, elementCount); + } + getInt32Array() { + if (this.dataType !== 6 /* int32 */) { + throw new Error("Invalid data type"); + } + const elementCount = ShapeUtil2.size(this.dims); + return elementCount === 0 ? new Int32Array() : new Int32Array(this.module.HEAP8.buffer, this.data, elementCount); + } + getUint16Array() { + if (this.dataType !== 10 /* float16 */ && this.dataType !== 4 /* uint16 */) { + throw new Error("Invalid data type"); + } + const elementCount = ShapeUtil2.size(this.dims); + return elementCount === 0 ? new Uint16Array() : new Uint16Array(this.module.HEAP8.buffer, this.data, elementCount); + } + reshape(newDims) { + if (ShapeUtil2.size(newDims) !== ShapeUtil2.size(this.dims)) { + throw new Error("Invalid new shape"); + } + return new _TensorViewImpl(this.module, this.dataType, this.data, newDims); + } + }; + ComputeContextImpl = class { + constructor(module2, backend2, contextDataOffset) { + this.module = module2; + this.backend = backend2; + this.customDataOffset = 0; + this.customDataSize = 0; + this.adapterInfo = backend2.adapterInfo; + const ptrSize = module2.PTR_SIZE; + let dataIndex = contextDataOffset / module2.PTR_SIZE; + const type = ptrSize === 4 ? "i32" : "i64"; + this.opKernelContext = Number(module2.getValue(ptrSize * dataIndex++, type)); + const inputCount = Number(module2.getValue(ptrSize * dataIndex++, type)); + this.outputCount = Number(module2.getValue(ptrSize * dataIndex++, type)); + this.customDataOffset = Number(module2.getValue(ptrSize * dataIndex++, "*")); + this.customDataSize = Number(module2.getValue(ptrSize * dataIndex++, type)); + const inputs = []; + for (let i = 0; i < inputCount; i++) { + const dataType = Number(module2.getValue(ptrSize * dataIndex++, type)); + const data = Number(module2.getValue(ptrSize * dataIndex++, "*")); + const dim = Number(module2.getValue(ptrSize * dataIndex++, type)); + const dims = []; + for (let d = 0; d < dim; d++) { + dims.push(Number(module2.getValue(ptrSize * dataIndex++, type))); + } + inputs.push(new TensorViewImpl(module2, dataType, data, dims)); + } + this.inputs = inputs; + } + get kernelCustomData() { + return this.backend.currentKernelCustomData; + } + get customDataBuffer() { + return this.module.HEAPU8.subarray(this.customDataOffset, this.customDataOffset + this.customDataSize); + } + compute(program, inputsOutputsMapping) { + const mappedInputs = inputsOutputsMapping?.inputs?.map((i) => typeof i === "number" ? this.inputs[i] : i) ?? this.inputs; + const outputIndices = inputsOutputsMapping?.outputs ?? []; + const createKernelOutput = (index, dataType, dims) => new TensorViewImpl(this.module, dataType, this.output(index, dims), dims); + const createTemporaryOutput = (dataType, dims) => { + const bufferSize = calculateTensorSizeInBytes(dataType, dims); + if (!bufferSize) { + throw new Error(`Unsupported data type: ${dataType}`); + } + const gpuDataId = bufferSize > 0 ? this.backend.gpuDataManager.create(bufferSize).id : 0; + return new TensorViewImpl(this.module, dataType, gpuDataId, dims); + }; + return this.backend.run( + program, + mappedInputs, + outputIndices, + createKernelOutput, + createTemporaryOutput, + this.outputCount + ); + } + output(index, dims) { + const stack = this.module.stackSave(); + try { + const ptrSize = this.module.PTR_SIZE; + const type = ptrSize === 4 ? "i32" : "i64"; + const data = this.module.stackAlloc( + (1 + dims.length) * ptrSize + /* sizeof(size_t) */ + ); + this.module.setValue(data, dims.length, type); + for (let i = 0; i < dims.length; i++) { + this.module.setValue(data + ptrSize * (i + 1), dims[i], type); + } + return this.module._JsepOutput(this.opKernelContext, index, data); + } catch (e) { + throw new Error( + `Failed to generate kernel's output[${index}] with dims [${dims}]. If you are running with pre-allocated output, please make sure the output type/dims are correct. Error: ${e}` + ); + } finally { + this.module.stackRestore(stack); + } + } + }; + init = async (name2, module2, env3, gpuAdapter) => { + const jsepInit = module2.jsepInit; + if (!jsepInit) { + throw new Error("Failed to initialize JSEP. The WebAssembly module is not built with JSEP support."); + } + if (name2 === "webgpu") { + if (true) { + const webGpuBackendImpl = (init_backend_webgpu(), __toCommonJS(backend_webgpu_exports)).WebGpuBackend; + const backend2 = new webGpuBackendImpl(); + await backend2.initialize(env3, gpuAdapter); + jsepInit("webgpu", [ + // backend + backend2, + // jsepAlloc() + (size) => backend2.alloc(Number(size)), + // jsepFree() + (ptr) => backend2.free(ptr), + // jsepCopy(src, dst, size, isSourceGpu) + (src, dst, size, isSourceGpu = false) => { + if (isSourceGpu) { + LOG_DEBUG( + "verbose", + () => `[WebGPU] jsepCopyGpuToGpu: src=${Number(src)}, dst=${Number(dst)}, size=${Number(size)}` + ); + backend2.memcpy(Number(src), Number(dst)); + } else { + LOG_DEBUG( + "verbose", + () => `[WebGPU] jsepCopyCpuToGpu: dataOffset=${Number(src)}, gpuDataId=${Number(dst)}, size=${Number(size)}` + ); + const data = module2.HEAPU8.subarray(Number(src >>> 0), Number(src >>> 0) + Number(size)); + backend2.upload(Number(dst), data); + } + }, + // jsepCopyAsync(src, dst, size) + async (gpuDataId, dataOffset, size) => { + LOG_DEBUG( + "verbose", + () => `[WebGPU] jsepCopyGpuToCpu: gpuDataId=${gpuDataId}, dataOffset=${dataOffset}, size=${size}` + ); + await backend2.download( + Number(gpuDataId), + () => module2.HEAPU8.subarray(Number(dataOffset) >>> 0, Number(dataOffset + size) >>> 0) + ); + }, + // jsepCreateKernel + (kernelType, kernelId, attribute) => backend2.createKernel( + kernelType, + Number(kernelId), + attribute, + module2.UTF8ToString(module2._JsepGetNodeName(Number(kernelId))) + ), + // jsepReleaseKernel + (kernel) => backend2.releaseKernel(kernel), + // jsepRun + (kernel, contextDataOffset, sessionHandle, errors) => { + LOG_DEBUG( + "verbose", + () => `[WebGPU] jsepRun: sessionHandle=${sessionHandle}, kernel=${kernel}, contextDataOffset=${contextDataOffset}` + ); + const context = new ComputeContextImpl(module2, backend2, Number(contextDataOffset)); + return backend2.computeKernel(Number(kernel), context, errors); + }, + // jsepCaptureBegin + () => backend2.captureBegin(), + // jsepCaptureEnd + () => backend2.captureEnd(), + // jsepReplay + () => backend2.replay() + ]); + } + } else { + const backend2 = new WebNNBackend(env3); + jsepInit("webnn", [ + backend2, + // jsepReserveTensorId + () => backend2.reserveTensorId(), + // jsepReleaseTensorId, + (tensorId) => backend2.releaseTensorId(tensorId), + // jsepEnsureTensor + async (sessionId, tensorId, onnxDataType, shape2, copyOld) => backend2.ensureTensor(sessionId, tensorId, onnxDataType, shape2, copyOld), + // jsepUploadTensor + (tensorId, data) => { + backend2.uploadTensor(tensorId, data); + }, + // jsepDownloadTensor + async (tensorId, dstBuffer) => backend2.downloadTensor(tensorId, dstBuffer) + ]); + } + }; + } + }); + + // web/lib/wasm/wasm-core-impl.ts + var initOrt, initRuntime, initEp, activeSessions, getSessionInputOutputCount, getSessionInputOutputMetadata, copyFromExternalBuffer, createSession, releaseSession, prepareInputOutputTensor, run, endProfiling, extractTransferableBuffers; + var init_wasm_core_impl = __esm({ + "web/lib/wasm/wasm-core-impl.ts"() { + "use strict"; + init_run_options(); + init_session_options(); + init_wasm_common(); + init_wasm_factory(); + init_wasm_utils(); + init_wasm_utils_load_file(); + initOrt = (numThreads, loggingLevel) => { + const errorCode = getInstance()._OrtInit(numThreads, loggingLevel); + if (errorCode !== 0) { + checkLastError("Can't initialize onnxruntime."); + } + }; + initRuntime = async (env3) => { + initOrt(env3.wasm.numThreads, logLevelStringToEnum(env3.logLevel)); + }; + initEp = async (env3, epName) => { + getInstance().asyncInit?.(); + if (epName === "webgpu" && false) { + getInstance().webgpuInit((device) => { + env3.webgpu.device = device; + }); + } + if (true) { + const initJsep = (init_init(), __toCommonJS(init_exports)).init; + if (epName === "webgpu" && true) { + if (typeof navigator === "undefined" || !navigator.gpu) { + throw new Error("WebGPU is not supported in current environment"); + } + let adapter = env3.webgpu.adapter; + if (!adapter) { + const powerPreference = env3.webgpu.powerPreference; + if (powerPreference !== void 0 && powerPreference !== "low-power" && powerPreference !== "high-performance") { + throw new Error(`Invalid powerPreference setting: "${powerPreference}"`); + } + const forceFallbackAdapter = env3.webgpu.forceFallbackAdapter; + if (forceFallbackAdapter !== void 0 && typeof forceFallbackAdapter !== "boolean") { + throw new Error(`Invalid forceFallbackAdapter setting: "${forceFallbackAdapter}"`); + } + adapter = await navigator.gpu.requestAdapter({ powerPreference, forceFallbackAdapter }); + if (!adapter) { + throw new Error( + 'Failed to get GPU adapter. You may need to enable flag "--enable-unsafe-webgpu" if you are using Chrome.' + ); + } + } else { + if (typeof adapter.limits !== "object" || typeof adapter.features !== "object" || typeof adapter.requestDevice !== "function") { + throw new Error("Invalid GPU adapter set in `env.webgpu.adapter`. It must be a GPUAdapter object."); + } + } + await initJsep("webgpu", getInstance(), env3, adapter); + } + if (epName === "webnn") { + if (typeof navigator === "undefined" || !navigator.ml) { + throw new Error("WebNN is not supported in current environment"); + } + await initJsep("webnn", getInstance(), env3); + } + } + }; + activeSessions = /* @__PURE__ */ new Map(); + getSessionInputOutputCount = (sessionHandle) => { + const wasm3 = getInstance(); + const stack = wasm3.stackSave(); + try { + const ptrSize = wasm3.PTR_SIZE; + const dataOffset = wasm3.stackAlloc(2 * ptrSize); + const errorCode = wasm3._OrtGetInputOutputCount(sessionHandle, dataOffset, dataOffset + ptrSize); + if (errorCode !== 0) { + checkLastError("Can't get session input/output count."); + } + const type = ptrSize === 4 ? "i32" : "i64"; + return [Number(wasm3.getValue(dataOffset, type)), Number(wasm3.getValue(dataOffset + ptrSize, type))]; + } finally { + wasm3.stackRestore(stack); + } + }; + getSessionInputOutputMetadata = (sessionHandle, index) => { + const wasm3 = getInstance(); + const stack = wasm3.stackSave(); + let metadataOffset = 0; + try { + const ptrSize = wasm3.PTR_SIZE; + const dataOffset = wasm3.stackAlloc(2 * ptrSize); + const errorCode = wasm3._OrtGetInputOutputMetadata(sessionHandle, index, dataOffset, dataOffset + ptrSize); + if (errorCode !== 0) { + checkLastError("Can't get session input/output metadata."); + } + const nameOffset = Number(wasm3.getValue(dataOffset, "*")); + metadataOffset = Number(wasm3.getValue(dataOffset + ptrSize, "*")); + const elementType = wasm3.HEAP32[metadataOffset / 4]; + if (elementType === 0) { + return [nameOffset, 0]; + } + const dimsCount = wasm3.HEAPU32[metadataOffset / 4 + 1]; + const dims = []; + for (let i = 0; i < dimsCount; i++) { + const symbolicDimNameOffset = Number(wasm3.getValue(metadataOffset + 8 + i * ptrSize, "*")); + dims.push( + symbolicDimNameOffset !== 0 ? wasm3.UTF8ToString(symbolicDimNameOffset) : Number(wasm3.getValue(metadataOffset + 8 + (i + dimsCount) * ptrSize, "*")) + ); + } + return [nameOffset, elementType, dims]; + } finally { + wasm3.stackRestore(stack); + if (metadataOffset !== 0) { + wasm3._OrtFree(metadataOffset); + } + } + }; + copyFromExternalBuffer = (model) => { + const wasm3 = getInstance(); + const modelDataOffset = wasm3._malloc(model.byteLength); + if (modelDataOffset === 0) { + throw new Error(`Can't create a session. failed to allocate a buffer of size ${model.byteLength}.`); + } + wasm3.HEAPU8.set(model, modelDataOffset); + return [modelDataOffset, model.byteLength]; + }; + createSession = async (modelData, options) => { + let modelDataOffset, modelDataLength; + const wasm3 = getInstance(); + if (Array.isArray(modelData)) { + [modelDataOffset, modelDataLength] = modelData; + } else if (modelData.buffer === wasm3.HEAPU8.buffer) { + [modelDataOffset, modelDataLength] = [modelData.byteOffset, modelData.byteLength]; + } else { + [modelDataOffset, modelDataLength] = copyFromExternalBuffer(modelData); + } + let sessionHandle = 0; + let sessionOptionsHandle = 0; + let ioBindingHandle = 0; + let allocs = []; + const inputNamesUTF8Encoded = []; + const outputNamesUTF8Encoded = []; + try { + [sessionOptionsHandle, allocs] = await setSessionOptions(options); + if (options?.externalData && wasm3.mountExternalData) { + const loadingPromises = []; + for (const file of options.externalData) { + const path = typeof file === "string" ? file : file.path; + loadingPromises.push( + loadFile(typeof file === "string" ? file : file.data).then((data) => { + wasm3.mountExternalData(path, data); + }) + ); + } + await Promise.all(loadingPromises); + } + for (const provider of options?.executionProviders ?? []) { + const providerName = typeof provider === "string" ? provider : provider.name; + if (providerName === "webnn") { + wasm3.shouldTransferToMLTensor = false; + if (typeof provider !== "string") { + const webnnOptions = provider; + const context = webnnOptions?.context; + const gpuDevice = webnnOptions?.gpuDevice; + const deviceType = webnnOptions?.deviceType; + const powerPreference = webnnOptions?.powerPreference; + if (context) { + wasm3.currentContext = context; + } else if (gpuDevice) { + wasm3.currentContext = await wasm3.webnnCreateMLContext(gpuDevice); + } else { + wasm3.currentContext = await wasm3.webnnCreateMLContext({ deviceType, powerPreference }); + } + } else { + wasm3.currentContext = await wasm3.webnnCreateMLContext(); + } + break; + } + } + sessionHandle = await wasm3._OrtCreateSession(modelDataOffset, modelDataLength, sessionOptionsHandle); + wasm3.webgpuOnCreateSession?.(sessionHandle); + if (sessionHandle === 0) { + checkLastError("Can't create a session."); + } + wasm3.jsepOnCreateSession?.(); + if (wasm3.currentContext) { + wasm3.webnnRegisterMLContext(sessionHandle, wasm3.currentContext); + wasm3.currentContext = void 0; + wasm3.shouldTransferToMLTensor = true; + } + const [inputCount, outputCount] = getSessionInputOutputCount(sessionHandle); + const enableGraphCapture = !!options?.enableGraphCapture; + const inputNames = []; + const outputNames = []; + const inputMetadata = []; + const outputMetadata = []; + const outputPreferredLocations = []; + for (let i = 0; i < inputCount; i++) { + const [nameOffset, elementType, shape2] = getSessionInputOutputMetadata(sessionHandle, i); + if (nameOffset === 0) { + checkLastError("Can't get an input name."); + } + inputNamesUTF8Encoded.push(nameOffset); + const name2 = wasm3.UTF8ToString(nameOffset); + inputNames.push(name2); + inputMetadata.push( + elementType === 0 ? { name: name2, isTensor: false } : { name: name2, isTensor: true, type: tensorDataTypeEnumToString(elementType), shape: shape2 } + ); + } + for (let i = 0; i < outputCount; i++) { + const [nameOffset, elementType, shape2] = getSessionInputOutputMetadata(sessionHandle, i + inputCount); + if (nameOffset === 0) { + checkLastError("Can't get an output name."); + } + outputNamesUTF8Encoded.push(nameOffset); + const nameString = wasm3.UTF8ToString(nameOffset); + outputNames.push(nameString); + outputMetadata.push( + elementType === 0 ? { name: nameString, isTensor: false } : { name: nameString, isTensor: true, type: tensorDataTypeEnumToString(elementType), shape: shape2 } + ); + if (true) { + if (enableGraphCapture && options?.preferredOutputLocation === void 0) { + outputPreferredLocations.push("gpu-buffer"); + continue; + } + const location2 = typeof options?.preferredOutputLocation === "string" ? options.preferredOutputLocation : options?.preferredOutputLocation?.[nameString] ?? "cpu"; + const isGraphOutput = wasm3.webnnIsGraphOutput; + if (location2 === "cpu" && isGraphOutput && isGraphOutput(sessionHandle, nameString)) { + outputPreferredLocations.push("ml-tensor-cpu-output"); + continue; + } + if (location2 !== "cpu" && location2 !== "cpu-pinned" && location2 !== "gpu-buffer" && location2 !== "ml-tensor") { + throw new Error(`Not supported preferred output location: ${location2}.`); + } + if (enableGraphCapture && location2 !== "gpu-buffer") { + throw new Error( + `Not supported preferred output location: ${location2}. Only 'gpu-buffer' location is supported when enableGraphCapture is true.` + ); + } + outputPreferredLocations.push(location2); + } + } + let bindingState = null; + if (outputPreferredLocations.some((l) => l === "gpu-buffer" || l === "ml-tensor" || l === "ml-tensor-cpu-output")) { + ioBindingHandle = wasm3._OrtCreateBinding(sessionHandle); + if (ioBindingHandle === 0) { + checkLastError("Can't create IO binding."); + } + bindingState = { + handle: ioBindingHandle, + outputPreferredLocations, + outputPreferredLocationsEncoded: outputPreferredLocations.map((l) => l === "ml-tensor-cpu-output" ? "ml-tensor" : l).map((l) => dataLocationStringToEnum(l)) + }; + } + activeSessions.set(sessionHandle, [ + sessionHandle, + inputNamesUTF8Encoded, + outputNamesUTF8Encoded, + bindingState, + enableGraphCapture, + false + ]); + return [sessionHandle, inputNames, outputNames, inputMetadata, outputMetadata]; + } catch (e) { + inputNamesUTF8Encoded.forEach((buf) => wasm3._OrtFree(buf)); + outputNamesUTF8Encoded.forEach((buf) => wasm3._OrtFree(buf)); + if (ioBindingHandle !== 0) { + if (wasm3._OrtReleaseBinding(ioBindingHandle) !== 0) { + checkLastError("Can't release IO binding."); + } + } + if (sessionHandle !== 0) { + if (wasm3._OrtReleaseSession(sessionHandle) !== 0) { + checkLastError("Can't release session."); + } + } + throw e; + } finally { + wasm3._free(modelDataOffset); + if (sessionOptionsHandle !== 0) { + if (wasm3._OrtReleaseSessionOptions(sessionOptionsHandle) !== 0) { + checkLastError("Can't release session options."); + } + } + allocs.forEach((alloc) => wasm3._free(alloc)); + wasm3.unmountExternalData?.(); + } + }; + releaseSession = (sessionId) => { + const wasm3 = getInstance(); + const session = activeSessions.get(sessionId); + if (!session) { + throw new Error(`cannot release session. invalid session id: ${sessionId}`); + } + const [sessionHandle, inputNamesUTF8Encoded, outputNamesUTF8Encoded, ioBindingState, enableGraphCapture] = session; + if (ioBindingState) { + if (enableGraphCapture) { + if (wasm3._OrtClearBoundOutputs(ioBindingState.handle) !== 0) { + checkLastError("Can't clear bound outputs."); + } + } + if (wasm3._OrtReleaseBinding(ioBindingState.handle) !== 0) { + checkLastError("Can't release IO binding."); + } + } + wasm3.jsepOnReleaseSession?.(sessionId); + wasm3.webnnOnReleaseSession?.(sessionId); + wasm3.webgpuOnReleaseSession?.(sessionId); + inputNamesUTF8Encoded.forEach((buf) => wasm3._OrtFree(buf)); + outputNamesUTF8Encoded.forEach((buf) => wasm3._OrtFree(buf)); + if (wasm3._OrtReleaseSession(sessionHandle) !== 0) { + checkLastError("Can't release session."); + } + activeSessions.delete(sessionId); + }; + prepareInputOutputTensor = async (tensor, tensorHandles, allocs, sessionId, tensorNameUTF8Encoded, index, enableGraphCapture = false) => { + if (!tensor) { + tensorHandles.push(0); + return; + } + const wasm3 = getInstance(); + const ptrSize = wasm3.PTR_SIZE; + const dataType = tensor[0]; + const dims = tensor[1]; + const location2 = tensor[3]; + let actualLocation = location2; + let rawData; + let dataByteLength; + if (dataType === "string" && (location2 === "gpu-buffer" || location2 === "ml-tensor")) { + throw new Error("String tensor is not supported on GPU."); + } + if (enableGraphCapture && location2 !== "gpu-buffer") { + throw new Error( + `External buffer must be provided for input/output index ${index} when enableGraphCapture is true.` + ); + } + if (location2 === "gpu-buffer") { + const gpuBuffer = tensor[2].gpuBuffer; + dataByteLength = calculateTensorSizeInBytes(tensorDataTypeStringToEnum(dataType), dims); + if (false) { + const registerBuffer = wasm3.webgpuRegisterBuffer; + if (!registerBuffer) { + throw new Error('Tensor location "gpu-buffer" is not supported without using WebGPU.'); + } + rawData = registerBuffer(gpuBuffer, sessionId); + } else { + const registerBuffer = wasm3.jsepRegisterBuffer; + if (!registerBuffer) { + throw new Error('Tensor location "gpu-buffer" is not supported without using WebGPU.'); + } + rawData = registerBuffer(sessionId, index, gpuBuffer, dataByteLength); + } + } else if (location2 === "ml-tensor") { + const mlTensor = tensor[2].mlTensor; + dataByteLength = calculateTensorSizeInBytes(tensorDataTypeStringToEnum(dataType), dims); + const registerMLTensor = wasm3.webnnRegisterMLTensor; + if (!registerMLTensor) { + throw new Error('Tensor location "ml-tensor" is not supported without using WebNN.'); + } + rawData = registerMLTensor(sessionId, mlTensor, tensorDataTypeStringToEnum(dataType), dims); + } else { + const data = tensor[2]; + if (Array.isArray(data)) { + dataByteLength = ptrSize * data.length; + rawData = wasm3._malloc(dataByteLength); + allocs.push(rawData); + for (let i = 0; i < data.length; i++) { + if (typeof data[i] !== "string") { + throw new TypeError(`tensor data at index ${i} is not a string`); + } + wasm3.setValue(rawData + i * ptrSize, allocWasmString(data[i], allocs), "*"); + } + } else { + const isGraphInput = wasm3.webnnIsGraphInput; + const isGraphOutput = wasm3.webnnIsGraphOutput; + if (dataType !== "string" && isGraphInput && isGraphOutput) { + const tensorName = wasm3.UTF8ToString(tensorNameUTF8Encoded); + if (isGraphInput(sessionId, tensorName) || isGraphOutput(sessionId, tensorName)) { + const dataTypeEnum = tensorDataTypeStringToEnum(dataType); + dataByteLength = calculateTensorSizeInBytes(dataTypeEnum, dims); + actualLocation = "ml-tensor"; + const createTemporaryTensor = wasm3.webnnCreateTemporaryTensor; + const uploadTensor = wasm3.webnnUploadTensor; + if (!createTemporaryTensor || !uploadTensor) { + throw new Error('Tensor location "ml-tensor" is not supported without using WebNN.'); + } + const tensorId = await createTemporaryTensor(sessionId, dataTypeEnum, dims); + uploadTensor(tensorId, new Uint8Array(data.buffer, data.byteOffset, data.byteLength)); + rawData = tensorId; + } else { + dataByteLength = data.byteLength; + rawData = wasm3._malloc(dataByteLength); + allocs.push(rawData); + wasm3.HEAPU8.set(new Uint8Array(data.buffer, data.byteOffset, dataByteLength), rawData); + } + } else { + dataByteLength = data.byteLength; + rawData = wasm3._malloc(dataByteLength); + allocs.push(rawData); + wasm3.HEAPU8.set(new Uint8Array(data.buffer, data.byteOffset, dataByteLength), rawData); + } + } + } + const stack = wasm3.stackSave(); + const dimsOffset = wasm3.stackAlloc(4 * dims.length); + try { + dims.forEach((d, index2) => wasm3.setValue(dimsOffset + index2 * ptrSize, d, ptrSize === 4 ? "i32" : "i64")); + const tensor2 = wasm3._OrtCreateTensor( + tensorDataTypeStringToEnum(dataType), + rawData, + dataByteLength, + dimsOffset, + dims.length, + dataLocationStringToEnum(actualLocation) + ); + if (tensor2 === 0) { + checkLastError(`Can't create tensor for input/output. session=${sessionId}, index=${index}.`); + } + tensorHandles.push(tensor2); + } finally { + wasm3.stackRestore(stack); + } + }; + run = async (sessionId, inputIndices, inputTensors, outputIndices, outputTensors, options) => { + const wasm3 = getInstance(); + const ptrSize = wasm3.PTR_SIZE; + const session = activeSessions.get(sessionId); + if (!session) { + throw new Error(`cannot run inference. invalid session id: ${sessionId}`); + } + const sessionHandle = session[0]; + const inputNamesUTF8Encoded = session[1]; + const outputNamesUTF8Encoded = session[2]; + const ioBindingState = session[3]; + const enableGraphCapture = session[4]; + const inputOutputBound = session[5]; + const inputCount = inputIndices.length; + const outputCount = outputIndices.length; + let runOptionsHandle = 0; + let runOptionsAllocs = []; + const inputTensorHandles = []; + const outputTensorHandles = []; + const inputOutputAllocs = []; + const beforeRunStack = wasm3.stackSave(); + const inputValuesOffset = wasm3.stackAlloc(inputCount * ptrSize); + const inputNamesOffset = wasm3.stackAlloc(inputCount * ptrSize); + const outputValuesOffset = wasm3.stackAlloc(outputCount * ptrSize); + const outputNamesOffset = wasm3.stackAlloc(outputCount * ptrSize); + try { + [runOptionsHandle, runOptionsAllocs] = setRunOptions(options); + for (let i = 0; i < inputCount; i++) { + await prepareInputOutputTensor( + inputTensors[i], + inputTensorHandles, + inputOutputAllocs, + sessionId, + inputNamesUTF8Encoded[inputIndices[i]], + inputIndices[i], + enableGraphCapture + ); + } + for (let i = 0; i < outputCount; i++) { + await prepareInputOutputTensor( + outputTensors[i], + outputTensorHandles, + inputOutputAllocs, + sessionId, + outputNamesUTF8Encoded[outputIndices[i]], + inputCount + outputIndices[i], + enableGraphCapture + ); + } + for (let i = 0; i < inputCount; i++) { + wasm3.setValue(inputValuesOffset + i * ptrSize, inputTensorHandles[i], "*"); + wasm3.setValue(inputNamesOffset + i * ptrSize, inputNamesUTF8Encoded[inputIndices[i]], "*"); + } + for (let i = 0; i < outputCount; i++) { + wasm3.setValue(outputValuesOffset + i * ptrSize, outputTensorHandles[i], "*"); + wasm3.setValue(outputNamesOffset + i * ptrSize, outputNamesUTF8Encoded[outputIndices[i]], "*"); + } + if (ioBindingState && !inputOutputBound) { + const { handle, outputPreferredLocations, outputPreferredLocationsEncoded } = ioBindingState; + if (inputNamesUTF8Encoded.length !== inputCount) { + throw new Error( + `input count from feeds (${inputCount}) is expected to be always equal to model's input count (${inputNamesUTF8Encoded.length}).` + ); + } + for (let i = 0; i < inputCount; i++) { + const index = inputIndices[i]; + const errorCode2 = await wasm3._OrtBindInput(handle, inputNamesUTF8Encoded[index], inputTensorHandles[i]); + if (errorCode2 !== 0) { + checkLastError(`Can't bind input[${i}] for session=${sessionId}.`); + } + } + for (let i = 0; i < outputCount; i++) { + const index = outputIndices[i]; + const location2 = outputTensors[i]?.[3]; + if (location2) { + const errorCode2 = wasm3._OrtBindOutput(handle, outputNamesUTF8Encoded[index], outputTensorHandles[i], 0); + if (errorCode2 !== 0) { + checkLastError(`Can't bind pre-allocated output[${i}] for session=${sessionId}.`); + } + } else { + const errorCode2 = wasm3._OrtBindOutput( + handle, + outputNamesUTF8Encoded[index], + 0, + outputPreferredLocationsEncoded[index] + ); + if (errorCode2 !== 0) { + checkLastError(`Can't bind output[${i}] to ${outputPreferredLocations[i]} for session=${sessionId}.`); + } + } + } + activeSessions.set(sessionId, [ + sessionHandle, + inputNamesUTF8Encoded, + outputNamesUTF8Encoded, + ioBindingState, + enableGraphCapture, + true + ]); + } + wasm3.jsepOnRunStart?.(sessionHandle); + wasm3.webnnOnRunStart?.(sessionHandle); + let errorCode; + if (ioBindingState) { + errorCode = await wasm3._OrtRunWithBinding( + sessionHandle, + ioBindingState.handle, + outputCount, + outputValuesOffset, + runOptionsHandle + ); + } else { + errorCode = await wasm3._OrtRun( + sessionHandle, + inputNamesOffset, + inputValuesOffset, + inputCount, + outputNamesOffset, + outputCount, + outputValuesOffset, + runOptionsHandle + ); + } + if (errorCode !== 0) { + checkLastError("failed to call OrtRun()."); + } + const output = []; + const outputPromises = []; + for (let i = 0; i < outputCount; i++) { + const tensor = Number(wasm3.getValue(outputValuesOffset + i * ptrSize, "*")); + if (tensor === outputTensorHandles[i]) { + output.push(outputTensors[i]); + continue; + } + const beforeGetTensorDataStack = wasm3.stackSave(); + const tensorDataOffset = wasm3.stackAlloc(4 * ptrSize); + let keepOutputTensor = false; + let type, dataOffset = 0; + try { + const errorCode2 = wasm3._OrtGetTensorData( + tensor, + tensorDataOffset, + tensorDataOffset + ptrSize, + tensorDataOffset + 2 * ptrSize, + tensorDataOffset + 3 * ptrSize + ); + if (errorCode2 !== 0) { + checkLastError(`Can't access output tensor data on index ${i}.`); + } + const valueType = ptrSize === 4 ? "i32" : "i64"; + const dataType = Number(wasm3.getValue(tensorDataOffset, valueType)); + dataOffset = wasm3.getValue(tensorDataOffset + ptrSize, "*"); + const dimsOffset = wasm3.getValue(tensorDataOffset + ptrSize * 2, "*"); + const dimsLength = Number(wasm3.getValue(tensorDataOffset + ptrSize * 3, valueType)); + const dims = []; + for (let i2 = 0; i2 < dimsLength; i2++) { + dims.push(Number(wasm3.getValue(dimsOffset + i2 * ptrSize, valueType))); + } + if (wasm3._OrtFree(dimsOffset) !== 0) { + checkLastError("Can't free memory for tensor dims."); + } + const size = dims.reduce((a, b) => a * b, 1); + type = tensorDataTypeEnumToString(dataType); + const preferredLocation = ioBindingState?.outputPreferredLocations[outputIndices[i]]; + if (type === "string") { + if (preferredLocation === "gpu-buffer" || preferredLocation === "ml-tensor") { + throw new Error("String tensor is not supported on GPU."); + } + const stringData = []; + for (let i2 = 0; i2 < size; i2++) { + const offset = wasm3.getValue(dataOffset + i2 * ptrSize, "*"); + const nextOffset = wasm3.getValue(dataOffset + (i2 + 1) * ptrSize, "*"); + const maxBytesToRead = i2 === size - 1 ? void 0 : nextOffset - offset; + stringData.push(wasm3.UTF8ToString(offset, maxBytesToRead)); + } + output.push([type, dims, stringData, "cpu"]); + } else { + if (preferredLocation === "gpu-buffer" && size > 0) { + const getBuffer = false ? wasm3.webgpuGetBuffer : wasm3.jsepGetBuffer; + if (!getBuffer) { + throw new Error('preferredLocation "gpu-buffer" is not supported without using WebGPU.'); + } + const gpuBuffer = getBuffer(dataOffset); + const bufferSize = calculateTensorSizeInBytes(dataType, size); + if (bufferSize === void 0 || !isGpuBufferSupportedType(type)) { + throw new Error(`Unsupported data type: ${type}`); + } + keepOutputTensor = true; + if (false) { + wasm3.webgpuRegisterBuffer(gpuBuffer, sessionId, dataOffset); + const downloadDataFunction = wasm3.webgpuCreateDownloader(gpuBuffer, bufferSize, sessionId); + output.push([ + type, + dims, + { + gpuBuffer, + download: async () => { + const arrayBuffer = await downloadDataFunction(); + const data = new (tensorTypeToTypedArrayConstructor(type))(arrayBuffer); + return data; + }, + dispose: () => { + if (wasm3._OrtReleaseTensor(tensor) !== 0) { + checkLastError("Can't release tensor."); + } + } + }, + "gpu-buffer" + ]); + } else { + output.push([ + type, + dims, + { + gpuBuffer, + download: wasm3.jsepCreateDownloader(gpuBuffer, bufferSize, type), + dispose: () => { + if (wasm3._OrtReleaseTensor(tensor) !== 0) { + checkLastError("Can't release tensor."); + } + } + }, + "gpu-buffer" + ]); + } + } else if (preferredLocation === "ml-tensor" && size > 0) { + const ensureTensor = wasm3.webnnEnsureTensor; + const isGraphInputOutputTypeSupported = wasm3.webnnIsGraphInputOutputTypeSupported; + if (!ensureTensor || !isGraphInputOutputTypeSupported) { + throw new Error('preferredLocation "ml-tensor" is not supported without using WebNN.'); + } + const tensorSize = calculateTensorSizeInBytes(dataType, size); + if (tensorSize === void 0 || !isMLTensorSupportedType(type)) { + throw new Error(`Unsupported data type: ${type}`); + } + if (!isGraphInputOutputTypeSupported(sessionId, type, false)) { + throw new Error( + `preferredLocation "ml-tensor" for ${type} output is not supported by current WebNN Context.` + ); + } + const mlTensor = await ensureTensor(sessionId, dataOffset, dataType, dims, false); + keepOutputTensor = true; + output.push([ + type, + dims, + { + mlTensor, + download: wasm3.webnnCreateMLTensorDownloader(dataOffset, type), + dispose: () => { + wasm3.webnnReleaseTensorId(dataOffset); + wasm3._OrtReleaseTensor(tensor); + } + }, + "ml-tensor" + ]); + } else if (preferredLocation === "ml-tensor-cpu-output" && size > 0) { + const data = wasm3.webnnCreateMLTensorDownloader(dataOffset, type)(); + const index = output.length; + keepOutputTensor = true; + outputPromises.push( + (async () => { + const result = [index, await data]; + wasm3.webnnReleaseTensorId(dataOffset); + wasm3._OrtReleaseTensor(tensor); + return result; + })() + ); + output.push([type, dims, [], "cpu"]); + } else { + const typedArrayConstructor = tensorTypeToTypedArrayConstructor(type); + const data = new typedArrayConstructor(size); + new Uint8Array(data.buffer, data.byteOffset, data.byteLength).set( + wasm3.HEAPU8.subarray(dataOffset, dataOffset + data.byteLength) + ); + output.push([type, dims, data, "cpu"]); + } + } + } finally { + wasm3.stackRestore(beforeGetTensorDataStack); + if (type === "string" && dataOffset) { + wasm3._free(dataOffset); + } + if (!keepOutputTensor) { + wasm3._OrtReleaseTensor(tensor); + } + } + } + if (ioBindingState && !enableGraphCapture) { + if (wasm3._OrtClearBoundOutputs(ioBindingState.handle) !== 0) { + checkLastError("Can't clear bound outputs."); + } + activeSessions.set(sessionId, [ + sessionHandle, + inputNamesUTF8Encoded, + outputNamesUTF8Encoded, + ioBindingState, + enableGraphCapture, + false + ]); + } + for (const [index, data] of await Promise.all(outputPromises)) { + output[index][2] = data; + } + return output; + } finally { + wasm3.webnnOnRunEnd?.(sessionHandle); + wasm3.stackRestore(beforeRunStack); + if (false) { + inputTensors.forEach((t) => { + if (t && t[3] === "gpu-buffer") { + wasm3.webgpuUnregisterBuffer(t[2].gpuBuffer); + } + }); + outputTensors.forEach((t) => { + if (t && t[3] === "gpu-buffer") { + wasm3.webgpuUnregisterBuffer(t[2].gpuBuffer); + } + }); + } + inputTensorHandles.forEach((v) => wasm3._OrtReleaseTensor(v)); + outputTensorHandles.forEach((v) => wasm3._OrtReleaseTensor(v)); + inputOutputAllocs.forEach((p) => wasm3._free(p)); + if (runOptionsHandle !== 0) { + wasm3._OrtReleaseRunOptions(runOptionsHandle); + } + runOptionsAllocs.forEach((p) => wasm3._free(p)); + } + }; + endProfiling = (sessionId) => { + const wasm3 = getInstance(); + const session = activeSessions.get(sessionId); + if (!session) { + throw new Error("invalid session id"); + } + const sessionHandle = session[0]; + const profileFileName = wasm3._OrtEndProfiling(sessionHandle); + if (profileFileName === 0) { + checkLastError("Can't get an profile file name."); + } + wasm3._OrtFree(profileFileName); + }; + extractTransferableBuffers = (tensors) => { + const buffers = []; + for (const tensor of tensors) { + const data = tensor[2]; + if (!Array.isArray(data) && "buffer" in data) { + buffers.push(data.buffer); + } + } + return buffers; + }; + } + }); + + // web/lib/wasm/proxy-wrapper.ts + var isProxy, proxyWorker, initializing2, initialized2, aborted2, temporaryObjectUrl, initWasmCallbacks, queuedCallbacks, enqueueCallbacks, ensureWorker, onProxyWorkerMessage, initializeWebAssemblyAndOrtRuntime, initializeOrtEp, copyFromExternalBuffer2, createSession2, releaseSession2, run2, endProfiling2; + var init_proxy_wrapper = __esm({ + "web/lib/wasm/proxy-wrapper.ts"() { + "use strict"; + init_esm(); + init_wasm_core_impl(); + init_wasm_factory(); + init_wasm_utils_import(); + isProxy = () => !!env2.wasm.proxy && typeof document !== "undefined"; + initializing2 = false; + initialized2 = false; + aborted2 = false; + queuedCallbacks = /* @__PURE__ */ new Map(); + enqueueCallbacks = (type, callbacks) => { + const queue = queuedCallbacks.get(type); + if (queue) { + queue.push(callbacks); + } else { + queuedCallbacks.set(type, [callbacks]); + } + }; + ensureWorker = () => { + if (initializing2 || !initialized2 || aborted2 || !proxyWorker) { + throw new Error("worker not ready"); + } + }; + onProxyWorkerMessage = (ev) => { + switch (ev.data.type) { + case "init-wasm": + initializing2 = false; + if (ev.data.err) { + aborted2 = true; + initWasmCallbacks[1](ev.data.err); + } else { + initialized2 = true; + initWasmCallbacks[0](); + } + if (temporaryObjectUrl) { + URL.revokeObjectURL(temporaryObjectUrl); + temporaryObjectUrl = void 0; + } + break; + case "init-ep": + case "copy-from": + case "create": + case "release": + case "run": + case "end-profiling": { + const callbacks = queuedCallbacks.get(ev.data.type); + if (ev.data.err) { + callbacks.shift()[1](ev.data.err); + } else { + callbacks.shift()[0](ev.data.out); + } + break; + } + default: + } + }; + initializeWebAssemblyAndOrtRuntime = async () => { + if (initialized2) { + return; + } + if (initializing2) { + throw new Error("multiple calls to 'initWasm()' detected."); + } + if (aborted2) { + throw new Error("previous call to 'initWasm()' failed."); + } + initializing2 = true; + if (isProxy()) { + return new Promise((resolve, reject) => { + proxyWorker?.terminate(); + void importProxyWorker().then(([objectUrl, worker]) => { + try { + proxyWorker = worker; + proxyWorker.onerror = (ev) => reject(ev); + proxyWorker.onmessage = onProxyWorkerMessage; + initWasmCallbacks = [resolve, reject]; + const message = { type: "init-wasm", in: env2 }; + if (!message.in.wasm.wasmPaths && objectUrl) { + const inferredWasmPathPrefix = inferWasmPathPrefixFromScriptSrc(); + if (inferredWasmPathPrefix) { + message.in.wasm.wasmPaths = inferredWasmPathPrefix; + } + } + if (false) { + message.in.wasm.wasmPaths = { + wasm: true ? new URL("ort-wasm-simd-threaded.jsep.wasm", void 0).href : new URL("ort-wasm-simd-threaded.wasm", void 0).href + }; + } + proxyWorker.postMessage(message); + temporaryObjectUrl = objectUrl; + } catch (e) { + reject(e); + } + }, reject); + }); + } else { + try { + await initializeWebAssembly(env2.wasm); + await initRuntime(env2); + initialized2 = true; + } catch (e) { + aborted2 = true; + throw e; + } finally { + initializing2 = false; + } + } + }; + initializeOrtEp = async (epName) => { + if (isProxy()) { + ensureWorker(); + return new Promise((resolve, reject) => { + enqueueCallbacks("init-ep", [resolve, reject]); + const message = { type: "init-ep", in: { epName, env: env2 } }; + proxyWorker.postMessage(message); + }); + } else { + await initEp(env2, epName); + } + }; + copyFromExternalBuffer2 = async (buffer) => { + if (isProxy()) { + ensureWorker(); + return new Promise((resolve, reject) => { + enqueueCallbacks("copy-from", [resolve, reject]); + const message = { type: "copy-from", in: { buffer } }; + proxyWorker.postMessage(message, [buffer.buffer]); + }); + } else { + return copyFromExternalBuffer(buffer); + } + }; + createSession2 = async (model, options) => { + if (isProxy()) { + if (options?.preferredOutputLocation) { + throw new Error('session option "preferredOutputLocation" is not supported for proxy.'); + } + ensureWorker(); + return new Promise((resolve, reject) => { + enqueueCallbacks("create", [resolve, reject]); + const message = { type: "create", in: { model, options: { ...options } } }; + const transferable = []; + if (model instanceof Uint8Array) { + transferable.push(model.buffer); + } + proxyWorker.postMessage(message, transferable); + }); + } else { + return createSession(model, options); + } + }; + releaseSession2 = async (sessionId) => { + if (isProxy()) { + ensureWorker(); + return new Promise((resolve, reject) => { + enqueueCallbacks("release", [resolve, reject]); + const message = { type: "release", in: sessionId }; + proxyWorker.postMessage(message); + }); + } else { + releaseSession(sessionId); + } + }; + run2 = async (sessionId, inputIndices, inputs, outputIndices, outputs, options) => { + if (isProxy()) { + if (inputs.some((t) => t[3] !== "cpu")) { + throw new Error("input tensor on GPU is not supported for proxy."); + } + if (outputs.some((t) => t)) { + throw new Error("pre-allocated output tensor is not supported for proxy."); + } + ensureWorker(); + return new Promise((resolve, reject) => { + enqueueCallbacks("run", [resolve, reject]); + const serializableInputs = inputs; + const message = { + type: "run", + in: { sessionId, inputIndices, inputs: serializableInputs, outputIndices, options } + }; + proxyWorker.postMessage(message, extractTransferableBuffers(serializableInputs)); + }); + } else { + return run(sessionId, inputIndices, inputs, outputIndices, outputs, options); + } + }; + endProfiling2 = async (sessionId) => { + if (isProxy()) { + ensureWorker(); + return new Promise((resolve, reject) => { + enqueueCallbacks("end-profiling", [resolve, reject]); + const message = { type: "end-profiling", in: sessionId }; + proxyWorker.postMessage(message); + }); + } else { + endProfiling(sessionId); + } + }; + } + }); + + // web/lib/wasm/session-handler-inference.ts + var encodeTensorMetadata, decodeTensorMetadata, OnnxruntimeWebAssemblySessionHandler; + var init_session_handler_inference2 = __esm({ + "web/lib/wasm/session-handler-inference.ts"() { + "use strict"; + init_esm(); + init_proxy_wrapper(); + init_wasm_common(); + init_wasm_utils_env(); + init_wasm_utils_load_file(); + encodeTensorMetadata = (tensor, getName) => { + switch (tensor.location) { + case "cpu": + return [tensor.type, tensor.dims, tensor.data, "cpu"]; + case "gpu-buffer": + return [tensor.type, tensor.dims, { gpuBuffer: tensor.gpuBuffer }, "gpu-buffer"]; + case "ml-tensor": + return [tensor.type, tensor.dims, { mlTensor: tensor.mlTensor }, "ml-tensor"]; + default: + throw new Error(`invalid data location: ${tensor.location} for ${getName()}`); + } + }; + decodeTensorMetadata = (tensor) => { + switch (tensor[3]) { + case "cpu": + return new Tensor2(tensor[0], tensor[2], tensor[1]); + case "gpu-buffer": { + const dataType = tensor[0]; + if (!isGpuBufferSupportedType(dataType)) { + throw new Error(`not supported data type: ${dataType} for deserializing GPU tensor`); + } + const { gpuBuffer, download, dispose } = tensor[2]; + return Tensor2.fromGpuBuffer(gpuBuffer, { dataType, dims: tensor[1], download, dispose }); + } + case "ml-tensor": { + const dataType = tensor[0]; + if (!isMLTensorSupportedType(dataType)) { + throw new Error(`not supported data type: ${dataType} for deserializing MLTensor tensor`); + } + const { mlTensor, download, dispose } = tensor[2]; + return Tensor2.fromMLTensor(mlTensor, { dataType, dims: tensor[1], download, dispose }); + } + default: + throw new Error(`invalid data location: ${tensor[3]}`); + } + }; + OnnxruntimeWebAssemblySessionHandler = class { + async fetchModelAndCopyToWasmMemory(path) { + return copyFromExternalBuffer2(await loadFile(path)); + } + async loadModel(pathOrBuffer, options) { + TRACE_FUNC_BEGIN(); + let model; + if (typeof pathOrBuffer === "string") { + if (isNode) { + model = await loadFile(pathOrBuffer); + } else { + model = await this.fetchModelAndCopyToWasmMemory(pathOrBuffer); + } + } else { + model = pathOrBuffer; + } + [this.sessionId, this.inputNames, this.outputNames, this.inputMetadata, this.outputMetadata] = await createSession2( + model, + options + ); + TRACE_FUNC_END(); + } + async dispose() { + return releaseSession2(this.sessionId); + } + async run(feeds, fetches, options) { + TRACE_FUNC_BEGIN(); + const inputArray = []; + const inputIndices = []; + Object.entries(feeds).forEach((kvp) => { + const name2 = kvp[0]; + const tensor = kvp[1]; + const index = this.inputNames.indexOf(name2); + if (index === -1) { + throw new Error(`invalid input '${name2}'`); + } + inputArray.push(tensor); + inputIndices.push(index); + }); + const outputArray = []; + const outputIndices = []; + Object.entries(fetches).forEach((kvp) => { + const name2 = kvp[0]; + const tensor = kvp[1]; + const index = this.outputNames.indexOf(name2); + if (index === -1) { + throw new Error(`invalid output '${name2}'`); + } + outputArray.push(tensor); + outputIndices.push(index); + }); + const inputs = inputArray.map( + (t, i) => encodeTensorMetadata(t, () => `input "${this.inputNames[inputIndices[i]]}"`) + ); + const outputs = outputArray.map( + (t, i) => t ? encodeTensorMetadata(t, () => `output "${this.outputNames[outputIndices[i]]}"`) : null + ); + const results = await run2(this.sessionId, inputIndices, inputs, outputIndices, outputs, options); + const resultMap = {}; + for (let i = 0; i < results.length; i++) { + resultMap[this.outputNames[outputIndices[i]]] = outputArray[i] ?? decodeTensorMetadata(results[i]); + } + TRACE_FUNC_END(); + return resultMap; + } + startProfiling() { + } + endProfiling() { + void endProfiling2(this.sessionId); + } + }; + } + }); + + // web/lib/backend-wasm.ts + var backend_wasm_exports = {}; + __export(backend_wasm_exports, { + OnnxruntimeWebAssemblyBackend: () => OnnxruntimeWebAssemblyBackend, + initializeFlags: () => initializeFlags, + wasmBackend: () => wasmBackend + }); + var initializeFlags, OnnxruntimeWebAssemblyBackend, wasmBackend; + var init_backend_wasm = __esm({ + "web/lib/backend-wasm.ts"() { + "use strict"; + init_esm(); + init_proxy_wrapper(); + init_session_handler_inference2(); + initializeFlags = () => { + if (typeof env2.wasm.initTimeout !== "number" || env2.wasm.initTimeout < 0) { + env2.wasm.initTimeout = 0; + } + const simd = env2.wasm.simd; + if (typeof simd !== "boolean" && simd !== void 0 && simd !== "fixed" && simd !== "relaxed") { + console.warn( + `Property "env.wasm.simd" is set to unknown value "${simd}". Reset it to \`false\` and ignore SIMD feature checking.` + ); + env2.wasm.simd = false; + } + if (typeof env2.wasm.proxy !== "boolean") { + env2.wasm.proxy = false; + } + if (typeof env2.wasm.trace !== "boolean") { + env2.wasm.trace = false; + } + if (typeof env2.wasm.numThreads !== "number" || !Number.isInteger(env2.wasm.numThreads) || env2.wasm.numThreads <= 0) { + if (typeof self !== "undefined" && !self.crossOriginIsolated) { + env2.wasm.numThreads = 1; + } else { + const numCpuLogicalCores = typeof navigator === "undefined" ? __require("node:os").cpus().length : navigator.hardwareConcurrency; + env2.wasm.numThreads = Math.min(4, Math.ceil((numCpuLogicalCores || 1) / 2)); + } + } + }; + OnnxruntimeWebAssemblyBackend = class { + /** + * This function initializes the WebAssembly backend. + * + * This function will be called only once for each backend name. It will be called the first time when + * `ort.InferenceSession.create()` is called with a registered backend name. + * + * @param backendName - the registered backend name. + */ + async init(backendName) { + initializeFlags(); + await initializeWebAssemblyAndOrtRuntime(); + await initializeOrtEp(backendName); + } + async createInferenceSessionHandler(pathOrBuffer, options) { + const handler = new OnnxruntimeWebAssemblySessionHandler(); + await handler.loadModel(pathOrBuffer, options); + return handler; + } + }; + wasmBackend = new OnnxruntimeWebAssemblyBackend(); + } + }); + + // web/lib/index.ts + var index_exports = {}; + __export(index_exports, { + InferenceSession: () => InferenceSession2, + TRACE: () => TRACE, + TRACE_FUNC_BEGIN: () => TRACE_FUNC_BEGIN, + TRACE_FUNC_END: () => TRACE_FUNC_END, + Tensor: () => Tensor2, + default: () => index_default, + env: () => env2, + registerBackend: () => registerBackend + }); + init_esm(); + init_esm(); + init_esm(); + + // web/lib/version.ts + var version2 = "1.23.0"; + + // web/lib/index.ts + var index_default = esm_exports; + if (true) { + const onnxjsBackend2 = (init_backend_onnxjs(), __toCommonJS(backend_onnxjs_exports)).onnxjsBackend; + registerBackend("webgl", onnxjsBackend2, -10); + } + if (true) { + const wasmBackend2 = (init_backend_wasm(), __toCommonJS(backend_wasm_exports)).wasmBackend; + if (true) { + registerBackend("webgpu", wasmBackend2, 5); + registerBackend("webnn", wasmBackend2, 5); + } + registerBackend("cpu", wasmBackend2, 10); + registerBackend("wasm", wasmBackend2, 10); + } + Object.defineProperty(env2.versions, "web", { value: version2, enumerable: true }); + return __toCommonJS(index_exports); +})(); +/** + * @license + * Copyright 2021 Google LLC. All Rights Reserved. + * 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. + * ============================================================================= + */ +/** + * @license + * Copyright 2020 Google LLC. All Rights Reserved. + * 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. + * ============================================================================= + */ +/** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * 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. + * ============================================================================= + */ +/*! Bundled license information: + +long/index.js: + (** + * @license + * Copyright 2009 The Closure Library Authors + * Copyright 2020 Daniel Wirtz / The long.js Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + *) +*/ +typeof exports=="object"&&typeof module=="object"&&(module.exports=ort); +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvYmFja2VuZC1pbXBsLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9vbm54cnVudGltZS1jb21tb24vbGliL2JhY2tlbmQudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvdmVyc2lvbi50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi9lbnYtaW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi9lbnYudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvdGVuc29yLWNvbnZlcnNpb24taW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItZmFjdG9yeS1pbXBsLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9vbm54cnVudGltZS1jb21tb24vbGliL3RlbnNvci1pbXBsLXR5cGUtbWFwcGluZy50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItdXRpbHMtaW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItaW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3IudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvdHJhY2UudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvaW5mZXJlbmNlLXNlc3Npb24taW1wbC50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi9pbmZlcmVuY2Utc2Vzc2lvbi50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItY29udmVyc2lvbi50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi90ZW5zb3ItZmFjdG9yeS50cyIsICIuLi9ub2RlX21vZHVsZXMvb25ueHJ1bnRpbWUtY29tbW9uL2xpYi9vbm54LW1vZGVsLnRzIiwgIi4uL25vZGVfbW9kdWxlcy9vbm54cnVudGltZS1jb21tb24vbGliL29ubngtdmFsdWUudHMiLCAiLi4vbm9kZV9tb2R1bGVzL29ubnhydW50aW1lLWNvbW1vbi9saWIvaW5kZXgudHMiLCAiLi4vbGliL29ubnhqcy9pbnN0cnVtZW50LnRzIiwgIi4uL2xpYi9vbm54anMvb3BzZXQudHMiLCAiLi4vbm9kZV9tb2R1bGVzL2d1aWQtdHlwZXNjcmlwdC9kaXN0L2d1aWQuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2xvbmcvaW5kZXguanMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9hcmctdHlwZS50cyIsICIuLi9ub2RlX21vZHVsZXMvZmxhdGJ1ZmZlcnMvanMvY29uc3RhbnRzLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy91dGlscy5qcyIsICIuLi9ub2RlX21vZHVsZXMvZmxhdGJ1ZmZlcnMvanMvZW5jb2RpbmcuanMiLCAiLi4vbm9kZV9tb2R1bGVzL2ZsYXRidWZmZXJzL2pzL2J5dGUtYnVmZmVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9idWlsZGVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9mbGF0YnVmZmVycy5qcyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLWFuZC1pbmRleC50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2F0dHJpYnV0ZS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbm9kZS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbm9kZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2VkZ2UtZW5kLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbm9kZS1lZGdlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvbm9kZXMtdG8tb3B0aW1pemUtaW5kaWNlcy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9uLXJlY29yZC50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL3J1bnRpbWUtb3B0aW1pemF0aW9uLXJlY29yZC1jb250YWluZXItZW50cnkudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9ydW50aW1lLW9wdGltaXphdGlvbnMudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90ZW5zb3ItZGF0YS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvdGVuc29yLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvc3BhcnNlLXRlbnNvci50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL21hcC10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvc2VxdWVuY2UtdHlwZS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RpbWVuc2lvbi12YWx1ZS10eXBlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGltZW5zaW9uLXZhbHVlLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZGltZW5zaW9uLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvc2hhcGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90ZW5zb3ItdHlwZS1hbmQtc2hhcGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90eXBlLWluZm8tdmFsdWUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy90eXBlLWluZm8udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy92YWx1ZS1pbmZvLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvZ3JhcGgudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9hdHRyaWJ1dGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kZXByZWNhdGVkLWtlcm5lbC1jcmVhdGUtaW5mb3MudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kZXByZWNhdGVkLW5vZGUtaW5kZXgtYW5kLWtlcm5lbC1kZWYtaGFzaC50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL2RlcHJlY2F0ZWQtc3ViLWdyYXBoLXNlc3Npb24tc3RhdGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9kZXByZWNhdGVkLXNlc3Npb24tc3RhdGUudHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy9rZXJuZWwtdHlwZS1zdHItYXJncy1lbnRyeS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL29wLWlkLWtlcm5lbC10eXBlLXN0ci1hcmdzLWVudHJ5LnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMva2VybmVsLXR5cGUtc3RyLXJlc29sdmVyLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvb3BlcmF0b3Itc2V0LWlkLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvc3RyaW5nLXN0cmluZy1lbnRyeS50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb25ueHJ1bnRpbWUvZmJzL21vZGVsLnRzIiwgIi4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vbm54cnVudGltZS9mYnMvaW5mZXJlbmNlLXNlc3Npb24udHMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ubnhydW50aW1lL2Zicy50cyIsICIuLi9saWIvb25ueGpzL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZC50cyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvYXNwcm9taXNlL2luZGV4LmpzIiwgIi4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9iYXNlNjQvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2V2ZW50ZW1pdHRlci9pbmRleC5qcyIsICIuLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvZmxvYXQvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2lucXVpcmUvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL3V0ZjgvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL3Bvb2wvaW5kZXguanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3V0aWwvbG9uZ2JpdHMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3V0aWwvbWluaW1hbC5qcyIsICIuLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvd3JpdGVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy93cml0ZXJfYnVmZmVyLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9yZWFkZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JlYWRlcl9idWZmZXIuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JwYy9zZXJ2aWNlLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9ycGMuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3Jvb3RzLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9pbmRleC1taW5pbWFsLmpzIiwgIi4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL21pbmltYWwuanMiLCAiLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubnguanMiLCAiLi4vbGliL29ubnhqcy91dGlsLnRzIiwgIi4uL2xpYi9vbm54anMvdGVuc29yLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1zb3VyY2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90eXBlcy50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3V0aWxzLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3BhY2tpbmctdXRpbHMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcGFjay50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZXNoYXBlLXBhY2tlZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy91aW50OC1lbmNvZGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdW5wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdGV4dHVyZS1kYXRhLWVuY29kZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLWxheW91dC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2luZmVyZW5jZS1oYW5kbGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2JhdGNoLW5vcm1hbGl6YXRpb24udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWRlZmluaXRpb25zLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2JpbmFyeS1vcC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jYXN0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbmNhdC1wYWNrZWQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29uY2F0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3VuYXJ5LW9wLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2Z1c2UtdXRpbHMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi1ncm91cGVkLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2ltMmNvbC1wYWNrLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL21hdG11bC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9tYXRtdWwtcGFjay50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LXBhY2sudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW0yY29sLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2RvdC1wcm9kdWN0LnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbnYudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi10cmFuc3Bvc2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdHJhbnNwb3NlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2RlcHRoLXRvLXNwYWNlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2ZsYXR0ZW4udHMiLCAiLi4vbGliL29ubnhqcy9vcGVyYXRvcnMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZ2F0aGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2dlbW0udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW1hZ2Utc2NhbGVyLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2luc3RhbmNlLW5vcm1hbGl6YXRpb24udHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvbHJuLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3BhZC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9wb29sLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3JlZHVjZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZXNoYXBlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Vwc2FtcGxlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Jlc2l6ZS1wYWNrZWQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc2hhcGUudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc2xpY2UudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc29mdG1heC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zcGxpdC50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zcXVlZXplLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3N1bS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy90aWxlLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3Vuc3F1ZWV6ZS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wLXJlc29sdmUtcnVsZXMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWZ1bmN0aW9uLWlubGluZXIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLWxheW91dC1zdHJhdGVneS50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtY29vcmRpbmF0ZS1saWIudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWVuY29kaW5nLWxpYi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZnJhZ2NvbG9yLWxpYi50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtc2hhcGUtdXRpbHMtbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC12ZWMtbGliLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1yZWdpc3RlcmVkLWxpYnMudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXByZXByb2Nlc3Nvci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3Byb2dyYW0tbWFuYWdlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3RleHR1cmUtbWFuYWdlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3Nlc3Npb24taGFuZGxlci50cyIsICIuLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3dlYmdsLWNvbnRleHQudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC93ZWJnbC1jb250ZXh0LWZhY3RvcnkudHMiLCAiLi4vbGliL29ubnhqcy9iYWNrZW5kcy9iYWNrZW5kLXdlYmdsLnRzIiwgIi4uL2xpYi9vbm54anMvYmFja2VuZC50cyIsICIuLi9saWIvb25ueGpzL2V4ZWN1dGlvbi1wbGFuLnRzIiwgIi4uL2xpYi9vbm54anMvYXR0cmlidXRlLnRzIiwgIi4uL2xpYi9vbm54anMvZ3JhcGgudHMiLCAiLi4vbGliL29ubnhqcy9tb2RlbC50cyIsICIuLi9saWIvb25ueGpzL3Nlc3Npb24udHMiLCAiLi4vbGliL29ubnhqcy9zZXNzaW9uLWhhbmRsZXItaW5mZXJlbmNlLnRzIiwgIi4uL2xpYi9iYWNrZW5kLW9ubnhqcy50cyIsICIuLi9saWIvd2FzbS93YXNtLXV0aWxzLWVudi50cyIsICIuLi9saWIvd2FzbS9wcm94eS13b3JrZXIvbWFpbi50cyIsICIuLi9saWIvd2FzbS93YXNtLXV0aWxzLWltcG9ydC50cyIsICIuLi9saWIvd2FzbS93YXNtLWZhY3RvcnkudHMiLCAiLi4vbGliL3dhc20vd2FzbS11dGlscy50cyIsICIuLi9saWIvd2FzbS9ydW4tb3B0aW9ucy50cyIsICIuLi9saWIvd2FzbS9zZXNzaW9uLW9wdGlvbnMudHMiLCAiLi4vbGliL3dhc20vd2FzbS1jb21tb24udHMiLCAiLi4vbGliL3dhc20vd2FzbS11dGlscy1sb2FkLWZpbGUudHMiLCAiLi4vbGliL3dhc20vanNlcC9sb2cudHMiLCAiLi4vbGliL3dhc20vanNlcC91dGlsLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvdGVuc29yLXZpZXcudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJubi90ZW5zb3ItbWFuYWdlci50cyIsICIuLi9saWIvd2FzbS9qc2VwL2JhY2tlbmQtd2Vibm4udHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvdHlwZXMudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvZ3B1LWRhdGEtbWFuYWdlci50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXkudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2NvbW1vbi50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvdHJhbnNwb3NlLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9yZWR1Y2Utc2hhcmVkLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9yZWR1Y2UudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2FyZ21pbm1heC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvYXR0ZW50aW9uLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9iYXRjaC1ub3JtLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9iaWFzLWFkZC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvdW5hcnktb3AudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2JpYXMtc3BsaXQtZ2VsdS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvYmluYXJ5LW9wLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9jb25jYXQudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2Z1c2UtdXRpbHMudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzLzNyZC1wYXJ0eS9hY3RpdmF0aW9uX3V0aWwudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzLzNyZC1wYXJ0eS9jb252X3V0aWwudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL21hdG11bC1zaGFkZXJzLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy8zcmQtcGFydHkvbWF0bXVsX3BhY2tlZF93ZWJncHUudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzLzNyZC1wYXJ0eS9jb252MmRfbW1fd2ViZ3B1LnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy8zcmQtcGFydHkvY29udjNkX25haXZlX3dlYmdwdS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvY29udi1ncm91cGVkLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9jb252LnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy8zcmQtcGFydHkvY29udl9iYWNrcHJvcF93ZWJncHUudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2NvbnYtdHJhbnNwb3NlLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9jdW1zdW0udHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2RlcHRoLXRvLXNwYWNlLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9laW5zdW0udHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2V4cGFuZC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvZmFzdC1nZWx1LnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9nYXRoZXIudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2dhdGhlci1uZC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvZ2F0aGVyLWJsb2NrLXF1YW50aXplZC50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvZ2F0aGVyLWVsZW1lbnRzLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9nZW1tLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9ncmlkLXNhbXBsZS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvbXVsdGloZWFkLWF0dGVudGlvbi50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvc3BsaXQudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3JvdGFyeS1lbWJlZGRpbmcudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL2dyb3VwLXF1ZXJ5LWF0dGVudGlvbi50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvaW5zdGFuY2Utbm9ybS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvbGF5ZXItbm9ybS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvbWF0bXVsLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9tYXRtdWxuYml0cy50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvcGFkLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9wb29sLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9xdWFudGl6ZS1saW5lYXIudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3JhbmdlLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9zY2F0dGVyLW5kLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wcy9yZXNpemUudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3NraXAtbGF5ZXItbm9ybS50cyIsICIuLi9saWIvd2FzbS9qc2VwL3dlYmdwdS9vcHMvc2xpY2UudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3NvZnRtYXgudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3RpbGUudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvb3BzL3doZXJlLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvd2ViZ3B1L29wLXJlc29sdmUtcnVsZXMudHMiLCAiLi4vbGliL3dhc20vanNlcC93ZWJncHUvcHJvZ3JhbS1tYW5hZ2VyLnRzIiwgIi4uL2xpYi93YXNtL2pzZXAvYmFja2VuZC13ZWJncHUudHMiLCAiLi4vbGliL3dhc20vanNlcC9pbml0LnRzIiwgIi4uL2xpYi93YXNtL3dhc20tY29yZS1pbXBsLnRzIiwgIi4uL2xpYi93YXNtL3Byb3h5LXdyYXBwZXIudHMiLCAiLi4vbGliL3dhc20vc2Vzc2lvbi1oYW5kbGVyLWluZmVyZW5jZS50cyIsICIuLi9saWIvYmFja2VuZC13YXNtLnRzIiwgIi4uL2xpYi9pbmRleC50cyIsICIuLi9saWIvdmVyc2lvbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEJhY2tlbmQgfSBmcm9tICcuL2JhY2tlbmQuanMnO1xuaW1wb3J0IHsgSW5mZXJlbmNlU2Vzc2lvbiB9IGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24uanMnO1xuXG5pbnRlcmZhY2UgQmFja2VuZEluZm8ge1xuICBiYWNrZW5kOiBCYWNrZW5kO1xuICBwcmlvcml0eTogbnVtYmVyO1xuXG4gIGluaXRQcm9taXNlPzogUHJvbWlzZTx2b2lkPjtcbiAgaW5pdGlhbGl6ZWQ/OiBib29sZWFuO1xuICBhYm9ydGVkPzogYm9vbGVhbjtcbiAgZXJyb3I/OiBzdHJpbmc7XG59XG5cbmNvbnN0IGJhY2tlbmRzOiBNYXA8c3RyaW5nLCBCYWNrZW5kSW5mbz4gPSBuZXcgTWFwKCk7XG5jb25zdCBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHk6IHN0cmluZ1tdID0gW107XG5cbi8qKlxuICogUmVnaXN0ZXIgYSBiYWNrZW5kLlxuICpcbiAqIEBwYXJhbSBuYW1lIC0gdGhlIG5hbWUgYXMgYSBrZXkgdG8gbG9va3VwIGFzIGFuIGV4ZWN1dGlvbiBwcm92aWRlci5cbiAqIEBwYXJhbSBiYWNrZW5kIC0gdGhlIGJhY2tlbmQgb2JqZWN0LlxuICogQHBhcmFtIHByaW9yaXR5IC0gYW4gaW50ZWdlciBpbmRpY2F0aW5nIHRoZSBwcmlvcml0eSBvZiB0aGUgYmFja2VuZC4gSGlnaGVyIG51bWJlciBtZWFucyBoaWdoZXIgcHJpb3JpdHkuIGlmIHByaW9yaXR5XG4gKiA8IDAsIGl0IHdpbGwgYmUgY29uc2lkZXJlZCBhcyBhICdiZXRhJyB2ZXJzaW9uIGFuZCB3aWxsIG5vdCBiZSB1c2VkIGFzIGEgZmFsbGJhY2sgYmFja2VuZCBieSBkZWZhdWx0LlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNvbnN0IHJlZ2lzdGVyQmFja2VuZCA9IChuYW1lOiBzdHJpbmcsIGJhY2tlbmQ6IEJhY2tlbmQsIHByaW9yaXR5OiBudW1iZXIpOiB2b2lkID0+IHtcbiAgaWYgKGJhY2tlbmQgJiYgdHlwZW9mIGJhY2tlbmQuaW5pdCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgYmFja2VuZC5jcmVhdGVJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IGN1cnJlbnRCYWNrZW5kID0gYmFja2VuZHMuZ2V0KG5hbWUpO1xuICAgIGlmIChjdXJyZW50QmFja2VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBiYWNrZW5kcy5zZXQobmFtZSwgeyBiYWNrZW5kLCBwcmlvcml0eSB9KTtcbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRCYWNrZW5kLnByaW9yaXR5ID4gcHJpb3JpdHkpIHtcbiAgICAgIC8vIHNhbWUgbmFtZSBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQgd2l0aCBhIGhpZ2hlciBwcmlvcml0eS4gc2tpcCByZWdpc3RlcmF0aW9uLlxuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoY3VycmVudEJhY2tlbmQucHJpb3JpdHkgPT09IHByaW9yaXR5KSB7XG4gICAgICBpZiAoY3VycmVudEJhY2tlbmQuYmFja2VuZCAhPT0gYmFja2VuZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCByZWdpc3RlciBiYWNrZW5kIFwiJHtuYW1lfVwiIHVzaW5nIHByaW9yaXR5ICR7cHJpb3JpdHl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHByaW9yaXR5ID49IDApIHtcbiAgICAgIGNvbnN0IGkgPSBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkuaW5kZXhPZihuYW1lKTtcbiAgICAgIGlmIChpICE9PSAtMSkge1xuICAgICAgICBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkuc3BsaWNlKGksIDEpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoYmFja2VuZHMuZ2V0KGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eVtpXSkhLnByaW9yaXR5IDw9IHByaW9yaXR5KSB7XG4gICAgICAgICAgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5LnNwbGljZShpLCAwLCBuYW1lKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5wdXNoKG5hbWUpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdub3QgYSB2YWxpZCBiYWNrZW5kJyk7XG59O1xuXG4vKipcbiAqIFRyeSB0byByZXNvbHZlIGFuZCBpbml0aWFsaXplIGEgYmFja2VuZC5cbiAqXG4gKiBAcGFyYW0gYmFja2VuZE5hbWUgLSB0aGUgbmFtZSBvZiB0aGUgYmFja2VuZC5cbiAqIEByZXR1cm5zIHRoZSBiYWNrZW5kIGluc3RhbmNlIGlmIHJlc29sdmVkIGFuZCBpbml0aWFsaXplZCBzdWNjZXNzZnVsbHksIG9yIGFuIGVycm9yIG1lc3NhZ2UgaWYgZmFpbGVkLlxuICovXG5jb25zdCB0cnlSZXNvbHZlQW5kSW5pdGlhbGl6ZUJhY2tlbmQgPSBhc3luYyAoYmFja2VuZE5hbWU6IHN0cmluZyk6IFByb21pc2U8QmFja2VuZCB8IHN0cmluZz4gPT4ge1xuICBjb25zdCBiYWNrZW5kSW5mbyA9IGJhY2tlbmRzLmdldChiYWNrZW5kTmFtZSk7XG4gIGlmICghYmFja2VuZEluZm8pIHtcbiAgICByZXR1cm4gJ2JhY2tlbmQgbm90IGZvdW5kLic7XG4gIH1cblxuICBpZiAoYmFja2VuZEluZm8uaW5pdGlhbGl6ZWQpIHtcbiAgICByZXR1cm4gYmFja2VuZEluZm8uYmFja2VuZDtcbiAgfSBlbHNlIGlmIChiYWNrZW5kSW5mby5hYm9ydGVkKSB7XG4gICAgcmV0dXJuIGJhY2tlbmRJbmZvLmVycm9yITtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBpc0luaXRpYWxpemluZyA9ICEhYmFja2VuZEluZm8uaW5pdFByb21pc2U7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghaXNJbml0aWFsaXppbmcpIHtcbiAgICAgICAgYmFja2VuZEluZm8uaW5pdFByb21pc2UgPSBiYWNrZW5kSW5mby5iYWNrZW5kLmluaXQoYmFja2VuZE5hbWUpO1xuICAgICAgfVxuICAgICAgYXdhaXQgYmFja2VuZEluZm8uaW5pdFByb21pc2U7XG4gICAgICBiYWNrZW5kSW5mby5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgICByZXR1cm4gYmFja2VuZEluZm8uYmFja2VuZDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoIWlzSW5pdGlhbGl6aW5nKSB7XG4gICAgICAgIGJhY2tlbmRJbmZvLmVycm9yID0gYCR7ZX1gO1xuICAgICAgICBiYWNrZW5kSW5mby5hYm9ydGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYWNrZW5kSW5mby5lcnJvciE7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGRlbGV0ZSBiYWNrZW5kSW5mby5pbml0UHJvbWlzZTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogUmVzb2x2ZSBleGVjdXRpb24gcHJvdmlkZXJzIGZyb20gdGhlIHNwZWNpZmljIHNlc3Npb24gb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIHRoZSBzZXNzaW9uIG9wdGlvbnMgb2JqZWN0LlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSB0dXBsZSBvZiBhbiBpbml0aWFsaXplZCBiYWNrZW5kIGluc3RhbmNlIGFuZCBhIHNlc3Npb24gb3B0aW9ucyBvYmplY3Qgd2l0aFxuICogZmlsdGVyZWQgRVAgbGlzdC5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCByZXNvbHZlQmFja2VuZEFuZEV4ZWN1dGlvblByb3ZpZGVycyA9IGFzeW5jIChcbiAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbik6IFByb21pc2U8W2JhY2tlbmQ6IEJhY2tlbmQsIG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnNdPiA9PiB7XG4gIC8vIGV4dHJhY3QgYmFja2VuZCBoaW50cyBmcm9tIHNlc3Npb24gb3B0aW9uc1xuICBjb25zdCBlcHMgPSBvcHRpb25zLmV4ZWN1dGlvblByb3ZpZGVycyB8fCBbXTtcbiAgY29uc3QgYmFja2VuZEhpbnRzID0gZXBzLm1hcCgoaSkgPT4gKHR5cGVvZiBpID09PSAnc3RyaW5nJyA/IGkgOiBpLm5hbWUpKTtcbiAgY29uc3QgYmFja2VuZE5hbWVzID0gYmFja2VuZEhpbnRzLmxlbmd0aCA9PT0gMCA/IGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eSA6IGJhY2tlbmRIaW50cztcblxuICAvLyB0cnkgdG8gcmVzb2x2ZSBhbmQgaW5pdGlhbGl6ZSBhbGwgcmVxdWVzdGVkIGJhY2tlbmRzXG4gIGxldCBiYWNrZW5kOiBCYWNrZW5kIHwgdW5kZWZpbmVkO1xuICBjb25zdCBlcnJvcnMgPSBbXTtcbiAgY29uc3QgYXZhaWxhYmxlQmFja2VuZE5hbWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgYmFja2VuZE5hbWUgb2YgYmFja2VuZE5hbWVzKSB7XG4gICAgY29uc3QgcmVzb2x2ZVJlc3VsdCA9IGF3YWl0IHRyeVJlc29sdmVBbmRJbml0aWFsaXplQmFja2VuZChiYWNrZW5kTmFtZSk7XG4gICAgaWYgKHR5cGVvZiByZXNvbHZlUmVzdWx0ID09PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3JzLnB1c2goeyBuYW1lOiBiYWNrZW5kTmFtZSwgZXJyOiByZXNvbHZlUmVzdWx0IH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIWJhY2tlbmQpIHtcbiAgICAgICAgYmFja2VuZCA9IHJlc29sdmVSZXN1bHQ7XG4gICAgICB9XG4gICAgICBpZiAoYmFja2VuZCA9PT0gcmVzb2x2ZVJlc3VsdCkge1xuICAgICAgICBhdmFpbGFibGVCYWNrZW5kTmFtZXMuYWRkKGJhY2tlbmROYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiBubyBiYWNrZW5kIGlzIGF2YWlsYWJsZSwgdGhyb3cgZXJyb3IuXG4gIGlmICghYmFja2VuZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgbm8gYXZhaWxhYmxlIGJhY2tlbmQgZm91bmQuIEVSUjogJHtlcnJvcnMubWFwKChlKSA9PiBgWyR7ZS5uYW1lfV0gJHtlLmVycn1gKS5qb2luKCcsICcpfWApO1xuICB9XG5cbiAgLy8gZm9yIGVhY2ggZXhwbGljaXRseSByZXF1ZXN0ZWQgYmFja2VuZCwgaWYgaXQncyBub3QgYXZhaWxhYmxlLCBvdXRwdXQgd2FybmluZyBtZXNzYWdlLlxuICBmb3IgKGNvbnN0IHsgbmFtZSwgZXJyIH0gb2YgZXJyb3JzKSB7XG4gICAgaWYgKGJhY2tlbmRIaW50cy5pbmNsdWRlcyhuYW1lKSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYHJlbW92aW5nIHJlcXVlc3RlZCBleGVjdXRpb24gcHJvdmlkZXIgXCIke25hbWV9XCIgZnJvbSBzZXNzaW9uIG9wdGlvbnMgYmVjYXVzZSBpdCBpcyBub3QgYXZhaWxhYmxlOiAke2Vycn1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBmaWx0ZXJlZEVwcyA9IGVwcy5maWx0ZXIoKGkpID0+IGF2YWlsYWJsZUJhY2tlbmROYW1lcy5oYXModHlwZW9mIGkgPT09ICdzdHJpbmcnID8gaSA6IGkubmFtZSkpO1xuXG4gIHJldHVybiBbXG4gICAgYmFja2VuZCxcbiAgICBuZXcgUHJveHkob3B0aW9ucywge1xuICAgICAgZ2V0OiAodGFyZ2V0LCBwcm9wKSA9PiB7XG4gICAgICAgIGlmIChwcm9wID09PSAnZXhlY3V0aW9uUHJvdmlkZXJzJykge1xuICAgICAgICAgIHJldHVybiBmaWx0ZXJlZEVwcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wKTtcbiAgICAgIH0sXG4gICAgfSksXG4gIF07XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBJbmZlcmVuY2VTZXNzaW9uIH0gZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5pbXBvcnQgeyBPbm54VmFsdWUgfSBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuXG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFNlc3Npb25IYW5kbGVyIHtcbiAgdHlwZSBGZWVkc1R5cGUgPSB7IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfTtcbiAgdHlwZSBGZXRjaGVzVHlwZSA9IHsgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB8IG51bGwgfTtcbiAgdHlwZSBSZXR1cm5UeXBlID0geyBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIH07XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBzaGFyZWQgU2Vzc2lvbkhhbmRsZXIgZnVuY3Rpb25hbGl0eVxuICpcbiAqIEBpZ25vcmVcbiAqL1xuaW50ZXJmYWNlIFNlc3Npb25IYW5kbGVyIHtcbiAgZGlzcG9zZSgpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIHJlYWRvbmx5IGlucHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICByZWFkb25seSBvdXRwdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgcmVhZG9ubHkgaW5wdXRNZXRhZGF0YTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhW107XG4gIHJlYWRvbmx5IG91dHB1dE1ldGFkYXRhOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBoYW5kbGVyIGluc3RhbmNlIG9mIGFuIGluZmVyZW5jZSBzZXNzaW9uLlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciBleHRlbmRzIFNlc3Npb25IYW5kbGVyIHtcbiAgc3RhcnRQcm9maWxpbmcoKTogdm9pZDtcbiAgZW5kUHJvZmlsaW5nKCk6IHZvaWQ7XG5cbiAgcnVuKFxuICAgIGZlZWRzOiBTZXNzaW9uSGFuZGxlci5GZWVkc1R5cGUsXG4gICAgZmV0Y2hlczogU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUsXG4gICAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zLFxuICApOiBQcm9taXNlPFNlc3Npb25IYW5kbGVyLlJldHVyblR5cGU+O1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBhIGJhY2tlbmQgdGhhdCBwcm92aWRlcyBpbXBsZW1lbnRhdGlvbiBvZiBtb2RlbCBpbmZlcmVuY2luZy5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFja2VuZCB7XG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSBiYWNrZW5kIGFzeW5jaHJvbm91c2x5LiBTaG91bGQgdGhyb3cgd2hlbiBmYWlsZWQuXG4gICAqL1xuICBpbml0KGJhY2tlbmROYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIGNyZWF0ZUluZmVyZW5jZVNlc3Npb25IYW5kbGVyKFxuICAgIHVyaU9yQnVmZmVyOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25IYW5kbGVyPjtcbn1cblxuZXhwb3J0IHsgcmVnaXN0ZXJCYWNrZW5kIH0gZnJvbSAnLi9iYWNrZW5kLWltcGwuanMnO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGJ5IC9qcy9zY3JpcHRzL3VwZGF0ZS12ZXJzaW9uLnRzXG4vLyBEbyBub3QgbW9kaWZ5IGZpbGUgY29udGVudCBtYW51YWxseS5cblxuZXhwb3J0IGNvbnN0IHZlcnNpb24gPSAnMS4yMy4wJztcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRW52IH0gZnJvbSAnLi9lbnYuanMnO1xuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4vdmVyc2lvbi5qcyc7XG5cbnR5cGUgTG9nTGV2ZWxUeXBlID0gRW52Wydsb2dMZXZlbCddO1xuXG5sZXQgbG9nTGV2ZWxWYWx1ZTogUmVxdWlyZWQ8TG9nTGV2ZWxUeXBlPiA9ICd3YXJuaW5nJztcblxuZXhwb3J0IGNvbnN0IGVudjogRW52ID0ge1xuICB3YXNtOiB7fSBhcyBFbnYuV2ViQXNzZW1ibHlGbGFncyxcbiAgd2ViZ2w6IHt9IGFzIEVudi5XZWJHTEZsYWdzLFxuICB3ZWJncHU6IHt9IGFzIEVudi5XZWJHcHVGbGFncyxcbiAgdmVyc2lvbnM6IHsgY29tbW9uOiB2ZXJzaW9uIH0sXG5cbiAgc2V0IGxvZ0xldmVsKHZhbHVlOiBMb2dMZXZlbFR5cGUpIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyB8fCBbJ3ZlcmJvc2UnLCAnaW5mbycsICd3YXJuaW5nJywgJ2Vycm9yJywgJ2ZhdGFsJ10uaW5kZXhPZih2YWx1ZSkgPT09IC0xKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGxvZ2dpbmcgbGV2ZWw6ICR7dmFsdWV9YCk7XG4gICAgfVxuICAgIGxvZ0xldmVsVmFsdWUgPSB2YWx1ZTtcbiAgfSxcbiAgZ2V0IGxvZ0xldmVsKCk6IFJlcXVpcmVkPExvZ0xldmVsVHlwZT4ge1xuICAgIHJldHVybiBsb2dMZXZlbFZhbHVlO1xuICB9LFxufTtcblxuLy8gc2V0IHByb3BlcnR5ICdsb2dMZXZlbCcgc28gdGhhdCB0aGV5IGNhbiBiZSBjb3JyZWN0bHkgdHJhbnNmZXJyZWQgdG8gd29ya2VyIGJ5IGBwb3N0TWVzc2FnZSgpYC5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbnYsICdsb2dMZXZlbCcsIHsgZW51bWVyYWJsZTogdHJ1ZSB9KTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZW52IGFzIGVudkltcGwgfSBmcm9tICcuL2Vudi1pbXBsLmpzJztcbmltcG9ydCB7IFRyeUdldEdsb2JhbFR5cGUgfSBmcm9tICcuL3R5cGUtaGVscGVyLmpzJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEVudiB7XG4gIGV4cG9ydCB0eXBlIFdhc21QYXRoUHJlZml4ID0gc3RyaW5nO1xuICBleHBvcnQgaW50ZXJmYWNlIFdhc21GaWxlUGF0aHMge1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIG92ZXJyaWRlIHBhdGggZm9yIHRoZSBtYWluIC53YXNtIGZpbGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhdGggc2hvdWxkIGJlIGFuIGFic29sdXRlIHBhdGguXG4gICAgICpcbiAgICAgKiBJZiBub3QgbW9kaWZpZWQsIHRoZSBmaWxlbmFtZSBvZiB0aGUgLndhc20gZmlsZSBpczpcbiAgICAgKiAtIGBvcnQtd2FzbS1zaW1kLXRocmVhZGVkLndhc21gIGZvciBkZWZhdWx0IGJ1aWxkXG4gICAgICogLSBgb3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc2VwLndhc21gIGZvciBKU0VQIGJ1aWxkICh3aXRoIFdlYkdQVSBhbmQgV2ViTk4pXG4gICAgICovXG4gICAgd2FzbT86IFVSTCB8IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBvdmVycmlkZSBwYXRoIGZvciB0aGUgbWFpbiAubWpzIGZpbGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhdGggc2hvdWxkIGJlIGFuIGFic29sdXRlIHBhdGguXG4gICAgICpcbiAgICAgKiBJZiBub3QgbW9kaWZpZWQsIHRoZSBmaWxlbmFtZSBvZiB0aGUgLm1qcyBmaWxlIGlzOlxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQubWpzYCBmb3IgZGVmYXVsdCBidWlsZFxuICAgICAqIC0gYG9ydC13YXNtLXNpbWQtdGhyZWFkZWQuanNlcC5tanNgIGZvciBKU0VQIGJ1aWxkICh3aXRoIFdlYkdQVSBhbmQgV2ViTk4pXG4gICAgICovXG4gICAgbWpzPzogVVJMIHwgc3RyaW5nO1xuICB9XG4gIGV4cG9ydCB0eXBlIFdhc21QcmVmaXhPckZpbGVQYXRocyA9IFdhc21QYXRoUHJlZml4IHwgV2FzbUZpbGVQYXRocztcbiAgZXhwb3J0IGludGVyZmFjZSBXZWJBc3NlbWJseUZsYWdzIHtcbiAgICAvKipcbiAgICAgKiBzZXQgb3IgZ2V0IG51bWJlciBvZiB0aHJlYWQocykuIElmIG9taXR0ZWQgb3Igc2V0IHRvIDAsIG51bWJlciBvZiB0aHJlYWQocykgd2lsbCBiZSBkZXRlcm1pbmVkIGJ5IHN5c3RlbS4gSWYgc2V0XG4gICAgICogdG8gMSwgbm8gd29ya2VyIHRocmVhZCB3aWxsIGJlIHNwYXduZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgd2hlbiBXZWJBc3NlbWJseSBtdWx0aXRocmVhZCBmZWF0dXJlIGlzIGF2YWlsYWJsZSBpbiBjdXJyZW50IGNvbnRleHQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGAwYFxuICAgICAqL1xuICAgIG51bVRocmVhZHM/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBzZXQgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gZW5hYmxlIFNJTUQuXG4gICAgICpcbiAgICAgKiBPTk5YIFJ1bnRpbWUgd2lsbCBwZXJmb3JtIGZlYXR1cmUgZGV0ZWN0aW9uIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5LiBTcGVjaWZpY2FsbHksIHdoZW4gdGhlIHZhbHVlIGlzXG4gICAgICogc2V0IHRvOlxuICAgICAqIC0gYHVuZGVmaW5lZGAsIGB0cnVlYCBvciBgXCJmaXhlZFwiYDogd2lsbCBjaGVjayBhdmFpbGFiaWxpdHkgb2YgRml4ZWQtd2lkdGggU0lNRC5cbiAgICAgKiAtIGBcInJlbGF4ZWRcImA6IHdpbGwgY2hlY2sgYXZhaWxhYmlsaXR5IG9mIFJlbGF4ZWQgU0lNRC5cbiAgICAgKiAtIGBmYWxzZWA6IHdpbGwgbm90IHBlcmZvcm0gU0lNRCBmZWF0dXJlIGNoZWNraW5nLlxuICAgICAqXG4gICAgICogU2V0dGluZyB0aGlzIHByb3BlcnR5IGRvZXMgbm90IG1ha2UgT05OWCBSdW50aW1lIHRvIHN3aXRjaCB0byB0aGUgY29ycmVzcG9uZGluZyBydW50aW1lIGF1dG9tYXRpY2FsbHkuIFVzZXIgbmVlZFxuICAgICAqIHRvIHNldCBgd2FzbVBhdGhzYCBvciBgd2FzbUJpbmFyeWAgcHJvcGVydHkgdG8gbG9hZCB0aGUgY29ycmVzcG9uZGluZyBydW50aW1lLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IHdoZW4gV2ViQXNzZW1ibHkgU0lNRCBmZWF0dXJlIGlzIGF2YWlsYWJsZSBpbiBjdXJyZW50IGNvbnRleHQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGB0cnVlYFxuICAgICAqL1xuICAgIHNpbWQ/OiBib29sZWFuIHwgJ2ZpeGVkJyB8ICdyZWxheGVkJztcblxuICAgIC8qKlxuICAgICAqIHNldCBvciBnZXQgYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0byBlbmFibGUgdHJhY2UuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIFVzZSBgZW52LnRyYWNlYCBpbnN0ZWFkLiBJZiBgZW52LnRyYWNlYCBpcyBzZXQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSBpZ25vcmVkLlxuICAgICAqL1xuICAgIHRyYWNlPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgYSBudW1iZXIgc3BlY2lmeWluZyB0aGUgdGltZW91dCBmb3IgaW5pdGlhbGl6YXRpb24gb2YgV2ViQXNzZW1ibHkgYmFja2VuZCwgaW4gbWlsbGlzZWNvbmRzLiBBIHplcm9cbiAgICAgKiB2YWx1ZSBpbmRpY2F0ZXMgbm8gdGltZW91dCBpcyBzZXQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGAwYFxuICAgICAqL1xuICAgIGluaXRUaW1lb3V0PzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogU2V0IGEgY3VzdG9tIFVSTCBwcmVmaXggdG8gdGhlIC53YXNtLy5tanMgZmlsZXMsIG9yIGFuIG9iamVjdCBvZiBvdmVycmlkZXMgZm9yIGJvdGggLndhc20vLm1qcyBmaWxlLiBUaGUgb3ZlcnJpZGVcbiAgICAgKiBwYXRoIHNob3VsZCBiZSBhbiBhYnNvbHV0ZSBwYXRoLlxuICAgICAqL1xuICAgIHdhc21QYXRocz86IFdhc21QcmVmaXhPckZpbGVQYXRocztcblxuICAgIC8qKlxuICAgICAqIFNldCBhIGN1c3RvbSBidWZmZXIgd2hpY2ggY29udGFpbnMgdGhlIFdlYkFzc2VtYmx5IGJpbmFyeS4gSWYgdGhpcyBwcm9wZXJ0eSBpcyBzZXQsIHRoZSBgd2FzbVBhdGhzYCBwcm9wZXJ0eSB3aWxsXG4gICAgICogYmUgaWdub3JlZC5cbiAgICAgKi9cbiAgICB3YXNtQmluYXJ5PzogQXJyYXlCdWZmZXJMaWtlIHwgVWludDhBcnJheTtcblxuICAgIC8qKlxuICAgICAqIFNldCBvciBnZXQgYSBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0byBwcm94eSB0aGUgZXhlY3V0aW9uIG9mIG1haW4gdGhyZWFkIHRvIGEgd29ya2VyIHRocmVhZC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgICAqL1xuICAgIHByb3h5PzogYm9vbGVhbjtcbiAgfVxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR0xGbGFncyB7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgV2ViR0wgQ29udGV4dCBJRCAod2ViZ2wgb3Igd2ViZ2wyKS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYCd3ZWJnbDInYFxuICAgICAqL1xuICAgIGNvbnRleHRJZD86ICd3ZWJnbCcgfCAnd2ViZ2wyJztcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIFdlYkdMIHJlbmRlcmluZyBjb250ZXh0LlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNvbnRleHQ6IFdlYkdMUmVuZGVyaW5nQ29udGV4dDtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBtYXhpbXVtIGJhdGNoIHNpemUgZm9yIG1hdG11bC4gMCBtZWFucyB0byBkaXNhYmxlIGJhdGNoaW5nLlxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBtYXRtdWxNYXhCYXRjaFNpemU/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgdGV4dHVyZSBjYWNoZSBtb2RlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgJ2Z1bGwnYFxuICAgICAqL1xuICAgIHRleHR1cmVDYWNoZU1vZGU/OiAnaW5pdGlhbGl6ZXJPbmx5JyB8ICdmdWxsJztcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwYWNrZWQgdGV4dHVyZSBtb2RlXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKi9cbiAgICBwYWNrPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHdoZXRoZXIgZW5hYmxlIGFzeW5jIGRvd25sb2FkLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICovXG4gICAgYXN5bmM/OiBib29sZWFuO1xuICB9XG5cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHcHVQcm9maWxpbmdEYXRhVjFUZW5zb3JNZXRhZGF0YSB7XG4gICAgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gICAgZGF0YVR5cGU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdwdVByb2ZpbGluZ0RhdGFWMSB7XG4gICAgdmVyc2lvbjogMTtcbiAgICBpbnB1dHNNZXRhZGF0YTogcmVhZG9ubHkgV2ViR3B1UHJvZmlsaW5nRGF0YVYxVGVuc29yTWV0YWRhdGFbXTtcbiAgICBvdXRwdXRzTWV0YWRhdGE6IHJlYWRvbmx5IFdlYkdwdVByb2ZpbGluZ0RhdGFWMVRlbnNvck1ldGFkYXRhW107XG4gICAga2VybmVsSWQ6IG51bWJlcjtcbiAgICBrZXJuZWxUeXBlOiBzdHJpbmc7XG4gICAga2VybmVsTmFtZTogc3RyaW5nO1xuICAgIHByb2dyYW1OYW1lOiBzdHJpbmc7XG4gICAgc3RhcnRUaW1lOiBudW1iZXI7XG4gICAgZW5kVGltZTogbnVtYmVyO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgV2ViR3B1UHJvZmlsaW5nRGF0YSA9IFdlYkdwdVByb2ZpbGluZ0RhdGFWMTtcblxuICBleHBvcnQgaW50ZXJmYWNlIFdlYkdwdUZsYWdzIHtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwcm9maWxpbmcgbW9kZS5cbiAgICAgKlxuICAgICAqIEBkZXByZWNhdGVkIFVzZSBgZW52LndlYmdwdS5wcm9maWxpbmcubW9kZWAgaW5zdGVhZC4gSWYgYGVudi53ZWJncHUucHJvZmlsaW5nLm1vZGVgIGlzIHNldCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlXG4gICAgICogaWdub3JlZC5cbiAgICAgKi9cbiAgICBwcm9maWxpbmdNb2RlPzogJ29mZicgfCAnZGVmYXVsdCc7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcHJvZmlsaW5nIGNvbmZpZ3VyYXRpb24uXG4gICAgICovXG4gICAgcHJvZmlsaW5nOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCBvciBnZXQgdGhlIHByb2ZpbGluZyBtb2RlLlxuICAgICAgICpcbiAgICAgICAqIEBkZWZhdWx0VmFsdWUgYCdvZmYnYFxuICAgICAgICovXG4gICAgICBtb2RlPzogJ29mZicgfCAnZGVmYXVsdCc7XG5cbiAgICAgIC8qKlxuICAgICAgICogU2V0IG9yIGdldCBhIGNhbGxiYWNrIGZ1bmN0aW9uIHdoZW4gYSBwcm9maWxpbmcgZGF0YSBpcyByZWNlaXZlZC4gSWYgbm90IHNldCwgdGhlIHByb2ZpbGluZyBkYXRhIHdpbGwgYmVcbiAgICAgICAqIHByaW50ZWQgdG8gY29uc29sZS5cbiAgICAgICAqL1xuICAgICAgb25kYXRhPzogKGRhdGE6IFdlYkdwdVByb2ZpbGluZ0RhdGEpID0+IHZvaWQ7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwb3dlciBwcmVmZXJlbmNlLlxuICAgICAqXG4gICAgICogU2V0dGluZyB0aGlzIHByb3BlcnR5IG9ubHkgaGFzIGVmZmVjdCBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGUgdmFsdWUgd2lsbCBiZVxuICAgICAqIHVzZWQgYXMgb3B0aW9ucyBmb3IgYG5hdmlnYXRvci5ncHUucmVxdWVzdEFkYXB0ZXIoKWAuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIGh0dHBzOi8vZ3B1d2ViLmdpdGh1Yi5pby9ncHV3ZWIvI2RpY3RkZWYtZ3B1cmVxdWVzdGFkYXB0ZXJvcHRpb25zfSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgdW5kZWZpbmVkYFxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWQgQ3JlYXRlIHlvdXIgb3duIEdQVUFkYXB0ZXIsIHVzZSBpdCB0byBjcmVhdGUgYSBHUFVEZXZpY2UgaW5zdGFuY2UgYW5kIHNldCB7QGxpbmsgZGV2aWNlfSBwcm9wZXJ0eSBpZlxuICAgICAqIHlvdSB3YW50IHRvIHVzZSBhIHNwZWNpZmljIHBvd2VyIHByZWZlcmVuY2UuXG4gICAgICovXG4gICAgcG93ZXJQcmVmZXJlbmNlPzogJ2xvdy1wb3dlcicgfCAnaGlnaC1wZXJmb3JtYW5jZSc7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgZm9yY2UgZmFsbGJhY2sgYWRhcHRlciBmbGFnLlxuICAgICAqXG4gICAgICogU2V0dGluZyB0aGlzIHByb3BlcnR5IG9ubHkgaGFzIGVmZmVjdCBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGUgdmFsdWUgd2lsbCBiZVxuICAgICAqIHVzZWQgYXMgb3B0aW9ucyBmb3IgYG5hdmlnYXRvci5ncHUucmVxdWVzdEFkYXB0ZXIoKWAuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIGh0dHBzOi8vZ3B1d2ViLmdpdGh1Yi5pby9ncHV3ZWIvI2RpY3RkZWYtZ3B1cmVxdWVzdGFkYXB0ZXJvcHRpb25zfSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgdW5kZWZpbmVkYFxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWQgQ3JlYXRlIHlvdXIgb3duIEdQVUFkYXB0ZXIsIHVzZSBpdCB0byBjcmVhdGUgYSBHUFVEZXZpY2UgaW5zdGFuY2UgYW5kIHNldCB7QGxpbmsgZGV2aWNlfSBwcm9wZXJ0eSBpZlxuICAgICAqIHlvdSB3YW50IHRvIHVzZSBhIHNwZWNpZmljIGZhbGxiYWNrIG9wdGlvbi5cbiAgICAgKi9cbiAgICBmb3JjZUZhbGxiYWNrQWRhcHRlcj86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgYWRhcHRlciBmb3IgV2ViR1BVLlxuICAgICAqXG4gICAgICogU2V0dGluZyB0aGlzIHByb3BlcnR5IG9ubHkgaGFzIGVmZmVjdCBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGUgdmFsdWUgd2lsbCBiZVxuICAgICAqIHVzZWQgYXMgdGhlIEdQVSBhZGFwdGVyIGZvciB0aGUgdW5kZXJseWluZyBXZWJHUFUgYmFja2VuZCB0byBjcmVhdGUgR1BVIGRldmljZS5cbiAgICAgKlxuICAgICAqIElmIHRoaXMgcHJvcGVydHkgaXMgbm90IHNldCwgaXQgd2lsbCBiZSBhdmFpbGFibGUgdG8gZ2V0IGFmdGVyIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlXG4gICAgICogdmFsdWUgd2lsbCBiZSB0aGUgR1BVIGFkYXB0ZXIgdGhhdCBjcmVhdGVkIGJ5IHRoZSB1bmRlcmx5aW5nIFdlYkdQVSBiYWNrZW5kLlxuICAgICAqXG4gICAgICogV2hlbiB1c2Ugd2l0aCBUeXBlU2NyaXB0LCB0aGUgdHlwZSBvZiB0aGlzIHByb3BlcnR5IGlzIGBHUFVBZGFwdGVyYCBkZWZpbmVkIGluIFwiQHdlYmdwdS90eXBlc1wiLlxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWQgSXQgaXMgbm8gbG9uZ2VyIHJlY29tbWVuZGVkIHRvIHVzZSB0aGlzIHByb3BlcnR5LiBUaGUgbGF0ZXN0IFdlYkdQVSBzcGVjIGFkZHMgYEdQVURldmljZS5hZGFwdGVySW5mb2BcbiAgICAgKiAoaHR0cHM6Ly93d3cudzMub3JnL1RSL3dlYmdwdS8jZG9tLWdwdWRldmljZS1hZGFwdGVyaW5mbyksIHdoaWNoIGFsbG93cyB0byBnZXQgdGhlIGFkYXB0ZXIgaW5mb3JtYXRpb24gZnJvbSB0aGVcbiAgICAgKiBkZXZpY2UuIFdoZW4gaXQncyBhdmFpbGFibGUsIHRoZXJlIGlzIG5vIG5lZWQgdG8gc2V0L2dldCB0aGUge0BsaW5rIGFkYXB0ZXJ9IHByb3BlcnR5LlxuICAgICAqL1xuICAgIGFkYXB0ZXI6IFRyeUdldEdsb2JhbFR5cGU8J0dQVUFkYXB0ZXInPjtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBHUFUgZGV2aWNlIGZvciBXZWJHUFUuXG4gICAgICpcbiAgICAgKiBUaGVyZSBhcmUgMyB2YWxpZCBzY2VuYXJpb3Mgb2YgYWNjZXNzaW5nIHRoaXMgcHJvcGVydHk6XG4gICAgICogLSBTZXQgYSB2YWx1ZSBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGUgdmFsdWUgd2lsbCBiZSB1c2VkIGJ5IHRoZSBXZWJHUFUgYmFja2VuZFxuICAgICAqIHRvIHBlcmZvcm0gY2FsY3VsYXRpb25zLiBJZiB0aGUgdmFsdWUgaXMgbm90IGEgYEdQVURldmljZWAgb2JqZWN0LCBhbiBlcnJvciB3aWxsIGJlIHRocm93bi5cbiAgICAgKiAtIEdldCB0aGUgdmFsdWUgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhpcyB3aWxsIHRyeSB0byBjcmVhdGUgYSBuZXcgR1BVRGV2aWNlXG4gICAgICogaW5zdGFuY2UuIFJldHVybnMgYSBgUHJvbWlzZWAgdGhhdCByZXNvbHZlcyB0byBhIGBHUFVEZXZpY2VgIG9iamVjdC5cbiAgICAgKiAtIEdldCB0aGUgdmFsdWUgYWZ0ZXIgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBSZXR1cm5zIGEgcmVzb2x2ZWQgYFByb21pc2VgIHRvIHRoZVxuICAgICAqIGBHUFVEZXZpY2VgIG9iamVjdCB1c2VkIGJ5IHRoZSBXZWJHUFUgYmFja2VuZC5cbiAgICAgKi9cbiAgICBnZXQgZGV2aWNlKCk6IFByb21pc2U8VHJ5R2V0R2xvYmFsVHlwZTwnR1BVRGV2aWNlJz4+O1xuICAgIHNldCBkZXZpY2UodmFsdWU6IFRyeUdldEdsb2JhbFR5cGU8J0dQVURldmljZSc+KTtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHdoZXRoZXIgdmFsaWRhdGUgaW5wdXQgY29udGVudC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgICAqL1xuICAgIHZhbGlkYXRlSW5wdXRDb250ZW50PzogYm9vbGVhbjtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVudiB7XG4gIC8qKlxuICAgKiBzZXQgdGhlIHNldmVyaXR5IGxldmVsIGZvciBsb2dnaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdFZhbHVlIGAnd2FybmluZydgXG4gICAqL1xuICBsb2dMZXZlbD86ICd2ZXJib3NlJyB8ICdpbmZvJyB8ICd3YXJuaW5nJyB8ICdlcnJvcicgfCAnZmF0YWwnO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZSB3aGV0aGVyIHJ1biBpbiBkZWJ1ZyBtb2RlLlxuICAgKlxuICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICovXG4gIGRlYnVnPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogc2V0IG9yIGdldCBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRvIGVuYWJsZSB0cmFjZS5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAqL1xuICB0cmFjZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEdldCB2ZXJzaW9uIG9mIHRoZSBjdXJyZW50IHBhY2thZ2UuXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uczoge1xuICAgIHJlYWRvbmx5IGNvbW1vbjogc3RyaW5nO1xuICAgIHJlYWRvbmx5IHdlYj86IHN0cmluZztcbiAgICByZWFkb25seSBub2RlPzogc3RyaW5nO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICByZWFkb25seSAncmVhY3QtbmF0aXZlJz86IHN0cmluZztcbiAgfTtcblxuICAvKipcbiAgICogUmVwcmVzZW50IGEgc2V0IG9mIGZsYWdzIGZvciBXZWJBc3NlbWJseVxuICAgKi9cbiAgcmVhZG9ubHkgd2FzbTogRW52LldlYkFzc2VtYmx5RmxhZ3M7XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudCBhIHNldCBvZiBmbGFncyBmb3IgV2ViR0xcbiAgICovXG4gIHJlYWRvbmx5IHdlYmdsOiBFbnYuV2ViR0xGbGFncztcblxuICAvKipcbiAgICogUmVwcmVzZW50IGEgc2V0IG9mIGZsYWdzIGZvciBXZWJHUFVcbiAgICovXG4gIHJlYWRvbmx5IHdlYmdwdTogRW52LldlYkdwdUZsYWdzO1xuXG4gIFtuYW1lOiBzdHJpbmddOiB1bmtub3duO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBhIHNldCBvZiBmbGFncyBhcyBhIGdsb2JhbCBzaW5nbGV0b24uXG4gKi9cbmV4cG9ydCBjb25zdCBlbnY6IEVudiA9IGVudkltcGw7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvclRvRGF0YVVybE9wdGlvbnMsIFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyB9IGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24uanMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci50b0RhdGFVUkwoKVxuICovXG5leHBvcnQgY29uc3QgdGVuc29yVG9EYXRhVVJMID0gKHRlbnNvcjogVGVuc29yLCBvcHRpb25zPzogVGVuc29yVG9EYXRhVXJsT3B0aW9ucyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNhbnZhcyA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKSA6IG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSk7XG4gIGNhbnZhcy53aWR0aCA9IHRlbnNvci5kaW1zWzNdO1xuICBjYW52YXMuaGVpZ2h0ID0gdGVuc29yLmRpbXNbMl07XG4gIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpIGFzXG4gICAgfCBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkRcbiAgICB8IE9mZnNjcmVlbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRFxuICAgIHwgbnVsbDtcblxuICBpZiAocGl4ZWxzMkRDb250ZXh0ICE9IG51bGwpIHtcbiAgICAvLyBEZWZhdWx0IHZhbHVlcyBmb3IgaGVpZ2h0IGFuZCB3aWR0aCAmIGZvcm1hdFxuICAgIGxldCB3aWR0aDogbnVtYmVyO1xuICAgIGxldCBoZWlnaHQ6IG51bWJlcjtcbiAgICBpZiAob3B0aW9ucz8udGVuc29yTGF5b3V0ICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy50ZW5zb3JMYXlvdXQgPT09ICdOSFdDJykge1xuICAgICAgd2lkdGggPSB0ZW5zb3IuZGltc1syXTtcbiAgICAgIGhlaWdodCA9IHRlbnNvci5kaW1zWzNdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWZhdWx0IGxheW91dCBpcyBOQ1dIXG4gICAgICB3aWR0aCA9IHRlbnNvci5kaW1zWzNdO1xuICAgICAgaGVpZ2h0ID0gdGVuc29yLmRpbXNbMl07XG4gICAgfVxuXG4gICAgY29uc3QgaW5wdXRmb3JtYXQgPSBvcHRpb25zPy5mb3JtYXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZm9ybWF0IDogJ1JHQic7XG5cbiAgICBjb25zdCBub3JtID0gb3B0aW9ucz8ubm9ybTtcbiAgICBsZXQgbm9ybU1lYW46IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGxldCBub3JtQmlhczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgaWYgKG5vcm0gPT09IHVuZGVmaW5lZCB8fCBub3JtLm1lYW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgbm9ybU1lYW4gPSBbMjU1LCAyNTUsIDI1NSwgMjU1XTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBub3JtLm1lYW4gPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1NZWFuID0gW25vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbl07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW5bMF0sIG5vcm0ubWVhblsxXSwgbm9ybS5tZWFuWzJdLCAwXTtcbiAgICAgICAgaWYgKG5vcm0ubWVhblszXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbm9ybU1lYW5bM10gPSBub3JtLm1lYW5bM107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG5vcm0gPT09IHVuZGVmaW5lZCB8fCBub3JtLmJpYXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbm9ybUJpYXMgPSBbMCwgMCwgMCwgMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2Ygbm9ybS5iaWFzID09PSAnbnVtYmVyJykge1xuICAgICAgICBub3JtQmlhcyA9IFtub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXNdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzWzBdLCBub3JtLmJpYXNbMV0sIG5vcm0uYmlhc1syXSwgMF07XG4gICAgICAgIGlmIChub3JtLmJpYXNbM10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5vcm1CaWFzWzNdID0gbm9ybS5iaWFzWzNdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc3RyaWRlID0gaGVpZ2h0ICogd2lkdGg7XG4gICAgLy8gRGVmYXVsdCBwb2ludGVyIGFzc2lnbm1lbnRzXG4gICAgbGV0IHJUZW5zb3JQb2ludGVyID0gMCxcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlLFxuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyLFxuICAgICAgYVRlbnNvclBvaW50ZXIgPSAtMTtcblxuICAgIC8vIFVwZGF0aW5nIHRoZSBwb2ludGVyIGFzc2lnbm1lbnRzIGJhc2VkIG9uIHRoZSBpbnB1dCBpbWFnZSBmb3JtYXRcbiAgICBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0JBJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgICBhVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDM7XG4gICAgfSBlbHNlIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQicpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgIH0gZWxzZSBpZiAoaW5wdXRmb3JtYXQgPT09ICdSQkcnKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhlaWdodDsgaSsrKSB7XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHdpZHRoOyBqKyspIHtcbiAgICAgICAgY29uc3QgUiA9ICgodGVuc29yLmRhdGFbclRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzBdKSAqIG5vcm1NZWFuWzBdOyAvLyBSIHZhbHVlXG4gICAgICAgIGNvbnN0IEcgPSAoKHRlbnNvci5kYXRhW2dUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1sxXSkgKiBub3JtTWVhblsxXTsgLy8gRyB2YWx1ZVxuICAgICAgICBjb25zdCBCID0gKCh0ZW5zb3IuZGF0YVtiVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMl0pICogbm9ybU1lYW5bMl07IC8vIEIgdmFsdWVcbiAgICAgICAgY29uc3QgQSA9IGFUZW5zb3JQb2ludGVyID09PSAtMSA/IDI1NSA6ICgodGVuc29yLmRhdGFbYVRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzNdKSAqIG5vcm1NZWFuWzNdOyAvLyBBIHZhbHVlXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvcmVzdHJpY3QtcGx1cy1vcGVyYW5kc1xuICAgICAgICBwaXhlbHMyRENvbnRleHQuZmlsbFN0eWxlID0gJ3JnYmEoJyArIFIgKyAnLCcgKyBHICsgJywnICsgQiArICcsJyArIEEgKyAnKSc7XG4gICAgICAgIHBpeGVsczJEQ29udGV4dC5maWxsUmVjdChqLCBpLCAxLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCd0b0RhdGFVUkwnIGluIGNhbnZhcykge1xuICAgICAgcmV0dXJuIGNhbnZhcy50b0RhdGFVUkwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0b0RhdGFVUkwgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgYWNjZXNzIGltYWdlIGRhdGEnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IudG9JbWFnZURhdGEoKVxuICovXG5leHBvcnQgY29uc3QgdGVuc29yVG9JbWFnZURhdGEgPSAodGVuc29yOiBUZW5zb3IsIG9wdGlvbnM/OiBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnMpOiBJbWFnZURhdGEgPT4ge1xuICBjb25zdCBwaXhlbHMyRENvbnRleHQgPVxuICAgIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKVxuICAgICAgOiAobmV3IE9mZnNjcmVlbkNhbnZhcygxLCAxKS5nZXRDb250ZXh0KCcyZCcpIGFzIE9mZnNjcmVlbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCk7XG4gIGxldCBpbWFnZTogSW1hZ2VEYXRhO1xuICBpZiAocGl4ZWxzMkRDb250ZXh0ICE9IG51bGwpIHtcbiAgICAvLyBEZWZhdWx0IHZhbHVlcyBmb3IgaGVpZ2h0IGFuZCB3aWR0aCAmIGZvcm1hdFxuICAgIGxldCB3aWR0aDogbnVtYmVyO1xuICAgIGxldCBoZWlnaHQ6IG51bWJlcjtcbiAgICBsZXQgY2hhbm5lbHM6IG51bWJlcjtcbiAgICBpZiAob3B0aW9ucz8udGVuc29yTGF5b3V0ICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy50ZW5zb3JMYXlvdXQgPT09ICdOSFdDJykge1xuICAgICAgd2lkdGggPSB0ZW5zb3IuZGltc1syXTtcbiAgICAgIGhlaWdodCA9IHRlbnNvci5kaW1zWzFdO1xuICAgICAgY2hhbm5lbHMgPSB0ZW5zb3IuZGltc1szXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRGVmYXVsdCBsYXlvdXQgaXMgTkNXSFxuICAgICAgd2lkdGggPSB0ZW5zb3IuZGltc1szXTtcbiAgICAgIGhlaWdodCA9IHRlbnNvci5kaW1zWzJdO1xuICAgICAgY2hhbm5lbHMgPSB0ZW5zb3IuZGltc1sxXTtcbiAgICB9XG4gICAgY29uc3QgaW5wdXRmb3JtYXQgPSBvcHRpb25zICE9PSB1bmRlZmluZWQgPyAob3B0aW9ucy5mb3JtYXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZm9ybWF0IDogJ1JHQicpIDogJ1JHQic7XG5cbiAgICBjb25zdCBub3JtID0gb3B0aW9ucz8ubm9ybTtcbiAgICBsZXQgbm9ybU1lYW46IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGxldCBub3JtQmlhczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgaWYgKG5vcm0gPT09IHVuZGVmaW5lZCB8fCBub3JtLm1lYW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgbm9ybU1lYW4gPSBbMjU1LCAyNTUsIDI1NSwgMjU1XTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBub3JtLm1lYW4gPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1NZWFuID0gW25vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbl07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW5bMF0sIG5vcm0ubWVhblsxXSwgbm9ybS5tZWFuWzJdLCAyNTVdO1xuICAgICAgICBpZiAobm9ybS5tZWFuWzNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBub3JtTWVhblszXSA9IG5vcm0ubWVhblszXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobm9ybSA9PT0gdW5kZWZpbmVkIHx8IG5vcm0uYmlhcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBub3JtQmlhcyA9IFswLCAwLCAwLCAwXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBub3JtLmJpYXMgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1CaWFzID0gW25vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhc107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtQmlhcyA9IFtub3JtLmJpYXNbMF0sIG5vcm0uYmlhc1sxXSwgbm9ybS5iaWFzWzJdLCAwXTtcbiAgICAgICAgaWYgKG5vcm0uYmlhc1szXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbm9ybUJpYXNbM10gPSBub3JtLmJpYXNbM107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzdHJpZGUgPSBoZWlnaHQgKiB3aWR0aDtcbiAgICBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoXG4gICAgICAgIChvcHRpb25zLmZvcm1hdCAhPT0gdW5kZWZpbmVkICYmIGNoYW5uZWxzID09PSA0ICYmIG9wdGlvbnMuZm9ybWF0ICE9PSAnUkdCQScpIHx8XG4gICAgICAgIChjaGFubmVscyA9PT0gMyAmJiBvcHRpb25zLmZvcm1hdCAhPT0gJ1JHQicgJiYgb3B0aW9ucy5mb3JtYXQgIT09ICdCR1InKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRlbnNvciBmb3JtYXQgZG9lc24ndCBtYXRjaCBpbnB1dCB0ZW5zb3IgZGltc1wiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBEZWZhdWx0IHBvaW50ZXIgYXNzaWdubWVudHNcbiAgICBjb25zdCBzdGVwID0gNDtcbiAgICBsZXQgckltYWdlUG9pbnRlciA9IDAsXG4gICAgICBnSW1hZ2VQb2ludGVyID0gMSxcbiAgICAgIGJJbWFnZVBvaW50ZXIgPSAyLFxuICAgICAgYUltYWdlUG9pbnRlciA9IDM7XG4gICAgbGV0IHJUZW5zb3JQb2ludGVyID0gMCxcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlLFxuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyLFxuICAgICAgYVRlbnNvclBvaW50ZXIgPSAtMTtcblxuICAgIC8vIFVwZGF0aW5nIHRoZSBwb2ludGVyIGFzc2lnbm1lbnRzIGJhc2VkIG9uIHRoZSBpbnB1dCBpbWFnZSBmb3JtYXRcbiAgICBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0JBJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgICBhVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDM7XG4gICAgfSBlbHNlIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQicpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgIH0gZWxzZSBpZiAoaW5wdXRmb3JtYXQgPT09ICdSQkcnKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICB9XG5cbiAgICBpbWFnZSA9IHBpeGVsczJEQ29udGV4dC5jcmVhdGVJbWFnZURhdGEod2lkdGgsIGhlaWdodCk7XG5cbiAgICBmb3IgKFxuICAgICAgbGV0IGkgPSAwO1xuICAgICAgaSA8IGhlaWdodCAqIHdpZHRoO1xuICAgICAgckltYWdlUG9pbnRlciArPSBzdGVwLCBnSW1hZ2VQb2ludGVyICs9IHN0ZXAsIGJJbWFnZVBvaW50ZXIgKz0gc3RlcCwgYUltYWdlUG9pbnRlciArPSBzdGVwLCBpKytcbiAgICApIHtcbiAgICAgIGltYWdlLmRhdGFbckltYWdlUG9pbnRlcl0gPSAoKHRlbnNvci5kYXRhW3JUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1swXSkgKiBub3JtTWVhblswXTsgLy8gUiB2YWx1ZVxuICAgICAgaW1hZ2UuZGF0YVtnSW1hZ2VQb2ludGVyXSA9ICgodGVuc29yLmRhdGFbZ1RlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzFdKSAqIG5vcm1NZWFuWzFdOyAvLyBHIHZhbHVlXG4gICAgICBpbWFnZS5kYXRhW2JJbWFnZVBvaW50ZXJdID0gKCh0ZW5zb3IuZGF0YVtiVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMl0pICogbm9ybU1lYW5bMl07IC8vIEIgdmFsdWVcbiAgICAgIGltYWdlLmRhdGFbYUltYWdlUG9pbnRlcl0gPVxuICAgICAgICBhVGVuc29yUG9pbnRlciA9PT0gLTEgPyAyNTUgOiAoKHRlbnNvci5kYXRhW2FUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1szXSkgKiBub3JtTWVhblszXTsgLy8gQSB2YWx1ZVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgYWNjZXNzIGltYWdlIGRhdGEnKTtcbiAgfVxuICByZXR1cm4gaW1hZ2U7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1xuICBPcHRpb25zRGltZW5zaW9ucyxcbiAgT3B0aW9uc0Zvcm1hdCxcbiAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzLFxuICBPcHRpb25zVGVuc29yRm9ybWF0LFxuICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnMsXG4gIFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zLFxuICBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zLFxuICBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnMsXG4gIFRlbnNvckZyb21VcmxPcHRpb25zLFxufSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLWltcGwuanMnO1xuaW1wb3J0IHsgVGVuc29yIGFzIFRlbnNvckludGVyZmFjZSB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuaW50ZXJmYWNlIEJ1ZmZlclRvVGVuc29yT3B0aW9uc1xuICBleHRlbmRzIE9wdGlvbnNEaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JMYXlvdXQsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzLFxuICAgIE9wdGlvbnNGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckZvcm1hdCB7fVxuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gaW1hZ2Ugb2JqZWN0XG4gKlxuICogQHBhcmFtIGJ1ZmZlciAtIEV4dHJhY3RlZCBpbWFnZSBidWZmZXIgZGF0YSAtIGFzc3VtaW5nIFJHQkEgZm9ybWF0XG4gKiBAcGFyYW0gaW1hZ2VGb3JtYXQgLSBpbnB1dCBpbWFnZSBjb25maWd1cmF0aW9uIC0gcmVxdWlyZWQgY29uZmlndXJhdGlvbnMgaGVpZ2h0LCB3aWR0aCwgZm9ybWF0XG4gKiBAcGFyYW0gdGVuc29yRm9ybWF0IC0gb3V0cHV0IHRlbnNvciBjb25maWd1cmF0aW9uIC0gRGVmYXVsdCBpcyBSR0IgZm9ybWF0XG4gKi9cbmV4cG9ydCBjb25zdCBidWZmZXJUb1RlbnNvciA9IChidWZmZXI6IFVpbnQ4Q2xhbXBlZEFycmF5IHwgdW5kZWZpbmVkLCBvcHRpb25zOiBCdWZmZXJUb1RlbnNvck9wdGlvbnMpOiBUZW5zb3IgPT4ge1xuICBpZiAoYnVmZmVyID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlIGJ1ZmZlciBtdXN0IGJlIGRlZmluZWQnKTtcbiAgfVxuICBpZiAob3B0aW9ucy5oZWlnaHQgPT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLndpZHRoID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlIGhlaWdodCBhbmQgd2lkdGggbXVzdCBiZSBkZWZpbmVkJyk7XG4gIH1cbiAgaWYgKG9wdGlvbnMudGVuc29yTGF5b3V0ID09PSAnTkhXQycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05IV0MgVGVuc29yIGxheW91dCBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICB9XG5cbiAgY29uc3QgeyBoZWlnaHQsIHdpZHRoIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IG5vcm0gPSBvcHRpb25zLm5vcm0gPz8geyBtZWFuOiAyNTUsIGJpYXM6IDAgfTtcbiAgbGV0IG5vcm1NZWFuOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgbGV0IG5vcm1CaWFzOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcblxuICBpZiAodHlwZW9mIG5vcm0ubWVhbiA9PT0gJ251bWJlcicpIHtcbiAgICBub3JtTWVhbiA9IFtub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW5dO1xuICB9IGVsc2Uge1xuICAgIG5vcm1NZWFuID0gW25vcm0ubWVhbiFbMF0sIG5vcm0ubWVhbiFbMV0sIG5vcm0ubWVhbiFbMl0sIG5vcm0ubWVhbiFbM10gPz8gMjU1XTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygbm9ybS5iaWFzID09PSAnbnVtYmVyJykge1xuICAgIG5vcm1CaWFzID0gW25vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhc107XG4gIH0gZWxzZSB7XG4gICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzIVswXSwgbm9ybS5iaWFzIVsxXSwgbm9ybS5iaWFzIVsyXSwgbm9ybS5iaWFzIVszXSA/PyAwXTtcbiAgfVxuXG4gIGNvbnN0IGlucHV0Zm9ybWF0ID0gb3B0aW9ucy5mb3JtYXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZm9ybWF0IDogJ1JHQkEnO1xuICAvLyBkZWZhdWx0IHZhbHVlIGlzIFJHQkEgc2luY2UgaW1hZ2VkYXRhIGFuZCBIVE1MSW1hZ2VFbGVtZW50IHVzZXMgaXRcblxuICBjb25zdCBvdXRwdXRmb3JtYXQgPVxuICAgIG9wdGlvbnMudGVuc29yRm9ybWF0ICE9PSB1bmRlZmluZWQgPyAob3B0aW9ucy50ZW5zb3JGb3JtYXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudGVuc29yRm9ybWF0IDogJ1JHQicpIDogJ1JHQic7XG4gIGNvbnN0IHN0cmlkZSA9IGhlaWdodCAqIHdpZHRoO1xuICBjb25zdCBmbG9hdDMyRGF0YSA9IG91dHB1dGZvcm1hdCA9PT0gJ1JHQkEnID8gbmV3IEZsb2F0MzJBcnJheShzdHJpZGUgKiA0KSA6IG5ldyBGbG9hdDMyQXJyYXkoc3RyaWRlICogMyk7XG5cbiAgLy8gRGVmYXVsdCBwb2ludGVyIGFzc2lnbm1lbnRzXG4gIGxldCBzdGVwID0gNCxcbiAgICBySW1hZ2VQb2ludGVyID0gMCxcbiAgICBnSW1hZ2VQb2ludGVyID0gMSxcbiAgICBiSW1hZ2VQb2ludGVyID0gMixcbiAgICBhSW1hZ2VQb2ludGVyID0gMztcbiAgbGV0IHJUZW5zb3JQb2ludGVyID0gMCxcbiAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSxcbiAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDIsXG4gICAgYVRlbnNvclBvaW50ZXIgPSAtMTtcblxuICAvLyBVcGRhdGluZyB0aGUgcG9pbnRlciBhc3NpZ25tZW50cyBiYXNlZCBvbiB0aGUgaW5wdXQgaW1hZ2UgZm9ybWF0XG4gIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQicpIHtcbiAgICBzdGVwID0gMztcbiAgICBySW1hZ2VQb2ludGVyID0gMDtcbiAgICBnSW1hZ2VQb2ludGVyID0gMTtcbiAgICBiSW1hZ2VQb2ludGVyID0gMjtcbiAgICBhSW1hZ2VQb2ludGVyID0gLTE7XG4gIH1cblxuICAvLyBVcGRhdGluZyB0aGUgcG9pbnRlciBhc3NpZ25tZW50cyBiYXNlZCBvbiB0aGUgb3V0cHV0IHRlbnNvciBmb3JtYXRcbiAgaWYgKG91dHB1dGZvcm1hdCA9PT0gJ1JHQkEnKSB7XG4gICAgYVRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAzO1xuICB9IGVsc2UgaWYgKG91dHB1dGZvcm1hdCA9PT0gJ1JCRycpIHtcbiAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICB9IGVsc2UgaWYgKG91dHB1dGZvcm1hdCA9PT0gJ0JHUicpIHtcbiAgICBiVGVuc29yUG9pbnRlciA9IDA7XG4gICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgclRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICB9XG5cbiAgZm9yIChcbiAgICBsZXQgaSA9IDA7XG4gICAgaSA8IHN0cmlkZTtcbiAgICBpKyssIHJJbWFnZVBvaW50ZXIgKz0gc3RlcCwgYkltYWdlUG9pbnRlciArPSBzdGVwLCBnSW1hZ2VQb2ludGVyICs9IHN0ZXAsIGFJbWFnZVBvaW50ZXIgKz0gc3RlcFxuICApIHtcbiAgICBmbG9hdDMyRGF0YVtyVGVuc29yUG9pbnRlcisrXSA9IChidWZmZXJbckltYWdlUG9pbnRlcl0gKyBub3JtQmlhc1swXSkgLyBub3JtTWVhblswXTtcbiAgICBmbG9hdDMyRGF0YVtnVGVuc29yUG9pbnRlcisrXSA9IChidWZmZXJbZ0ltYWdlUG9pbnRlcl0gKyBub3JtQmlhc1sxXSkgLyBub3JtTWVhblsxXTtcbiAgICBmbG9hdDMyRGF0YVtiVGVuc29yUG9pbnRlcisrXSA9IChidWZmZXJbYkltYWdlUG9pbnRlcl0gKyBub3JtQmlhc1syXSkgLyBub3JtTWVhblsyXTtcbiAgICBpZiAoYVRlbnNvclBvaW50ZXIgIT09IC0xICYmIGFJbWFnZVBvaW50ZXIgIT09IC0xKSB7XG4gICAgICBmbG9hdDMyRGF0YVthVGVuc29yUG9pbnRlcisrXSA9IChidWZmZXJbYUltYWdlUG9pbnRlcl0gKyBub3JtQmlhc1szXSkgLyBub3JtTWVhblszXTtcbiAgICB9XG4gIH1cblxuICAvLyBGbG9hdDMyQXJyYXkgLT4gb3J0LlRlbnNvclxuICBjb25zdCBvdXRwdXRUZW5zb3IgPVxuICAgIG91dHB1dGZvcm1hdCA9PT0gJ1JHQkEnXG4gICAgICA/IG5ldyBUZW5zb3IoJ2Zsb2F0MzInLCBmbG9hdDMyRGF0YSwgWzEsIDQsIGhlaWdodCwgd2lkdGhdKVxuICAgICAgOiBuZXcgVGVuc29yKCdmbG9hdDMyJywgZmxvYXQzMkRhdGEsIFsxLCAzLCBoZWlnaHQsIHdpZHRoXSk7XG4gIHJldHVybiBvdXRwdXRUZW5zb3I7XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci5mcm9tSW1hZ2UoKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckZyb21JbWFnZSA9IGFzeW5jIChcbiAgaW1hZ2U6IEltYWdlRGF0YSB8IEhUTUxJbWFnZUVsZW1lbnQgfCBJbWFnZUJpdG1hcCB8IHN0cmluZyxcbiAgb3B0aW9ucz86XG4gICAgfCBUZW5zb3JGcm9tSW1hZ2VEYXRhT3B0aW9uc1xuICAgIHwgVGVuc29yRnJvbUltYWdlRWxlbWVudE9wdGlvbnNcbiAgICB8IFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnNcbiAgICB8IFRlbnNvckZyb21VcmxPcHRpb25zLFxuKTogUHJvbWlzZTxUZW5zb3I+ID0+IHtcbiAgLy8gY2hlY2tpbmcgdGhlIHR5cGUgb2YgaW1hZ2Ugb2JqZWN0XG4gIGNvbnN0IGlzSFRNTEltYWdlRWxlID0gdHlwZW9mIEhUTUxJbWFnZUVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGltYWdlIGluc3RhbmNlb2YgSFRNTEltYWdlRWxlbWVudDtcbiAgY29uc3QgaXNJbWFnZURhdGFFbGUgPSB0eXBlb2YgSW1hZ2VEYXRhICE9PSAndW5kZWZpbmVkJyAmJiBpbWFnZSBpbnN0YW5jZW9mIEltYWdlRGF0YTtcbiAgY29uc3QgaXNJbWFnZUJpdG1hcCA9IHR5cGVvZiBJbWFnZUJpdG1hcCAhPT0gJ3VuZGVmaW5lZCcgJiYgaW1hZ2UgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcDtcbiAgY29uc3QgaXNTdHJpbmcgPSB0eXBlb2YgaW1hZ2UgPT09ICdzdHJpbmcnO1xuXG4gIGxldCBkYXRhOiBVaW50OENsYW1wZWRBcnJheSB8IHVuZGVmaW5lZDtcbiAgbGV0IGJ1ZmZlclRvVGVuc29yT3B0aW9uczogQnVmZmVyVG9UZW5zb3JPcHRpb25zID0gb3B0aW9ucyA/PyB7fTtcblxuICBjb25zdCBjcmVhdGVDYW52YXMgPSAoKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBPZmZzY3JlZW5DYW52YXMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gbmV3IE9mZnNjcmVlbkNhbnZhcygxLCAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW52YXMgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfTtcbiAgY29uc3QgY3JlYXRlQ2FudmFzQ29udGV4dCA9IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50IHwgT2Zmc2NyZWVuQ2FudmFzKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBIVE1MQ2FudmFzRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgY2FudmFzIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpIHtcbiAgICAgIHJldHVybiBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICB9IGVsc2UgaWYgKGNhbnZhcyBpbnN0YW5jZW9mIE9mZnNjcmVlbkNhbnZhcykge1xuICAgICAgcmV0dXJuIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpIGFzIE9mZnNjcmVlbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9O1xuICAvLyBmaWxsaW5nIGFuZCBjaGVja2luZyBpbWFnZSBjb25maWd1cmF0aW9uIG9wdGlvbnNcbiAgaWYgKGlzSFRNTEltYWdlRWxlKSB7XG4gICAgLy8gSFRNTEltYWdlRWxlbWVudCAtIGltYWdlIG9iamVjdCAtIGZvcm1hdCBpcyBSR0JBIGJ5IGRlZmF1bHRcbiAgICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcbiAgICBjYW52YXMud2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICBjYW52YXMuaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQoY2FudmFzKTtcblxuICAgIGlmIChwaXhlbHMyRENvbnRleHQgIT0gbnVsbCkge1xuICAgICAgbGV0IGhlaWdodCA9IGltYWdlLmhlaWdodDtcbiAgICAgIGxldCB3aWR0aCA9IGltYWdlLndpZHRoO1xuICAgICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnJlc2l6ZWRIZWlnaHQgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnJlc2l6ZWRXaWR0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGhlaWdodCA9IG9wdGlvbnMucmVzaXplZEhlaWdodDtcbiAgICAgICAgd2lkdGggPSBvcHRpb25zLnJlc2l6ZWRXaWR0aDtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICBpZiAob3B0aW9ucy50ZW5zb3JGb3JtYXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW1hZ2UgaW5wdXQgY29uZmlnIGZvcm1hdCBtdXN0IGJlIFJHQkEgZm9yIEhUTUxJbWFnZUVsZW1lbnQnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMudGVuc29yRm9ybWF0ID0gJ1JHQkEnO1xuICAgICAgICB9XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy53aWR0aCA9IHdpZHRoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLnRlbnNvckZvcm1hdCA9ICdSR0JBJztcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmhlaWdodCA9IGhlaWdodDtcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLndpZHRoID0gd2lkdGg7XG4gICAgICB9XG5cbiAgICAgIHBpeGVsczJEQ29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDApO1xuICAgICAgZGF0YSA9IHBpeGVsczJEQ29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCkuZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGFjY2VzcyBpbWFnZSBkYXRhJyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzSW1hZ2VEYXRhRWxlKSB7XG4gICAgbGV0IGhlaWdodDogbnVtYmVyO1xuICAgIGxldCB3aWR0aDogbnVtYmVyO1xuXG4gICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnJlc2l6ZWRXaWR0aCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMucmVzaXplZEhlaWdodCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBoZWlnaHQgPSBvcHRpb25zLnJlc2l6ZWRIZWlnaHQ7XG4gICAgICB3aWR0aCA9IG9wdGlvbnMucmVzaXplZFdpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICBoZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgICB3aWR0aCA9IGltYWdlLndpZHRoO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5mb3JtYXQgPSAnUkdCQSc7XG4gICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmhlaWdodCA9IGhlaWdodDtcbiAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMud2lkdGggPSB3aWR0aDtcblxuICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHRlbXBDYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcblxuICAgICAgdGVtcENhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgdGVtcENhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG5cbiAgICAgIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQodGVtcENhbnZhcyk7XG5cbiAgICAgIGlmIChwaXhlbHMyRENvbnRleHQgIT0gbnVsbCkge1xuICAgICAgICBwaXhlbHMyRENvbnRleHQucHV0SW1hZ2VEYXRhKGltYWdlLCAwLCAwKTtcbiAgICAgICAgZGF0YSA9IHBpeGVsczJEQ29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCkuZGF0YTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBhY2Nlc3MgaW1hZ2UgZGF0YScpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBkYXRhID0gaW1hZ2UuZGF0YTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNJbWFnZUJpdG1hcCkge1xuICAgIC8vIEltYWdlQml0bWFwIC0gaW1hZ2Ugb2JqZWN0IC0gZm9ybWF0IG11c3QgYmUgcHJvdmlkZWQgYnkgdXNlclxuICAgIGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgaW1hZ2UgY29uZmlnIHdpdGggZm9ybWF0IGZvciBJbWFnZWJpdG1hcCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbnZhcyA9IGNyZWF0ZUNhbnZhcygpO1xuICAgIGNhbnZhcy53aWR0aCA9IGltYWdlLndpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgY29uc3QgcGl4ZWxzMkRDb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dChjYW52YXMpO1xuXG4gICAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgICBjb25zdCBoZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgICBjb25zdCB3aWR0aCA9IGltYWdlLndpZHRoO1xuICAgICAgcGl4ZWxzMkRDb250ZXh0LmRyYXdJbWFnZShpbWFnZSwgMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICBkYXRhID0gcGl4ZWxzMkRDb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCB3aWR0aCwgaGVpZ2h0KS5kYXRhO1xuICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmhlaWdodCA9IGhlaWdodDtcbiAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy53aWR0aCA9IHdpZHRoO1xuICAgICAgcmV0dXJuIGJ1ZmZlclRvVGVuc29yKGRhdGEsIGJ1ZmZlclRvVGVuc29yT3B0aW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBhY2Nlc3MgaW1hZ2UgZGF0YScpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc1N0cmluZykge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0KGNhbnZhcyk7XG4gICAgICBpZiAoIWltYWdlIHx8ICFjb250ZXh0KSB7XG4gICAgICAgIHJldHVybiByZWplY3QoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5ld0ltYWdlID0gbmV3IEltYWdlKCk7XG4gICAgICBuZXdJbWFnZS5jcm9zc09yaWdpbiA9ICdBbm9ueW1vdXMnO1xuICAgICAgbmV3SW1hZ2Uuc3JjID0gaW1hZ2U7XG4gICAgICBuZXdJbWFnZS5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgIGNhbnZhcy53aWR0aCA9IG5ld0ltYWdlLndpZHRoO1xuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gbmV3SW1hZ2UuaGVpZ2h0O1xuICAgICAgICBjb250ZXh0LmRyYXdJbWFnZShuZXdJbWFnZSwgMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICAgICAgY29uc3QgaW1nID0gY29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcblxuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMuaGVpZ2h0ID0gY2FudmFzLmhlaWdodDtcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLndpZHRoID0gY2FudmFzLndpZHRoO1xuICAgICAgICByZXNvbHZlKGJ1ZmZlclRvVGVuc29yKGltZy5kYXRhLCBidWZmZXJUb1RlbnNvck9wdGlvbnMpKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBkYXRhIHByb3ZpZGVkIGlzIG5vdCBzdXBwb3J0ZWQgLSBhYm9ydGVkIHRlbnNvciBjcmVhdGlvbicpO1xuICB9XG5cbiAgaWYgKGRhdGEgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBidWZmZXJUb1RlbnNvcihkYXRhLCBidWZmZXJUb1RlbnNvck9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgZGF0YSBwcm92aWRlZCBpcyBub3Qgc3VwcG9ydGVkIC0gYWJvcnRlZCB0ZW5zb3IgY3JlYXRpb24nKTtcbiAgfVxufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbVRleHR1cmUoKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckZyb21UZXh0dXJlID0gPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuVGV4dHVyZURhdGFUeXBlcz4oXG4gIHRleHR1cmU6IFRlbnNvckludGVyZmFjZS5UZXh0dXJlVHlwZSxcbiAgb3B0aW9uczogVGVuc29yRnJvbVRleHR1cmVPcHRpb25zPFQ+LFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0LCBkb3dubG9hZCwgZGlzcG9zZSB9ID0gb3B0aW9ucztcbiAgLy8gQWx3YXlzIGFzc3VtZSBSR0JBRjMyLiBUT0RPOiBzdXBwb3J0IGRpZmZlcmVudCB0ZXh0dXJlIGZvcm1hdFxuICBjb25zdCBkaW1zID0gWzEsIGhlaWdodCwgd2lkdGgsIDRdO1xuICByZXR1cm4gbmV3IFRlbnNvcih7IGxvY2F0aW9uOiAndGV4dHVyZScsIHR5cGU6ICdmbG9hdDMyJywgdGV4dHVyZSwgZGltcywgZG93bmxvYWQsIGRpc3Bvc2UgfSk7XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci5mcm9tR3B1QnVmZmVyKCkuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JGcm9tR3B1QnVmZmVyID0gPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuR3B1QnVmZmVyRGF0YVR5cGVzPihcbiAgZ3B1QnVmZmVyOiBUZW5zb3JJbnRlcmZhY2UuR3B1QnVmZmVyVHlwZSxcbiAgb3B0aW9uczogVGVuc29yRnJvbUdwdUJ1ZmZlck9wdGlvbnM8VD4sXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB7IGRhdGFUeXBlLCBkaW1zLCBkb3dubG9hZCwgZGlzcG9zZSB9ID0gb3B0aW9ucztcbiAgcmV0dXJuIG5ldyBUZW5zb3IoeyBsb2NhdGlvbjogJ2dwdS1idWZmZXInLCB0eXBlOiBkYXRhVHlwZSA/PyAnZmxvYXQzMicsIGdwdUJ1ZmZlciwgZGltcywgZG93bmxvYWQsIGRpc3Bvc2UgfSk7XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci5mcm9tTUxUZW5zb3IoKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckZyb21NTFRlbnNvciA9IDxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLk1MVGVuc29yRGF0YVR5cGVzPihcbiAgbWxUZW5zb3I6IFRlbnNvckludGVyZmFjZS5NTFRlbnNvclR5cGUsXG4gIG9wdGlvbnM6IFRlbnNvckZyb21NTFRlbnNvck9wdGlvbnM8VD4sXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB7IGRhdGFUeXBlLCBkaW1zLCBkb3dubG9hZCwgZGlzcG9zZSB9ID0gb3B0aW9ucztcbiAgcmV0dXJuIG5ldyBUZW5zb3IoeyBsb2NhdGlvbjogJ21sLXRlbnNvcicsIHR5cGU6IGRhdGFUeXBlID8/ICdmbG9hdDMyJywgbWxUZW5zb3IsIGRpbXMsIGRvd25sb2FkLCBkaXNwb3NlIH0pO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbVBpbm5lZEJ1ZmZlcigpLlxuICovXG5leHBvcnQgY29uc3QgdGVuc29yRnJvbVBpbm5lZEJ1ZmZlciA9IDxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLkNwdVBpbm5lZERhdGFUeXBlcz4oXG4gIHR5cGU6IFQsXG4gIGJ1ZmZlcjogVGVuc29ySW50ZXJmYWNlLkRhdGFUeXBlTWFwW1RdLFxuICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBUZW5zb3IgPT4gbmV3IFRlbnNvcih7IGxvY2F0aW9uOiAnY3B1LXBpbm5lZCcsIHR5cGUsIGRhdGE6IGJ1ZmZlciwgZGltczogZGltcyA/PyBbYnVmZmVyLmxlbmd0aF0gfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuZXhwb3J0IHR5cGUgU3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycyA9XG4gIHwgRmxvYXQzMkFycmF5Q29uc3RydWN0b3JcbiAgfCBVaW50OEFycmF5Q29uc3RydWN0b3JcbiAgfCBJbnQ4QXJyYXlDb25zdHJ1Y3RvclxuICB8IFVpbnQxNkFycmF5Q29uc3RydWN0b3JcbiAgfCBJbnQxNkFycmF5Q29uc3RydWN0b3JcbiAgfCBJbnQzMkFycmF5Q29uc3RydWN0b3JcbiAgfCBCaWdJbnQ2NEFycmF5Q29uc3RydWN0b3JcbiAgfCBVaW50OEFycmF5Q29uc3RydWN0b3JcbiAgfCBGbG9hdDY0QXJyYXlDb25zdHJ1Y3RvclxuICB8IFVpbnQzMkFycmF5Q29uc3RydWN0b3JcbiAgfCBCaWdVaW50NjRBcnJheUNvbnN0cnVjdG9yO1xuZXhwb3J0IHR5cGUgU3VwcG9ydGVkVHlwZWRBcnJheSA9IEluc3RhbmNlVHlwZTxTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzPjtcblxuLy8gYSBydW50aW1lIG1hcCB0aGF0IG1hcHMgdHlwZSBzdHJpbmcgdG8gVHlwZWRBcnJheSBjb25zdHJ1Y3Rvci4gU2hvdWxkIG1hdGNoIFRlbnNvci5EYXRhVHlwZU1hcC5cbmV4cG9ydCBjb25zdCBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQID0gbmV3IE1hcDxzdHJpbmcsIFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnM+KFtcbiAgWydmbG9hdDMyJywgRmxvYXQzMkFycmF5XSxcbiAgWyd1aW50OCcsIFVpbnQ4QXJyYXldLFxuICBbJ2ludDgnLCBJbnQ4QXJyYXldLFxuICBbJ3VpbnQxNicsIFVpbnQxNkFycmF5XSxcbiAgWydpbnQxNicsIEludDE2QXJyYXldLFxuICBbJ2ludDMyJywgSW50MzJBcnJheV0sXG4gIFsnYm9vbCcsIFVpbnQ4QXJyYXldLFxuICBbJ2Zsb2F0NjQnLCBGbG9hdDY0QXJyYXldLFxuICBbJ3VpbnQzMicsIFVpbnQzMkFycmF5XSxcbiAgWydpbnQ0JywgVWludDhBcnJheV0sXG4gIFsndWludDQnLCBVaW50OEFycmF5XSxcbl0pO1xuXG4vLyBhIHJ1bnRpbWUgbWFwIHRoYXQgbWFwcyB0eXBlIHN0cmluZyB0byBUeXBlZEFycmF5IGNvbnN0cnVjdG9yLiBTaG91bGQgbWF0Y2ggVGVuc29yLkRhdGFUeXBlTWFwLlxuZXhwb3J0IGNvbnN0IE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAgPSBuZXcgTWFwPFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnMsIFRlbnNvci5UeXBlPihbXG4gIFtGbG9hdDMyQXJyYXksICdmbG9hdDMyJ10sXG4gIFtVaW50OEFycmF5LCAndWludDgnXSxcbiAgW0ludDhBcnJheSwgJ2ludDgnXSxcbiAgW1VpbnQxNkFycmF5LCAndWludDE2J10sXG4gIFtJbnQxNkFycmF5LCAnaW50MTYnXSxcbiAgW0ludDMyQXJyYXksICdpbnQzMiddLFxuICBbRmxvYXQ2NEFycmF5LCAnZmxvYXQ2NCddLFxuICBbVWludDMyQXJyYXksICd1aW50MzInXSxcbl0pO1xuXG4vLyB0aGUgZm9sbG93aW5nIGNvZGUgYWxsb3dzIGRlbGF5aW5nIGV4ZWN1dGlvbiBvZiBCaWdJbnQvRmxvYXQxNkFycmF5IGNoZWNraW5nLiBUaGlzIGFsbG93cyBsYXp5IGluaXRpYWxpemF0aW9uIGZvclxuLy8gTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUCBhbmQgTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUCwgd2hpY2ggYWxsb3dzIEJpZ0ludC9GbG9hdDE2QXJyYXlcbi8vIHBvbHlmaWxsIGlmIGF2YWlsYWJsZS5cbmxldCBpc1R5cGVkQXJyYXlDaGVja2VkID0gZmFsc2U7XG5leHBvcnQgY29uc3QgY2hlY2tUeXBlZEFycmF5ID0gKCkgPT4ge1xuICBpZiAoIWlzVHlwZWRBcnJheUNoZWNrZWQpIHtcbiAgICBpc1R5cGVkQXJyYXlDaGVja2VkID0gdHJ1ZTtcbiAgICBjb25zdCBpc0JpZ0ludDY0QXJyYXlBdmFpbGFibGUgPSB0eXBlb2YgQmlnSW50NjRBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiYgQmlnSW50NjRBcnJheS5mcm9tO1xuICAgIGNvbnN0IGlzQmlnVWludDY0QXJyYXlBdmFpbGFibGUgPSB0eXBlb2YgQmlnVWludDY0QXJyYXkgIT09ICd1bmRlZmluZWQnICYmIEJpZ1VpbnQ2NEFycmF5LmZyb207XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgRmxvYXQxNkFycmF5ID0gKGdsb2JhbFRoaXMgYXMgYW55KS5GbG9hdDE2QXJyYXk7XG4gICAgY29uc3QgaXNGbG9hdDE2QXJyYXlBdmFpbGFibGUgPSB0eXBlb2YgRmxvYXQxNkFycmF5ICE9PSAndW5kZWZpbmVkJyAmJiBGbG9hdDE2QXJyYXkuZnJvbTtcblxuICAgIGlmIChpc0JpZ0ludDY0QXJyYXlBdmFpbGFibGUpIHtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAuc2V0KCdpbnQ2NCcsIEJpZ0ludDY0QXJyYXkpO1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUC5zZXQoQmlnSW50NjRBcnJheSwgJ2ludDY0Jyk7XG4gICAgfVxuICAgIGlmIChpc0JpZ1VpbnQ2NEFycmF5QXZhaWxhYmxlKSB7XG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLnNldCgndWludDY0JywgQmlnVWludDY0QXJyYXkpO1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUC5zZXQoQmlnVWludDY0QXJyYXksICd1aW50NjQnKTtcbiAgICB9XG4gICAgaWYgKGlzRmxvYXQxNkFycmF5QXZhaWxhYmxlKSB7XG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLnNldCgnZmxvYXQxNicsIEZsb2F0MTZBcnJheSk7XG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLnNldChGbG9hdDE2QXJyYXksICdmbG9hdDE2Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGlmIEZsb2F0MTZBcnJheSBpcyBub3QgYXZhaWxhYmxlLCB1c2UgJ1VpbnQxNkFycmF5JyB0byBzdG9yZSB0aGUgZGF0YS5cbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAuc2V0KCdmbG9hdDE2JywgVWludDE2QXJyYXkpO1xuICAgIH1cbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtcbiAgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG4gIE1MVGVuc29yQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxufSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLWltcGwuanMnO1xuXG4vKipcbiAqIGNhbGN1bGF0ZSBzaXplIGZyb20gZGltcy5cbiAqXG4gKiBAcGFyYW0gZGltcyB0aGUgZGltcyBhcnJheS4gTWF5IGJlIGFuIGlsbGVnYWwgaW5wdXQuXG4gKi9cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVTaXplID0gKGRpbXM6IHJlYWRvbmx5IHVua25vd25bXSk6IG51bWJlciA9PiB7XG4gIGxldCBzaXplID0gMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgZGltID0gZGltc1tpXTtcbiAgICBpZiAodHlwZW9mIGRpbSAhPT0gJ251bWJlcicgfHwgIU51bWJlci5pc1NhZmVJbnRlZ2VyKGRpbSkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGRpbXNbJHtpfV0gbXVzdCBiZSBhbiBpbnRlZ2VyLCBnb3Q6ICR7ZGltfWApO1xuICAgIH1cbiAgICBpZiAoZGltIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYGRpbXNbJHtpfV0gbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLCBnb3Q6ICR7ZGltfWApO1xuICAgIH1cbiAgICBzaXplICo9IGRpbTtcbiAgfVxuICByZXR1cm4gc2l6ZTtcbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLnJlc2hhcGUoKVxuICovXG5leHBvcnQgY29uc3QgdGVuc29yUmVzaGFwZSA9ICh0ZW5zb3I6IFRlbnNvciwgZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3IgPT4ge1xuICBzd2l0Y2ggKHRlbnNvci5sb2NhdGlvbikge1xuICAgIGNhc2UgJ2NwdSc6XG4gICAgICByZXR1cm4gbmV3IFRlbnNvcih0ZW5zb3IudHlwZSwgdGVuc29yLmRhdGEsIGRpbXMpO1xuICAgIGNhc2UgJ2NwdS1waW5uZWQnOlxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3Ioe1xuICAgICAgICBsb2NhdGlvbjogJ2NwdS1waW5uZWQnLFxuICAgICAgICBkYXRhOiB0ZW5zb3IuZGF0YSBhcyBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnNbJ2RhdGEnXSxcbiAgICAgICAgdHlwZTogdGVuc29yLnR5cGUgYXMgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzWyd0eXBlJ10sXG4gICAgICAgIGRpbXMsXG4gICAgICB9KTtcbiAgICBjYXNlICd0ZXh0dXJlJzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHtcbiAgICAgICAgbG9jYXRpb246ICd0ZXh0dXJlJyxcbiAgICAgICAgdGV4dHVyZTogdGVuc29yLnRleHR1cmUsXG4gICAgICAgIHR5cGU6IHRlbnNvci50eXBlIGFzIFRleHR1cmVDb25zdHJ1Y3RvclBhcmFtZXRlcnNbJ3R5cGUnXSxcbiAgICAgICAgZGltcyxcbiAgICAgIH0pO1xuICAgIGNhc2UgJ2dwdS1idWZmZXInOlxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3Ioe1xuICAgICAgICBsb2NhdGlvbjogJ2dwdS1idWZmZXInLFxuICAgICAgICBncHVCdWZmZXI6IHRlbnNvci5ncHVCdWZmZXIsXG4gICAgICAgIHR5cGU6IHRlbnNvci50eXBlIGFzIEdwdUJ1ZmZlckNvbnN0cnVjdG9yUGFyYW1ldGVyc1sndHlwZSddLFxuICAgICAgICBkaW1zLFxuICAgICAgfSk7XG4gICAgY2FzZSAnbWwtdGVuc29yJzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHtcbiAgICAgICAgbG9jYXRpb246ICdtbC10ZW5zb3InLFxuICAgICAgICBtbFRlbnNvcjogdGVuc29yLm1sVGVuc29yLFxuICAgICAgICB0eXBlOiB0ZW5zb3IudHlwZSBhcyBNTFRlbnNvckNvbnN0cnVjdG9yUGFyYW1ldGVyc1sndHlwZSddLFxuICAgICAgICBkaW1zLFxuICAgICAgfSk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdGVuc29yUmVzaGFwZTogdGVuc29yIGxvY2F0aW9uICR7dGVuc29yLmxvY2F0aW9ufSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IHRlbnNvclRvRGF0YVVSTCwgdGVuc29yVG9JbWFnZURhdGEgfSBmcm9tICcuL3RlbnNvci1jb252ZXJzaW9uLWltcGwuanMnO1xuaW1wb3J0IHsgVGVuc29yVG9EYXRhVXJsT3B0aW9ucywgVGVuc29yVG9JbWFnZURhdGFPcHRpb25zIH0gZnJvbSAnLi90ZW5zb3ItY29udmVyc2lvbi5qcyc7XG5pbXBvcnQge1xuICB0ZW5zb3JGcm9tR3B1QnVmZmVyLFxuICB0ZW5zb3JGcm9tSW1hZ2UsXG4gIHRlbnNvckZyb21NTFRlbnNvcixcbiAgdGVuc29yRnJvbVBpbm5lZEJ1ZmZlcixcbiAgdGVuc29yRnJvbVRleHR1cmUsXG59IGZyb20gJy4vdGVuc29yLWZhY3RvcnktaW1wbC5qcyc7XG5pbXBvcnQge1xuICBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG4gIEdwdUJ1ZmZlckNvbnN0cnVjdG9yUGFyYW1ldGVycyxcbiAgTUxUZW5zb3JDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG4gIFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zLFxuICBUZW5zb3JGcm9tSW1hZ2VCaXRtYXBPcHRpb25zLFxuICBUZW5zb3JGcm9tSW1hZ2VEYXRhT3B0aW9ucyxcbiAgVGVuc29yRnJvbUltYWdlRWxlbWVudE9wdGlvbnMsXG4gIFRlbnNvckZyb21NTFRlbnNvck9wdGlvbnMsXG4gIFRlbnNvckZyb21UZXh0dXJlT3B0aW9ucyxcbiAgVGVuc29yRnJvbVVybE9wdGlvbnMsXG4gIFRleHR1cmVDb25zdHJ1Y3RvclBhcmFtZXRlcnMsXG59IGZyb20gJy4vdGVuc29yLWZhY3RvcnkuanMnO1xuaW1wb3J0IHtcbiAgY2hlY2tUeXBlZEFycmF5LFxuICBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLFxuICBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLFxuICBTdXBwb3J0ZWRUeXBlZEFycmF5LFxuICBTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzLFxufSBmcm9tICcuL3RlbnNvci1pbXBsLXR5cGUtbWFwcGluZy5qcyc7XG5pbXBvcnQgeyBjYWxjdWxhdGVTaXplLCB0ZW5zb3JSZXNoYXBlIH0gZnJvbSAnLi90ZW5zb3ItdXRpbHMtaW1wbC5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgYXMgVGVuc29ySW50ZXJmYWNlIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuXG4vLyB0eXBlIGFsaWFzZXMgZm9yIHRob3NlIGV4cG9ydGVkIGZyb20gVGVuc29yIGludGVyZmFjZVxuXG50eXBlIFRlbnNvclR5cGUgPSBUZW5zb3JJbnRlcmZhY2UuVHlwZTtcbnR5cGUgVGVuc29yRGF0YVR5cGUgPSBUZW5zb3JJbnRlcmZhY2UuRGF0YVR5cGU7XG50eXBlIFRlbnNvckRhdGFMb2NhdGlvbiA9IFRlbnNvckludGVyZmFjZS5EYXRhTG9jYXRpb247XG50eXBlIFRlbnNvclRleHR1cmVUeXBlID0gVGVuc29ySW50ZXJmYWNlLlRleHR1cmVUeXBlO1xudHlwZSBUZW5zb3JHcHVCdWZmZXJUeXBlID0gVGVuc29ySW50ZXJmYWNlLkdwdUJ1ZmZlclR5cGU7XG50eXBlIFRlbnNvck1MVGVuc29yVHlwZSA9IFRlbnNvckludGVyZmFjZS5NTFRlbnNvclR5cGU7XG5cbi8qKlxuICogdGhlIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvciBpbnRlcmZhY2UuXG4gKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY2xhc3MgVGVuc29yIGltcGxlbWVudHMgVGVuc29ySW50ZXJmYWNlIHtcbiAgLy8gI3JlZ2lvbiBjb25zdHJ1Y3RvcnNcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IENQVSB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICB0eXBlOiBUZW5zb3JUeXBlLFxuICAgIGRhdGE6IFRlbnNvckRhdGFUeXBlIHwgVWludDhDbGFtcGVkQXJyYXkgfCByZWFkb25seSBzdHJpbmdbXSB8IHJlYWRvbmx5IG51bWJlcltdIHwgcmVhZG9ubHkgYm9vbGVhbltdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBDUFUgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLiBUeXBlIGlzIGluZmVycmVkIGZyb20gZGF0YS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIGRhdGE6IFRlbnNvckRhdGFUeXBlIHwgVWludDhDbGFtcGVkQXJyYXkgfCByZWFkb25seSBzdHJpbmdbXSB8IHJlYWRvbmx5IGJvb2xlYW5bXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBwaW5uZWQgQ1BVIGRhdGEgd2l0aCB0aGUgZ2l2ZW4gdHlwZSBhbmQgZGltcy5cbiAgICpcbiAgICogVGVuc29yJ3MgbG9jYXRpb24gd2lsbCBiZSBzZXQgdG8gJ2NwdS1waW5uZWQnLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gU3BlY2lmeSB0aGUgcGFyYW1ldGVycyB0byBjb25zdHJ1Y3QgdGhlIHRlbnNvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHBhcmFtczogQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzKTtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIFdlYkdMIHRleHR1cmUgd2l0aCB0aGUgZ2l2ZW4gdHlwZSBhbmQgZGltcy5cbiAgICpcbiAgICogVGVuc29yJ3MgbG9jYXRpb24gd2lsbCBiZSBzZXQgdG8gJ3RleHR1cmUnLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gU3BlY2lmeSB0aGUgcGFyYW1ldGVycyB0byBjb25zdHJ1Y3QgdGhlIHRlbnNvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHBhcmFtczogVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVycyk7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBXZWJHUFUgYnVmZmVyIHdpdGggdGhlIGdpdmVuIHR5cGUgYW5kIGRpbXMuXG4gICAqXG4gICAqIFRlbnNvcidzIGxvY2F0aW9uIHdpbGwgYmUgc2V0IHRvICdncHUtYnVmZmVyJy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFNwZWNpZnkgdGhlIHBhcmFtZXRlcnMgdG8gY29uc3RydWN0IHRoZSB0ZW5zb3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwYXJhbXM6IEdwdUJ1ZmZlckNvbnN0cnVjdG9yUGFyYW1ldGVycyk7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIFdlYk5OIE1MVGVuc29yIHdpdGggdGhlIGdpdmVuIHR5cGUgYW5kIGRpbXMuXG4gICAqXG4gICAqIFRlbnNvcidzIGxvY2F0aW9uIHdpbGwgYmUgc2V0IHRvICdtbC10ZW5zb3InLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gU3BlY2lmeSB0aGUgcGFyYW1ldGVycyB0byBjb25zdHJ1Y3QgdGhlIHRlbnNvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHBhcmFtczogTUxUZW5zb3JDb25zdHJ1Y3RvclBhcmFtZXRlcnMpO1xuXG4gIC8qKlxuICAgKiBpbXBsZW1lbnRhdGlvbi5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIGFyZzA6XG4gICAgICB8IFRlbnNvclR5cGVcbiAgICAgIHwgVGVuc29yRGF0YVR5cGVcbiAgICAgIHwgVWludDhDbGFtcGVkQXJyYXlcbiAgICAgIHwgcmVhZG9ubHkgc3RyaW5nW11cbiAgICAgIHwgcmVhZG9ubHkgYm9vbGVhbltdXG4gICAgICB8IENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVyc1xuICAgICAgfCBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzXG4gICAgICB8IEdwdUJ1ZmZlckNvbnN0cnVjdG9yUGFyYW1ldGVyc1xuICAgICAgfCBNTFRlbnNvckNvbnN0cnVjdG9yUGFyYW1ldGVycyxcbiAgICBhcmcxPzogVGVuc29yRGF0YVR5cGUgfCBVaW50OENsYW1wZWRBcnJheSB8IHJlYWRvbmx5IG51bWJlcltdIHwgcmVhZG9ubHkgc3RyaW5nW10gfCByZWFkb25seSBib29sZWFuW10sXG4gICAgYXJnMj86IHJlYWRvbmx5IG51bWJlcltdLFxuICApIHtcbiAgICAvLyBwZXJmb3JtIG9uZS10aW1lIGNoZWNrIGZvciBCaWdJbnQvRmxvYXQxNkFycmF5IHN1cHBvcnRcbiAgICBjaGVja1R5cGVkQXJyYXkoKTtcblxuICAgIGxldCB0eXBlOiBUZW5zb3JUeXBlO1xuICAgIGxldCBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcblxuICAgIGlmICh0eXBlb2YgYXJnMCA9PT0gJ29iamVjdCcgJiYgJ2xvY2F0aW9uJyBpbiBhcmcwKSB7XG4gICAgICAvL1xuICAgICAgLy8gY29uc3RydWN0aW5nIHRlbnNvciBmcm9tIHNwZWNpZmljIGxvY2F0aW9uXG4gICAgICAvL1xuICAgICAgdGhpcy5kYXRhTG9jYXRpb24gPSBhcmcwLmxvY2F0aW9uO1xuICAgICAgdHlwZSA9IGFyZzAudHlwZTtcbiAgICAgIGRpbXMgPSBhcmcwLmRpbXM7XG4gICAgICBzd2l0Y2ggKGFyZzAubG9jYXRpb24pIHtcbiAgICAgICAgY2FzZSAnY3B1LXBpbm5lZCc6IHtcbiAgICAgICAgICBjb25zdCBleHBlY3RlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvciA9IE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAuZ2V0KHR5cGUpO1xuICAgICAgICAgIGlmICghZXhwZWN0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYHVuc3VwcG9ydGVkIHR5cGUgXCIke3R5cGV9XCIgdG8gY3JlYXRlIHRlbnNvciBmcm9tIHBpbm5lZCBidWZmZXJgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCEoYXJnMC5kYXRhIGluc3RhbmNlb2YgZXhwZWN0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3IpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBidWZmZXIgc2hvdWxkIGJlIG9mIHR5cGUgJHtleHBlY3RlZFR5cGVkQXJyYXlDb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmNwdURhdGEgPSBhcmcwLmRhdGE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAndGV4dHVyZSc6IHtcbiAgICAgICAgICBpZiAodHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlIFwiJHt0eXBlfVwiIHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbSB0ZXh0dXJlYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuZ3B1VGV4dHVyZURhdGEgPSBhcmcwLnRleHR1cmU7XG4gICAgICAgICAgdGhpcy5kb3dubG9hZGVyID0gYXJnMC5kb3dubG9hZDtcbiAgICAgICAgICB0aGlzLmRpc3Bvc2VyID0gYXJnMC5kaXNwb3NlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2dwdS1idWZmZXInOiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdHlwZSAhPT0gJ2Zsb2F0MzInICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnZmxvYXQxNicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdpbnQzMicgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdpbnQ2NCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICd1aW50MzInICYmXG4gICAgICAgICAgICB0eXBlICE9PSAndWludDgnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnYm9vbCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICd1aW50NCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdpbnQ0J1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZSBcIiR7dHlwZX1cIiB0byBjcmVhdGUgdGVuc29yIGZyb20gZ3B1IGJ1ZmZlcmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmdwdUJ1ZmZlckRhdGEgPSBhcmcwLmdwdUJ1ZmZlcjtcbiAgICAgICAgICB0aGlzLmRvd25sb2FkZXIgPSBhcmcwLmRvd25sb2FkO1xuICAgICAgICAgIHRoaXMuZGlzcG9zZXIgPSBhcmcwLmRpc3Bvc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnbWwtdGVuc29yJzoge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGUgIT09ICdmbG9hdDMyJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2Zsb2F0MTYnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50MzInICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50NjQnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAndWludDMyJyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQ2NCcgJiZcbiAgICAgICAgICAgIHR5cGUgIT09ICdpbnQ4JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ3VpbnQ4JyAmJlxuICAgICAgICAgICAgdHlwZSAhPT0gJ2Jvb2wnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAndWludDQnICYmXG4gICAgICAgICAgICB0eXBlICE9PSAnaW50NCdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYHVuc3VwcG9ydGVkIHR5cGUgXCIke3R5cGV9XCIgdG8gY3JlYXRlIHRlbnNvciBmcm9tIE1MVGVuc29yYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubWxUZW5zb3JEYXRhID0gYXJnMC5tbFRlbnNvcjtcbiAgICAgICAgICB0aGlzLmRvd25sb2FkZXIgPSBhcmcwLmRvd25sb2FkO1xuICAgICAgICAgIHRoaXMuZGlzcG9zZXIgPSBhcmcwLmRpc3Bvc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbnNvciBjb25zdHJ1Y3RvcjogdW5zdXBwb3J0ZWQgbG9jYXRpb24gJyR7dGhpcy5kYXRhTG9jYXRpb259J2ApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvL1xuICAgICAgLy8gY29uc3RydWN0aW5nIHRlbnNvciBvZiBsb2NhdGlvbiAnY3B1J1xuICAgICAgLy9cbiAgICAgIGxldCBkYXRhOiBUZW5zb3JEYXRhVHlwZTtcbiAgICAgIGxldCBtYXliZURpbXM6IHR5cGVvZiBhcmcxIHwgdHlwZW9mIGFyZzI7XG4gICAgICAvLyBjaGVjayB3aGV0aGVyIGFyZzAgaXMgdHlwZSBvciBkYXRhXG4gICAgICBpZiAodHlwZW9mIGFyZzAgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIC8vXG4gICAgICAgIC8vIE92ZXJyaWRlOiBjb25zdHJ1Y3Rvcih0eXBlLCBkYXRhLCAuLi4pXG4gICAgICAgIC8vXG4gICAgICAgIHR5cGUgPSBhcmcwO1xuICAgICAgICBtYXliZURpbXMgPSBhcmcyO1xuICAgICAgICBpZiAoYXJnMCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAvLyBzdHJpbmcgdGVuc29yXG4gICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFyZzEpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQSBzdHJpbmcgdGVuc29yJ3MgZGF0YSBtdXN0IGJlIGEgc3RyaW5nIGFycmF5LlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gd2UgZG9uJ3QgY2hlY2sgd2hldGhlciBldmVyeSBlbGVtZW50IGluIHRoZSBhcnJheSBpcyBzdHJpbmc7IHRoaXMgaXMgdG9vIHNsb3cuIHdlIGFzc3VtZSBpdCdzIGNvcnJlY3QgYW5kXG4gICAgICAgICAgLy8gZXJyb3Igd2lsbCBiZSBwb3B1bGF0ZWQgYXQgaW5mZXJlbmNlXG4gICAgICAgICAgZGF0YSA9IGFyZzE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gbnVtZXJpYyB0ZW5zb3JcbiAgICAgICAgICBjb25zdCB0eXBlZEFycmF5Q29uc3RydWN0b3IgPSBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLmdldChhcmcwKTtcbiAgICAgICAgICBpZiAodHlwZWRBcnJheUNvbnN0cnVjdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFVuc3VwcG9ydGVkIHRlbnNvciB0eXBlOiAke2FyZzB9LmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcxKSkge1xuICAgICAgICAgICAgaWYgKChhcmcwID09PSAnZmxvYXQxNicgJiYgdHlwZWRBcnJheUNvbnN0cnVjdG9yID09PSBVaW50MTZBcnJheSkgfHwgYXJnMCA9PT0gJ3VpbnQ0JyB8fCBhcmcwID09PSAnaW50NCcpIHtcbiAgICAgICAgICAgICAgLy8gLSAnZmxvYXQxNic6XG4gICAgICAgICAgICAgIC8vICAgV2hlbiBubyBGbG9hdDE2QXJyYXkgcG9seWZpbGwgaXMgdXNlZCwgd2UgY2Fubm90IGNyZWF0ZSAnZmxvYXQxNicgdGVuc29yIGZyb20gbnVtYmVyIGFycmF5LlxuICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAvLyAgIFRocm93IGVycm9yIGhlcmUgYmVjYXVzZSB3aGVuIHVzZXIgdHJ5IHRvIHVzZSBudW1iZXIgYXJyYXkgYXMgZGF0YSxcbiAgICAgICAgICAgICAgLy8gICBlLmcuIG5ldyBUZW5zb3IoJ2Zsb2F0MTYnLCBbMSwgMiwgMywgNF0sIGRpbXMpKSwgaXQgd2lsbCBhY3R1YWxseSBjYWxsXG4gICAgICAgICAgICAgIC8vICAgVWludDE2QXJyYXkuZnJvbShhcmcxKSB3aGljaCBnZW5lcmF0ZXMgd3JvbmcgZGF0YS5cbiAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgLy8gLSAndWludDQnIGFuZCAnaW50NCc6XG4gICAgICAgICAgICAgIC8vICAgVWludDhBcnJheS5mcm9tKGFyZzEpIHdpbGwgZ2VuZXJhdGUgd3JvbmcgZGF0YSBmb3IgJ3VpbnQ0JyBhbmQgJ2ludDQnIHRlbnNvci5cbiAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgICAgICBgQ3JlYXRpbmcgYSAke2FyZzB9IHRlbnNvciBmcm9tIG51bWJlciBhcnJheSBpcyBub3Qgc3VwcG9ydGVkLiBQbGVhc2UgdXNlICR7dHlwZWRBcnJheUNvbnN0cnVjdG9yLm5hbWV9IGFzIGRhdGEuYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnMCA9PT0gJ3VpbnQ2NCcgfHwgYXJnMCA9PT0gJ2ludDY0Jykge1xuICAgICAgICAgICAgICAvLyB1c2UgJ2FzIGFueScgaGVyZSBiZWNhdXNlOlxuICAgICAgICAgICAgICAvLyAxLiBUeXBlU2NyaXB0J3MgY2hlY2sgb24gdHlwZSBvZiAnQXJyYXkuaXNBcnJheSgpJyBkb2VzIG5vdCB3b3JrIHdpdGggcmVhZG9ubHkgYXJyYXlzLlxuICAgICAgICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy8xNzAwMlxuICAgICAgICAgICAgICAvLyAyLiBUeXBlU2NyaXB0J3MgY2hlY2sgb24gdW5pb24gdHlwZSBvZiAnKEJpZ0ludDY0QXJyYXlDb25zdHJ1Y3RvcnxCaWdVaW50NjRBcnJheUNvbnN0cnVjdG9yKS5mcm9tKCknXG4gICAgICAgICAgICAgIC8vIGRvZXMgbm90IGFjY2VwdCBwYXJhbWV0ZXIgbWFwRm4uXG4gICAgICAgICAgICAgIC8vIDMuIHBhcmFtZXRlcnMgb2YgJ1N1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnMuZnJvbSgpJyBkb2VzIG5vdCBtYXRjaCB0aGUgcmVxdWlyZW1lbnQgb2YgdGhlIHVuaW9uXG4gICAgICAgICAgICAgIC8vIHR5cGUuXG5cbiAgICAgICAgICAgICAgLy8gYXNzdW1lICdhcmcxJyBpcyBvZiB0eXBlIFwicmVhZG9ubHkgbnVtYmVyW118cmVhZG9ubHkgYmlnaW50W11cIiBoZXJlLlxuXG4gICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICAgIGRhdGEgPSAodHlwZWRBcnJheUNvbnN0cnVjdG9yIGFzIGFueSkuZnJvbShhcmcxLCBCaWdJbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gYXNzdW1lICdhcmcxJyBpcyBvZiB0eXBlIFwicmVhZG9ubHkgbnVtYmVyW11cIiBoZXJlLlxuICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgICBkYXRhID0gKHR5cGVkQXJyYXlDb25zdHJ1Y3RvciBhcyBhbnkpLmZyb20oYXJnMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChhcmcxIGluc3RhbmNlb2YgdHlwZWRBcnJheUNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICBkYXRhID0gYXJnMTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGFyZzEgaW5zdGFuY2VvZiBVaW50OENsYW1wZWRBcnJheSkge1xuICAgICAgICAgICAgaWYgKGFyZzAgPT09ICd1aW50OCcpIHtcbiAgICAgICAgICAgICAgZGF0YSA9IFVpbnQ4QXJyYXkuZnJvbShhcmcxKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEEgVWludDhDbGFtcGVkQXJyYXkgdGVuc29yJ3MgZGF0YSBtdXN0IGJlIHR5cGUgb2YgdWludDhgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGFyZzAgPT09ICdmbG9hdDE2JyAmJiBhcmcxIGluc3RhbmNlb2YgVWludDE2QXJyYXkgJiYgdHlwZWRBcnJheUNvbnN0cnVjdG9yICE9PSBVaW50MTZBcnJheSkge1xuICAgICAgICAgICAgLy8gd2hlbiBGbG9hdDE2QXJyYXkgaXMgYXZhaWxhYmxlIGFuZCBkYXRhIGlzIG9mIHR5cGUgVWludDE2QXJyYXkuXG4gICAgICAgICAgICAvLyBXZSBhbGxvdyBVaW50MTZBcnJheSB0byBiZSBwYXNzZWQgaW4gYXMgZGF0YSBmb3IgJ2Zsb2F0MTYnIHRlbnNvciB1bnRpbCBGbG9hdDE2QXJyYXkgaXMgZ2VuZXJhbGx5XG4gICAgICAgICAgICAvLyBzdXBwb3J0ZWQgaW4gSmF2YVNjcmlwdCBlbnZpcm9ubWVudC5cblxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgIGRhdGEgPSBuZXcgKGdsb2JhbFRoaXMgYXMgYW55KS5GbG9hdDE2QXJyYXkoYXJnMS5idWZmZXIsIGFyZzEuYnl0ZU9mZnNldCwgYXJnMS5sZW5ndGgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBBICR7dHlwZX0gdGVuc29yJ3MgZGF0YSBtdXN0IGJlIHR5cGUgb2YgJHt0eXBlZEFycmF5Q29uc3RydWN0b3J9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvL1xuICAgICAgICAvLyBPdmVycmlkZTogY29uc3RydWN0b3IoZGF0YSwgLi4uKVxuICAgICAgICAvL1xuICAgICAgICBtYXliZURpbXMgPSBhcmcxO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcwKSkge1xuICAgICAgICAgIC8vIG9ubHkgYm9vbGVhbltdIGFuZCBzdHJpbmdbXSBpcyBzdXBwb3J0ZWRcbiAgICAgICAgICBpZiAoYXJnMC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RlbnNvciB0eXBlIGNhbm5vdCBiZSBpbmZlcnJlZCBmcm9tIGFuIGVtcHR5IGFycmF5LicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBmaXJzdEVsZW1lbnRUeXBlID0gdHlwZW9mIGFyZzBbMF07XG4gICAgICAgICAgaWYgKGZpcnN0RWxlbWVudFR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0eXBlID0gJ3N0cmluZyc7XG4gICAgICAgICAgICBkYXRhID0gYXJnMDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGZpcnN0RWxlbWVudFR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgdHlwZSA9ICdib29sJztcbiAgICAgICAgICAgIC8vICdhcmcwJyBpcyBvZiB0eXBlICdib29sZWFuW10nLiBVaW50OEFycmF5LmZyb20oYm9vbGVhbltdKSBhY3R1YWxseSB3b3JrcywgYnV0IHR5cGVzY3JpcHQgdGhpbmtzIHRoaXMgaXNcbiAgICAgICAgICAgIC8vIHdyb25nIHR5cGUuIFdlIHVzZSAnYXMgYW55JyB0byBtYWtlIGl0IGhhcHB5LlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgIGRhdGEgPSBVaW50OEFycmF5LmZyb20oYXJnMCBhcyBhbnlbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgZWxlbWVudCB0eXBlIG9mIGRhdGEgYXJyYXk6ICR7Zmlyc3RFbGVtZW50VHlwZX0uYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGFyZzAgaW5zdGFuY2VvZiBVaW50OENsYW1wZWRBcnJheSkge1xuICAgICAgICAgIHR5cGUgPSAndWludDgnO1xuICAgICAgICAgIGRhdGEgPSBVaW50OEFycmF5LmZyb20oYXJnMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZ2V0IHRlbnNvciB0eXBlIGZyb20gVHlwZWRBcnJheVxuICAgICAgICAgIGNvbnN0IG1hcHBlZFR5cGUgPSBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLmdldChcbiAgICAgICAgICAgIGFyZzAuY29uc3RydWN0b3IgYXMgU3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycyxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChtYXBwZWRUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFVuc3VwcG9ydGVkIHR5cGUgZm9yIHRlbnNvciBkYXRhOiAke2FyZzAuY29uc3RydWN0b3J9LmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0eXBlID0gbWFwcGVkVHlwZTtcbiAgICAgICAgICBkYXRhID0gYXJnMCBhcyBTdXBwb3J0ZWRUeXBlZEFycmF5O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHR5cGUgYW5kIGRhdGEgaXMgcHJvY2Vzc2VkLCBub3cgcHJvY2Vzc2luZyBkaW1zXG4gICAgICBpZiAobWF5YmVEaW1zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gYXNzdW1lIDEtRCB0ZW5zb3IgaWYgZGltcyBvbWl0dGVkXG4gICAgICAgIG1heWJlRGltcyA9IFtkYXRhLmxlbmd0aF07XG4gICAgICB9IGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KG1heWJlRGltcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkEgdGVuc29yJ3MgZGltcyBtdXN0IGJlIGEgbnVtYmVyIGFycmF5XCIpO1xuICAgICAgfVxuICAgICAgZGltcyA9IG1heWJlRGltcyBhcyByZWFkb25seSBudW1iZXJbXTtcblxuICAgICAgdGhpcy5jcHVEYXRhID0gZGF0YTtcbiAgICAgIHRoaXMuZGF0YUxvY2F0aW9uID0gJ2NwdSc7XG4gICAgfVxuXG4gICAgLy8gcGVyZm9ybSBjaGVjayBvbiBkaW1zXG4gICAgY29uc3Qgc2l6ZSA9IGNhbGN1bGF0ZVNpemUoZGltcyk7XG4gICAgLy8gaWYgZGF0YSBpcyBvbiBDUFUsIGNoZWNrIHdoZXRoZXIgZGF0YSBsZW5ndGggbWF0Y2hlcyB0ZW5zb3Igc2l6ZVxuICAgIGlmICh0aGlzLmNwdURhdGEgJiYgc2l6ZSAhPT0gdGhpcy5jcHVEYXRhLmxlbmd0aCkge1xuICAgICAgaWYgKCh0eXBlID09PSAndWludDQnIHx8IHR5cGUgPT09ICdpbnQ0JykgJiYgTWF0aC5jZWlsKHNpemUgLyAyKSA9PT0gdGhpcy5jcHVEYXRhLmxlbmd0aCkge1xuICAgICAgICAvLyBmb3IgKHUpaW50NCwgdGhlIGRhdGEgbGVuZ3RoIGlzIGhhbGYgb2YgdGhlIHRlbnNvciBzaXplLiBTbyB3ZSBjaGVjayB0aGlzIHNwZWNpYWwgY2FzZSB3aGVuIHNpemUgaXMgb2RkLlxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3IncyBzaXplKCR7c2l6ZX0pIGRvZXMgbm90IG1hdGNoIGRhdGEgbGVuZ3RoKCR7dGhpcy5jcHVEYXRhLmxlbmd0aH0pLmApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgdGhpcy5kaW1zID0gZGltcztcbiAgICB0aGlzLnNpemUgPSBzaXplO1xuICB9XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIGZhY3RvcnlcbiAgc3RhdGljIGFzeW5jIGZyb21JbWFnZShcbiAgICBpbWFnZTogSW1hZ2VEYXRhIHwgSFRNTEltYWdlRWxlbWVudCB8IEltYWdlQml0bWFwIHwgc3RyaW5nLFxuICAgIG9wdGlvbnM/OlxuICAgICAgfCBUZW5zb3JGcm9tSW1hZ2VEYXRhT3B0aW9uc1xuICAgICAgfCBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9uc1xuICAgICAgfCBUZW5zb3JGcm9tSW1hZ2VCaXRtYXBPcHRpb25zXG4gICAgICB8IFRlbnNvckZyb21VcmxPcHRpb25zLFxuICApOiBQcm9taXNlPFRlbnNvckludGVyZmFjZT4ge1xuICAgIHJldHVybiB0ZW5zb3JGcm9tSW1hZ2UoaW1hZ2UsIG9wdGlvbnMpO1xuICB9XG5cbiAgc3RhdGljIGZyb21UZXh0dXJlPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuVGV4dHVyZURhdGFUeXBlcz4oXG4gICAgdGV4dHVyZTogVGVuc29yVGV4dHVyZVR5cGUsXG4gICAgb3B0aW9uczogVGVuc29yRnJvbVRleHR1cmVPcHRpb25zPFQ+LFxuICApOiBUZW5zb3JJbnRlcmZhY2Uge1xuICAgIHJldHVybiB0ZW5zb3JGcm9tVGV4dHVyZSh0ZXh0dXJlLCBvcHRpb25zKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tR3B1QnVmZmVyPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuR3B1QnVmZmVyRGF0YVR5cGVzPihcbiAgICBncHVCdWZmZXI6IFRlbnNvckdwdUJ1ZmZlclR5cGUsXG4gICAgb3B0aW9uczogVGVuc29yRnJvbUdwdUJ1ZmZlck9wdGlvbnM8VD4sXG4gICk6IFRlbnNvckludGVyZmFjZSB7XG4gICAgcmV0dXJuIHRlbnNvckZyb21HcHVCdWZmZXIoZ3B1QnVmZmVyLCBvcHRpb25zKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tTUxUZW5zb3I8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5NTFRlbnNvckRhdGFUeXBlcz4oXG4gICAgbWxUZW5zb3I6IFRlbnNvck1MVGVuc29yVHlwZSxcbiAgICBvcHRpb25zOiBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zPFQ+LFxuICApOiBUZW5zb3JJbnRlcmZhY2Uge1xuICAgIHJldHVybiB0ZW5zb3JGcm9tTUxUZW5zb3IobWxUZW5zb3IsIG9wdGlvbnMpO1xuICB9XG5cbiAgc3RhdGljIGZyb21QaW5uZWRCdWZmZXI8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5DcHVQaW5uZWREYXRhVHlwZXM+KFxuICAgIHR5cGU6IFQsXG4gICAgYnVmZmVyOiBUZW5zb3JJbnRlcmZhY2UuRGF0YVR5cGVNYXBbVF0sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUZW5zb3Ige1xuICAgIHJldHVybiB0ZW5zb3JGcm9tUGlubmVkQnVmZmVyKHR5cGUsIGJ1ZmZlciwgZGltcyk7XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBjb252ZXJzaW9uc1xuICB0b0RhdGFVUkwob3B0aW9ucz86IFRlbnNvclRvRGF0YVVybE9wdGlvbnMpOiBzdHJpbmcge1xuICAgIHJldHVybiB0ZW5zb3JUb0RhdGFVUkwodGhpcywgb3B0aW9ucyk7XG4gIH1cblxuICB0b0ltYWdlRGF0YShvcHRpb25zPzogVGVuc29yVG9JbWFnZURhdGFPcHRpb25zKTogSW1hZ2VEYXRhIHtcbiAgICByZXR1cm4gdGVuc29yVG9JbWFnZURhdGEodGhpcywgb3B0aW9ucyk7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHVibGljIGZpZWxkc1xuICByZWFkb25seSBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgdHlwZTogVGVuc29yVHlwZTtcbiAgcmVhZG9ubHkgc2l6ZTogbnVtYmVyO1xuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBwcml2YXRlIGZpZWxkc1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhLlxuICAgKi9cbiAgcHJpdmF0ZSBkYXRhTG9jYXRpb246IFRlbnNvckRhdGFMb2NhdGlvbjtcblxuICAvKipcbiAgICogc3RvcmVzIHRoZSBkYXRhIG9uIENQVSwgaWYgbG9jYXRpb24gaXMgJ2NwdScgb3IgJ2NwdS1waW5uZWQnLiBvdGhlcndpc2UgZW1wdHkuXG4gICAqL1xuICBwcml2YXRlIGNwdURhdGE/OiBUZW5zb3JEYXRhVHlwZTtcblxuICAvKipcbiAgICogc3RvcmVzIHRoZSB1bmRlcmx5aW5nIHRleHR1cmUgd2hlbiBsb2NhdGlvbiBpcyAndGV4dHVyZScuIG90aGVyd2lzZSBlbXB0eS5cbiAgICovXG4gIHByaXZhdGUgZ3B1VGV4dHVyZURhdGE/OiBUZW5zb3JUZXh0dXJlVHlwZTtcblxuICAvKipcbiAgICogc3RvcmVzIHRoZSB1bmRlcmx5aW5nIEdQVSBidWZmZXIgd2hlbiBsb2NhdGlvbiBpcyAnZ3B1LWJ1ZmZlcicuIG90aGVyd2lzZSBlbXB0eS5cbiAgICovXG4gIHByaXZhdGUgZ3B1QnVmZmVyRGF0YT86IFRlbnNvckdwdUJ1ZmZlclR5cGU7XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgdW5kZXJseWluZyBXZWJOTiBNTFRlbnNvciB3aGVuIGxvY2F0aW9uIGlzICdtbC10ZW5zb3InLiBvdGhlcndpc2UgZW1wdHkuXG4gICAqL1xuICBwcml2YXRlIG1sVGVuc29yRGF0YT86IFRlbnNvck1MVGVuc29yVHlwZTtcblxuICAvKipcbiAgICogc3RvcmVzIGFuIG9wdGlvbmFsIGRvd25sb2FkZXIgZnVuY3Rpb24gdG8gZG93bmxvYWQgZGF0YSBmcm9tIEdQVSB0byBDUFUuXG4gICAqL1xuICBwcml2YXRlIGRvd25sb2FkZXI/KCk6IFByb21pc2U8VGVuc29yRGF0YVR5cGU+O1xuXG4gIC8qKlxuICAgKiBhIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBkYXRhIGlzIGJlaW5nIGRvd25sb2FkZWQgZnJvbSBHUFUgdG8gQ1BVLlxuICAgKi9cbiAgcHJpdmF0ZSBpc0Rvd25sb2FkaW5nPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogc3RvcmVzIGFuIG9wdGlvbmFsIGRpc3Bvc2VyIGZ1bmN0aW9uIHRvIGRpc3Bvc2UgdGhlIHVuZGVybHlpbmcgZGF0YS5cbiAgICovXG4gIHByaXZhdGUgZGlzcG9zZXI/KCk6IHZvaWQ7XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHByb3BlcnRpZXNcbiAgZ2V0IGRhdGEoKTogVGVuc29yRGF0YVR5cGUge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBpZiAoIXRoaXMuY3B1RGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnVGhlIGRhdGEgaXMgbm90IG9uIENQVS4gVXNlIGBnZXREYXRhKClgIHRvIGRvd25sb2FkIEdQVSBkYXRhIHRvIENQVSwgJyArXG4gICAgICAgICAgJ29yIHVzZSBgdGV4dHVyZWAgb3IgYGdwdUJ1ZmZlcmAgcHJvcGVydHkgdG8gYWNjZXNzIHRoZSBHUFUgZGF0YSBkaXJlY3RseS4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY3B1RGF0YTtcbiAgfVxuXG4gIGdldCBsb2NhdGlvbigpOiBUZW5zb3JEYXRhTG9jYXRpb24ge1xuICAgIHJldHVybiB0aGlzLmRhdGFMb2NhdGlvbjtcbiAgfVxuXG4gIGdldCB0ZXh0dXJlKCk6IFRlbnNvclRleHR1cmVUeXBlIHtcbiAgICB0aGlzLmVuc3VyZVZhbGlkKCk7XG4gICAgaWYgKCF0aGlzLmdwdVRleHR1cmVEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBkYXRhIGlzIG5vdCBzdG9yZWQgYXMgYSBXZWJHTCB0ZXh0dXJlLicpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5ncHVUZXh0dXJlRGF0YTtcbiAgfVxuXG4gIGdldCBncHVCdWZmZXIoKTogVGVuc29yR3B1QnVmZmVyVHlwZSB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIGlmICghdGhpcy5ncHVCdWZmZXJEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBkYXRhIGlzIG5vdCBzdG9yZWQgYXMgYSBXZWJHUFUgYnVmZmVyLicpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5ncHVCdWZmZXJEYXRhO1xuICB9XG5cbiAgZ2V0IG1sVGVuc29yKCk6IFRlbnNvck1MVGVuc29yVHlwZSB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIGlmICghdGhpcy5tbFRlbnNvckRhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGRhdGEgaXMgbm90IHN0b3JlZCBhcyBhIFdlYk5OIE1MVGVuc29yLicpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5tbFRlbnNvckRhdGE7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gbWV0aG9kc1xuXG4gIGFzeW5jIGdldERhdGEocmVsZWFzZURhdGE/OiBib29sZWFuKTogUHJvbWlzZTxUZW5zb3JEYXRhVHlwZT4ge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBzd2l0Y2ggKHRoaXMuZGF0YUxvY2F0aW9uKSB7XG4gICAgICBjYXNlICdjcHUnOlxuICAgICAgY2FzZSAnY3B1LXBpbm5lZCc6XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGE7XG4gICAgICBjYXNlICd0ZXh0dXJlJzpcbiAgICAgIGNhc2UgJ2dwdS1idWZmZXInOlxuICAgICAgY2FzZSAnbWwtdGVuc29yJzoge1xuICAgICAgICBpZiAoIXRoaXMuZG93bmxvYWRlcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGN1cnJlbnQgdGVuc29yIGlzIG5vdCBjcmVhdGVkIHdpdGggYSBzcGVjaWZpZWQgZGF0YSBkb3dubG9hZGVyLicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzRG93bmxvYWRpbmcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjdXJyZW50IHRlbnNvciBpcyBiZWluZyBkb3dubG9hZGVkLicpO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5pc0Rvd25sb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5kb3dubG9hZGVyKCk7XG4gICAgICAgICAgdGhpcy5kb3dubG9hZGVyID0gdW5kZWZpbmVkO1xuICAgICAgICAgIHRoaXMuZGF0YUxvY2F0aW9uID0gJ2NwdSc7XG4gICAgICAgICAgdGhpcy5jcHVEYXRhID0gZGF0YTtcblxuICAgICAgICAgIGlmIChyZWxlYXNlRGF0YSAmJiB0aGlzLmRpc3Bvc2VyKSB7XG4gICAgICAgICAgICB0aGlzLmRpc3Bvc2VyKCk7XG4gICAgICAgICAgICB0aGlzLmRpc3Bvc2VyID0gdW5kZWZpbmVkO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRoaXMuaXNEb3dubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBnZXQgZGF0YSBmcm9tIGxvY2F0aW9uOiAke3RoaXMuZGF0YUxvY2F0aW9ufWApO1xuICAgIH1cbiAgfVxuXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNEb3dubG9hZGluZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY3VycmVudCB0ZW5zb3IgaXMgYmVpbmcgZG93bmxvYWRlZC4nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5kaXNwb3Nlcikge1xuICAgICAgdGhpcy5kaXNwb3NlcigpO1xuICAgICAgdGhpcy5kaXNwb3NlciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhpcy5jcHVEYXRhID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZ3B1VGV4dHVyZURhdGEgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5ncHVCdWZmZXJEYXRhID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWxUZW5zb3JEYXRhID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZG93bmxvYWRlciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmlzRG93bmxvYWRpbmcgPSB1bmRlZmluZWQ7XG5cbiAgICB0aGlzLmRhdGFMb2NhdGlvbiA9ICdub25lJztcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHRlbnNvciB1dGlsaXRpZXNcbiAgcHJpdmF0ZSBlbnN1cmVWYWxpZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kYXRhTG9jYXRpb24gPT09ICdub25lJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgdGVuc29yIGlzIGRpc3Bvc2VkLicpO1xuICAgIH1cbiAgfVxuXG4gIHJlc2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3JJbnRlcmZhY2Uge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBpZiAodGhpcy5kb3dubG9hZGVyIHx8IHRoaXMuZGlzcG9zZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlc2hhcGUgYSB0ZW5zb3IgdGhhdCBvd25zIEdQVSByZXNvdXJjZS4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRlbnNvclJlc2hhcGUodGhpcywgZGltcyk7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3JGYWN0b3J5IH0gZnJvbSAnLi90ZW5zb3ItZmFjdG9yeS5qcyc7XG5pbXBvcnQgeyBUZW5zb3IgYXMgVGVuc29ySW1wbCB9IGZyb20gJy4vdGVuc29yLWltcGwuanMnO1xuaW1wb3J0IHsgVHlwZWRUZW5zb3JVdGlscyB9IGZyb20gJy4vdGVuc29yLXV0aWxzLmpzJztcbmltcG9ydCB7IFRyeUdldEdsb2JhbFR5cGUgfSBmcm9tICcuL3R5cGUtaGVscGVyLmpzJztcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZSAqL1xuXG4vKipcbiAqIHJlcHJlc2VudCBhIGJhc2ljIHRlbnNvciB3aXRoIHNwZWNpZmllZCBkaW1lbnNpb25zIGFuZCBkYXRhIHR5cGUuXG4gKi9cbmludGVyZmFjZSBUeXBlZFRlbnNvckJhc2U8VCBleHRlbmRzIFRlbnNvci5UeXBlPiB7XG4gIC8qKlxuICAgKiBHZXQgdGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogR2V0IHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU6IFQ7XG4gIC8qKlxuICAgKiBHZXQgdGhlIGJ1ZmZlciBkYXRhIG9mIHRoZSB0ZW5zb3IuXG4gICAqXG4gICAqIElmIHRoZSBkYXRhIGlzIG5vdCBvbiBDUFUgKGVnLiBpdCdzIGluIHRoZSBmb3JtIG9mIFdlYkdMIHRleHR1cmUgb3IgV2ViR1BVIGJ1ZmZlciksIHRocm93IGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RdO1xuICAvKipcbiAgICogR2V0IHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YS5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiBUZW5zb3IuRGF0YUxvY2F0aW9uO1xuICAvKipcbiAgICogR2V0IHRoZSBXZWJHTCB0ZXh0dXJlIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBub3Qgb24gR1BVIGFzIFdlYkdMIHRleHR1cmUsIHRocm93IGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgdGV4dHVyZTogVGVuc29yLlRleHR1cmVUeXBlO1xuICAvKipcbiAgICogR2V0IHRoZSBXZWJHUFUgYnVmZmVyIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBub3Qgb24gR1BVIGFzIFdlYkdQVSBidWZmZXIsIHRocm93IGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgZ3B1QnVmZmVyOiBUZW5zb3IuR3B1QnVmZmVyVHlwZTtcblxuICAvKipcbiAgICogR2V0IHRoZSBXZWJOTiBNTFRlbnNvciB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICpcbiAgICogSWYgdGhlIGRhdGEgaXMgbm90IGluIGEgV2ViTk4gTUxUZW5zb3IsIHRocm93IGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgbWxUZW5zb3I6IFRlbnNvci5NTFRlbnNvclR5cGU7XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYnVmZmVyIGRhdGEgb2YgdGhlIHRlbnNvci5cbiAgICpcbiAgICogSWYgdGhlIGRhdGEgaXMgb24gQ1BVLCByZXR1cm5zIHRoZSBkYXRhIGltbWVkaWF0ZWx5LlxuICAgKiBJZiB0aGUgZGF0YSBpcyBvbiBHUFUsIGRvd25sb2FkcyB0aGUgZGF0YSBhbmQgcmV0dXJucyB0aGUgcHJvbWlzZS5cbiAgICpcbiAgICogQHBhcmFtIHJlbGVhc2VEYXRhIC0gd2hldGhlciByZWxlYXNlIHRoZSBkYXRhIG9uIEdQVS4gSWdub3JlIGlmIGRhdGEgaXMgYWxyZWFkeSBvbiBDUFUuXG4gICAqL1xuICBnZXREYXRhKHJlbGVhc2VEYXRhPzogYm9vbGVhbik6IFByb21pc2U8VGVuc29yLkRhdGFUeXBlTWFwW1RdPjtcblxuICAvKipcbiAgICogRGlzcG9zZSB0aGUgdGVuc29yIGRhdGEuXG4gICAqXG4gICAqIElmIHRoZSBkYXRhIGlzIG9uIENQVSwgcmVtb3ZlIGl0cyBpbnRlcm5hbCByZWZlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgZGF0YS5cbiAgICogSWYgdGhlIGRhdGEgaXMgb24gR1BVLCByZWxlYXNlIHRoZSBkYXRhIG9uIEdQVS5cbiAgICpcbiAgICogQWZ0ZXIgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLCB0aGUgdGVuc29yIGlzIGNvbnNpZGVyZWQgbm8gbG9uZ2VyIHZhbGlkLiBJdHMgbG9jYXRpb24gd2lsbCBiZSBzZXQgdG8gJ25vbmUnLlxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xufVxuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgVGVuc29yIHtcbiAgaW50ZXJmYWNlIERhdGFUeXBlTWFwIHtcbiAgICBmbG9hdDMyOiBGbG9hdDMyQXJyYXk7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgaW50ODogSW50OEFycmF5O1xuICAgIHVpbnQxNjogVWludDE2QXJyYXk7XG4gICAgaW50MTY6IEludDE2QXJyYXk7XG4gICAgaW50MzI6IEludDMyQXJyYXk7XG4gICAgaW50NjQ6IEJpZ0ludDY0QXJyYXk7XG4gICAgc3RyaW5nOiBzdHJpbmdbXTtcbiAgICBib29sOiBVaW50OEFycmF5O1xuICAgIGZsb2F0MTY6IFVpbnQxNkFycmF5OyAvLyBLZWVwIHVzaW5nIFVpbnQxNkFycmF5IHVudGlsIHdlIGhhdmUgYSBjb25jcmV0ZSBzb2x1dGlvbiBmb3IgZmxvYXQgMTYuXG4gICAgZmxvYXQ2NDogRmxvYXQ2NEFycmF5O1xuICAgIHVpbnQzMjogVWludDMyQXJyYXk7XG4gICAgdWludDY0OiBCaWdVaW50NjRBcnJheTtcbiAgICAvLyBjb21wbGV4NjQ6IG5ldmVyO1xuICAgIC8vIGNvbXBsZXgxMjg6IG5ldmVyO1xuICAgIC8vIGJmbG9hdDE2OiBuZXZlcjtcbiAgICB1aW50NDogVWludDhBcnJheTtcbiAgICBpbnQ0OiBJbnQ4QXJyYXk7XG4gIH1cblxuICBpbnRlcmZhY2UgRWxlbWVudFR5cGVNYXAge1xuICAgIGZsb2F0MzI6IG51bWJlcjtcbiAgICB1aW50ODogbnVtYmVyO1xuICAgIGludDg6IG51bWJlcjtcbiAgICB1aW50MTY6IG51bWJlcjtcbiAgICBpbnQxNjogbnVtYmVyO1xuICAgIGludDMyOiBudW1iZXI7XG4gICAgaW50NjQ6IGJpZ2ludDtcbiAgICBzdHJpbmc6IHN0cmluZztcbiAgICBib29sOiBib29sZWFuO1xuICAgIGZsb2F0MTY6IG51bWJlcjsgLy8gS2VlcCB1c2luZyBVaW50MTZBcnJheSB1bnRpbCB3ZSBoYXZlIGEgY29uY3JldGUgc29sdXRpb24gZm9yIGZsb2F0IDE2LlxuICAgIGZsb2F0NjQ6IG51bWJlcjtcbiAgICB1aW50MzI6IG51bWJlcjtcbiAgICB1aW50NjQ6IGJpZ2ludDtcbiAgICAvLyBjb21wbGV4NjQ6IG5ldmVyO1xuICAgIC8vIGNvbXBsZXgxMjg6IG5ldmVyO1xuICAgIC8vIGJmbG9hdDE2OiBuZXZlcjtcbiAgICB1aW50NDogbnVtYmVyO1xuICAgIGludDQ6IG51bWJlcjtcbiAgfVxuXG4gIHR5cGUgRGF0YVR5cGUgPSBEYXRhVHlwZU1hcFtUeXBlXTtcbiAgdHlwZSBFbGVtZW50VHlwZSA9IEVsZW1lbnRUeXBlTWFwW1R5cGVdO1xuXG4gIC8qKlxuICAgKiBzdXBwb3J0ZWQgZGF0YSB0eXBlcyBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBwaW5uZWQgQ1BVIGJ1ZmZlclxuICAgKi9cbiAgZXhwb3J0IHR5cGUgQ3B1UGlubmVkRGF0YVR5cGVzID0gRXhjbHVkZTxUZW5zb3IuVHlwZSwgJ3N0cmluZyc+O1xuXG4gIC8qKlxuICAgKiB0eXBlIGFsaWFzIGZvciBXZWJHTCB0ZXh0dXJlXG4gICAqL1xuICBleHBvcnQgdHlwZSBUZXh0dXJlVHlwZSA9IFdlYkdMVGV4dHVyZTtcblxuICAvKipcbiAgICogc3VwcG9ydGVkIGRhdGEgdHlwZXMgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgV2ViR0wgdGV4dHVyZVxuICAgKi9cbiAgZXhwb3J0IHR5cGUgVGV4dHVyZURhdGFUeXBlcyA9ICdmbG9hdDMyJztcblxuICB0eXBlIEdwdUJ1ZmZlclR5cGVGYWxsYmFjayA9IHsgc2l6ZTogbnVtYmVyOyBtYXBTdGF0ZTogJ3VubWFwcGVkJyB8ICdwZW5kaW5nJyB8ICdtYXBwZWQnIH07XG4gIC8qKlxuICAgKiB0eXBlIGFsaWFzIGZvciBXZWJHUFUgYnVmZmVyXG4gICAqL1xuICBleHBvcnQgdHlwZSBHcHVCdWZmZXJUeXBlID0gVHJ5R2V0R2xvYmFsVHlwZTwnR1BVQnVmZmVyJywgR3B1QnVmZmVyVHlwZUZhbGxiYWNrPjtcblxuICB0eXBlIE1MVGVuc29yVHlwZUZhbGxiYWNrID0geyBkZXN0cm95KCk6IHZvaWQgfTtcbiAgLyoqXG4gICAqIHR5cGUgYWxpYXMgZm9yIFdlYk5OIE1MVGVuc29yXG4gICAqXG4gICAqIFRoZSBzcGVjaWZpY2F0aW9uIGZvciBXZWJOTidzIE1MVGVuc29yIGlzIGN1cnJlbnRseSBpbiBmbHV4LlxuICAgKi9cbiAgZXhwb3J0IHR5cGUgTUxUZW5zb3JUeXBlID0gVHJ5R2V0R2xvYmFsVHlwZTwnTUxUZW5zb3InLCBNTFRlbnNvclR5cGVGYWxsYmFjaz47XG5cbiAgLyoqXG4gICAqIHN1cHBvcnRlZCBkYXRhIHR5cGVzIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIFdlYkdQVSBidWZmZXJcbiAgICovXG4gIGV4cG9ydCB0eXBlIEdwdUJ1ZmZlckRhdGFUeXBlcyA9ICdmbG9hdDMyJyB8ICdmbG9hdDE2JyB8ICdpbnQzMicgfCAnaW50NjQnIHwgJ3VpbnQzMicgfCAndWludDgnIHwgJ2Jvb2wnO1xuXG4gIC8qKlxuICAgKiBzdXBwb3J0ZWQgZGF0YSB0eXBlcyBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBXZWJOTiBNTFRlbnNvclxuICAgKi9cbiAgZXhwb3J0IHR5cGUgTUxUZW5zb3JEYXRhVHlwZXMgPVxuICAgIHwgJ2Zsb2F0MzInXG4gICAgfCAnZmxvYXQxNidcbiAgICB8ICdpbnQ4J1xuICAgIHwgJ3VpbnQ4J1xuICAgIHwgJ2ludDMyJ1xuICAgIHwgJ3VpbnQzMidcbiAgICB8ICdpbnQ2NCdcbiAgICB8ICd1aW50NjQnXG4gICAgfCAnYm9vbCdcbiAgICB8ICd1aW50NCdcbiAgICB8ICdpbnQ0JztcblxuICAvKipcbiAgICogcmVwcmVzZW50IHdoZXJlIHRoZSB0ZW5zb3IgZGF0YSBpcyBzdG9yZWRcbiAgICovXG4gIGV4cG9ydCB0eXBlIERhdGFMb2NhdGlvbiA9ICdub25lJyB8ICdjcHUnIHwgJ2NwdS1waW5uZWQnIHwgJ3RleHR1cmUnIHwgJ2dwdS1idWZmZXInIHwgJ21sLXRlbnNvcic7XG5cbiAgLyoqXG4gICAqIHJlcHJlc2VudCB0aGUgZGF0YSB0eXBlIG9mIGEgdGVuc29yXG4gICAqL1xuICBleHBvcnQgdHlwZSBUeXBlID0ga2V5b2YgRGF0YVR5cGVNYXA7XG59XG5cbi8qKlxuICogUmVwcmVzZW50IG11bHRpLWRpbWVuc2lvbmFsIGFycmF5cyB0byBmZWVkIHRvIG9yIGZldGNoIGZyb20gbW9kZWwgaW5mZXJlbmNpbmcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHlwZWRUZW5zb3I8VCBleHRlbmRzIFRlbnNvci5UeXBlPiBleHRlbmRzIFR5cGVkVGVuc29yQmFzZTxUPiwgVHlwZWRUZW5zb3JVdGlsczxUPiB7fVxuLyoqXG4gKiBSZXByZXNlbnQgbXVsdGktZGltZW5zaW9uYWwgYXJyYXlzIHRvIGZlZWQgdG8gb3IgZmV0Y2ggZnJvbSBtb2RlbCBpbmZlcmVuY2luZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZW5zb3IgZXh0ZW5kcyBUeXBlZFRlbnNvckJhc2U8VGVuc29yLlR5cGU+LCBUeXBlZFRlbnNvclV0aWxzPFRlbnNvci5UeXBlPiB7fVxuXG4vKipcbiAqIHR5cGUgVGVuc29yQ29uc3RydWN0b3IgZGVmaW5lcyB0aGUgY29uc3RydWN0b3JzIG9mICdUZW5zb3InIHRvIGNyZWF0ZSBDUFUgdGVuc29yIGluc3RhbmNlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JDb25zdHJ1Y3RvciBleHRlbmRzIFRlbnNvckZhY3Rvcnkge1xuICAvLyAjcmVnaW9uIENQVSB0ZW5zb3IgLSBzcGVjaWZ5IGVsZW1lbnQgdHlwZVxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHN0cmluZyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKFxuICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgIGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFsnc3RyaW5nJ10gfCByZWFkb25seSBzdHJpbmdbXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFR5cGVkVGVuc29yPCdzdHJpbmcnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGJvb2wgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChcbiAgICB0eXBlOiAnYm9vbCcsXG4gICAgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwWydib29sJ10gfCByZWFkb25seSBib29sZWFuW10sXG4gICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBUeXBlZFRlbnNvcjwnYm9vbCc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdWludDggdGVuc29yIG9iamVjdCBmcm9tIGEgVWludDhDbGFtcGVkQXJyYXksIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKHR5cGU6ICd1aW50OCcsIGRhdGE6IFVpbnQ4Q2xhbXBlZEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDgnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IDY0LWJpdCBpbnRlZ2VyIHR5cGVkIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gdHlwZSwgZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBTcGVjaWZ5IHRoZSBlbGVtZW50IHR5cGUuXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyA8VCBleHRlbmRzICd1aW50NjQnIHwgJ2ludDY0Jz4oXG4gICAgdHlwZTogVCxcbiAgICBkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbVF0gfCByZWFkb25seSBiaWdpbnRbXSB8IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVHlwZWRUZW5zb3I8VD47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBudW1lcmljIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gdHlwZSwgZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBTcGVjaWZ5IHRoZSBlbGVtZW50IHR5cGUuXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyA8VCBleHRlbmRzIEV4Y2x1ZGU8VGVuc29yLlR5cGUsICdzdHJpbmcnIHwgJ2Jvb2wnIHwgJ3VpbnQ2NCcgfCAnaW50NjQnPj4oXG4gICAgdHlwZTogVCxcbiAgICBkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbVF0gfCByZWFkb25seSBudW1iZXJbXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFR5cGVkVGVuc29yPFQ+O1xuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBDUFUgdGVuc29yIC0gaW5mZXIgZWxlbWVudCB0eXBlc1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgZmxvYXQzMiB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogRmxvYXQzMkFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnZmxvYXQzMic+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgaW50OCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogSW50OEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnaW50OCc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdWludDggdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IFVpbnQ4QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCd1aW50OCc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdWludDggdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IFVpbnQ4Q2xhbXBlZEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDgnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQxNiB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogVWludDE2QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCd1aW50MTYnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGludDE2IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBJbnQxNkFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnaW50MTYnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGludDMyIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBJbnQzMkFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnaW50MzInPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGludDY0IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBCaWdJbnQ2NEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnaW50NjQnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHN0cmluZyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogcmVhZG9ubHkgc3RyaW5nW10sIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdzdHJpbmcnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGJvb2wgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IHJlYWRvbmx5IGJvb2xlYW5bXSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2Jvb2wnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGZsb2F0NjQgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKGRhdGE6IEZsb2F0NjRBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2Zsb2F0NjQnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQzMiB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogVWludDMyQXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCd1aW50MzInPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQ2NCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyAoZGF0YTogQmlnVWludDY0QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCd1aW50NjQnPjtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBDUFUgdGVuc29yIC0gZmFsbCBiYWNrIHRvIG5vbi1nZW5lcmljIHRlbnNvciB0eXBlIGRlY2xhcmF0aW9uXG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcgKFxuICAgIHR5cGU6IFRlbnNvci5UeXBlLFxuICAgIGRhdGE6IFRlbnNvci5EYXRhVHlwZSB8IHJlYWRvbmx5IG51bWJlcltdIHwgcmVhZG9ubHkgc3RyaW5nW10gfCByZWFkb25seSBiaWdpbnRbXSB8IHJlYWRvbmx5IGJvb2xlYW5bXSxcbiAgICBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gICk6IFRlbnNvcjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3IChkYXRhOiBUZW5zb3IuRGF0YVR5cGUsIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvcjtcbiAgLy8gI2VuZHJlZ2lvblxufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgY29uc3QgVGVuc29yID0gVGVuc29ySW1wbCBhcyBUZW5zb3JDb25zdHJ1Y3RvcjtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZW52IH0gZnJvbSAnLi9lbnYtaW1wbC5qcyc7XG5cbi8qKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY29uc3QgVFJBQ0UgPSAoZGV2aWNlVHlwZTogc3RyaW5nLCBsYWJlbDogc3RyaW5nKSA9PiB7XG4gIGlmICh0eXBlb2YgZW52LnRyYWNlID09PSAndW5kZWZpbmVkJyA/ICFlbnYud2FzbS50cmFjZSA6ICFlbnYudHJhY2UpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgY29uc29sZS50aW1lU3RhbXAoYCR7ZGV2aWNlVHlwZX06Ok9SVDo6JHtsYWJlbH1gKTtcbn07XG5cbmNvbnN0IFRSQUNFX0ZVTkMgPSAobXNnOiBzdHJpbmcsIGV4dHJhTXNnPzogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IEVycm9yKCkuc3RhY2s/LnNwbGl0KC9cXHJcXG58XFxyfFxcbi9nKSB8fCBbXTtcbiAgbGV0IGhhc1RyYWNlRnVuYyA9IGZhbHNlO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHN0YWNrLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGhhc1RyYWNlRnVuYyAmJiAhc3RhY2tbaV0uaW5jbHVkZXMoJ1RSQUNFX0ZVTkMnKSkge1xuICAgICAgbGV0IGxhYmVsID0gYEZVTkNfJHttc2d9Ojoke3N0YWNrW2ldLnRyaW0oKS5zcGxpdCgnICcpWzFdfWA7XG4gICAgICBpZiAoZXh0cmFNc2cpIHtcbiAgICAgICAgbGFiZWwgKz0gYDo6JHtleHRyYU1zZ31gO1xuICAgICAgfVxuICAgICAgVFJBQ0UoJ0NQVScsIGxhYmVsKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHN0YWNrW2ldLmluY2x1ZGVzKCdUUkFDRV9GVU5DJykpIHtcbiAgICAgIGhhc1RyYWNlRnVuYyA9IHRydWU7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNvbnN0IFRSQUNFX0ZVTkNfQkVHSU4gPSAoZXh0cmFNc2c/OiBzdHJpbmcpID0+IHtcbiAgaWYgKHR5cGVvZiBlbnYudHJhY2UgPT09ICd1bmRlZmluZWQnID8gIWVudi53YXNtLnRyYWNlIDogIWVudi50cmFjZSkge1xuICAgIHJldHVybjtcbiAgfVxuICBUUkFDRV9GVU5DKCdCRUdJTicsIGV4dHJhTXNnKTtcbn07XG5cbi8qKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY29uc3QgVFJBQ0VfRlVOQ19FTkQgPSAoZXh0cmFNc2c/OiBzdHJpbmcpID0+IHtcbiAgaWYgKHR5cGVvZiBlbnYudHJhY2UgPT09ICd1bmRlZmluZWQnID8gIWVudi53YXNtLnRyYWNlIDogIWVudi50cmFjZSkge1xuICAgIHJldHVybjtcbiAgfVxuICBUUkFDRV9GVU5DKCdFTkQnLCBleHRyYU1zZyk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyByZXNvbHZlQmFja2VuZEFuZEV4ZWN1dGlvblByb3ZpZGVycyB9IGZyb20gJy4vYmFja2VuZC1pbXBsLmpzJztcbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi9iYWNrZW5kLmpzJztcbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24gYXMgSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZSB9IGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24uanMnO1xuaW1wb3J0IHsgT25ueFZhbHVlIH0gZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcbmltcG9ydCB7IFRSQUNFX0ZVTkNfQkVHSU4sIFRSQUNFX0ZVTkNfRU5EIH0gZnJvbSAnLi90cmFjZS5qcyc7XG5cbnR5cGUgU2Vzc2lvbk9wdGlvbnMgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlNlc3Npb25PcHRpb25zO1xudHlwZSBSdW5PcHRpb25zID0gSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5SdW5PcHRpb25zO1xudHlwZSBGZWVkc1R5cGUgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLkZlZWRzVHlwZTtcbnR5cGUgRmV0Y2hlc1R5cGUgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLkZldGNoZXNUeXBlO1xudHlwZSBSZXR1cm5UeXBlID0gSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5SZXR1cm5UeXBlO1xuXG5leHBvcnQgY2xhc3MgSW5mZXJlbmNlU2Vzc2lvbiBpbXBsZW1lbnRzIEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2Uge1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKGhhbmRsZXI6IEluZmVyZW5jZVNlc3Npb25IYW5kbGVyKSB7XG4gICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjtcbiAgfVxuICBydW4oZmVlZHM6IEZlZWRzVHlwZSwgb3B0aW9ucz86IFJ1bk9wdGlvbnMpOiBQcm9taXNlPFJldHVyblR5cGU+O1xuICBydW4oZmVlZHM6IEZlZWRzVHlwZSwgZmV0Y2hlczogRmV0Y2hlc1R5cGUsIG9wdGlvbnM/OiBSdW5PcHRpb25zKTogUHJvbWlzZTxSZXR1cm5UeXBlPjtcbiAgYXN5bmMgcnVuKGZlZWRzOiBGZWVkc1R5cGUsIGFyZzE/OiBGZXRjaGVzVHlwZSB8IFJ1bk9wdGlvbnMsIGFyZzI/OiBSdW5PcHRpb25zKTogUHJvbWlzZTxSZXR1cm5UeXBlPiB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTigpO1xuICAgIGNvbnN0IGZldGNoZXM6IHsgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB8IG51bGwgfSA9IHt9O1xuICAgIGxldCBvcHRpb25zOiBSdW5PcHRpb25zID0ge307XG4gICAgLy8gY2hlY2sgaW5wdXRzXG4gICAgaWYgKHR5cGVvZiBmZWVkcyAhPT0gJ29iamVjdCcgfHwgZmVlZHMgPT09IG51bGwgfHwgZmVlZHMgaW5zdGFuY2VvZiBUZW5zb3IgfHwgQXJyYXkuaXNBcnJheShmZWVkcykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgIFwiJ2ZlZWRzJyBtdXN0IGJlIGFuIG9iamVjdCB0aGF0IHVzZSBpbnB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCBpc0ZldGNoZXNFbXB0eSA9IHRydWU7XG4gICAgLy8gZGV0ZXJtaW5lIHdoaWNoIG92ZXJyaWRlIGlzIGJlaW5nIHVzZWRcbiAgICBpZiAodHlwZW9mIGFyZzEgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAoYXJnMSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmV4cGVjdGVkIGFyZ3VtZW50WzFdOiBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgICAgIH1cbiAgICAgIGlmIChhcmcxIGluc3RhbmNlb2YgVGVuc29yKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInZmV0Y2hlcycgY2Fubm90IGJlIGEgVGVuc29yXCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcxKSkge1xuICAgICAgICBpZiAoYXJnMS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ2ZldGNoZXMnIGNhbm5vdCBiZSBhbiBlbXB0eSBhcnJheS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgaXNGZXRjaGVzRW1wdHkgPSBmYWxzZTtcbiAgICAgICAgLy8gb3V0cHV0IG5hbWVzXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBhcmcxKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidmZXRjaGVzJyBtdXN0IGJlIGEgc3RyaW5nIGFycmF5IG9yIGFuIG9iamVjdC5cIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0aGlzLm91dHB1dE5hbWVzLmluZGV4T2YobmFtZSkgPT09IC0xKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJ2ZldGNoZXMnIGNvbnRhaW5zIGludmFsaWQgb3V0cHV0IG5hbWU6ICR7bmFtZX0uYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZldGNoZXNbbmFtZV0gPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBhcmcyID09PSAnb2JqZWN0JyAmJiBhcmcyICE9PSBudWxsKSB7XG4gICAgICAgICAgb3B0aW9ucyA9IGFyZzI7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidvcHRpb25zJyBtdXN0IGJlIGFuIG9iamVjdC5cIik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGRlY2lkZSB3aGV0aGVyIGFyZzEgaXMgZmV0Y2hlcyBvciBvcHRpb25zXG4gICAgICAgIC8vIGlmIGFueSBvdXRwdXQgbmFtZSBpcyBwcmVzZW50IGFuZCBpdHMgdmFsdWUgaXMgdmFsaWQgT25ueFZhbHVlLCB3ZSBjb25zaWRlciBpdCBmZXRjaGVzXG4gICAgICAgIGxldCBpc0ZldGNoZXMgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgYXJnMUtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhhcmcxKTtcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIHRoaXMub3V0cHV0TmFtZXMpIHtcbiAgICAgICAgICBpZiAoYXJnMUtleXMuaW5kZXhPZihuYW1lKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNvbnN0IHYgPSAoYXJnMSBhcyBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLk51bGxhYmxlT25ueFZhbHVlTWFwVHlwZSlbbmFtZV07XG4gICAgICAgICAgICBpZiAodiA9PT0gbnVsbCB8fCB2IGluc3RhbmNlb2YgVGVuc29yKSB7XG4gICAgICAgICAgICAgIGlzRmV0Y2hlcyA9IHRydWU7XG4gICAgICAgICAgICAgIGlzRmV0Y2hlc0VtcHR5ID0gZmFsc2U7XG4gICAgICAgICAgICAgIGZldGNoZXNbbmFtZV0gPSB2O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0ZldGNoZXMpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGFyZzIgPT09ICdvYmplY3QnICYmIGFyZzIgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBhcmcyO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3B0aW9ucyA9IGFyZzEgYXMgUnVuT3B0aW9ucztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5leHBlY3RlZCBhcmd1bWVudFsxXTogbXVzdCBiZSAnZmV0Y2hlcycgb3IgJ29wdGlvbnMnLlwiKTtcbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiBhbGwgaW5wdXRzIGFyZSBpbiBmZWVkXG4gICAgZm9yIChjb25zdCBuYW1lIG9mIHRoaXMuaW5wdXROYW1lcykge1xuICAgICAgaWYgKHR5cGVvZiBmZWVkc1tuYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dCAnJHtuYW1lfScgaXMgbWlzc2luZyBpbiAnZmVlZHMnLmApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGlmIG5vIGZldGNoZXMgaXMgc3BlY2lmaWVkLCB3ZSB1c2UgdGhlIGZ1bGwgb3V0cHV0IG5hbWVzIGxpc3RcbiAgICBpZiAoaXNGZXRjaGVzRW1wdHkpIHtcbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLm91dHB1dE5hbWVzKSB7XG4gICAgICAgIGZldGNoZXNbbmFtZV0gPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGZlZWRzLCBmZXRjaGVzIGFuZCBvcHRpb25zIGFyZSBwcmVwYXJlZFxuXG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuaGFuZGxlci5ydW4oZmVlZHMsIGZldGNoZXMsIG9wdGlvbnMpO1xuICAgIGNvbnN0IHJldHVyblZhbHVlOiB7IFtuYW1lOiBzdHJpbmddOiBPbm54VmFsdWUgfSA9IHt9O1xuICAgIGZvciAoY29uc3Qga2V5IGluIHJlc3VsdHMpIHtcbiAgICAgIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHRzLCBrZXkpKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHJlc3VsdHNba2V5XTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFRlbnNvcikge1xuICAgICAgICAgIHJldHVyblZhbHVlW2tleV0gPSByZXN1bHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVba2V5XSA9IG5ldyBUZW5zb3IocmVzdWx0LnR5cGUsIHJlc3VsdC5kYXRhLCByZXN1bHQuZGltcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgVFJBQ0VfRlVOQ19FTkQoKTtcbiAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gIH1cblxuICBhc3luYyByZWxlYXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIuZGlzcG9zZSgpO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZShwYXRoOiBzdHJpbmcsIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT47XG4gIHN0YXRpYyBjcmVhdGUoYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT47XG4gIHN0YXRpYyBjcmVhdGUoXG4gICAgYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsXG4gICAgYnl0ZU9mZnNldDogbnVtYmVyLFxuICAgIGJ5dGVMZW5ndGg/OiBudW1iZXIsXG4gICAgb3B0aW9ucz86IFNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2U+O1xuICBzdGF0aWMgY3JlYXRlKGJ1ZmZlcjogVWludDhBcnJheSwgb3B0aW9ucz86IFNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPjtcbiAgc3RhdGljIGFzeW5jIGNyZWF0ZShcbiAgICBhcmcwOiBzdHJpbmcgfCBBcnJheUJ1ZmZlckxpa2UgfCBVaW50OEFycmF5LFxuICAgIGFyZzE/OiBTZXNzaW9uT3B0aW9ucyB8IG51bWJlcixcbiAgICBhcmcyPzogbnVtYmVyLFxuICAgIGFyZzM/OiBTZXNzaW9uT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPiB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTigpO1xuICAgIC8vIGVpdGhlciBsb2FkIGZyb20gYSBmaWxlIG9yIGJ1ZmZlclxuICAgIGxldCBmaWxlUGF0aE9yVWludDhBcnJheTogc3RyaW5nIHwgVWludDhBcnJheTtcbiAgICBsZXQgb3B0aW9uczogU2Vzc2lvbk9wdGlvbnMgPSB7fTtcblxuICAgIGlmICh0eXBlb2YgYXJnMCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGZpbGVQYXRoT3JVaW50OEFycmF5ID0gYXJnMDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYXJnMCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIGZpbGVQYXRoT3JVaW50OEFycmF5ID0gYXJnMDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInb3B0aW9ucycgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICBhcmcwIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHxcbiAgICAgICh0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIGFyZzAgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcilcbiAgICApIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IGFyZzA7XG4gICAgICBsZXQgYnl0ZU9mZnNldCA9IDA7XG4gICAgICBsZXQgYnl0ZUxlbmd0aCA9IGFyZzAuYnl0ZUxlbmd0aDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGJ5dGVPZmZzZXQgPSBhcmcxO1xuICAgICAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGJ5dGVPZmZzZXQpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInYnl0ZU9mZnNldCcgbXVzdCBiZSBhbiBpbnRlZ2VyLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYnl0ZU9mZnNldCA+PSBidWZmZXIuYnl0ZUxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnYnl0ZU9mZnNldCcgaXMgb3V0IG9mIHJhbmdlIFswLCAke2J1ZmZlci5ieXRlTGVuZ3RofSkuYCk7XG4gICAgICAgIH1cbiAgICAgICAgYnl0ZUxlbmd0aCA9IGFyZzAuYnl0ZUxlbmd0aCAtIGJ5dGVPZmZzZXQ7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBieXRlTGVuZ3RoID0gYXJnMjtcbiAgICAgICAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGJ5dGVMZW5ndGgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIidieXRlTGVuZ3RoJyBtdXN0IGJlIGFuIGludGVnZXIuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYnl0ZUxlbmd0aCA8PSAwIHx8IGJ5dGVPZmZzZXQgKyBieXRlTGVuZ3RoID4gYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnYnl0ZUxlbmd0aCcgaXMgb3V0IG9mIHJhbmdlICgwLCAke2J1ZmZlci5ieXRlTGVuZ3RoIC0gYnl0ZU9mZnNldH1dLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIGFyZzMgPT09ICdvYmplY3QnICYmIGFyZzMgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBhcmczO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiJ29wdGlvbnMnIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidieXRlTGVuZ3RoJyBtdXN0IGJlIGEgbnVtYmVyLlwiKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidvcHRpb25zJyBtdXN0IGJlIGFuIG9iamVjdC5cIik7XG4gICAgICB9XG4gICAgICBmaWxlUGF0aE9yVWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmV4cGVjdGVkIGFyZ3VtZW50WzBdOiBtdXN0IGJlICdwYXRoJyBvciAnYnVmZmVyJy5cIik7XG4gICAgfVxuXG4gICAgLy8gcmVzb2x2ZSBiYWNrZW5kLCB1cGRhdGUgc2Vzc2lvbiBvcHRpb25zIHdpdGggdmFsaWRhdGVkIEVQcywgYW5kIGNyZWF0ZSBzZXNzaW9uIGhhbmRsZXJcbiAgICBjb25zdCBbYmFja2VuZCwgb3B0aW9uc1dpdGhWYWxpZGF0ZWRFUHNdID0gYXdhaXQgcmVzb2x2ZUJhY2tlbmRBbmRFeGVjdXRpb25Qcm92aWRlcnMob3B0aW9ucyk7XG4gICAgY29uc3QgaGFuZGxlciA9IGF3YWl0IGJhY2tlbmQuY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoZmlsZVBhdGhPclVpbnQ4QXJyYXksIG9wdGlvbnNXaXRoVmFsaWRhdGVkRVBzKTtcbiAgICBUUkFDRV9GVU5DX0VORCgpO1xuICAgIHJldHVybiBuZXcgSW5mZXJlbmNlU2Vzc2lvbihoYW5kbGVyKTtcbiAgfVxuXG4gIHN0YXJ0UHJvZmlsaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlci5zdGFydFByb2ZpbGluZygpO1xuICB9XG4gIGVuZFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLmhhbmRsZXIuZW5kUHJvZmlsaW5nKCk7XG4gIH1cblxuICBnZXQgaW5wdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5pbnB1dE5hbWVzO1xuICB9XG4gIGdldCBvdXRwdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5vdXRwdXROYW1lcztcbiAgfVxuXG4gIGdldCBpbnB1dE1ldGFkYXRhKCk6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuVmFsdWVNZXRhZGF0YVtdIHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVyLmlucHV0TWV0YWRhdGE7XG4gIH1cblxuICBnZXQgb3V0cHV0TWV0YWRhdGEoKTogcmVhZG9ubHkgSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZS5WYWx1ZU1ldGFkYXRhW10ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIub3V0cHV0TWV0YWRhdGE7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZXI6IEluZmVyZW5jZVNlc3Npb25IYW5kbGVyO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBJbmZlcmVuY2VTZXNzaW9uIGFzIEluZmVyZW5jZVNlc3Npb25JbXBsIH0gZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi1pbXBsLmpzJztcbmltcG9ydCB7IE9ubnhNb2RlbE9wdGlvbnMgfSBmcm9tICcuL29ubngtbW9kZWwuanMnO1xuaW1wb3J0IHsgT25ueFZhbHVlLCBPbm54VmFsdWVEYXRhTG9jYXRpb24gfSBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuaW1wb3J0IHR5cGUgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvci5qcyc7XG5pbXBvcnQgeyBUcnlHZXRHbG9iYWxUeXBlIH0gZnJvbSAnLi90eXBlLWhlbHBlci5qcyc7XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmUgKi9cblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEluZmVyZW5jZVNlc3Npb24ge1xuICAvLyAjcmVnaW9uIGlucHV0L291dHB1dCB0eXBlc1xuXG4gIHR5cGUgT25ueFZhbHVlTWFwVHlwZSA9IHsgcmVhZG9ubHkgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB9O1xuICB0eXBlIE51bGxhYmxlT25ueFZhbHVlTWFwVHlwZSA9IHsgcmVhZG9ubHkgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB8IG51bGwgfTtcblxuICAvKipcbiAgICogQSBmZWVkcyAobW9kZWwgaW5wdXRzKSBpcyBhbiBvYmplY3QgdGhhdCB1c2VzIGlucHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICovXG4gIHR5cGUgRmVlZHNUeXBlID0gT25ueFZhbHVlTWFwVHlwZTtcblxuICAvKipcbiAgICogQSBmZXRjaGVzIChtb2RlbCBvdXRwdXRzKSBjb3VsZCBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZzpcbiAgICpcbiAgICogLSBPbWl0dGVkLiBVc2UgbW9kZWwncyBvdXRwdXQgbmFtZXMgZGVmaW5pdGlvbi5cbiAgICogLSBBbiBhcnJheSBvZiBzdHJpbmcgaW5kaWNhdGluZyB0aGUgb3V0cHV0IG5hbWVzLlxuICAgKiAtIEFuIG9iamVjdCB0aGF0IHVzZSBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIG9yIG51bGwgYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAqXG4gICAqIEByZW1hcmtcbiAgICogZGlmZmVyZW50IGZyb20gaW5wdXQgYXJndW1lbnQsIGluIG91dHB1dCwgT25ueFZhbHVlIGlzIG9wdGlvbmFsLiBJZiBhbiBPbm54VmFsdWUgaXMgcHJlc2VudCBpdCB3aWxsIGJlXG4gICAqIHVzZWQgYXMgYSBwcmUtYWxsb2NhdGVkIHZhbHVlIGJ5IHRoZSBpbmZlcmVuY2UgZW5naW5lOyBpZiBvbWl0dGVkLCBpbmZlcmVuY2UgZW5naW5lIHdpbGwgYWxsb2NhdGUgYnVmZmVyXG4gICAqIGludGVybmFsbHkuXG4gICAqL1xuICB0eXBlIEZldGNoZXNUeXBlID0gcmVhZG9ubHkgc3RyaW5nW10gfCBOdWxsYWJsZU9ubnhWYWx1ZU1hcFR5cGU7XG5cbiAgLyoqXG4gICAqIEEgaW5mZXJlbmNpbmcgcmV0dXJuIHR5cGUgaXMgYW4gb2JqZWN0IHRoYXQgdXNlcyBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKi9cbiAgdHlwZSBSZXR1cm5UeXBlID0gT25ueFZhbHVlTWFwVHlwZTtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBzZXNzaW9uIG9wdGlvbnNcblxuICAvKipcbiAgICogQSBzZXQgb2YgY29uZmlndXJhdGlvbnMgZm9yIHNlc3Npb24gYmVoYXZpb3IuXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFNlc3Npb25PcHRpb25zIGV4dGVuZHMgT25ueE1vZGVsT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogQW4gYXJyYXkgb2YgZXhlY3V0aW9uIHByb3ZpZGVyIG9wdGlvbnMuXG4gICAgICpcbiAgICAgKiBBbiBleGVjdXRpb24gcHJvdmlkZXIgb3B0aW9uIGNhbiBiZSBhIHN0cmluZyBpbmRpY2F0aW5nIHRoZSBuYW1lIG9mIHRoZSBleGVjdXRpb24gcHJvdmlkZXIsXG4gICAgICogb3IgYW4gb2JqZWN0IG9mIGNvcnJlc3BvbmRpbmcgdHlwZS5cbiAgICAgKi9cbiAgICBleGVjdXRpb25Qcm92aWRlcnM/OiByZWFkb25seSBFeGVjdXRpb25Qcm92aWRlckNvbmZpZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGludHJhIE9QIHRocmVhZHMgbnVtYmVyLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkuXG4gICAgICovXG4gICAgaW50cmFPcE51bVRocmVhZHM/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaW50ZXIgT1AgdGhyZWFkcyBudW1iZXIuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKS5cbiAgICAgKi9cbiAgICBpbnRlck9wTnVtVGhyZWFkcz86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBmcmVlIGRpbWVuc2lvbiBvdmVycmlkZS5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBmcmVlRGltZW5zaW9uT3ZlcnJpZGVzPzogeyByZWFkb25seSBbZGltZW5zaW9uTmFtZTogc3RyaW5nXTogbnVtYmVyIH07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3B0aW1pemF0aW9uIGxldmVsLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGdyYXBoT3B0aW1pemF0aW9uTGV2ZWw/OiAnZGlzYWJsZWQnIHwgJ2Jhc2ljJyB8ICdleHRlbmRlZCcgfCAnYWxsJztcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZW5hYmxlIENQVSBtZW1vcnkgYXJlbmEuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZW5hYmxlQ3B1TWVtQXJlbmE/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBlbmFibGUgbWVtb3J5IHBhdHRlcm4uXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZW5hYmxlTWVtUGF0dGVybj86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRpb24gbW9kZS5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBleGVjdXRpb25Nb2RlPzogJ3NlcXVlbnRpYWwnIHwgJ3BhcmFsbGVsJztcblxuICAgIC8qKlxuICAgICAqIE9wdGltaXplZCBtb2RlbCBmaWxlIHBhdGguXG4gICAgICpcbiAgICAgKiBJZiB0aGlzIHNldHRpbmcgaXMgc3BlY2lmaWVkLCB0aGUgb3B0aW1pemVkIG1vZGVsIHdpbGwgYmUgZHVtcGVkLiBJbiBicm93c2VyLCBhIGJsb2Igd2lsbCBiZSBjcmVhdGVkXG4gICAgICogd2l0aCBhIHBvcC11cCB3aW5kb3cuXG4gICAgICovXG4gICAgb3B0aW1pemVkTW9kZWxGaWxlUGF0aD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZW5hYmxlIHByb2ZpbGluZy5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhIHBsYWNlaG9sZGVyIGZvciBhIGZ1dHVyZSB1c2UuXG4gICAgICovXG4gICAgZW5hYmxlUHJvZmlsaW5nPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEZpbGUgcHJlZml4IGZvciBwcm9maWxpbmcuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYSBwbGFjZWhvbGRlciBmb3IgYSBmdXR1cmUgdXNlLlxuICAgICAqL1xuICAgIHByb2ZpbGVGaWxlUHJlZml4Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTG9nIElELlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGxvZ0lkPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogTG9nIHNldmVyaXR5IGxldmVsLiBTZWVcbiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhydW50aW1lL2Jsb2IvbWFpbi9pbmNsdWRlL29ubnhydW50aW1lL2NvcmUvY29tbW9uL2xvZ2dpbmcvc2V2ZXJpdHkuaFxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGxvZ1NldmVyaXR5TGV2ZWw/OiAwIHwgMSB8IDIgfCAzIHwgNDtcblxuICAgIC8qKlxuICAgICAqIExvZyB2ZXJib3NpdHkgbGV2ZWwuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICovXG4gICAgbG9nVmVyYm9zaXR5TGV2ZWw/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHN0cmluZyBhcyBhIHByZWZlcnJlZCBkYXRhIGxvY2F0aW9uIGZvciBhbGwgb3V0cHV0cywgb3IgYW4gb2JqZWN0IHRoYXQgdXNlIG91dHB1dCBuYW1lcyBhcyBrZXlzIGFuZCBhXG4gICAgICogcHJlZmVycmVkIGRhdGEgbG9jYXRpb24gYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgV2ViIGZvciBXZWJHTCBhbmQgV2ViR1BVIEVQLlxuICAgICAqL1xuICAgIHByZWZlcnJlZE91dHB1dExvY2F0aW9uPzogT25ueFZhbHVlRGF0YUxvY2F0aW9uIHwgeyByZWFkb25seSBbb3V0cHV0TmFtZTogc3RyaW5nXTogT25ueFZhbHVlRGF0YUxvY2F0aW9uIH07XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIGVuYWJsZSBncmFwaCBjYXB0dXJlLlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSBXZWIgZm9yIFdlYkdQVSBFUC5cbiAgICAgKi9cbiAgICBlbmFibGVHcmFwaENhcHR1cmU/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogU3RvcmUgY29uZmlndXJhdGlvbnMgZm9yIGEgc2Vzc2lvbi4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL3Nlc3Npb24vXG4gICAgICogb25ueHJ1bnRpbWVfc2Vzc2lvbl9vcHRpb25zX2NvbmZpZ19rZXlzLmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBXZWJBc3NlbWJseSBiYWNrZW5kLiBXaWxsIHN1cHBvcnQgTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUgbGF0ZXJcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBleHRyYToge1xuICAgICAqICAgc2Vzc2lvbjoge1xuICAgICAqICAgICBzZXRfZGVub3JtYWxfYXNfemVybzogXCIxXCIsXG4gICAgICogICAgIGRpc2FibGVfcHJlcGFja2luZzogXCIxXCJcbiAgICAgKiAgIH0sXG4gICAgICogICBvcHRpbWl6YXRpb246IHtcbiAgICAgKiAgICAgZW5hYmxlX2dlbHVfYXBwcm94aW1hdGlvbjogXCIxXCJcbiAgICAgKiAgIH1cbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZXh0cmE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgfVxuXG4gIC8vICNyZWdpb24gZXhlY3V0aW9uIHByb3ZpZGVyc1xuXG4gIC8vIEN1cnJlbnRseSwgd2UgaGF2ZSB0aGUgZm9sbG93aW5nIGJhY2tlbmRzIHRvIHN1cHBvcnQgZXhlY3V0aW9uIHByb3ZpZGVyczpcbiAgLy8gQmFja2VuZCBOb2RlLmpzIGJpbmRpbmc6IHN1cHBvcnRzICdjcHUnLCAnZG1sJyAod2luMzIpLCAnY29yZW1sJyAobWFjT1MpIGFuZCAnY3VkYScgKGxpbnV4KS5cbiAgLy8gQmFja2VuZCBXZWJBc3NlbWJseTogc3VwcG9ydHMgJ2NwdScsICd3YXNtJywgJ3dlYmdwdScgYW5kICd3ZWJubicuXG4gIC8vIEJhY2tlbmQgT05OWC5qczogc3VwcG9ydHMgJ3dlYmdsJy5cbiAgLy8gQmFja2VuZCBSZWFjdCBOYXRpdmU6IHN1cHBvcnRzICdjcHUnLCAneG5ucGFjaycsICdjb3JlbWwnIChpT1MpLCAnbm5hcGknIChBbmRyb2lkKS5cbiAgaW50ZXJmYWNlIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uTWFwIHtcbiAgICBjb3JlbWw6IENvcmVNTEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIGNwdTogQ3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgY3VkYTogQ3VkYUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIGRtbDogRG1sRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgbm5hcGk6IE5uYXBpRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgdGVuc29ycnQ6IFRlbnNvclJ0RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgd2FzbTogV2ViQXNzZW1ibHlFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICB3ZWJnbDogV2ViR0xFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICB3ZWJncHU6IFdlYkdwdUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHdlYm5uOiBXZWJOTkV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHFubjogUW5uRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgeG5ucGFjazogWG5ucGFja0V4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICB9XG5cbiAgdHlwZSBFeGVjdXRpb25Qcm92aWRlck5hbWUgPSBrZXlvZiBFeGVjdXRpb25Qcm92aWRlck9wdGlvbk1hcDtcbiAgdHlwZSBFeGVjdXRpb25Qcm92aWRlckNvbmZpZyA9XG4gICAgfCBFeGVjdXRpb25Qcm92aWRlck9wdGlvbk1hcFtFeGVjdXRpb25Qcm92aWRlck5hbWVdXG4gICAgfCBFeGVjdXRpb25Qcm92aWRlck9wdGlvblxuICAgIHwgRXhlY3V0aW9uUHJvdmlkZXJOYW1lXG4gICAgfCBzdHJpbmc7XG5cbiAgZXhwb3J0IGludGVyZmFjZSBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ2NwdSc7XG4gICAgdXNlQXJlbmE/OiBib29sZWFuO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ3VkYUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdjdWRhJztcbiAgICBkZXZpY2VJZD86IG51bWJlcjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIERtbEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdkbWwnO1xuICAgIGRldmljZUlkPzogbnVtYmVyO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVGVuc29yUnRFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAndGVuc29ycnQnO1xuICAgIGRldmljZUlkPzogbnVtYmVyO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViQXNzZW1ibHlFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnd2FzbSc7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHTEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd3ZWJnbCc7XG4gICAgLy8gVE9ETzogYWRkIGZsYWdzXG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBYbm5wYWNrRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3hubnBhY2snO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3dlYmdwdSc7XG4gICAgcHJlZmVycmVkTGF5b3V0PzogJ05DSFcnIHwgJ05IV0MnO1xuICB9XG5cbiAgLy8gI3JlZ2lvbiBXZWJOTiBvcHRpb25zXG5cbiAgaW50ZXJmYWNlIFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJOYW1lIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd3ZWJubic7XG4gIH1cblxuICAvKipcbiAgICogUmVwcmVzZW50cyBhIHNldCBvZiBvcHRpb25zIGZvciBjcmVhdGluZyBhIFdlYk5OIE1MQ29udGV4dC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL3d3dy53My5vcmcvVFIvd2Vibm4vI2RpY3RkZWYtbWxjb250ZXh0b3B0aW9uc1xuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJOTkNvbnRleHRPcHRpb25zIHtcbiAgICBkZXZpY2VUeXBlPzogJ2NwdScgfCAnZ3B1JyB8ICducHUnO1xuICAgIG51bVRocmVhZHM/OiBudW1iZXI7XG4gICAgcG93ZXJQcmVmZXJlbmNlPzogJ2RlZmF1bHQnIHwgJ2xvdy1wb3dlcicgfCAnaGlnaC1wZXJmb3JtYW5jZSc7XG4gIH1cblxuICAvKipcbiAgICogUmVwcmVzZW50cyBhIHNldCBvZiBvcHRpb25zIGZvciBXZWJOTiBleGVjdXRpb24gcHJvdmlkZXIgd2l0aG91dCBNTENvbnRleHQuXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFdlYk5OT3B0aW9uc1dpdGhvdXRNTENvbnRleHQgZXh0ZW5kcyBXZWJOTkV4ZWN1dGlvblByb3ZpZGVyTmFtZSwgV2ViTk5Db250ZXh0T3B0aW9ucyB7XG4gICAgY29udGV4dD86IG5ldmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgYSBzZXQgb2Ygb3B0aW9ucyBmb3IgV2ViTk4gZXhlY3V0aW9uIHByb3ZpZGVyIHdpdGggTUxDb250ZXh0LlxuICAgKlxuICAgKiBXaGVuIE1MQ29udGV4dCBpcyBwcm92aWRlZCwgdGhlIGRldmljZVR5cGUgaXMgYWxzbyByZXF1aXJlZCBzbyB0aGF0IHRoZSBXZWJOTiBFUCBjYW4gZGV0ZXJtaW5lIHRoZSBwcmVmZXJyZWRcbiAgICogY2hhbm5lbCBsYXlvdXQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSL3dlYm5uLyNkb20tbWwtY3JlYXRlY29udGV4dFxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJOTk9wdGlvbnNXaXRoTUxDb250ZXh0XG4gICAgZXh0ZW5kcyBXZWJOTkV4ZWN1dGlvblByb3ZpZGVyTmFtZSxcbiAgICAgIE9taXQ8V2ViTk5Db250ZXh0T3B0aW9ucywgJ2RldmljZVR5cGUnPixcbiAgICAgIFJlcXVpcmVkPFBpY2s8V2ViTk5Db250ZXh0T3B0aW9ucywgJ2RldmljZVR5cGUnPj4ge1xuICAgIGNvbnRleHQ6IFRyeUdldEdsb2JhbFR5cGU8J01MQ29udGV4dCc+O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgYSBzZXQgb2Ygb3B0aW9ucyBmb3IgV2ViTk4gZXhlY3V0aW9uIHByb3ZpZGVyIHdpdGggTUxDb250ZXh0IHdoaWNoIGlzIGNyZWF0ZWQgZnJvbSBHUFVEZXZpY2UuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSL3dlYm5uLyNkb20tbWwtY3JlYXRlY29udGV4dC1ncHVkZXZpY2VcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViTk5PcHRpb25zV2ViR3B1IGV4dGVuZHMgV2ViTk5FeGVjdXRpb25Qcm92aWRlck5hbWUge1xuICAgIGNvbnRleHQ6IFRyeUdldEdsb2JhbFR5cGU8J01MQ29udGV4dCc+O1xuICAgIGdwdURldmljZTogVHJ5R2V0R2xvYmFsVHlwZTwnR1BVRGV2aWNlJz47XG4gIH1cblxuICAvKipcbiAgICogT3B0aW9ucyBmb3IgV2ViTk4gZXhlY3V0aW9uIHByb3ZpZGVyLlxuICAgKi9cbiAgZXhwb3J0IHR5cGUgV2ViTk5FeGVjdXRpb25Qcm92aWRlck9wdGlvbiA9XG4gICAgfCBXZWJOTk9wdGlvbnNXaXRob3V0TUxDb250ZXh0XG4gICAgfCBXZWJOTk9wdGlvbnNXaXRoTUxDb250ZXh0XG4gICAgfCBXZWJOTk9wdGlvbnNXZWJHcHU7XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgUW5uRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3Fubic7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgUU5OIGJhY2tlbmQgdHlwZS4gRS5nLiwgJ2NwdScgb3IgJ2h0cCcuXG4gICAgICogTXV0dWFsbHkgZXhjbHVzaXZlIHdpdGggYGJhY2tlbmRQYXRoYC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0ICdodHAnXG4gICAgICovXG4gICAgYmFja2VuZFR5cGU/OiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBhIHBhdGggdG8gdGhlIFFOTiBiYWNrZW5kIGxpYnJhcnkuXG4gICAgICogTXV0dWFsbHkgZXhjbHVzaXZlIHdpdGggYGJhY2tlbmRUeXBlYC5cbiAgICAgKi9cbiAgICBiYWNrZW5kUGF0aD86IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHdoZXRoZXIgdG8gZW5hYmxlIEhUUCBGUDE2IHByZWNpc2lvbi5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgKi9cbiAgICBlbmFibGVGcDE2UHJlY2lzaW9uPzogYm9vbGVhbjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIENvcmVNTEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdjb3JlbWwnO1xuICAgIC8qKlxuICAgICAqIFRoZSBiaXQgZmxhZ3MgZm9yIENvcmVNTCBleGVjdXRpb24gcHJvdmlkZXIuXG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKiBDT1JFTUxfRkxBR19VU0VfQ1BVX09OTFkgPSAweDAwMVxuICAgICAqIENPUkVNTF9GTEFHX0VOQUJMRV9PTl9TVUJHUkFQSCA9IDB4MDAyXG4gICAgICogQ09SRU1MX0ZMQUdfT05MWV9FTkFCTEVfREVWSUNFX1dJVEhfQU5FID0gMHgwMDRcbiAgICAgKiBDT1JFTUxfRkxBR19PTkxZX0FMTE9XX1NUQVRJQ19JTlBVVF9TSEFQRVMgPSAweDAwOFxuICAgICAqIENPUkVNTF9GTEFHX0NSRUFURV9NTFBST0dSQU0gPSAweDAxMFxuICAgICAqIENPUkVNTF9GTEFHX1VTRV9DUFVfQU5EX0dQVSA9IDB4MDIwXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBTZWUgaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL3Byb3ZpZGVycy9jb3JlbWwvY29yZW1sX3Byb3ZpZGVyX2ZhY3RvcnkuaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogVGhpcyBmbGFnIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcpLlxuICAgICAqL1xuICAgIGNvcmVNbEZsYWdzPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byB1c2UgQ1BVIG9ubHkgaW4gQ29yZU1MIEVQLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChyZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIHVzZUNQVU9ubHk/OiBib29sZWFuO1xuICAgIHVzZUNQVUFuZEdQVT86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB3aGV0aGVyIHRvIGVuYWJsZSBDb3JlTUwgRVAgb24gc3ViZ3JhcGguXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKHJlYWN0LW5hdGl2ZSkuXG4gICAgICovXG4gICAgZW5hYmxlT25TdWJncmFwaD86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB3aGV0aGVyIHRvIG9ubHkgZW5hYmxlIENvcmVNTCBFUCBmb3IgQXBwbGUgZGV2aWNlcyB3aXRoIEFORSAoQXBwbGUgTmV1cmFsIEVuZ2luZSkuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKHJlYWN0LW5hdGl2ZSkuXG4gICAgICovXG4gICAgb25seUVuYWJsZURldmljZVdpdGhBTkU/OiBib29sZWFuO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgTm5hcGlFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnbm5hcGknO1xuICAgIHVzZUZQMTY/OiBib29sZWFuO1xuICAgIHVzZU5DSFc/OiBib29sZWFuO1xuICAgIGNwdURpc2FibGVkPzogYm9vbGVhbjtcbiAgICBjcHVPbmx5PzogYm9vbGVhbjtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcnVuIG9wdGlvbnNcblxuICAvKipcbiAgICogQSBzZXQgb2YgY29uZmlndXJhdGlvbnMgZm9yIGluZmVyZW5jZSBydW4gYmVoYXZpb3JcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgUnVuT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogTG9nIHNldmVyaXR5IGxldmVsLiBTZWVcbiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhydW50aW1lL2Jsb2IvbWFpbi9pbmNsdWRlL29ubnhydW50aW1lL2NvcmUvY29tbW9uL2xvZ2dpbmcvc2V2ZXJpdHkuaFxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGxvZ1NldmVyaXR5TGV2ZWw/OiAwIHwgMSB8IDIgfCAzIHwgNDtcblxuICAgIC8qKlxuICAgICAqIExvZyB2ZXJib3NpdHkgbGV2ZWwuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICovXG4gICAgbG9nVmVyYm9zaXR5TGV2ZWw/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBUZXJtaW5hdGUgYWxsIGluY29tcGxldGUgT3J0UnVuIGNhbGxzIGFzIHNvb24gYXMgcG9zc2libGUgaWYgdHJ1ZVxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqL1xuICAgIHRlcm1pbmF0ZT86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBBIHRhZyBmb3IgdGhlIFJ1bigpIGNhbGxzIHVzaW5nIHRoaXNcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICB0YWc/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYSBzaW5nbGUgcnVuIGNvbmZpZ3VyYXRpb24gZW50cnkuIFNlZVxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueHJ1bnRpbWUvYmxvYi9tYWluL2luY2x1ZGUvb25ueHJ1bnRpbWUvY29yZS9zZXNzaW9uL1xuICAgICAqIG9ubnhydW50aW1lX3J1bl9vcHRpb25zX2NvbmZpZ19rZXlzLmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBXZWJBc3NlbWJseSBiYWNrZW5kLiBXaWxsIHN1cHBvcnQgTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUgbGF0ZXJcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGV4dHJhOiB7XG4gICAgICogICBtZW1vcnk6IHtcbiAgICAgKiAgICAgZW5hYmxlX21lbW9yeV9hcmVuYV9zaHJpbmthZ2U6IFwiMVwiLFxuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBleHRyYT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gdmFsdWUgbWV0YWRhdGFcblxuICAvKipcbiAgICogVGhlIGNvbW1vbiBwYXJ0IG9mIHRoZSB2YWx1ZSBtZXRhZGF0YSB0eXBlIGZvciBib3RoIHRlbnNvciBhbmQgbm9uLXRlbnNvciB2YWx1ZXMuXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFZhbHVlTWV0YWRhdGFCYXNlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgc3BlY2lmaWVkIGlucHV0IG9yIG91dHB1dC5cbiAgICAgKi9cbiAgICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIH1cblxuICAvKipcbiAgICogUmVwcmVzZW50cyB0aGUgbWV0YWRhdGEgb2YgYSBub24tdGVuc29yIHZhbHVlLlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBOb25UZW5zb3JWYWx1ZU1ldGFkYXRhIGV4dGVuZHMgVmFsdWVNZXRhZGF0YUJhc2Uge1xuICAgIC8qKlxuICAgICAqIEdldCBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGUgdmFsdWUgaXMgYSB0ZW5zb3IuXG4gICAgICovXG4gICAgcmVhZG9ubHkgaXNUZW5zb3I6IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIG1ldGFkYXRhIG9mIGEgdGVuc29yIHZhbHVlLlxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBUZW5zb3JWYWx1ZU1ldGFkYXRhIGV4dGVuZHMgVmFsdWVNZXRhZGF0YUJhc2Uge1xuICAgIC8qKlxuICAgICAqIEdldCBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGUgdmFsdWUgaXMgYSB0ZW5zb3IuXG4gICAgICovXG4gICAgcmVhZG9ubHkgaXNUZW5zb3I6IHRydWU7XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICAgKi9cbiAgICByZWFkb25seSB0eXBlOiBUZW5zb3IuVHlwZTtcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHNoYXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgc2hhcGUgaXMgbm90IGRlZmluZWQsIHRoZSB2YWx1ZSB3aWxsIGFuIGVtcHR5IGFycmF5LiBPdGhlcndpc2UsIGl0IHdpbGwgYmUgYW4gYXJyYXkgcmVwcmVzZW50aW5nIHRoZSBzaGFwZVxuICAgICAqIG9mIHRoZSB0ZW5zb3IuIEVhY2ggZWxlbWVudCBpbiB0aGUgYXJyYXkgY2FuIGJlIGEgbnVtYmVyIG9yIGEgc3RyaW5nLiBJZiB0aGUgZWxlbWVudCBpcyBhIG51bWJlciwgaXQgcmVwcmVzZW50c1xuICAgICAqIHRoZSBjb3JyZXNwb25kaW5nIGRpbWVuc2lvbiBzaXplLiBJZiB0aGUgZWxlbWVudCBpcyBhIHN0cmluZywgaXQgcmVwcmVzZW50cyBhIHN5bWJvbGljIGRpbWVuc2lvbi5cbiAgICAgKi9cbiAgICByZWFkb25seSBzaGFwZTogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIG1ldGFkYXRhIG9mIGEgdmFsdWUuXG4gICAqL1xuICBleHBvcnQgdHlwZSBWYWx1ZU1ldGFkYXRhID0gTm9uVGVuc29yVmFsdWVNZXRhZGF0YSB8IFRlbnNvclZhbHVlTWV0YWRhdGE7XG5cbiAgLy8gI2VuZHJlZ2lvblxufVxuXG4vKipcbiAqIFJlcHJlc2VudCBhIHJ1bnRpbWUgaW5zdGFuY2Ugb2YgYW4gT05OWCBtb2RlbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgLy8gI3JlZ2lvbiBydW4oKVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIHRoZSBtb2RlbCBhc3luY2hyb25vdXNseSB3aXRoIHRoZSBnaXZlbiBmZWVkcyBhbmQgb3B0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIGZlZWRzIC0gUmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGVsIGlucHV0LiBTZWUgdHlwZSBkZXNjcmlwdGlvbiBvZiBgSW5mZXJlbmNlU2Vzc2lvbi5JbnB1dFR5cGVgIGZvciBkZXRhaWwuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwuIEEgc2V0IG9mIG9wdGlvbnMgdGhhdCBjb250cm9scyB0aGUgYmVoYXZpb3Igb2YgbW9kZWwgaW5mZXJlbmNlLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIG1hcCwgd2hpY2ggdXNlcyBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKi9cbiAgcnVuKGZlZWRzOiBJbmZlcmVuY2VTZXNzaW9uLkZlZWRzVHlwZSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbi5SZXR1cm5UeXBlPjtcblxuICAvKipcbiAgICogRXhlY3V0ZSB0aGUgbW9kZWwgYXN5bmNocm9ub3VzbHkgd2l0aCB0aGUgZ2l2ZW4gZmVlZHMsIGZldGNoZXMgYW5kIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmZWVkcyAtIFJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBpbnB1dC4gU2VlIHR5cGUgZGVzY3JpcHRpb24gb2YgYEluZmVyZW5jZVNlc3Npb24uSW5wdXRUeXBlYCBmb3IgZGV0YWlsLlxuICAgKiBAcGFyYW0gZmV0Y2hlcyAtIFJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBvdXRwdXQuIFNlZSB0eXBlIGRlc2NyaXB0aW9uIG9mIGBJbmZlcmVuY2VTZXNzaW9uLk91dHB1dFR5cGVgIGZvclxuICAgKiBkZXRhaWwuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwuIEEgc2V0IG9mIG9wdGlvbnMgdGhhdCBjb250cm9scyB0aGUgYmVoYXZpb3Igb2YgbW9kZWwgaW5mZXJlbmNlLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIG1hcCwgd2hpY2ggdXNlcyBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKi9cbiAgcnVuKFxuICAgIGZlZWRzOiBJbmZlcmVuY2VTZXNzaW9uLkZlZWRzVHlwZSxcbiAgICBmZXRjaGVzOiBJbmZlcmVuY2VTZXNzaW9uLkZldGNoZXNUeXBlLFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbi5SZXR1cm5UeXBlPjtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiByZWxlYXNlKClcblxuICAvKipcbiAgICogUmVsZWFzZSB0aGUgaW5mZXJlbmNlIHNlc3Npb24gYW5kIHRoZSB1bmRlcmx5aW5nIHJlc291cmNlcy5cbiAgICovXG4gIHJlbGVhc2UoKTogUHJvbWlzZTx2b2lkPjtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBwcm9maWxpbmdcblxuICAvKipcbiAgICogU3RhcnQgcHJvZmlsaW5nLlxuICAgKi9cbiAgc3RhcnRQcm9maWxpbmcoKTogdm9pZDtcblxuICAvKipcbiAgICogRW5kIHByb2ZpbGluZy5cbiAgICovXG4gIGVuZFByb2ZpbGluZygpOiB2b2lkO1xuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIG1ldGFkYXRhXG5cbiAgLyoqXG4gICAqIEdldCBpbnB1dCBuYW1lcyBvZiB0aGUgbG9hZGVkIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEdldCBvdXRwdXQgbmFtZXMgb2YgdGhlIGxvYWRlZCBtb2RlbC5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgICogR2V0IGlucHV0IG1ldGFkYXRhIG9mIHRoZSBsb2FkZWQgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSBpbnB1dE1ldGFkYXRhOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXTtcblxuICAvKipcbiAgICogR2V0IG91dHB1dCBtZXRhZGF0YSBvZiB0aGUgbG9hZGVkIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0TWV0YWRhdGE6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YVtdO1xuXG4gIC8vICNlbmRyZWdpb25cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbmZlcmVuY2VTZXNzaW9uRmFjdG9yeSB7XG4gIC8vICNyZWdpb24gY3JlYXRlKClcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uIGFuZCBsb2FkIG1vZGVsIGFzeW5jaHJvbm91c2x5IGZyb20gYW4gT05OWCBtb2RlbCBmaWxlLlxuICAgKlxuICAgKiBAcGFyYW0gdXJpIC0gVGhlIFVSSSBvciBmaWxlIHBhdGggb2YgdGhlIG1vZGVsIHRvIGxvYWQuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gc3BlY2lmeSBjb25maWd1cmF0aW9uIGZvciBjcmVhdGluZyBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gSW5mZXJlbmNlU2Vzc2lvbiBvYmplY3QuXG4gICAqL1xuICBjcmVhdGUodXJpOiBzdHJpbmcsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uPjtcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uIGFuZCBsb2FkIG1vZGVsIGFzeW5jaHJvbm91c2x5IGZyb20gYW4gYXJyYXkgYnVmZXIuXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBbiBBcnJheUJ1ZmZlciByZXByZXNlbnRhdGlvbiBvZiBhbiBPTk5YIG1vZGVsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbj47XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgbG9hZCBtb2RlbCBhc3luY2hyb25vdXNseSBmcm9tIHNlZ21lbnQgb2YgYW4gYXJyYXkgYnVmZXIuXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBbiBBcnJheUJ1ZmZlciByZXByZXNlbnRhdGlvbiBvZiBhbiBPTk5YIG1vZGVsLlxuICAgKiBAcGFyYW0gYnl0ZU9mZnNldCAtIFRoZSBiZWdpbm5pbmcgb2YgdGhlIHNwZWNpZmllZCBwb3J0aW9uIG9mIHRoZSBhcnJheSBidWZmZXIuXG4gICAqIEBwYXJhbSBieXRlTGVuZ3RoIC0gVGhlIGxlbmd0aCBpbiBieXRlcyBvZiB0aGUgYXJyYXkgYnVmZmVyLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKFxuICAgIGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLFxuICAgIGJ5dGVPZmZzZXQ6IG51bWJlcixcbiAgICBieXRlTGVuZ3RoPzogbnVtYmVyLFxuICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuICApOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24+O1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24gYW5kIGxvYWQgbW9kZWwgYXN5bmNocm9ub3VzbHkgZnJvbSBhIFVpbnQ4QXJyYXkuXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBIFVpbnQ4QXJyYXkgcmVwcmVzZW50YXRpb24gb2YgYW4gT05OWCBtb2RlbC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBzcGVjaWZ5IGNvbmZpZ3VyYXRpb24gZm9yIGNyZWF0aW5nIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBJbmZlcmVuY2VTZXNzaW9uIG9iamVjdC5cbiAgICovXG4gIGNyZWF0ZShidWZmZXI6IFVpbnQ4QXJyYXksIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uPjtcblxuICAvLyAjZW5kcmVnaW9uXG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmV4cG9ydCBjb25zdCBJbmZlcmVuY2VTZXNzaW9uOiBJbmZlcmVuY2VTZXNzaW9uRmFjdG9yeSA9IEluZmVyZW5jZVNlc3Npb25JbXBsO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBPcHRpb25zRm9ybWF0LCBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMsIE9wdGlvbnNUZW5zb3JMYXlvdXQgfSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JUb0RhdGFVcmxPcHRpb25zIGV4dGVuZHMgT3B0aW9uc1RlbnNvckxheW91dCwgT3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yVG9JbWFnZURhdGFPcHRpb25zIGV4dGVuZHMgT3B0aW9uc1RlbnNvckxheW91dCwgT3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udmVyc2lvblV0aWxzIHtcbiAgLyoqXG4gICAqIGNyZWF0ZXMgYSBEYXRhVVJMIGluc3RhbmNlIGZyb20gdGVuc29yXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyBhIERhdGFVUkwgaW5zdGFuY2UgZnJvbSB0aGUgdGVuc29yLlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGBmb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIEByZXR1cm5zIGEgRGF0YVVSTCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBpbWFnZSBjb252ZXJ0ZWQgZnJvbSB0ZW5zb3IgZGF0YVxuICAgKi9cbiAgdG9EYXRhVVJMKG9wdGlvbnM/OiBUZW5zb3JUb0RhdGFVcmxPcHRpb25zKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBjcmVhdGVzIGFuIEltYWdlRGF0YSBpbnN0YW5jZSBmcm9tIHRlbnNvclxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgYW4gSW1hZ2VEYXRhIGluc3RhbmNlIGZyb20gdGhlIHRlbnNvci5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgZm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiBAcmV0dXJucyBhbiBJbWFnZURhdGEgaW5zdGFuY2UgcmVwcmVzZW50aW5nIHRoZSBpbWFnZSBjb252ZXJ0ZWQgZnJvbSB0ZW5zb3IgZGF0YVxuICAgKi9cbiAgdG9JbWFnZURhdGEob3B0aW9ucz86IFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyk6IEltYWdlRGF0YTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yLCBUeXBlZFRlbnNvciB9IGZyb20gJy4vdGVuc29yLmpzJztcblxuZXhwb3J0IHR5cGUgSW1hZ2VGb3JtYXQgPSAnUkdCJyB8ICdSR0JBJyB8ICdCR1InIHwgJ1JCRyc7XG5leHBvcnQgdHlwZSBJbWFnZVRlbnNvckxheW91dCA9ICdOSFdDJyB8ICdOQ0hXJztcblxuLy8gdGhlIGZvbGxvd2luZyByZWdpb24gY29udGFpbnMgdHlwZSBkZWZpbml0aW9ucyBmb3IgY29uc3RydWN0aW5nIHRlbnNvciBmcm9tIGEgc3BlY2lmaWMgbG9jYXRpb24uXG5cbi8vICNyZWdpb24gdHlwZXMgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgc3BlY2lmaWMgbG9jYXRpb25cblxuLyoqXG4gKiByZXByZXNlbnQgY29tbW9uIHByb3BlcnRpZXMgb2YgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBzcGVjaWZpYyBsb2NhdGlvbi5cbiAqL1xuaW50ZXJmYWNlIENvbW1vbkNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiBleHRlbmRzIFBpY2s8VGVuc29yLCAnZGltcyc+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLlxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogVDtcbn1cblxuLyoqXG4gKiByZXByZXNlbnQgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBHUFUgcmVzb3VyY2UuXG4gKi9cbmludGVyZmFjZSBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLlR5cGU+IHtcbiAgLyoqXG4gICAqIGFuIG9wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGRvd25sb2FkIGRhdGEgZnJvbSBHUFUgdG8gQ1BVLlxuICAgKlxuICAgKiBJZiBub3QgcHJvdmlkZWQsIHRoZSB0ZW5zb3IgdHJlYXQgdGhlIEdQVSBkYXRhIGFzIGV4dGVybmFsIHJlc291cmNlLlxuICAgKi9cbiAgZG93bmxvYWQ/KCk6IFByb21pc2U8VGVuc29yLkRhdGFUeXBlTWFwW1RdPjtcblxuICAvKipcbiAgICogYW4gb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSB0ZW5zb3IgaXMgZGlzcG9zZWQuXG4gICAqXG4gICAqIElmIG5vdCBwcm92aWRlZCwgdGhlIHRlbnNvciB0cmVhdCB0aGUgR1BVIGRhdGEgYXMgZXh0ZXJuYWwgcmVzb3VyY2UuXG4gICAqL1xuICBkaXNwb3NlPygpOiB2b2lkO1xufVxuXG4vKipcbiAqIHJlcHJlc2VudCB0aGUgcGFyYW1ldGVyIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIHBpbm5lZCBDUFUgYnVmZmVyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQgZXh0ZW5kcyBUZW5zb3IuQ3B1UGlubmVkRGF0YVR5cGVzID0gVGVuc29yLkNwdVBpbm5lZERhdGFUeXBlcz5cbiAgZXh0ZW5kcyBDb21tb25Db25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEgdG8gYmUgJ2NwdS1waW5uZWQnLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9jYXRpb246ICdjcHUtcGlubmVkJztcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIENQVSBwaW5uZWQgYnVmZmVyIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RdO1xufVxuXG4vKipcbiAqIHJlcHJlc2VudCB0aGUgcGFyYW1ldGVyIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIFdlYkdMIHRleHR1cmVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQgZXh0ZW5kcyBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcyA9IFRlbnNvci5UZXh0dXJlRGF0YVR5cGVzPlxuICBleHRlbmRzIENvbW1vbkNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPixcbiAgICBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YSB0byBiZSAndGV4dHVyZScuXG4gICAqL1xuICByZWFkb25seSBsb2NhdGlvbjogJ3RleHR1cmUnO1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgV2ViR0wgdGV4dHVyZSB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICovXG4gIHJlYWRvbmx5IHRleHR1cmU6IFRlbnNvci5UZXh0dXJlVHlwZTtcbn1cblxuLyoqXG4gKiByZXByZXNlbnQgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBXZWJHUFUgYnVmZmVyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQgZXh0ZW5kcyBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzID0gVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlcz5cbiAgZXh0ZW5kcyBDb21tb25Db25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4sXG4gICAgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEgdG8gYmUgJ2dwdS1idWZmZXInLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9jYXRpb246ICdncHUtYnVmZmVyJztcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIFdlYkdQVSBidWZmZXIgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqL1xuICByZWFkb25seSBncHVCdWZmZXI6IFRlbnNvci5HcHVCdWZmZXJUeXBlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1MVGVuc29yQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQgZXh0ZW5kcyBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXMgPSBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXM+XG4gIGV4dGVuZHMgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+LFxuICAgIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICdtbC10ZW5zb3InLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9jYXRpb246ICdtbC10ZW5zb3InO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBXZWJOTiBNTFRlbnNvciB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICovXG4gIHJlYWRvbmx5IG1sVGVuc29yOiBUZW5zb3IuTUxUZW5zb3JUeXBlO1xufVxuXG4vLyAjZW5kcmVnaW9uXG5cbi8vIHRoZSBmb2xsb3dpbmcgcmVnaW9uIGNvbnRhaW5zIHR5cGUgZGVmaW5pdGlvbnMgb2YgZWFjaCBpbmRpdmlkdWFsIG9wdGlvbnMuXG4vLyB0aGUgdGVuc29yIGZhY3RvcnkgZnVuY3Rpb25zIHVzZSBhIGNvbXBvc2l0aW9uIG9mIHRob3NlIG9wdGlvbnMgYXMgdGhlIHBhcmFtZXRlciB0eXBlLlxuXG4vLyAjcmVnaW9uIE9wdGlvbnMgZmllbGRzXG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc0Zvcm1hdCB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIGltYWdlIGZvcm1hdCByZXByZXNlbnRlZCBpbiBSR0JBIGNvbG9yIHNwYWNlLlxuICAgKi9cbiAgZm9ybWF0PzogSW1hZ2VGb3JtYXQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc1RlbnNvckZvcm1hdCB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIGltYWdlIGZvcm1hdCBvZiB0aGUgdGVuc29yLlxuICAgKlxuICAgKiBOT1RFOiB0aGlzIGlzIGRpZmZlcmVudCBmcm9tIG9wdGlvbiAnZm9ybWF0Jy4gV2hpbGUgb3B0aW9uICdmb3JtYXQnIHJlcHJlc2VudHMgdGhlIG9yaWdpbmFsIGltYWdlLCAndGVuc29yRm9ybWF0J1xuICAgKiByZXByZXNlbnRzIHRoZSB0YXJnZXQgZm9ybWF0IG9mIHRoZSB0ZW5zb3IuIEEgdHJhbnNwb3NlIHdpbGwgYmUgcGVyZm9ybWVkIGlmIHRoZXkgYXJlIGRpZmZlcmVudC5cbiAgICovXG4gIHRlbnNvckZvcm1hdD86IEltYWdlRm9ybWF0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNUZW5zb3JEYXRhVHlwZSB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLlxuICAgKi9cbiAgZGF0YVR5cGU/OiAnZmxvYXQzMicgfCAndWludDgnO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNUZW5zb3JMYXlvdXQge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSB0ZW5zb3IgbGF5b3V0IHdoZW4gcmVwcmVzZW50aW5nIGRhdGEgb2Ygb25lIG9yIG1vcmUgaW1hZ2UocykuXG4gICAqL1xuICB0ZW5zb3JMYXlvdXQ/OiBJbWFnZVRlbnNvckxheW91dDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zRGltZW5zaW9ucyB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIGltYWdlIGhlaWdodCBpbiBwaXhlbFxuICAgKi9cbiAgaGVpZ2h0PzogbnVtYmVyO1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSB3aWR0aCBpbiBwaXhlbFxuICAgKi9cbiAgd2lkdGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uUmVzaXplZERpbWVuc2lvbnMge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSByZXNpemVkIGhlaWdodC4gSWYgb21pdHRlZCwgb3JpZ2luYWwgaGVpZ2h0IHdpbGwgYmUgdXNlZC5cbiAgICovXG4gIHJlc2l6ZWRIZWlnaHQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgcmVzaXplZCB3aWR0aCAtIGNhbiBiZSBhY2Nlc3NlZCB2aWEgdGVuc29yIGRpbWVuc2lvbnMgYXMgd2VsbFxuICAgKi9cbiAgcmVzaXplZFdpZHRoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgbm9ybWFsaXphdGlvbiBwYXJhbWV0ZXJzIHdoZW4gcHJlcHJvY2Vzc2luZyB0aGUgaW1hZ2UgYXMgbW9kZWwgaW5wdXQuXG4gICAqXG4gICAqIERhdGEgZWxlbWVudCBhcmUgcmFuZ2VkIGZyb20gMCB0byAyNTUuXG4gICAqL1xuICBub3JtPzoge1xuICAgIC8qKlxuICAgICAqIFRoZSAnYmlhcycgdmFsdWUgZm9yIGltYWdlIG5vcm1hbGl6YXRpb24uXG4gICAgICogLSBJZiBvbWl0dGVkLCB1c2UgZGVmYXVsdCB2YWx1ZSAwLlxuICAgICAqIC0gSWYgaXQncyBhIHNpbmdsZSBudW1iZXIsIGFwcGx5IHRvIGVhY2ggY2hhbm5lbFxuICAgICAqIC0gSWYgaXQncyBhbiBhcnJheSBvZiAzIG9yIDQgbnVtYmVycywgYXBwbHkgZWxlbWVudC13aXNlLiBOdW1iZXIgb2YgZWxlbWVudHMgbmVlZCB0byBtYXRjaCB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzXG4gICAgICogZm9yIHRoZSBjb3JyZXNwb25kaW5nIGltYWdlIGZvcm1hdFxuICAgICAqL1xuICAgIGJpYXM/OiBudW1iZXIgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICAvKipcbiAgICAgKiBUaGUgJ21lYW4nIHZhbHVlIGZvciBpbWFnZSBub3JtYWxpemF0aW9uLlxuICAgICAqIC0gSWYgb21pdHRlZCwgdXNlIGRlZmF1bHQgdmFsdWUgMjU1LlxuICAgICAqIC0gSWYgaXQncyBhIHNpbmdsZSBudW1iZXIsIGFwcGx5IHRvIGVhY2ggY2hhbm5lbFxuICAgICAqIC0gSWYgaXQncyBhbiBhcnJheSBvZiAzIG9yIDQgbnVtYmVycywgYXBwbHkgZWxlbWVudC13aXNlLiBOdW1iZXIgb2YgZWxlbWVudHMgbmVlZCB0byBtYXRjaCB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzXG4gICAgICogZm9yIHRoZSBjb3JyZXNwb25kaW5nIGltYWdlIGZvcm1hdFxuICAgICAqL1xuICAgIG1lYW4/OiBudW1iZXIgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgfTtcbn1cblxuLy8gI2VuZHJlZ2lvblxuXG4vLyAjcmVnaW9uIE9wdGlvbnMgY29tcG9zaXRpb25cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tSW1hZ2VEYXRhT3B0aW9uc1xuICBleHRlbmRzIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLFxuICAgIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsXG4gICAgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUltYWdlRWxlbWVudE9wdGlvbnNcbiAgZXh0ZW5kcyBPcHRpb25SZXNpemVkRGltZW5zaW9ucyxcbiAgICBPcHRpb25zVGVuc29yRm9ybWF0LFxuICAgIE9wdGlvbnNUZW5zb3JMYXlvdXQsXG4gICAgT3B0aW9uc1RlbnNvckRhdGFUeXBlLFxuICAgIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21VcmxPcHRpb25zXG4gIGV4dGVuZHMgT3B0aW9uc0RpbWVuc2lvbnMsXG4gICAgT3B0aW9uUmVzaXplZERpbWVuc2lvbnMsXG4gICAgT3B0aW9uc1RlbnNvckZvcm1hdCxcbiAgICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICAgIE9wdGlvbnNUZW5zb3JEYXRhVHlwZSxcbiAgICBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tSW1hZ2VCaXRtYXBPcHRpb25zXG4gIGV4dGVuZHMgT3B0aW9uUmVzaXplZERpbWVuc2lvbnMsXG4gICAgT3B0aW9uc1RlbnNvckZvcm1hdCxcbiAgICBPcHRpb25zVGVuc29yTGF5b3V0LFxuICAgIE9wdGlvbnNUZW5zb3JEYXRhVHlwZSxcbiAgICBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnM8VCBleHRlbmRzIFRlbnNvci5UZXh0dXJlRGF0YVR5cGVzPlxuICBleHRlbmRzIFJlcXVpcmVkPE9wdGlvbnNEaW1lbnNpb25zPixcbiAgICBPcHRpb25zRm9ybWF0LFxuICAgIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IC8qIFRPRE86IGFkZCBtb3JlICovIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUdwdUJ1ZmZlck9wdGlvbnM8VCBleHRlbmRzIFRlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXM+XG4gIGV4dGVuZHMgUGljazxUZW5zb3IsICdkaW1zJz4sXG4gICAgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIGRhdGFUeXBlPzogVDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tTUxUZW5zb3JPcHRpb25zPFQgZXh0ZW5kcyBUZW5zb3IuTUxUZW5zb3JEYXRhVHlwZXM+XG4gIGV4dGVuZHMgUGljazxUZW5zb3IsICdkaW1zJz4sXG4gICAgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIGRhdGFUeXBlPzogVDtcbn1cblxuLy8gI2VuZHJlZ2lvblxuXG4vKipcbiAqIHR5cGUgVGVuc29yRmFjdG9yeSBkZWZpbmVzIHRoZSBmYWN0b3J5IGZ1bmN0aW9ucyBvZiAnVGVuc29yJyB0byBjcmVhdGUgdGVuc29yIGluc3RhbmNlcyBmcm9tIGV4aXN0aW5nIGRhdGEgb3JcbiAqIHJlc291cmNlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGYWN0b3J5IHtcbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIGFuIEltYWdlRGF0YSBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIGltYWdlRGF0YSAtIHRoZSBJbWFnZURhdGEgb2JqZWN0IHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGVuc29yIGZyb20gSW1hZ2VEYXRhLlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGB0ZW5zb3JGb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIC0gYGRhdGFUeXBlYDogYCdmbG9hdDMyJ2BcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tSW1hZ2UoXG4gICAgaW1hZ2VEYXRhOiBJbWFnZURhdGEsXG4gICAgb3B0aW9ucz86IFRlbnNvckZyb21JbWFnZURhdGFPcHRpb25zLFxuICApOiBQcm9taXNlPFR5cGVkVGVuc29yPCdmbG9hdDMyJz4gfCBUeXBlZFRlbnNvcjwndWludDgnPj47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIGEgSFRNTEltYWdlRWxlbWVudCBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIGltYWdlRWxlbWVudCAtIHRoZSBIVE1MSW1hZ2VFbGVtZW50IG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIEhUTUxJbWFnZUVsZW1lbnQuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZShcbiAgICBpbWFnZUVsZW1lbnQ6IEhUTUxJbWFnZUVsZW1lbnQsXG4gICAgb3B0aW9ucz86IFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zLFxuICApOiBQcm9taXNlPFR5cGVkVGVuc29yPCdmbG9hdDMyJz4gfCBUeXBlZFRlbnNvcjwndWludDgnPj47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIFVSTFxuICAgKlxuICAgKiBAcGFyYW0gdXJsU291cmNlIC0gYSBzdHJpbmcgYXMgYSBVUkwgdG8gdGhlIGltYWdlIG9yIGEgZGF0YSBVUkwgY29udGFpbmluZyB0aGUgaW1hZ2UgZGF0YS5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIFVSTC5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgdGVuc29yRm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiAtIGBkYXRhVHlwZWA6IGAnZmxvYXQzMidgXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbUltYWdlKHVybFNvdXJjZTogc3RyaW5nLCBvcHRpb25zPzogVGVuc29yRnJvbVVybE9wdGlvbnMpOiBQcm9taXNlPFR5cGVkVGVuc29yPCdmbG9hdDMyJz4gfCBUeXBlZFRlbnNvcjwndWludDgnPj47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIGFuIEltYWdlQml0bWFwIG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0gYml0bWFwIC0gdGhlIEltYWdlQml0bWFwIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIFVSTC5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgdGVuc29yRm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiAtIGBkYXRhVHlwZWA6IGAnZmxvYXQzMidgXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbUltYWdlKFxuICAgIGJpdG1hcDogSW1hZ2VCaXRtYXAsXG4gICAgb3B0aW9uczogVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+IHwgVHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhIFdlYkdMIHRleHR1cmVcbiAgICpcbiAgICogQHBhcmFtIHRleHR1cmUgLSB0aGUgV2ViR0xUZXh0dXJlIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIFdlYkdMIHRleHR1cmUuXG4gICAqXG4gICAqIFRoZSBvcHRpb25zIGluY2x1ZGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAqIC0gYHdpZHRoYDogdGhlIHdpZHRoIG9mIHRoZSB0ZXh0dXJlLiBSZXF1aXJlZC5cbiAgICogLSBgaGVpZ2h0YDogdGhlIGhlaWdodCBvZiB0aGUgdGV4dHVyZS4gUmVxdWlyZWQuXG4gICAqIC0gYGZvcm1hdGA6IHRoZSBmb3JtYXQgb2YgdGhlIHRleHR1cmUuIElmIG9taXR0ZWQsIGFzc3VtZSAnUkdCQScuXG4gICAqIC0gYGRvd25sb2FkYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZG93bmxvYWQgdGhlIHRlbnNvciBkYXRhIGZyb20gR1BVIHRvIENQVS4gSWYgb21pdHRlZCwgdGhlIEdQVSBkYXRhXG4gICAqIHdpbGwgbm90IGJlIGFibGUgdG8gZG93bmxvYWQuIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgYSBHUFUgYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLiBVc2VycyBkb24ndFxuICAgKiBuZWVkIHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICogLSBgZGlzcG9zZWA6IGFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGRpc3Bvc2UgdGhlIHRlbnNvciBkYXRhIG9uIEdQVS4gSWYgb21pdHRlZCwgdGhlIEdQVSBkYXRhIHdpbGwgbm90IGJlIGRpc3Bvc2VkLlxuICAgKiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IGEgR1BVIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3QgbmVlZCB0byBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqXG4gICAqIEByZXR1cm5zIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbVRleHR1cmU8VCBleHRlbmRzIFRlbnNvci5UZXh0dXJlRGF0YVR5cGVzID0gJ2Zsb2F0MzInPihcbiAgICB0ZXh0dXJlOiBUZW5zb3IuVGV4dHVyZVR5cGUsXG4gICAgb3B0aW9uczogVGVuc29yRnJvbVRleHR1cmVPcHRpb25zPFQ+LFxuICApOiBUeXBlZFRlbnNvcjwnZmxvYXQzMic+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhIFdlYkdQVSBidWZmZXJcbiAgICpcbiAgICogQHBhcmFtIGJ1ZmZlciAtIHRoZSBHUFVCdWZmZXIgb2JqZWN0IHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGVuc29yIGZyb20gV2ViR1BVIGJ1ZmZlci5cbiAgICpcbiAgICogVGhlIG9wdGlvbnMgaW5jbHVkZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAgICogLSBgZGF0YVR5cGVgOiB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGFzc3VtZSAnZmxvYXQzMicuXG4gICAqIC0gYGRpbXNgOiB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIFJlcXVpcmVkLlxuICAgKiAtIGBkb3dubG9hZGA6IGFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGRvd25sb2FkIHRoZSB0ZW5zb3IgZGF0YSBmcm9tIEdQVSB0byBDUFUuIElmIG9taXR0ZWQsIHRoZSBHUFUgZGF0YVxuICAgKiB3aWxsIG5vdCBiZSBhYmxlIHRvIGRvd25sb2FkLiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IGEgR1BVIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3RcbiAgICogbmVlZCB0byBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqIC0gYGRpc3Bvc2VgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkaXNwb3NlIHRoZSB0ZW5zb3IgZGF0YSBvbiBHUFUuIElmIG9taXR0ZWQsIHRoZSBHUFUgZGF0YSB3aWxsIG5vdCBiZSBkaXNwb3NlZC5cbiAgICogVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSBhIEdQVSBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0IG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21HcHVCdWZmZXI8VCBleHRlbmRzIFRlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXM+KFxuICAgIGJ1ZmZlcjogVGVuc29yLkdwdUJ1ZmZlclR5cGUsXG4gICAgb3B0aW9uczogVGVuc29yRnJvbUdwdUJ1ZmZlck9wdGlvbnM8VD4sXG4gICk6IFR5cGVkVGVuc29yPFQ+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhIFdlYk5OIE1MVGVuc29yXG4gICAqXG4gICAqIEBwYXJhbSB0ZW5zb3IgLSB0aGUgTUxUZW5zb3Igb2JqZWN0IHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGVuc29yIGZyb20gYSBXZWJOTiBNTFRlbnNvci5cbiAgICpcbiAgICogVGhlIG9wdGlvbnMgaW5jbHVkZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAgICogLSBgZGF0YVR5cGVgOiB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGFzc3VtZSAnZmxvYXQzMicuXG4gICAqIC0gYGRpbXNgOiB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIFJlcXVpcmVkLlxuICAgKiAtIGBkb3dubG9hZGA6IGFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGRvd25sb2FkIHRoZSB0ZW5zb3IgZGF0YSBmcm9tIHRoZSBNTFRlbnNvciB0byBDUFUuIElmIG9taXR0ZWQsIHRoZSBNTFRlbnNvclxuICAgKiBkYXRhIHdpbGwgbm90IGJlIGFibGUgdG8gZG93bmxvYWQuIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgdGhlIFdlYk5OIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy5cbiAgICogVXNlcnMgZG9uJ3QgbmVlZCB0byBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqIC0gYGRpc3Bvc2VgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkaXNwb3NlIHRoZSB0ZW5zb3IgZGF0YSBvbiB0aGUgV2ViTk4gTUxUZW5zb3IuIElmIG9taXR0ZWQsIHRoZSBNTFRlbnNvciB3aWxsXG4gICAqIG5vdCBiZSBkaXNwb3NlZC4gVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSB0aGUgV2ViTk4gYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLiBVc2VycyBkb24ndCBuZWVkIHRvXG4gICAqIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMgYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tTUxUZW5zb3I8VCBleHRlbmRzIFRlbnNvci5NTFRlbnNvckRhdGFUeXBlcz4oXG4gICAgdGVuc29yOiBUZW5zb3IuTUxUZW5zb3JUeXBlLFxuICAgIG9wdGlvbnM6IFRlbnNvckZyb21NTFRlbnNvck9wdGlvbnM8VD4sXG4gICk6IFR5cGVkVGVuc29yPFQ+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhIHByZS1hbGxvY2F0ZWQgYnVmZmVyLiBUaGUgYnVmZmVyIHdpbGwgYmUgdXNlZCBhcyBhIHBpbm5lZCBidWZmZXIuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gdGhlIHRlbnNvciBlbGVtZW50IHR5cGUuXG4gICAqIEBwYXJhbSBidWZmZXIgLSBhIFR5cGVkQXJyYXkgY29ycmVzcG9uZGluZyB0byB0aGUgdHlwZS5cbiAgICogQHBhcmFtIGRpbXMgLSBzcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbVBpbm5lZEJ1ZmZlcjxUIGV4dGVuZHMgRXhjbHVkZTxUZW5zb3IuVHlwZSwgJ3N0cmluZyc+PihcbiAgICB0eXBlOiBULFxuICAgIGJ1ZmZlcjogVGVuc29yLkRhdGFUeXBlTWFwW1RdLFxuICAgIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVHlwZWRUZW5zb3I8VD47XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogQSBzdHJpbmcgdGhhdCByZXByZXNlbnRzIGEgZmlsZSdzIFVSTCBvciBwYXRoLlxuICpcbiAqIFBhdGggaXMgdmFpbGFibGUgb25seSBpbiBvbm54cnVudGltZS1ub2RlIG9yIG9ubnhydW50aW1lLXdlYiBydW5uaW5nIGluIE5vZGUuanMuXG4gKi9cbmV4cG9ydCB0eXBlIEZpbGVVcmxPclBhdGggPSBzdHJpbmc7XG5cbi8qKlxuICogQSBCbG9iIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYSBmaWxlLlxuICovXG5leHBvcnQgdHlwZSBGaWxlQmxvYiA9IEJsb2I7XG5cbi8qKlxuICogQSBVaW50OEFycmF5LCBBcnJheUJ1ZmZlciBvciBTaGFyZWRBcnJheUJ1ZmZlciBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgZmlsZSBjb250ZW50LlxuICpcbiAqIFdoZW4gaXQgaXMgYW4gQXJyYXlCdWZmZXIgb3IgU2hhcmVkQXJyYXlCdWZmZXIsIHRoZSB3aG9sZSBidWZmZXIgaXMgYXNzdW1lZCB0byBiZSB0aGUgZmlsZSBjb250ZW50LlxuICovXG5leHBvcnQgdHlwZSBGaWxlRGF0YSA9IFVpbnQ4QXJyYXkgfCBBcnJheUJ1ZmZlckxpa2U7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIGZpbGUgdGhhdCBjYW4gYmUgbG9hZGVkIGJ5IHRoZSBPTk5YIFJ1bnRpbWUgSmF2YVNjcmlwdCBBUEkuXG4gKi9cbmV4cG9ydCB0eXBlIEZpbGVUeXBlID0gRmlsZVVybE9yUGF0aCB8IEZpbGVCbG9iIHwgRmlsZURhdGE7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBleHRlcm5hbCBkYXRhIGZpbGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXh0ZXJuYWxEYXRhRmlsZURlc2NyaXB0aW9uIHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGV4dGVybmFsIGRhdGEgZmlsZS5cbiAgICovXG4gIGRhdGE6IEZpbGVUeXBlO1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgZmlsZSBwYXRoLlxuICAgKi9cbiAgcGF0aDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gZXh0ZXJuYWwgZGF0YSBmaWxlLlxuICpcbiAqIFdoZW4gdXNpbmcgYSBzdHJpbmcsIGl0IHNob3VsZCBiZSBhIGZpbGUgVVJMIG9yIHBhdGggdGhhdCBpbiB0aGUgc2FtZSBkaXJlY3RvcnkgYXMgdGhlIG1vZGVsIGZpbGUuXG4gKi9cbmV4cG9ydCB0eXBlIEV4dGVybmFsRGF0YUZpbGVUeXBlID0gRXh0ZXJuYWxEYXRhRmlsZURlc2NyaXB0aW9uIHwgRmlsZVVybE9yUGF0aDtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBtb2RlbCBsb2FkaW5nLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE9ubnhNb2RlbE9wdGlvbnMge1xuICAvKipcbiAgICogU3BlY2lmeWluZyBhIGxpc3Qgb2YgZmlsZXMgdGhhdCByZXByZXNlbnRzIHRoZSBleHRlcm5hbCBkYXRhLlxuICAgKi9cbiAgZXh0ZXJuYWxEYXRhPzogcmVhZG9ubHkgRXh0ZXJuYWxEYXRhRmlsZVR5cGVbXTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3IuanMnO1xuXG5leHBvcnQgdHlwZSBOb25UZW5zb3JUeXBlID0gbmV2ZXI7XG5cbi8qKlxuICogVHlwZSBPbm54VmFsdWUgUmVwcmVzZW50cyBib3RoIHRlbnNvcnMgYW5kIG5vbi10ZW5zb3JzIHZhbHVlIGZvciBtb2RlbCdzIGlucHV0cy9vdXRwdXRzLlxuICpcbiAqIE5PVEU6IGN1cnJlbnRseSBub3Qgc3VwcG9ydCBub24tdGVuc29yXG4gKi9cbmV4cG9ydCB0eXBlIE9ubnhWYWx1ZSA9IFRlbnNvciB8IE5vblRlbnNvclR5cGU7XG5cbi8qKlxuICogVHlwZSBPbm54VmFsdWVEYXRhTG9jYXRpb24gcmVwcmVzZW50cyB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEgb2YgYW4gT25ueFZhbHVlLlxuICovXG5leHBvcnQgdHlwZSBPbm54VmFsdWVEYXRhTG9jYXRpb24gPSBUZW5zb3IuRGF0YUxvY2F0aW9uO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKipcbiAqICMgT05OWCBSdW50aW1lIEphdmFTY3JpcHQgQVBJXG4gKlxuICogT05OWCBSdW50aW1lIEphdmFTY3JpcHQgQVBJIGlzIGEgdW5pZmllZCBBUEkgZm9yIGFsbCBKYXZhU2NyaXB0IHVzYWdlcywgaW5jbHVkaW5nIHRoZSBmb2xsb3dpbmcgTlBNIHBhY2thZ2VzOlxuICpcbiAqIC0gW29ubnhydW50aW1lLW5vZGVdKGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL29ubnhydW50aW1lLW5vZGUpXG4gKiAtIFtvbm54cnVudGltZS13ZWJdKGh0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL29ubnhydW50aW1lLXdlYilcbiAqIC0gW29ubnhydW50aW1lLXJlYWN0LW5hdGl2ZV0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2Uvb25ueHJ1bnRpbWUtcmVhY3QtbmF0aXZlKVxuICpcbiAqIFNlZSBhbHNvOlxuICogLSBbR2V0IFN0YXJ0ZWRdKGh0dHBzOi8vb25ueHJ1bnRpbWUuYWkvZG9jcy9nZXQtc3RhcnRlZC93aXRoLWphdmFzY3JpcHQvKVxuICogLSBbSW5mZXJlbmNlIGV4YW1wbGVzXShodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhydW50aW1lLWluZmVyZW5jZS1leGFtcGxlcy90cmVlL21haW4vanMpXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9iYWNrZW5kLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vZW52LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vaW5mZXJlbmNlLXNlc3Npb24uanMnO1xuZXhwb3J0ICogZnJvbSAnLi90ZW5zb3IuanMnO1xuZXhwb3J0ICogZnJvbSAnLi90ZW5zb3ItY29udmVyc2lvbi5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdHJhY2UuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9vbm54LW1vZGVsLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vb25ueC12YWx1ZS5qcyc7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vYmFja2VuZHMvd2ViZ2wvd2ViZ2wtY29udGV4dCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBMb2dnZXIge1xuICBleHBvcnQgaW50ZXJmYWNlIFNldmVyaXR5VHlwZU1hcCB7XG4gICAgdmVyYm9zZTogJ3YnO1xuICAgIGluZm86ICdpJztcbiAgICB3YXJuaW5nOiAndyc7XG4gICAgZXJyb3I6ICdlJztcbiAgICBmYXRhbDogJ2YnO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgU2V2ZXJpdHkgPSBrZXlvZiBTZXZlcml0eVR5cGVNYXA7XG5cbiAgZXhwb3J0IHR5cGUgUHJvdmlkZXIgPSAnbm9uZScgfCAnY29uc29sZSc7XG5cbiAgLyoqXG4gICAqIExvZ2dpbmcgY29uZmlnIHRoYXQgdXNlZCB0byBjb250cm9sIHRoZSBiZWhhdmlvciBvZiBsb2dnZXJcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnIHtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBsb2dnaW5nIHByb3ZpZGVyLiAnY29uc29sZScgYnkgZGVmYXVsdFxuICAgICAqL1xuICAgIHByb3ZpZGVyPzogUHJvdmlkZXI7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgbWluaW1hbCBsb2dnZXIgc2VydmVyaXR5LiAnd2FybmluZycgYnkgZGVmYXVsdFxuICAgICAqL1xuICAgIG1pbmltYWxTZXZlcml0eT86IExvZ2dlci5TZXZlcml0eTtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIG91dHB1dCBkYXRlIHRpbWUgaW4gbG9nLiB0cnVlIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBsb2dEYXRlVGltZT86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0byBvdXRwdXQgc291cmNlIGluZm9ybWF0aW9uIChOb3QgeWV0IHN1cHBvcnRlZCkuIGZhbHNlIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBsb2dTb3VyY2VMb2NhdGlvbj86IGJvb2xlYW47XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIENhdGVnb3JpemVkTG9nZ2VyIHtcbiAgICB2ZXJib3NlKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gICAgaW5mbyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIHdhcm5pbmcoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICBlcnJvcihjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmVcbmV4cG9ydCBpbnRlcmZhY2UgTG9nZ2VyIHtcbiAgKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXI7XG5cbiAgdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB2ZXJib3NlKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGluZm8oY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgaW5mbyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIHdhcm5pbmcoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXJyb3IoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZmF0YWwoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZmF0YWwoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcblxuICAvKipcbiAgICogUmVzZXQgdGhlIGxvZ2dlciBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0gY29uZmlnIHNwZWNpZnkgYW4gb3B0aW9uYWwgZGVmYXVsdCBjb25maWdcbiAgICovXG4gIHJlc2V0KGNvbmZpZz86IExvZ2dlci5Db25maWcpOiB2b2lkO1xuICAvKipcbiAgICogU2V0IHRoZSBsb2dnZXIncyBiZWhhdmlvciBvbiB0aGUgZ2l2ZW4gY2F0ZWdvcnlcbiAgICogQHBhcmFtIGNhdGVnb3J5IHNwZWNpZnkgYSBjYXRlZ29yeSBzdHJpbmcuIElmICcqJyBpcyBzcGVjaWZpZWQsIGFsbCBwcmV2aW91cyBjb25maWd1cmF0aW9uIHdpbGwgYmUgb3ZlcndyaXR0ZW4uIElmXG4gICAqICcnIGlzIHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgYmVoYXZpb3Igd2lsbCBiZSB1cGRhdGVkLlxuICAgKiBAcGFyYW0gY29uZmlnIHRoZSBjb25maWcgb2JqZWN0IHRvIGluZGljYXRlIHRoZSBsb2dnZXIncyBiZWhhdmlvclxuICAgKi9cbiAgc2V0KGNhdGVnb3J5OiBzdHJpbmcsIGNvbmZpZzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3IgZnJvbSBvcnQtY29tbW9uIGVudlxuICAgKiBAcGFyYW0gZW52IHRoZSBlbnYgdXNlZCB0byBzZXQgbG9nZ2VyLiBDdXJyZW50bHkgb25seSBzZXR0aW5nIGxvZ2xldmVsIGlzIHN1cHBvcnRlZCB0aHJvdWdoIEVudi5cbiAgICovXG4gIHNldFdpdGhFbnYoZW52OiBFbnYpOiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nLCBjYXRlZ29yeT86IHN0cmluZyk6IHZvaWQ7XG59XG5jbGFzcyBOb09wTG9nZ2VyUHJvdmlkZXIgaW1wbGVtZW50cyBMb2dnZXJQcm92aWRlciB7XG4gIGxvZyhfc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgX2NvbnRlbnQ6IHN0cmluZywgX2NhdGVnb3J5Pzogc3RyaW5nKSB7XG4gICAgLy8gZG8gbm90aGluZ1xuICB9XG59XG5jbGFzcyBDb25zb2xlTG9nZ2VyUHJvdmlkZXIgaW1wbGVtZW50cyBMb2dnZXJQcm92aWRlciB7XG4gIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcsIGNhdGVnb3J5Pzogc3RyaW5nKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLmxvZyhgJHt0aGlzLmNvbG9yKHNldmVyaXR5KX0gJHtjYXRlZ29yeSA/ICdcXHgxYlszNW0nICsgY2F0ZWdvcnkgKyAnXFx4MWJbMG0gJyA6ICcnfSR7Y29udGVudH1gKTtcbiAgfVxuXG4gIHByaXZhdGUgY29sb3Ioc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSkge1xuICAgIHN3aXRjaCAoc2V2ZXJpdHkpIHtcbiAgICAgIGNhc2UgJ3ZlcmJvc2UnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzM0OzQwbXZcXHgxYlswbSc7XG4gICAgICBjYXNlICdpbmZvJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszMm1pXFx4MWJbMG0nO1xuICAgICAgY2FzZSAnd2FybmluZyc6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzA7NDNtd1xceDFiWzBtJztcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszMTs0MG1lXFx4MWJbMG0nO1xuICAgICAgY2FzZSAnZmF0YWwnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzEwMW1mXFx4MWJbMG0nO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBzZXZlcml0eTogJHtzZXZlcml0eX1gKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgU0VWRVJJVFlfVkFMVUUgPSB7XG4gIHZlcmJvc2U6IDEwMDAsXG4gIGluZm86IDIwMDAsXG4gIHdhcm5pbmc6IDQwMDAsXG4gIGVycm9yOiA1MDAwLFxuICBmYXRhbDogNjAwMCxcbn07XG5cbmNvbnN0IExPR0dFUl9QUk9WSURFUl9NQVA6IHsgcmVhZG9ubHkgW3Byb3ZpZGVyOiBzdHJpbmddOiBSZWFkb25seTxMb2dnZXJQcm92aWRlcj4gfSA9IHtcbiAgWydub25lJ106IG5ldyBOb09wTG9nZ2VyUHJvdmlkZXIoKSxcbiAgWydjb25zb2xlJ106IG5ldyBDb25zb2xlTG9nZ2VyUHJvdmlkZXIoKSxcbn07XG5jb25zdCBMT0dHRVJfREVGQVVMVF9DT05GSUcgPSB7XG4gIHByb3ZpZGVyOiAnY29uc29sZScsXG4gIG1pbmltYWxTZXZlcml0eTogJ3dhcm5pbmcnLFxuICBsb2dEYXRlVGltZTogdHJ1ZSxcbiAgbG9nU291cmNlTG9jYXRpb246IGZhbHNlLFxufTtcbmxldCBMT0dHRVJfQ09ORklHX01BUDogeyBbY2F0ZWdvcnk6IHN0cmluZ106IFJlYWRvbmx5PFJlcXVpcmVkPExvZ2dlci5Db25maWc+PiB9ID0ge1xuICBbJyddOiBMT0dHRVJfREVGQVVMVF9DT05GSUcgYXMgUmVxdWlyZWQ8TG9nZ2VyLkNvbmZpZz4sXG59O1xuXG5mdW5jdGlvbiBsb2coY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlcjtcbmZ1bmN0aW9uIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuZnVuY3Rpb24gbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG5mdW5jdGlvbiBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgYXJnMTogc3RyaW5nLCBhcmcyPzogc3RyaW5nKTogdm9pZDtcbmZ1bmN0aW9uIGxvZyhcbiAgYXJnMDogc3RyaW5nIHwgTG9nZ2VyLlNldmVyaXR5LFxuICBhcmcxPzogc3RyaW5nLFxuICBhcmcyPzogc3RyaW5nIHwgbnVtYmVyLFxuICBhcmczPzogbnVtYmVyLFxuKTogTG9nZ2VyLkNhdGVnb3JpemVkTG9nZ2VyIHwgdm9pZCB7XG4gIGlmIChhcmcxID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlcjtcbiAgICByZXR1cm4gY3JlYXRlQ2F0ZWdvcml6ZWRMb2dnZXIoYXJnMCk7XG4gIH0gZWxzZSBpZiAoYXJnMiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjb250ZW50KTtcbiAgICBsb2dJbnRlcm5hbChhcmcwIGFzIExvZ2dlci5TZXZlcml0eSwgYXJnMSwgMSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgPT09ICdudW1iZXInICYmIGFyZzMgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGxvZyhzZXZlcml0eSwgY29udGVudCwgc3RhY2spXG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzEsIGFyZzIpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyID09PSAnc3RyaW5nJyAmJiBhcmczID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coc2V2ZXJpdHksIGNhdGVnb3J5LCBjb250ZW50KVxuICAgIGxvZ0ludGVybmFsKGFyZzAgYXMgTG9nZ2VyLlNldmVyaXR5LCBhcmcyLCAxLCBhcmcxKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIGFyZzMgPT09ICdudW1iZXInKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjYXRlZ29yeSwgY29udGVudCwgc3RhY2spXG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzIsIGFyZzMsIGFyZzEpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2lucHV0IGlzIHZhbGlkJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2F0ZWdvcml6ZWRMb2dnZXIoY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlciB7XG4gIHJldHVybiB7XG4gICAgdmVyYm9zZTogbG9nLnZlcmJvc2UuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgaW5mbzogbG9nLmluZm8uYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgd2FybmluZzogbG9nLndhcm5pbmcuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgZXJyb3I6IGxvZy5lcnJvci5iaW5kKG51bGwsIGNhdGVnb3J5KSxcbiAgICBmYXRhbDogbG9nLmZhdGFsLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICB9O1xufVxuXG4vLyBOT1RFOiBhcmd1bWVudCAnY2F0ZWdvcnknIGlzIHB1dCB0aGUgbGFzdCBwYXJhbWV0ZXIgYmVhY2F1c2UgdHlwZXNjcmlwdFxuLy8gZG9lc24ndCBhbGxvdyBvcHRpb25hbCBhcmd1bWVudCBwdXQgaW4gZnJvbnQgb2YgcmVxdWlyZWQgYXJndW1lbnQuIFRoaXNcbi8vIG9yZGVyIGlzIGRpZmZlcmVudCBmcm9tIGEgdXN1YWwgbG9nZ2luZyBBUEkuXG5mdW5jdGlvbiBsb2dJbnRlcm5hbChzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcsIF9zdGFjazogbnVtYmVyLCBjYXRlZ29yeT86IHN0cmluZykge1xuICBjb25zdCBjb25maWcgPSBMT0dHRVJfQ09ORklHX01BUFtjYXRlZ29yeSB8fCAnJ10gfHwgTE9HR0VSX0NPTkZJR19NQVBbJyddO1xuICBpZiAoU0VWRVJJVFlfVkFMVUVbc2V2ZXJpdHldIDwgU0VWRVJJVFlfVkFMVUVbY29uZmlnLm1pbmltYWxTZXZlcml0eV0pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoY29uZmlnLmxvZ0RhdGVUaW1lKSB7XG4gICAgY29udGVudCA9IGAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX18JHtjb250ZW50fWA7XG4gIH1cblxuICBpZiAoY29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uKSB7XG4gICAgLy8gVE9ETzogY2FsY3VsYXRlIHNvdXJjZSBsb2NhdGlvbiBmcm9tICdzdGFjaydcbiAgfVxuXG4gIExPR0dFUl9QUk9WSURFUl9NQVBbY29uZmlnLnByb3ZpZGVyXS5sb2coc2V2ZXJpdHksIGNvbnRlbnQsIGNhdGVnb3J5KTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1uYW1lc3BhY2Vcbm5hbWVzcGFjZSBsb2cge1xuICBleHBvcnQgZnVuY3Rpb24gdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gdmVyYm9zZShjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gdmVyYm9zZShhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ3ZlcmJvc2UnLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gaW5mbyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gaW5mbyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gaW5mbyhhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ2luZm8nLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gd2FybmluZyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gd2FybmluZyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gd2FybmluZyhhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ3dhcm5pbmcnLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGVycm9yKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBlcnJvcihhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ2Vycm9yJywgYXJnMCwgYXJnMSk7XG4gIH1cbiAgZXhwb3J0IGZ1bmN0aW9uIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBmYXRhbChjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gZmF0YWwoYXJnMDogc3RyaW5nLCBhcmcxPzogc3RyaW5nKSB7XG4gICAgbG9nKCdmYXRhbCcsIGFyZzAsIGFyZzEpO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHJlc2V0KGNvbmZpZz86IExvZ2dlci5Db25maWcpOiB2b2lkIHtcbiAgICBMT0dHRVJfQ09ORklHX01BUCA9IHt9O1xuICAgIHNldCgnJywgY29uZmlnIHx8IHt9KTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gc2V0KGNhdGVnb3J5OiBzdHJpbmcsIGNvbmZpZzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQge1xuICAgIGlmIChjYXRlZ29yeSA9PT0gJyonKSB7XG4gICAgICByZXNldChjb25maWcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBwcmV2aW91c0NvbmZpZyA9IExPR0dFUl9DT05GSUdfTUFQW2NhdGVnb3J5XSB8fCBMT0dHRVJfREVGQVVMVF9DT05GSUc7XG4gICAgICBMT0dHRVJfQ09ORklHX01BUFtjYXRlZ29yeV0gPSB7XG4gICAgICAgIHByb3ZpZGVyOiBjb25maWcucHJvdmlkZXIgfHwgcHJldmlvdXNDb25maWcucHJvdmlkZXIsXG4gICAgICAgIG1pbmltYWxTZXZlcml0eTogY29uZmlnLm1pbmltYWxTZXZlcml0eSB8fCBwcmV2aW91c0NvbmZpZy5taW5pbWFsU2V2ZXJpdHksXG4gICAgICAgIGxvZ0RhdGVUaW1lOiBjb25maWcubG9nRGF0ZVRpbWUgPT09IHVuZGVmaW5lZCA/IHByZXZpb3VzQ29uZmlnLmxvZ0RhdGVUaW1lIDogY29uZmlnLmxvZ0RhdGVUaW1lLFxuICAgICAgICBsb2dTb3VyY2VMb2NhdGlvbjpcbiAgICAgICAgICBjb25maWcubG9nU291cmNlTG9jYXRpb24gPT09IHVuZGVmaW5lZCA/IHByZXZpb3VzQ29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uIDogY29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiB3ZSB3YW50IHRvIHN1cHBvcnQgd2lsZGNhcmQgb3IgcmVnZXg/XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gc2V0V2l0aEVudihlbnY6IEVudik6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZzogTG9nZ2VyLkNvbmZpZyA9IHt9O1xuICAgIGlmIChlbnYubG9nTGV2ZWwpIHtcbiAgICAgIGNvbmZpZy5taW5pbWFsU2V2ZXJpdHkgPSBlbnYubG9nTGV2ZWwgYXMgTG9nZ2VyLlNldmVyaXR5O1xuICAgIH1cbiAgICBzZXQoJycsIGNvbmZpZyk7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmUsIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IExvZ2dlcjogTG9nZ2VyID0gbG9nO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgUHJvZmlsZXIge1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgbWF4TnVtYmVyRXZlbnRzPzogbnVtYmVyO1xuICAgIGZsdXNoQmF0Y2hTaXplPzogbnVtYmVyO1xuICAgIGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIEV2ZW50Q2F0ZWdvcnkgPSAnc2Vzc2lvbicgfCAnbm9kZScgfCAnb3AnIHwgJ2JhY2tlbmQnO1xuXG4gIGV4cG9ydCBpbnRlcmZhY2UgRXZlbnQge1xuICAgIGVuZCgpOiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcbiAgfVxufVxuLy8gVE9ET1xuLy8gY2xhc3MgV2ViR0xFdmVudCBpbXBsZW1lbnRzIFByb2ZpbGVyLkV2ZW50IHt9XG5cbmNsYXNzIEV2ZW50IGltcGxlbWVudHMgUHJvZmlsZXIuRXZlbnQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksXG4gICAgcHVibGljIG5hbWU6IHN0cmluZyxcbiAgICBwdWJsaWMgc3RhcnRUaW1lOiBudW1iZXIsXG4gICAgcHJpdmF0ZSBlbmRDYWxsYmFjazogKGU6IEV2ZW50KSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPixcbiAgICBwdWJsaWMgdGltZXI/OiBXZWJHTFF1ZXJ5LFxuICAgIHB1YmxpYyBjdHg/OiBXZWJHTENvbnRleHQsXG4gICkge31cblxuICBhc3luYyBlbmQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5kQ2FsbGJhY2sodGhpcyk7XG4gIH1cblxuICBhc3luYyBjaGVja1RpbWVyKCk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgaWYgKHRoaXMuY3R4ID09PSB1bmRlZmluZWQgfHwgdGhpcy50aW1lciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHdlYmdsIHRpbWVyIGZvdW5kJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3R4LmVuZFRpbWVyKCk7XG4gICAgICByZXR1cm4gdGhpcy5jdHgud2FpdEZvclF1ZXJ5QW5kR2V0VGltZSh0aGlzLnRpbWVyKTtcbiAgICB9XG4gIH1cbn1cblxuY2xhc3MgRXZlbnRSZWNvcmQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksXG4gICAgcHVibGljIG5hbWU6IHN0cmluZyxcbiAgICBwdWJsaWMgc3RhcnRUaW1lOiBudW1iZXIsXG4gICAgcHVibGljIGVuZFRpbWU6IG51bWJlcixcbiAgKSB7fVxufVxuXG5leHBvcnQgY2xhc3MgUHJvZmlsZXIge1xuICBzdGF0aWMgY3JlYXRlKGNvbmZpZz86IFByb2ZpbGVyLkNvbmZpZyk6IFByb2ZpbGVyIHtcbiAgICBpZiAoY29uZmlnID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBuZXcgdGhpcygpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IHRoaXMoY29uZmlnLm1heE51bWJlckV2ZW50cywgY29uZmlnLmZsdXNoQmF0Y2hTaXplLCBjb25maWcuZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzKTtcbiAgfVxuXG4gIHByaXZhdGUgY29uc3RydWN0b3IobWF4TnVtYmVyRXZlbnRzPzogbnVtYmVyLCBmbHVzaEJhdGNoU2l6ZT86IG51bWJlciwgZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzPzogbnVtYmVyKSB7XG4gICAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX21heE51bWJlckV2ZW50cyA9IG1heE51bWJlckV2ZW50cyA9PT0gdW5kZWZpbmVkID8gMTAwMDAgOiBtYXhOdW1iZXJFdmVudHM7XG4gICAgdGhpcy5fZmx1c2hCYXRjaFNpemUgPSBmbHVzaEJhdGNoU2l6ZSA9PT0gdW5kZWZpbmVkID8gMTAgOiBmbHVzaEJhdGNoU2l6ZTtcbiAgICB0aGlzLl9mbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHMgPSBmbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHMgPT09IHVuZGVmaW5lZCA/IDUwMDAgOiBmbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHM7XG4gIH1cblxuICAvLyBzdGFydCBwcm9maWxpbmdcbiAgc3RhcnQoKSB7XG4gICAgdGhpcy5fc3RhcnRlZCA9IHRydWU7XG4gICAgdGhpcy5fdGltaW5nRXZlbnRzID0gW107XG4gICAgdGhpcy5fZmx1c2hUaW1lID0gbm93KCk7XG4gICAgdGhpcy5fZmx1c2hQb2ludGVyID0gMDtcbiAgfVxuXG4gIC8vIHN0b3AgcHJvZmlsaW5nXG4gIHN0b3AoKSB7XG4gICAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGZvciAoOyB0aGlzLl9mbHVzaFBvaW50ZXIgPCB0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoOyB0aGlzLl9mbHVzaFBvaW50ZXIrKykge1xuICAgICAgdGhpcy5sb2dPbmVFdmVudCh0aGlzLl90aW1pbmdFdmVudHNbdGhpcy5fZmx1c2hQb2ludGVyXSk7XG4gICAgfVxuICB9XG5cbiAgLy8gY3JlYXRlIGFuIGV2ZW50IHNjb3BlIGZvciB0aGUgc3BlY2lmaWMgZnVuY3Rpb25cbiAgZXZlbnQ8VD4oY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIG5hbWU6IHN0cmluZywgZnVuYzogKCkgPT4gVCwgY3R4PzogV2ViR0xDb250ZXh0KTogVDtcbiAgZXZlbnQ8VD4oY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIG5hbWU6IHN0cmluZywgZnVuYzogKCkgPT4gUHJvbWlzZTxUPiwgY3R4PzogV2ViR0xDb250ZXh0KTogUHJvbWlzZTxUPjtcblxuICBldmVudDxUPihcbiAgICBjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgZnVuYzogKCkgPT4gVCB8IFByb21pc2U8VD4sXG4gICAgY3R4PzogV2ViR0xDb250ZXh0LFxuICApOiBUIHwgUHJvbWlzZTxUPiB7XG4gICAgY29uc3QgZXZlbnQgPSB0aGlzLl9zdGFydGVkID8gdGhpcy5iZWdpbihjYXRlZ29yeSwgbmFtZSwgY3R4KSA6IHVuZGVmaW5lZDtcbiAgICBsZXQgaXNQcm9taXNlID0gZmFsc2U7XG5cbiAgICBjb25zdCByZXMgPSBmdW5jKCk7XG5cbiAgICAvLyB3ZSBjb25zaWRlciBhIHRoZW4tYWJsZSBvYmplY3QgaXMgYSBwcm9taXNlXG4gICAgaWYgKHJlcyAmJiB0eXBlb2YgKHJlcyBhcyBQcm9taXNlPFQ+KS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpc1Byb21pc2UgPSB0cnVlO1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgKHJlcyBhcyBQcm9taXNlPFQ+KS50aGVuKFxuICAgICAgICAgIGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgLy8gZnVsZmlsbGVkXG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgYXdhaXQgZXZlbnQuZW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGFzeW5jIChyZWFzb24pID0+IHtcbiAgICAgICAgICAgIC8vIHJlamVjdGVkXG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgYXdhaXQgZXZlbnQuZW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICghaXNQcm9taXNlICYmIGV2ZW50KSB7XG4gICAgICBjb25zdCBldmVudFJlcyA9IGV2ZW50LmVuZCgpO1xuICAgICAgaWYgKGV2ZW50UmVzICYmIHR5cGVvZiBldmVudFJlcy50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxUPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgZXZlbnRSZXMudGhlbihcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgLy8gZnVsZmlsbGVkXG4gICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAocmVhc29uKSA9PiB7XG4gICAgICAgICAgICAgIC8vIHJlamVjdGVkXG4gICAgICAgICAgICAgIHJlamVjdChyZWFzb24pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8vIGJlZ2luIGFuIGV2ZW50XG4gIGJlZ2luKGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LCBuYW1lOiBzdHJpbmcsIGN0eD86IFdlYkdMQ29udGV4dCk6IEV2ZW50IHtcbiAgICBpZiAoIXRoaXMuX3N0YXJ0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncHJvZmlsZXIgaXMgbm90IHN0YXJ0ZWQgeWV0Jyk7XG4gICAgfVxuICAgIGlmIChjdHggPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gbm93KCk7XG4gICAgICB0aGlzLmZsdXNoKHN0YXJ0VGltZSk7XG4gICAgICByZXR1cm4gbmV3IEV2ZW50KGNhdGVnb3J5LCBuYW1lLCBzdGFydFRpbWUsIChlKSA9PiB0aGlzLmVuZFN5bmMoZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0aW1lcjogV2ViR0xRdWVyeSA9IGN0eC5iZWdpblRpbWVyKCk7XG4gICAgICByZXR1cm4gbmV3IEV2ZW50KGNhdGVnb3J5LCBuYW1lLCAwLCBhc3luYyAoZSkgPT4gdGhpcy5lbmQoZSksIHRpbWVyLCBjdHgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVuZCB0aGUgc3BlY2lmaWMgZXZlbnRcbiAgcHJpdmF0ZSBhc3luYyBlbmQoZXZlbnQ6IEV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZW5kVGltZTogbnVtYmVyID0gYXdhaXQgZXZlbnQuY2hlY2tUaW1lcigpO1xuICAgIGlmICh0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoIDwgdGhpcy5fbWF4TnVtYmVyRXZlbnRzKSB7XG4gICAgICB0aGlzLl90aW1pbmdFdmVudHMucHVzaChuZXcgRXZlbnRSZWNvcmQoZXZlbnQuY2F0ZWdvcnksIGV2ZW50Lm5hbWUsIGV2ZW50LnN0YXJ0VGltZSwgZW5kVGltZSkpO1xuICAgICAgdGhpcy5mbHVzaChlbmRUaW1lKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVuZFN5bmMoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZW5kVGltZTogbnVtYmVyID0gbm93KCk7XG4gICAgaWYgKHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGggPCB0aGlzLl9tYXhOdW1iZXJFdmVudHMpIHtcbiAgICAgIHRoaXMuX3RpbWluZ0V2ZW50cy5wdXNoKG5ldyBFdmVudFJlY29yZChldmVudC5jYXRlZ29yeSwgZXZlbnQubmFtZSwgZXZlbnQuc3RhcnRUaW1lLCBlbmRUaW1lKSk7XG4gICAgICB0aGlzLmZsdXNoKGVuZFRpbWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9nT25lRXZlbnQoZXZlbnQ6IEV2ZW50UmVjb3JkKSB7XG4gICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICBgUHJvZmlsZXIuJHtldmVudC5jYXRlZ29yeX1gLFxuICAgICAgYCR7KGV2ZW50LmVuZFRpbWUgLSBldmVudC5zdGFydFRpbWUpLnRvRml4ZWQoMil9bXMgb24gZXZlbnQgJyR7ZXZlbnQubmFtZX0nIGF0ICR7ZXZlbnQuZW5kVGltZS50b0ZpeGVkKDIpfWAsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZmx1c2goY3VycmVudFRpbWU6IG51bWJlcikge1xuICAgIGlmIChcbiAgICAgIHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGggLSB0aGlzLl9mbHVzaFBvaW50ZXIgPj0gdGhpcy5fZmx1c2hCYXRjaFNpemUgfHxcbiAgICAgIGN1cnJlbnRUaW1lIC0gdGhpcy5fZmx1c2hUaW1lID49IHRoaXMuX2ZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kc1xuICAgICkge1xuICAgICAgLy8gc2hvdWxkIGZsdXNoIHdoZW4gZWl0aGVyIGJhdGNoIHNpemUgYWNjdW1sYXRlZCBvciBpbnRlcnZhbCBlbGVwc2VkXG5cbiAgICAgIGZvciAoXG4gICAgICAgIGNvbnN0IHByZXZpb3VzUG9pbnRlciA9IHRoaXMuX2ZsdXNoUG9pbnRlcjtcbiAgICAgICAgdGhpcy5fZmx1c2hQb2ludGVyIDwgcHJldmlvdXNQb2ludGVyICsgdGhpcy5fZmx1c2hCYXRjaFNpemUgJiYgdGhpcy5fZmx1c2hQb2ludGVyIDwgdGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5fZmx1c2hQb2ludGVyKytcbiAgICAgICkge1xuICAgICAgICB0aGlzLmxvZ09uZUV2ZW50KHRoaXMuX3RpbWluZ0V2ZW50c1t0aGlzLl9mbHVzaFBvaW50ZXJdKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fZmx1c2hUaW1lID0gbm93KCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHN0YXJ0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXJ0ZWQ7XG4gIH1cbiAgcHJpdmF0ZSBfc3RhcnRlZCA9IGZhbHNlO1xuICBwcml2YXRlIF90aW1pbmdFdmVudHM6IEV2ZW50UmVjb3JkW107XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbWF4TnVtYmVyRXZlbnRzOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZmx1c2hCYXRjaFNpemU6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBfZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSBfZmx1c2hUaW1lOiBudW1iZXI7XG4gIHByaXZhdGUgX2ZsdXNoUG9pbnRlciA9IDA7XG59XG5cbi8qKlxuICogcmV0dXJucyBhIG51bWJlciB0byByZXByZXNlbnQgdGhlIGN1cnJlbnQgdGltZXN0YW1wIGluIGEgcmVzb2x1dGlvbiBhcyBoaWdoIGFzIHBvc3NpYmxlLlxuICovXG5leHBvcnQgY29uc3Qgbm93ID0gdHlwZW9mIHBlcmZvcm1hbmNlICE9PSAndW5kZWZpbmVkJyAmJiBwZXJmb3JtYW5jZS5ub3cgPyAoKSA9PiBwZXJmb3JtYW5jZS5ub3coKSA6IERhdGUubm93O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4vb3BlcmF0b3JzJztcblxuZXhwb3J0IGludGVyZmFjZSBPcFNldCB7XG4gIGRvbWFpbjogc3RyaW5nO1xuICB2ZXJzaW9uOiBudW1iZXI7XG59XG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgT3BTZXQge1xuICAvKipcbiAgICogRG9tYWluIG9mIGFuIG9wc2V0LCBpdCBjYW4gYmUgYW4gZW1wdHkgc3RyaW5nKGRlZmF1bHQgdmFsdWUsIHJlcHJlc2VudCBmb3IgYWkub25ueCksIG9yICdhaS5vbm54Lm1sJ1xuICAgKi9cbiAgdHlwZSBEb21haW4gPSAnJyB8ICdhaS5vbm54Lm1sJyB8ICdjb20ubWljcm9zb2Z0JztcbiAgLyoqXG4gICAqIEEgcmVzb2x2ZSBydWxlIGNvbnNpc3RzIG9mIDQgb3IgNSBpdGVtczogb3BUeXBlLCBvcFNldERvbWFpbiwgdmVyc2lvblNlbGVjdG9yLCBvcGVyYXRvckltcGxlbWVudGF0aW9uIGFuZFxuICAgKiBvcGVyYXRvckluaXRpYWxpemF0aW9uIChvcHRpb25hbClcbiAgICovXG4gIHR5cGUgUmVzb2x2ZVJ1bGUgPVxuICAgIHwgW3N0cmluZywgRG9tYWluLCBzdHJpbmcsIE9wZXJhdG9ySW1wbGVtZW50YXRpb248R3JhcGguTm9kZT5dXG4gICAgfCBbc3RyaW5nLCBEb21haW4sIHN0cmluZywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjx1bmtub3duPiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbjx1bmtub3duPl07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlT3BlcmF0b3Iobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBydWxlczogcmVhZG9ubHkgT3BTZXQuUmVzb2x2ZVJ1bGVbXSkge1xuICBmb3IgKGNvbnN0IHJ1bGUgb2YgcnVsZXMpIHtcbiAgICBjb25zdCBvcFR5cGUgPSBydWxlWzBdO1xuICAgIGNvbnN0IGRvbWFpbiA9IHJ1bGVbMV07XG4gICAgY29uc3QgdmVyc2lvblNlbGVjdG9yID0gcnVsZVsyXTtcbiAgICBjb25zdCBvcEltcGwgPSBydWxlWzNdO1xuICAgIGNvbnN0IG9wSW5pdCA9IHJ1bGVbNF07XG5cbiAgICBpZiAobm9kZS5vcFR5cGUgPT09IG9wVHlwZSkge1xuICAgICAgLy8gb3BlcmF0b3IgdHlwZSBtYXRjaGVzXG4gICAgICBmb3IgKGNvbnN0IG9wc2V0IG9mIG9wc2V0cykge1xuICAgICAgICAvLyBvcHNldCAnJyBhbmQgJ2FpLm9ubngnIGFyZSBjb25zaWRlcmVkIHRoZSBzYW1lLlxuICAgICAgICBpZiAob3BzZXQuZG9tYWluID09PSBkb21haW4gfHwgKG9wc2V0LmRvbWFpbiA9PT0gJ2FpLm9ubngnICYmIGRvbWFpbiA9PT0gJycpKSB7XG4gICAgICAgICAgLy8gb3BzZXQgZG9tYWluIGZvdW5kXG4gICAgICAgICAgaWYgKG1hdGNoU2VsZWN0b3Iob3BzZXQudmVyc2lvbiwgdmVyc2lvblNlbGVjdG9yKSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgb3BJbXBsLCBvcEluaXQgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgIGBjYW5ub3QgcmVzb2x2ZSBvcGVyYXRvciAnJHtub2RlLm9wVHlwZX0nIHdpdGggb3BzZXRzOiAke29wc2V0c1xuICAgICAgLm1hcCgoc2V0KSA9PiBgJHtzZXQuZG9tYWluIHx8ICdhaS5vbm54J30gdiR7c2V0LnZlcnNpb259YClcbiAgICAgIC5qb2luKCcsICcpfWAsXG4gICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoU2VsZWN0b3IodmVyc2lvbjogbnVtYmVyLCBzZWxlY3Rvcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChzZWxlY3Rvci5lbmRzV2l0aCgnKycpKSB7XG4gICAgLy8gbWluaW11bSB2ZXJzaW9uIG1hdGNoICgnNysnIGV4cGVjdHMgdmVyc2lvbj49NylcbiAgICBjb25zdCByYW5nZVN0YXJ0ID0gTnVtYmVyLnBhcnNlSW50KHNlbGVjdG9yLnN1YnN0cmluZygwLCBzZWxlY3Rvci5sZW5ndGggLSAxKSwgMTApO1xuICAgIHJldHVybiAhaXNOYU4ocmFuZ2VTdGFydCkgJiYgcmFuZ2VTdGFydCA8PSB2ZXJzaW9uO1xuICB9IGVsc2UgaWYgKHNlbGVjdG9yLnNwbGl0KCctJykubGVuZ3RoID09PSAyKSB7XG4gICAgLy8gcmFuZ2UgbWF0Y2ggKCc2LTgnIGV4cGVjdHMgNjw9dmVyc2lvbjw9OClcbiAgICBjb25zdCBwYWlyID0gc2VsZWN0b3Iuc3BsaXQoJy0nKTtcbiAgICBjb25zdCByYW5nZVN0YXJ0ID0gTnVtYmVyLnBhcnNlSW50KHBhaXJbMF0sIDEwKTtcbiAgICBjb25zdCByYW5nZUVuZCA9IE51bWJlci5wYXJzZUludChwYWlyWzFdLCAxMCk7XG4gICAgcmV0dXJuICFpc05hTihyYW5nZVN0YXJ0KSAmJiAhaXNOYU4ocmFuZ2VFbmQpICYmIHJhbmdlU3RhcnQgPD0gdmVyc2lvbiAmJiB2ZXJzaW9uIDw9IHJhbmdlRW5kO1xuICB9IGVsc2Uge1xuICAgIC8vIGV4YWN0IG1hdGNoICgnNycgZXhwZWN0cyB2ZXJzaW9uPT09NylcbiAgICByZXR1cm4gTnVtYmVyLnBhcnNlSW50KHNlbGVjdG9yLCAxMCkgPT09IHZlcnNpb247XG4gIH1cbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcclxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcclxudmFyIEd1aWQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBHdWlkKGd1aWQpIHtcclxuICAgICAgICBpZiAoIWd1aWQpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXJndW1lbnQ7IGB2YWx1ZWAgaGFzIG5vIHZhbHVlLlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IEd1aWQuRU1QVFk7XHJcbiAgICAgICAgaWYgKGd1aWQgJiYgR3VpZC5pc0d1aWQoZ3VpZCkpIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IGd1aWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgR3VpZC5pc0d1aWQgPSBmdW5jdGlvbiAoZ3VpZCkge1xyXG4gICAgICAgIHZhciB2YWx1ZSA9IGd1aWQudG9TdHJpbmcoKTtcclxuICAgICAgICByZXR1cm4gZ3VpZCAmJiAoZ3VpZCBpbnN0YW5jZW9mIEd1aWQgfHwgR3VpZC52YWxpZGF0b3IudGVzdCh2YWx1ZSkpO1xyXG4gICAgfTtcclxuICAgIEd1aWQuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgR3VpZChbR3VpZC5nZW4oMiksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDMpXS5qb2luKFwiLVwiKSk7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5jcmVhdGVFbXB0eSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEd1aWQoXCJlbXB0eWd1aWRcIik7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5wYXJzZSA9IGZ1bmN0aW9uIChndWlkKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBHdWlkKGd1aWQpO1xyXG4gICAgfTtcclxuICAgIEd1aWQucmF3ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBbR3VpZC5nZW4oMiksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDMpXS5qb2luKFwiLVwiKTtcclxuICAgIH07XHJcbiAgICBHdWlkLmdlbiA9IGZ1bmN0aW9uIChjb3VudCkge1xyXG4gICAgICAgIHZhciBvdXQgPSBcIlwiO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xyXG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYml0d2lzZVxyXG4gICAgICAgICAgICBvdXQgKz0gKCgoMSArIE1hdGgucmFuZG9tKCkpICogMHgxMDAwMCkgfCAwKS50b1N0cmluZygxNikuc3Vic3RyaW5nKDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb3V0O1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgICAgIC8vIENvbXBhcmluZyBzdHJpbmcgYHZhbHVlYCBhZ2FpbnN0IHByb3ZpZGVkIGBndWlkYCB3aWxsIGF1dG8tY2FsbFxyXG4gICAgICAgIC8vIHRvU3RyaW5nIG9uIGBndWlkYCBmb3IgY29tcGFyaXNvblxyXG4gICAgICAgIHJldHVybiBHdWlkLmlzR3VpZChvdGhlcikgJiYgdGhpcy52YWx1ZSA9PT0gb3RoZXIudG9TdHJpbmcoKTtcclxuICAgIH07XHJcbiAgICBHdWlkLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlID09PSBHdWlkLkVNUFRZO1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZVxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgR3VpZC52YWxpZGF0b3IgPSBuZXcgUmVnRXhwKFwiXlthLXowLTldezh9LVthLXowLTldezR9LVthLXowLTldezR9LVthLXowLTldezR9LVthLXowLTldezEyfSRcIiwgXCJpXCIpO1xyXG4gICAgR3VpZC5FTVBUWSA9IFwiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCI7XHJcbiAgICByZXR1cm4gR3VpZDtcclxufSgpKTtcclxuZXhwb3J0cy5HdWlkID0gR3VpZDtcclxuIiwgIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDA5IFRoZSBDbG9zdXJlIExpYnJhcnkgQXV0aG9yc1xuICogQ29weXJpZ2h0IDIwMjAgRGFuaWVsIFdpcnR6IC8gVGhlIGxvbmcuanMgQXV0aG9ycy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuXG4vLyBXZWJBc3NlbWJseSBvcHRpbWl6YXRpb25zIHRvIGRvIG5hdGl2ZSBpNjQgbXVsdGlwbGljYXRpb24gYW5kIGRpdmlkZVxudmFyIHdhc20gPSBudWxsO1xudHJ5IHtcbiAgd2FzbSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZShuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKG5ldyBVaW50OEFycmF5KFtcbiAgICAwLCA5NywgMTE1LCAxMDksIDEsIDAsIDAsIDAsIDEsIDEzLCAyLCA5NiwgMCwgMSwgMTI3LCA5NiwgNCwgMTI3LCAxMjcsIDEyNywgMTI3LCAxLCAxMjcsIDMsIDcsIDYsIDAsIDEsIDEsIDEsIDEsIDEsIDYsIDYsIDEsIDEyNywgMSwgNjUsIDAsIDExLCA3LCA1MCwgNiwgMywgMTA5LCAxMTcsIDEwOCwgMCwgMSwgNSwgMTAwLCAxMDUsIDExOCwgOTUsIDExNSwgMCwgMiwgNSwgMTAwLCAxMDUsIDExOCwgOTUsIDExNywgMCwgMywgNSwgMTE0LCAxMDEsIDEwOSwgOTUsIDExNSwgMCwgNCwgNSwgMTE0LCAxMDEsIDEwOSwgOTUsIDExNywgMCwgNSwgOCwgMTAzLCAxMDEsIDExNiwgOTUsIDEwNCwgMTA1LCAxMDMsIDEwNCwgMCwgMCwgMTAsIDE5MSwgMSwgNiwgNCwgMCwgMzUsIDAsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjYsIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyNywgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI4LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjksIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEzMCwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMVxuICBdKSksIHt9KS5leHBvcnRzO1xufSBjYXRjaCAoZSkge1xuICAvLyBubyB3YXNtIHN1cHBvcnQgOihcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgNjQgYml0IHR3bydzLWNvbXBsZW1lbnQgaW50ZWdlciwgZ2l2ZW4gaXRzIGxvdyBhbmQgaGlnaCAzMiBiaXQgdmFsdWVzIGFzICpzaWduZWQqIGludGVnZXJzLlxuICogIFNlZSB0aGUgZnJvbSogZnVuY3Rpb25zIGJlbG93IGZvciBtb3JlIGNvbnZlbmllbnQgd2F5cyBvZiBjb25zdHJ1Y3RpbmcgTG9uZ3MuXG4gKiBAZXhwb3J0cyBMb25nXG4gKiBAY2xhc3MgQSBMb25nIGNsYXNzIGZvciByZXByZXNlbnRpbmcgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyIHZhbHVlLlxuICogQHBhcmFtIHtudW1iZXJ9IGxvdyBUaGUgbG93IChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoIFRoZSBoaWdoIChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBMb25nKGxvdywgaGlnaCwgdW5zaWduZWQpIHtcblxuICAvKipcbiAgICogVGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgdGhpcy5sb3cgPSBsb3cgfCAwO1xuXG4gIC8qKlxuICAgKiBUaGUgaGlnaCAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgdGhpcy5oaWdoID0gaGlnaCB8IDA7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIHRoaXMudW5zaWduZWQgPSAhIXVuc2lnbmVkO1xufVxuXG4vLyBUaGUgaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gb2YgYSBsb25nIGlzIHRoZSB0d28gZ2l2ZW4gc2lnbmVkLCAzMi1iaXQgdmFsdWVzLlxuLy8gV2UgdXNlIDMyLWJpdCBwaWVjZXMgYmVjYXVzZSB0aGVzZSBhcmUgdGhlIHNpemUgb2YgaW50ZWdlcnMgb24gd2hpY2hcbi8vIEphdmFzY3JpcHQgcGVyZm9ybXMgYml0LW9wZXJhdGlvbnMuICBGb3Igb3BlcmF0aW9ucyBsaWtlIGFkZGl0aW9uIGFuZFxuLy8gbXVsdGlwbGljYXRpb24sIHdlIHNwbGl0IGVhY2ggbnVtYmVyIGludG8gMTYgYml0IHBpZWNlcywgd2hpY2ggY2FuIGVhc2lseSBiZVxuLy8gbXVsdGlwbGllZCB3aXRoaW4gSmF2YXNjcmlwdCdzIGZsb2F0aW5nLXBvaW50IHJlcHJlc2VudGF0aW9uIHdpdGhvdXQgb3ZlcmZsb3dcbi8vIG9yIGNoYW5nZSBpbiBzaWduLlxuLy9cbi8vIEluIHRoZSBhbGdvcml0aG1zIGJlbG93LCB3ZSBmcmVxdWVudGx5IHJlZHVjZSB0aGUgbmVnYXRpdmUgY2FzZSB0byB0aGVcbi8vIHBvc2l0aXZlIGNhc2UgYnkgbmVnYXRpbmcgdGhlIGlucHV0KHMpIGFuZCB0aGVuIHBvc3QtcHJvY2Vzc2luZyB0aGUgcmVzdWx0LlxuLy8gTm90ZSB0aGF0IHdlIG11c3QgQUxXQVlTIGNoZWNrIHNwZWNpYWxseSB3aGV0aGVyIHRob3NlIHZhbHVlcyBhcmUgTUlOX1ZBTFVFXG4vLyAoLTJeNjMpIGJlY2F1c2UgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUUgKHNpbmNlIDJeNjMgY2Fubm90IGJlIHJlcHJlc2VudGVkIGFzXG4vLyBhIHBvc2l0aXZlIG51bWJlciwgaXQgb3ZlcmZsb3dzIGJhY2sgaW50byBhIG5lZ2F0aXZlKS4gIE5vdCBoYW5kbGluZyB0aGlzXG4vLyBjYXNlIHdvdWxkIG9mdGVuIHJlc3VsdCBpbiBpbmZpbml0ZSByZWN1cnNpb24uXG4vL1xuLy8gQ29tbW9uIGNvbnN0YW50IHZhbHVlcyBaRVJPLCBPTkUsIE5FR19PTkUsIGV0Yy4gYXJlIGRlZmluZWQgYmVsb3cgdGhlIGZyb20qXG4vLyBtZXRob2RzIG9uIHdoaWNoIHRoZXkgZGVwZW5kLlxuXG4vKipcbiAqIEFuIGluZGljYXRvciB1c2VkIHRvIHJlbGlhYmx5IGRldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBMb25nIG9yIG5vdC5cbiAqIEB0eXBlIHtib29sZWFufVxuICogQGNvbnN0XG4gKiBAcHJpdmF0ZVxuICovXG5Mb25nLnByb3RvdHlwZS5fX2lzTG9uZ19fO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoTG9uZy5wcm90b3R5cGUsIFwiX19pc0xvbmdfX1wiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqIEBpbm5lclxuICovXG5mdW5jdGlvbiBpc0xvbmcob2JqKSB7XG4gIHJldHVybiAob2JqICYmIG9ialtcIl9faXNMb25nX19cIl0pID09PSB0cnVlO1xufVxuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHsqfSB2YWx1ZSBudW1iZXJcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gY3R6MzIodmFsdWUpIHtcbiAgdmFyIGMgPSBNYXRoLmNsejMyKHZhbHVlICYgLXZhbHVlKTtcbiAgcmV0dXJuIHZhbHVlID8gMzEgLSBjIDogYztcbn1cblxuLyoqXG4gKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhIExvbmcuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7Kn0gb2JqIE9iamVjdFxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmcuaXNMb25nID0gaXNMb25nO1xuXG4vKipcbiAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIGludGVnZXIgdmFsdWVzLlxuICogQHR5cGUgeyFPYmplY3R9XG4gKiBAaW5uZXJcbiAqL1xudmFyIElOVF9DQUNIRSA9IHt9O1xuXG4vKipcbiAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLlxuICogQHR5cGUgeyFPYmplY3R9XG4gKiBAaW5uZXJcbiAqL1xudmFyIFVJTlRfQ0FDSEUgPSB7fTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbUludCh2YWx1ZSwgdW5zaWduZWQpIHtcbiAgdmFyIG9iaiwgY2FjaGVkT2JqLCBjYWNoZTtcbiAgaWYgKHVuc2lnbmVkKSB7XG4gICAgdmFsdWUgPj4+PSAwO1xuICAgIGlmIChjYWNoZSA9ICgwIDw9IHZhbHVlICYmIHZhbHVlIDwgMjU2KSkge1xuICAgICAgY2FjaGVkT2JqID0gVUlOVF9DQUNIRVt2YWx1ZV07XG4gICAgICBpZiAoY2FjaGVkT2JqKVxuICAgICAgICByZXR1cm4gY2FjaGVkT2JqO1xuICAgIH1cbiAgICBvYmogPSBmcm9tQml0cyh2YWx1ZSwgMCwgdHJ1ZSk7XG4gICAgaWYgKGNhY2hlKVxuICAgICAgVUlOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XG4gICAgcmV0dXJuIG9iajtcbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSB8PSAwO1xuICAgIGlmIChjYWNoZSA9ICgtMTI4IDw9IHZhbHVlICYmIHZhbHVlIDwgMTI4KSkge1xuICAgICAgY2FjaGVkT2JqID0gSU5UX0NBQ0hFW3ZhbHVlXTtcbiAgICAgIGlmIChjYWNoZWRPYmopXG4gICAgICAgIHJldHVybiBjYWNoZWRPYmo7XG4gICAgfVxuICAgIG9iaiA9IGZyb21CaXRzKHZhbHVlLCB2YWx1ZSA8IDAgPyAtMSA6IDAsIGZhbHNlKTtcbiAgICBpZiAoY2FjaGUpXG4gICAgICBJTlRfQ0FDSEVbdmFsdWVdID0gb2JqO1xuICAgIHJldHVybiBvYmo7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIDMyIGJpdCBpbnRlZ2VyIHZhbHVlLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIDMyIGJpdCBpbnRlZ2VyIGluIHF1ZXN0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tSW50ID0gZnJvbUludDtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSwgdW5zaWduZWQpIHtcbiAgaWYgKGlzTmFOKHZhbHVlKSlcbiAgICByZXR1cm4gdW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gIGlmICh1bnNpZ25lZCkge1xuICAgIGlmICh2YWx1ZSA8IDApXG4gICAgICByZXR1cm4gVVpFUk87XG4gICAgaWYgKHZhbHVlID49IFRXT19QV1JfNjRfREJMKVxuICAgICAgcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRTtcbiAgfSBlbHNlIHtcbiAgICBpZiAodmFsdWUgPD0gLVRXT19QV1JfNjNfREJMKVxuICAgICAgcmV0dXJuIE1JTl9WQUxVRTtcbiAgICBpZiAodmFsdWUgKyAxID49IFRXT19QV1JfNjNfREJMKVxuICAgICAgcmV0dXJuIE1BWF9WQUxVRTtcbiAgfVxuICBpZiAodmFsdWUgPCAwKVxuICAgIHJldHVybiBmcm9tTnVtYmVyKC12YWx1ZSwgdW5zaWduZWQpLm5lZygpO1xuICByZXR1cm4gZnJvbUJpdHMoKHZhbHVlICUgVFdPX1BXUl8zMl9EQkwpIHwgMCwgKHZhbHVlIC8gVFdPX1BXUl8zMl9EQkwpIHwgMCwgdW5zaWduZWQpO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gdmFsdWUsIHByb3ZpZGVkIHRoYXQgaXQgaXMgYSBmaW5pdGUgbnVtYmVyLiBPdGhlcndpc2UsIHplcm8gaXMgcmV0dXJuZWQuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgbnVtYmVyIGluIHF1ZXN0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tTnVtYmVyID0gZnJvbU51bWJlcjtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gbG93Qml0c1xuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGZyb21CaXRzKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCkge1xuICByZXR1cm4gbmV3IExvbmcobG93Qml0cywgaGlnaEJpdHMsIHVuc2lnbmVkKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIDY0IGJpdCBpbnRlZ2VyIHRoYXQgY29tZXMgYnkgY29uY2F0ZW5hdGluZyB0aGUgZ2l2ZW4gbG93IGFuZCBoaWdoIGJpdHMuIEVhY2ggaXNcbiAqICBhc3N1bWVkIHRvIHVzZSAzMiBiaXRzLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gbG93Qml0cyBUaGUgbG93IDMyIGJpdHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoQml0cyBUaGUgaGlnaCAzMiBiaXRzXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tQml0cyA9IGZyb21CaXRzO1xuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGJhc2VcbiAqIEBwYXJhbSB7bnVtYmVyfSBleHBvbmVudFxuICogQHJldHVybnMge251bWJlcn1cbiAqIEBpbm5lclxuICovXG52YXIgcG93X2RibCA9IE1hdGgucG93OyAvLyBVc2VkIDQgdGltZXMgKDQqOCB0byAxNSs0KVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7KGJvb2xlYW58bnVtYmVyKT19IHVuc2lnbmVkXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4XG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbVN0cmluZyhzdHIsIHVuc2lnbmVkLCByYWRpeCkge1xuICBpZiAoc3RyLmxlbmd0aCA9PT0gMClcbiAgICB0aHJvdyBFcnJvcignZW1wdHkgc3RyaW5nJyk7XG4gIGlmICh0eXBlb2YgdW5zaWduZWQgPT09ICdudW1iZXInKSB7XG4gICAgLy8gRm9yIGdvb2cubWF0aC5sb25nIGNvbXBhdGliaWxpdHlcbiAgICByYWRpeCA9IHVuc2lnbmVkO1xuICAgIHVuc2lnbmVkID0gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgdW5zaWduZWQgPSAhIXVuc2lnbmVkO1xuICB9XG4gIGlmIChzdHIgPT09IFwiTmFOXCIgfHwgc3RyID09PSBcIkluZmluaXR5XCIgfHwgc3RyID09PSBcIitJbmZpbml0eVwiIHx8IHN0ciA9PT0gXCItSW5maW5pdHlcIilcbiAgICByZXR1cm4gdW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gIHJhZGl4ID0gcmFkaXggfHwgMTA7XG4gIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeClcbiAgICB0aHJvdyBSYW5nZUVycm9yKCdyYWRpeCcpO1xuXG4gIHZhciBwO1xuICBpZiAoKHAgPSBzdHIuaW5kZXhPZignLScpKSA+IDApXG4gICAgdGhyb3cgRXJyb3IoJ2ludGVyaW9yIGh5cGhlbicpO1xuICBlbHNlIGlmIChwID09PSAwKSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcoc3RyLnN1YnN0cmluZygxKSwgdW5zaWduZWQsIHJhZGl4KS5uZWcoKTtcbiAgfVxuXG4gIC8vIERvIHNldmVyYWwgKDgpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cbiAgLy8gbWluaW1pemUgdGhlIGNhbGxzIHRvIHRoZSB2ZXJ5IGV4cGVuc2l2ZSBlbXVsYXRlZCBkaXYuXG4gIHZhciByYWRpeFRvUG93ZXIgPSBmcm9tTnVtYmVyKHBvd19kYmwocmFkaXgsIDgpKTtcblxuICB2YXIgcmVzdWx0ID0gWkVSTztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpICs9IDgpIHtcbiAgICB2YXIgc2l6ZSA9IE1hdGgubWluKDgsIHN0ci5sZW5ndGggLSBpKSxcbiAgICAgIHZhbHVlID0gcGFyc2VJbnQoc3RyLnN1YnN0cmluZyhpLCBpICsgc2l6ZSksIHJhZGl4KTtcbiAgICBpZiAoc2l6ZSA8IDgpIHtcbiAgICAgIHZhciBwb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgc2l6ZSkpO1xuICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChwb3dlcikuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChyYWRpeFRvUG93ZXIpO1xuICAgICAgcmVzdWx0ID0gcmVzdWx0LmFkZChmcm9tTnVtYmVyKHZhbHVlKSk7XG4gICAgfVxuICB9XG4gIHJlc3VsdC51bnNpZ25lZCA9IHVuc2lnbmVkO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBzdHJpbmcsIHdyaXR0ZW4gdXNpbmcgdGhlIHNwZWNpZmllZCByYWRpeC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciBUaGUgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgTG9uZ1xuICogQHBhcmFtIHsoYm9vbGVhbnxudW1iZXIpPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHBhcmFtIHtudW1iZXI9fSByYWRpeCBUaGUgcmFkaXggaW4gd2hpY2ggdGhlIHRleHQgaXMgd3JpdHRlbiAoMi0zNiksIGRlZmF1bHRzIHRvIDEwXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tU3RyaW5nID0gZnJvbVN0cmluZztcblxuLyoqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxuICogQHJldHVybnMgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGZyb21WYWx1ZSh2YWwsIHVuc2lnbmVkKSB7XG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJylcbiAgICByZXR1cm4gZnJvbU51bWJlcih2YWwsIHVuc2lnbmVkKTtcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKVxuICAgIHJldHVybiBmcm9tU3RyaW5nKHZhbCwgdW5zaWduZWQpO1xuICAvLyBUaHJvd3MgZm9yIG5vbi1vYmplY3RzLCBjb252ZXJ0cyBub24taW5zdGFuY2VvZiBMb25nOlxuICByZXR1cm4gZnJvbUJpdHModmFsLmxvdywgdmFsLmhpZ2gsIHR5cGVvZiB1bnNpZ25lZCA9PT0gJ2Jvb2xlYW4nID8gdW5zaWduZWQgOiB2YWwudW5zaWduZWQpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgdmFsdWUgdG8gYSBMb25nIHVzaW5nIHRoZSBhcHByb3ByaWF0ZSBmcm9tKiBmdW5jdGlvbiBmb3IgaXRzIHR5cGUuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsIFZhbHVlXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmcuZnJvbVZhbHVlID0gZnJvbVZhbHVlO1xuXG4vLyBOT1RFOiB0aGUgY29tcGlsZXIgc2hvdWxkIGlubGluZSB0aGVzZSBjb25zdGFudCB2YWx1ZXMgYmVsb3cgYW5kIHRoZW4gcmVtb3ZlIHRoZXNlIHZhcmlhYmxlcywgc28gdGhlcmUgc2hvdWxkIGJlXG4vLyBubyBydW50aW1lIHBlbmFsdHkgZm9yIHRoZXNlLlxuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl8xNl9EQkwgPSAxIDw8IDE2O1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl8yNF9EQkwgPSAxIDw8IDI0O1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl8zMl9EQkwgPSBUV09fUFdSXzE2X0RCTCAqIFRXT19QV1JfMTZfREJMO1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl82NF9EQkwgPSBUV09fUFdSXzMyX0RCTCAqIFRXT19QV1JfMzJfREJMO1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl82M19EQkwgPSBUV09fUFdSXzY0X0RCTCAvIDI7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGNvbnN0XG4gKiBAaW5uZXJcbiAqL1xudmFyIFRXT19QV1JfMjQgPSBmcm9tSW50KFRXT19QV1JfMjRfREJMKTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIFpFUk8gPSBmcm9tSW50KDApO1xuXG4vKipcbiAqIFNpZ25lZCB6ZXJvLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLlpFUk8gPSBaRVJPO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgVVpFUk8gPSBmcm9tSW50KDAsIHRydWUpO1xuXG4vKipcbiAqIFVuc2lnbmVkIHplcm8uXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuVVpFUk8gPSBVWkVSTztcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE9ORSA9IGZyb21JbnQoMSk7XG5cbi8qKlxuICogU2lnbmVkIG9uZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5PTkUgPSBPTkU7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBVT05FID0gZnJvbUludCgxLCB0cnVlKTtcblxuLyoqXG4gKiBVbnNpZ25lZCBvbmUuXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuVU9ORSA9IFVPTkU7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBORUdfT05FID0gZnJvbUludCgtMSk7XG5cbi8qKlxuICogU2lnbmVkIG5lZ2F0aXZlIG9uZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5ORUdfT05FID0gTkVHX09ORTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE1BWF9WQUxVRSA9IGZyb21CaXRzKDB4RkZGRkZGRkYgfCAwLCAweDdGRkZGRkZGIHwgMCwgZmFsc2UpO1xuXG4vKipcbiAqIE1heGltdW0gc2lnbmVkIHZhbHVlLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk1BWF9WQUxVRSA9IE1BWF9WQUxVRTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE1BWF9VTlNJR05FRF9WQUxVRSA9IGZyb21CaXRzKDB4RkZGRkZGRkYgfCAwLCAweEZGRkZGRkZGIHwgMCwgdHJ1ZSk7XG5cbi8qKlxuICogTWF4aW11bSB1bnNpZ25lZCB2YWx1ZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5NQVhfVU5TSUdORURfVkFMVUUgPSBNQVhfVU5TSUdORURfVkFMVUU7XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBNSU5fVkFMVUUgPSBmcm9tQml0cygwLCAweDgwMDAwMDAwIHwgMCwgZmFsc2UpO1xuXG4vKipcbiAqIE1pbmltdW0gc2lnbmVkIHZhbHVlLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk1JTl9WQUxVRSA9IE1JTl9WQUxVRTtcblxuLyoqXG4gKiBAYWxpYXMgTG9uZy5wcm90b3R5cGVcbiAqIEBpbm5lclxuICovXG52YXIgTG9uZ1Byb3RvdHlwZSA9IExvbmcucHJvdG90eXBlO1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgMzIgYml0IGludGVnZXIsIGFzc3VtaW5nIGl0IGlzIGEgMzIgYml0IGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLnRvSW50ID0gZnVuY3Rpb24gdG9JbnQoKSB7XG4gIHJldHVybiB0aGlzLnVuc2lnbmVkID8gdGhpcy5sb3cgPj4+IDAgOiB0aGlzLmxvdztcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhlIExvbmcgdG8gYSB0aGUgbmVhcmVzdCBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZhbHVlIChkb3VibGUsIDUzIGJpdCBtYW50aXNzYSkuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIoKSB7XG4gIGlmICh0aGlzLnVuc2lnbmVkKVxuICAgIHJldHVybiAoKHRoaXMuaGlnaCA+Pj4gMCkgKiBUV09fUFdSXzMyX0RCTCkgKyAodGhpcy5sb3cgPj4+IDApO1xuICByZXR1cm4gdGhpcy5oaWdoICogVFdPX1BXUl8zMl9EQkwgKyAodGhpcy5sb3cgPj4+IDApO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBhIHN0cmluZyB3cml0dGVuIGluIHRoZSBzcGVjaWZpZWQgcmFkaXguXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFJhZGl4ICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKiBAb3ZlcnJpZGVcbiAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGByYWRpeGAgaXMgb3V0IG9mIHJhbmdlXG4gKi9cbkxvbmdQcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhyYWRpeCkge1xuICByYWRpeCA9IHJhZGl4IHx8IDEwO1xuICBpZiAocmFkaXggPCAyIHx8IDM2IDwgcmFkaXgpXG4gICAgdGhyb3cgUmFuZ2VFcnJvcigncmFkaXgnKTtcbiAgaWYgKHRoaXMuaXNaZXJvKCkpXG4gICAgcmV0dXJuICcwJztcbiAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7IC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxuICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gY2hhbmdlIHRoZSBMb25nIHZhbHVlIGJlZm9yZSBpdCBjYW4gYmUgbmVnYXRlZCwgc28gd2UgcmVtb3ZlXG4gICAgICAvLyB0aGUgYm90dG9tLW1vc3QgZGlnaXQgaW4gdGhpcyBiYXNlIGFuZCB0aGVuIHJlY3Vyc2UgdG8gZG8gdGhlIHJlc3QuXG4gICAgICB2YXIgcmFkaXhMb25nID0gZnJvbU51bWJlcihyYWRpeCksXG4gICAgICAgIGRpdiA9IHRoaXMuZGl2KHJhZGl4TG9uZyksXG4gICAgICAgIHJlbTEgPSBkaXYubXVsKHJhZGl4TG9uZykuc3ViKHRoaXMpO1xuICAgICAgcmV0dXJuIGRpdi50b1N0cmluZyhyYWRpeCkgKyByZW0xLnRvSW50KCkudG9TdHJpbmcocmFkaXgpO1xuICAgIH0gZWxzZVxuICAgICAgcmV0dXJuICctJyArIHRoaXMubmVnKCkudG9TdHJpbmcocmFkaXgpO1xuICB9XG5cbiAgLy8gRG8gc2V2ZXJhbCAoNikgZGlnaXRzIGVhY2ggdGltZSB0aHJvdWdoIHRoZSBsb29wLCBzbyBhcyB0b1xuICAvLyBtaW5pbWl6ZSB0aGUgY2FsbHMgdG8gdGhlIHZlcnkgZXhwZW5zaXZlIGVtdWxhdGVkIGRpdi5cbiAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgNiksIHRoaXMudW5zaWduZWQpLFxuICAgIHJlbSA9IHRoaXM7XG4gIHZhciByZXN1bHQgPSAnJztcbiAgd2hpbGUgKHRydWUpIHtcbiAgICB2YXIgcmVtRGl2ID0gcmVtLmRpdihyYWRpeFRvUG93ZXIpLFxuICAgICAgaW50dmFsID0gcmVtLnN1YihyZW1EaXYubXVsKHJhZGl4VG9Qb3dlcikpLnRvSW50KCkgPj4+IDAsXG4gICAgICBkaWdpdHMgPSBpbnR2YWwudG9TdHJpbmcocmFkaXgpO1xuICAgIHJlbSA9IHJlbURpdjtcbiAgICBpZiAocmVtLmlzWmVybygpKVxuICAgICAgcmV0dXJuIGRpZ2l0cyArIHJlc3VsdDtcbiAgICBlbHNlIHtcbiAgICAgIHdoaWxlIChkaWdpdHMubGVuZ3RoIDwgNilcbiAgICAgICAgZGlnaXRzID0gJzAnICsgZGlnaXRzO1xuICAgICAgcmVzdWx0ID0gJycgKyBkaWdpdHMgKyByZXN1bHQ7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIGhpZ2ggMzIgYml0cyBhcyBhIHNpZ25lZCBpbnRlZ2VyLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn0gU2lnbmVkIGhpZ2ggYml0c1xuICovXG5Mb25nUHJvdG90eXBlLmdldEhpZ2hCaXRzID0gZnVuY3Rpb24gZ2V0SGlnaEJpdHMoKSB7XG4gIHJldHVybiB0aGlzLmhpZ2g7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIGhpZ2ggMzIgYml0cyBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgaGlnaCBiaXRzXG4gKi9cbkxvbmdQcm90b3R5cGUuZ2V0SGlnaEJpdHNVbnNpZ25lZCA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzVW5zaWduZWQoKSB7XG4gIHJldHVybiB0aGlzLmhpZ2ggPj4+IDA7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgbG93IGJpdHNcbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzID0gZnVuY3Rpb24gZ2V0TG93Qml0cygpIHtcbiAgcmV0dXJuIHRoaXMubG93O1xufTtcblxuLyoqXG4gKiBHZXRzIHRoZSBsb3cgMzIgYml0cyBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgbG93IGJpdHNcbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzVW5zaWduZWQgPSBmdW5jdGlvbiBnZXRMb3dCaXRzVW5zaWduZWQoKSB7XG4gIHJldHVybiB0aGlzLmxvdyA+Pj4gMDtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIGJpdHMgbmVlZGVkIHRvIHJlcHJlc2VudCB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhpcyBMb25nLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZXROdW1CaXRzQWJzID0gZnVuY3Rpb24gZ2V0TnVtQml0c0FicygpIHtcbiAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSAvLyBVbnNpZ25lZCBMb25ncyBhcmUgbmV2ZXIgbmVnYXRpdmVcbiAgICByZXR1cm4gdGhpcy5lcShNSU5fVkFMVUUpID8gNjQgOiB0aGlzLm5lZygpLmdldE51bUJpdHNBYnMoKTtcbiAgdmFyIHZhbCA9IHRoaXMuaGlnaCAhPSAwID8gdGhpcy5oaWdoIDogdGhpcy5sb3c7XG4gIGZvciAodmFyIGJpdCA9IDMxOyBiaXQgPiAwOyBiaXQtLSlcbiAgICBpZiAoKHZhbCAmICgxIDw8IGJpdCkpICE9IDApXG4gICAgICBicmVhaztcbiAgcmV0dXJuIHRoaXMuaGlnaCAhPSAwID8gYml0ICsgMzMgOiBiaXQgKyAxO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgemVyby5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmlzWmVybyA9IGZ1bmN0aW9uIGlzWmVybygpIHtcbiAgcmV0dXJuIHRoaXMuaGlnaCA9PT0gMCAmJiB0aGlzLmxvdyA9PT0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHplcm8uIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjaXNaZXJvfS5cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmVxeiA9IExvbmdQcm90b3R5cGUuaXNaZXJvO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG5lZ2F0aXZlLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuaXNOZWdhdGl2ZSA9IGZ1bmN0aW9uIGlzTmVnYXRpdmUoKSB7XG4gIHJldHVybiAhdGhpcy51bnNpZ25lZCAmJiB0aGlzLmhpZ2ggPCAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBwb3NpdGl2ZSBvciB6ZXJvLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuaXNQb3NpdGl2ZSA9IGZ1bmN0aW9uIGlzUG9zaXRpdmUoKSB7XG4gIHJldHVybiB0aGlzLnVuc2lnbmVkIHx8IHRoaXMuaGlnaCA+PSAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBvZGQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5pc09kZCA9IGZ1bmN0aW9uIGlzT2RkKCkge1xuICByZXR1cm4gKHRoaXMubG93ICYgMSkgPT09IDE7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGV2ZW4uXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5pc0V2ZW4gPSBmdW5jdGlvbiBpc0V2ZW4oKSB7XG4gIHJldHVybiAodGhpcy5sb3cgJiAxKSA9PT0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyhvdGhlcikge1xuICBpZiAoIWlzTG9uZyhvdGhlcikpXG4gICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICBpZiAodGhpcy51bnNpZ25lZCAhPT0gb3RoZXIudW5zaWduZWQgJiYgKHRoaXMuaGlnaCA+Pj4gMzEpID09PSAxICYmIChvdGhlci5oaWdoID4+PiAzMSkgPT09IDEpXG4gICAgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdGhpcy5oaWdoID09PSBvdGhlci5oaWdoICYmIHRoaXMubG93ID09PSBvdGhlci5sb3c7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZXF1YWxzfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZXEgPSBMb25nUHJvdG90eXBlLmVxdWFscztcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubm90RXF1YWxzID0gZnVuY3Rpb24gbm90RXF1YWxzKG90aGVyKSB7XG4gIHJldHVybiAhdGhpcy5lcSgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI25vdEVxdWFsc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLm5lcSA9IExvbmdQcm90b3R5cGUubm90RXF1YWxzO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubmUgPSBMb25nUHJvdG90eXBlLm5vdEVxdWFscztcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubGVzc1RoYW4gPSBmdW5jdGlvbiBsZXNzVGhhbihvdGhlcikge1xuICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPCAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFufS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubHQgPSBMb25nUHJvdG90eXBlLmxlc3NUaGFuO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBsZXNzVGhhbk9yRXF1YWwob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpIDw9IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW5PckVxdWFsfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubHRlID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWw7XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbk9yRXF1YWx9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5sZSA9IExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbiA9IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuKG90aGVyKSB7XG4gIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA+IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW59LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ndCA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW47XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbCA9IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuT3JFcXVhbChvdGhlcikge1xuICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPj0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbk9yRXF1YWx9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ndGUgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbDtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2dyZWF0ZXJUaGFuT3JFcXVhbH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmdlID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWw7XG5cbi8qKlxuICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7bnVtYmVyfSAwIGlmIHRoZXkgYXJlIHRoZSBzYW1lLCAxIGlmIHRoZSB0aGlzIGlzIGdyZWF0ZXIgYW5kIC0xXG4gKiAgaWYgdGhlIGdpdmVuIG9uZSBpcyBncmVhdGVyXG4gKi9cbkxvbmdQcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUob3RoZXIpIHtcbiAgaWYgKCFpc0xvbmcob3RoZXIpKVxuICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcbiAgaWYgKHRoaXMuZXEob3RoZXIpKVxuICAgIHJldHVybiAwO1xuICB2YXIgdGhpc05lZyA9IHRoaXMuaXNOZWdhdGl2ZSgpLFxuICAgIG90aGVyTmVnID0gb3RoZXIuaXNOZWdhdGl2ZSgpO1xuICBpZiAodGhpc05lZyAmJiAhb3RoZXJOZWcpXG4gICAgcmV0dXJuIC0xO1xuICBpZiAoIXRoaXNOZWcgJiYgb3RoZXJOZWcpXG4gICAgcmV0dXJuIDE7XG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHNpZ24gYml0cyBhcmUgdGhlIHNhbWVcbiAgaWYgKCF0aGlzLnVuc2lnbmVkKVxuICAgIHJldHVybiB0aGlzLnN1YihvdGhlcikuaXNOZWdhdGl2ZSgpID8gLTEgOiAxO1xuICAvLyBCb3RoIGFyZSBwb3NpdGl2ZSBpZiBhdCBsZWFzdCBvbmUgaXMgdW5zaWduZWRcbiAgcmV0dXJuIChvdGhlci5oaWdoID4+PiAwKSA+ICh0aGlzLmhpZ2ggPj4+IDApIHx8IChvdGhlci5oaWdoID09PSB0aGlzLmhpZ2ggJiYgKG90aGVyLmxvdyA+Pj4gMCkgPiAodGhpcy5sb3cgPj4+IDApKSA/IC0xIDogMTtcbn07XG5cbi8qKlxuICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY29tcGFyZX0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcbiAqICBpZiB0aGUgZ2l2ZW4gb25lIGlzIGdyZWF0ZXJcbiAqL1xuTG9uZ1Byb3RvdHlwZS5jb21wID0gTG9uZ1Byb3RvdHlwZS5jb21wYXJlO1xuXG4vKipcbiAqIE5lZ2F0ZXMgdGhpcyBMb25nJ3MgdmFsdWUuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUxvbmd9IE5lZ2F0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLm5lZ2F0ZSA9IGZ1bmN0aW9uIG5lZ2F0ZSgpIHtcbiAgaWYgKCF0aGlzLnVuc2lnbmVkICYmIHRoaXMuZXEoTUlOX1ZBTFVFKSlcbiAgICByZXR1cm4gTUlOX1ZBTFVFO1xuICByZXR1cm4gdGhpcy5ub3QoKS5hZGQoT05FKTtcbn07XG5cbi8qKlxuICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNuZWdhdGV9LlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7IUxvbmd9IE5lZ2F0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLm5lZyA9IExvbmdQcm90b3R5cGUubmVnYXRlO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHN1bSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGFkZGVuZCBBZGRlbmRcbiAqIEByZXR1cm5zIHshTG9uZ30gU3VtXG4gKi9cbkxvbmdQcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkKGFkZGVuZCkge1xuICBpZiAoIWlzTG9uZyhhZGRlbmQpKVxuICAgIGFkZGVuZCA9IGZyb21WYWx1ZShhZGRlbmQpO1xuXG4gIC8vIERpdmlkZSBlYWNoIG51bWJlciBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIHN1bSB0aGUgY2h1bmtzLlxuXG4gIHZhciBhNDggPSB0aGlzLmhpZ2ggPj4+IDE2O1xuICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xuICB2YXIgYTE2ID0gdGhpcy5sb3cgPj4+IDE2O1xuICB2YXIgYTAwID0gdGhpcy5sb3cgJiAweEZGRkY7XG5cbiAgdmFyIGI0OCA9IGFkZGVuZC5oaWdoID4+PiAxNjtcbiAgdmFyIGIzMiA9IGFkZGVuZC5oaWdoICYgMHhGRkZGO1xuICB2YXIgYjE2ID0gYWRkZW5kLmxvdyA+Pj4gMTY7XG4gIHZhciBiMDAgPSBhZGRlbmQubG93ICYgMHhGRkZGO1xuXG4gIHZhciBjNDggPSAwLCBjMzIgPSAwLCBjMTYgPSAwLCBjMDAgPSAwO1xuICBjMDAgKz0gYTAwICsgYjAwO1xuICBjMTYgKz0gYzAwID4+PiAxNjtcbiAgYzAwICY9IDB4RkZGRjtcbiAgYzE2ICs9IGExNiArIGIxNjtcbiAgYzMyICs9IGMxNiA+Pj4gMTY7XG4gIGMxNiAmPSAweEZGRkY7XG4gIGMzMiArPSBhMzIgKyBiMzI7XG4gIGM0OCArPSBjMzIgPj4+IDE2O1xuICBjMzIgJj0gMHhGRkZGO1xuICBjNDggKz0gYTQ4ICsgYjQ4O1xuICBjNDggJj0gMHhGRkZGO1xuICByZXR1cm4gZnJvbUJpdHMoKGMxNiA8PCAxNikgfCBjMDAsIChjNDggPDwgMTYpIHwgYzMyLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxuICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXG4gKi9cbkxvbmdQcm90b3R5cGUuc3VidHJhY3QgPSBmdW5jdGlvbiBzdWJ0cmFjdChzdWJ0cmFoZW5kKSB7XG4gIGlmICghaXNMb25nKHN1YnRyYWhlbmQpKVxuICAgIHN1YnRyYWhlbmQgPSBmcm9tVmFsdWUoc3VidHJhaGVuZCk7XG4gIHJldHVybiB0aGlzLmFkZChzdWJ0cmFoZW5kLm5lZygpKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc3VidHJhY3R9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxuICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXG4gKi9cbkxvbmdQcm90b3R5cGUuc3ViID0gTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBwcm9kdWN0IG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gbXVsdGlwbGllciBNdWx0aXBsaWVyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFByb2R1Y3RcbiAqL1xuTG9uZ1Byb3RvdHlwZS5tdWx0aXBseSA9IGZ1bmN0aW9uIG11bHRpcGx5KG11bHRpcGxpZXIpIHtcbiAgaWYgKHRoaXMuaXNaZXJvKCkpXG4gICAgcmV0dXJuIHRoaXM7XG4gIGlmICghaXNMb25nKG11bHRpcGxpZXIpKVxuICAgIG11bHRpcGxpZXIgPSBmcm9tVmFsdWUobXVsdGlwbGllcik7XG5cbiAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XG4gIGlmICh3YXNtKSB7XG4gICAgdmFyIGxvdyA9IHdhc21bXCJtdWxcIl0odGhpcy5sb3csXG4gICAgICB0aGlzLmhpZ2gsXG4gICAgICBtdWx0aXBsaWVyLmxvdyxcbiAgICAgIG11bHRpcGxpZXIuaGlnaCk7XG4gICAgcmV0dXJuIGZyb21CaXRzKGxvdywgd2FzbVtcImdldF9oaWdoXCJdKCksIHRoaXMudW5zaWduZWQpO1xuICB9XG5cbiAgaWYgKG11bHRpcGxpZXIuaXNaZXJvKCkpXG4gICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpXG4gICAgcmV0dXJuIG11bHRpcGxpZXIuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XG4gIGlmIChtdWx0aXBsaWVyLmVxKE1JTl9WQUxVRSkpXG4gICAgcmV0dXJuIHRoaXMuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XG5cbiAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XG4gICAgaWYgKG11bHRpcGxpZXIuaXNOZWdhdGl2ZSgpKVxuICAgICAgcmV0dXJuIHRoaXMubmVnKCkubXVsKG11bHRpcGxpZXIubmVnKCkpO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiB0aGlzLm5lZygpLm11bChtdWx0aXBsaWVyKS5uZWcoKTtcbiAgfSBlbHNlIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSlcbiAgICByZXR1cm4gdGhpcy5tdWwobXVsdGlwbGllci5uZWcoKSkubmVnKCk7XG5cbiAgLy8gSWYgYm90aCBsb25ncyBhcmUgc21hbGwsIHVzZSBmbG9hdCBtdWx0aXBsaWNhdGlvblxuICBpZiAodGhpcy5sdChUV09fUFdSXzI0KSAmJiBtdWx0aXBsaWVyLmx0KFRXT19QV1JfMjQpKVxuICAgIHJldHVybiBmcm9tTnVtYmVyKHRoaXMudG9OdW1iZXIoKSAqIG11bHRpcGxpZXIudG9OdW1iZXIoKSwgdGhpcy51bnNpZ25lZCk7XG5cbiAgLy8gRGl2aWRlIGVhY2ggbG9uZyBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIGFkZCB1cCA0eDQgcHJvZHVjdHMuXG4gIC8vIFdlIGNhbiBza2lwIHByb2R1Y3RzIHRoYXQgd291bGQgb3ZlcmZsb3cuXG5cbiAgdmFyIGE0OCA9IHRoaXMuaGlnaCA+Pj4gMTY7XG4gIHZhciBhMzIgPSB0aGlzLmhpZ2ggJiAweEZGRkY7XG4gIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XG4gIHZhciBhMDAgPSB0aGlzLmxvdyAmIDB4RkZGRjtcblxuICB2YXIgYjQ4ID0gbXVsdGlwbGllci5oaWdoID4+PiAxNjtcbiAgdmFyIGIzMiA9IG11bHRpcGxpZXIuaGlnaCAmIDB4RkZGRjtcbiAgdmFyIGIxNiA9IG11bHRpcGxpZXIubG93ID4+PiAxNjtcbiAgdmFyIGIwMCA9IG11bHRpcGxpZXIubG93ICYgMHhGRkZGO1xuXG4gIHZhciBjNDggPSAwLCBjMzIgPSAwLCBjMTYgPSAwLCBjMDAgPSAwO1xuICBjMDAgKz0gYTAwICogYjAwO1xuICBjMTYgKz0gYzAwID4+PiAxNjtcbiAgYzAwICY9IDB4RkZGRjtcbiAgYzE2ICs9IGExNiAqIGIwMDtcbiAgYzMyICs9IGMxNiA+Pj4gMTY7XG4gIGMxNiAmPSAweEZGRkY7XG4gIGMxNiArPSBhMDAgKiBiMTY7XG4gIGMzMiArPSBjMTYgPj4+IDE2O1xuICBjMTYgJj0gMHhGRkZGO1xuICBjMzIgKz0gYTMyICogYjAwO1xuICBjNDggKz0gYzMyID4+PiAxNjtcbiAgYzMyICY9IDB4RkZGRjtcbiAgYzMyICs9IGExNiAqIGIxNjtcbiAgYzQ4ICs9IGMzMiA+Pj4gMTY7XG4gIGMzMiAmPSAweEZGRkY7XG4gIGMzMiArPSBhMDAgKiBiMzI7XG4gIGM0OCArPSBjMzIgPj4+IDE2O1xuICBjMzIgJj0gMHhGRkZGO1xuICBjNDggKz0gYTQ4ICogYjAwICsgYTMyICogYjE2ICsgYTE2ICogYjMyICsgYTAwICogYjQ4O1xuICBjNDggJj0gMHhGRkZGO1xuICByZXR1cm4gZnJvbUJpdHMoKGMxNiA8PCAxNikgfCBjMDAsIChjNDggPDwgMTYpIHwgYzMyLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcHJvZHVjdCBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbXVsdGlwbHl9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG11bHRpcGxpZXIgTXVsdGlwbGllclxuICogQHJldHVybnMgeyFMb25nfSBQcm9kdWN0XG4gKi9cbkxvbmdQcm90b3R5cGUubXVsID0gTG9uZ1Byb3RvdHlwZS5tdWx0aXBseTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBkaXZpZGVkIGJ5IHRoZSBzcGVjaWZpZWQuIFRoZSByZXN1bHQgaXMgc2lnbmVkIGlmIHRoaXMgTG9uZyBpcyBzaWduZWQgb3JcbiAqICB1bnNpZ25lZCBpZiB0aGlzIExvbmcgaXMgdW5zaWduZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBRdW90aWVudFxuICovXG5Mb25nUHJvdG90eXBlLmRpdmlkZSA9IGZ1bmN0aW9uIGRpdmlkZShkaXZpc29yKSB7XG4gIGlmICghaXNMb25nKGRpdmlzb3IpKVxuICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XG4gIGlmIChkaXZpc29yLmlzWmVybygpKVxuICAgIHRocm93IEVycm9yKCdkaXZpc2lvbiBieSB6ZXJvJyk7XG5cbiAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XG4gIGlmICh3YXNtKSB7XG4gICAgLy8gZ3VhcmQgYWdhaW5zdCBzaWduZWQgZGl2aXNpb24gb3ZlcmZsb3c6IHRoZSBsYXJnZXN0XG4gICAgLy8gbmVnYXRpdmUgbnVtYmVyIC8gLTEgd291bGQgYmUgMSBsYXJnZXIgdGhhbiB0aGUgbGFyZ2VzdFxuICAgIC8vIHBvc2l0aXZlIG51bWJlciwgZHVlIHRvIHR3bydzIGNvbXBsZW1lbnQuXG4gICAgaWYgKCF0aGlzLnVuc2lnbmVkICYmXG4gICAgICB0aGlzLmhpZ2ggPT09IC0weDgwMDAwMDAwICYmXG4gICAgICBkaXZpc29yLmxvdyA9PT0gLTEgJiYgZGl2aXNvci5oaWdoID09PSAtMSkge1xuICAgICAgLy8gYmUgY29uc2lzdGVudCB3aXRoIG5vbi13YXNtIGNvZGUgcGF0aFxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHZhciBsb3cgPSAodGhpcy51bnNpZ25lZCA/IHdhc21bXCJkaXZfdVwiXSA6IHdhc21bXCJkaXZfc1wiXSkoXG4gICAgICB0aGlzLmxvdyxcbiAgICAgIHRoaXMuaGlnaCxcbiAgICAgIGRpdmlzb3IubG93LFxuICAgICAgZGl2aXNvci5oaWdoXG4gICAgKTtcbiAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtW1wiZ2V0X2hpZ2hcIl0oKSwgdGhpcy51bnNpZ25lZCk7XG4gIH1cblxuICBpZiAodGhpcy5pc1plcm8oKSlcbiAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgdmFyIGFwcHJveCwgcmVtLCByZXM7XG4gIGlmICghdGhpcy51bnNpZ25lZCkge1xuICAgIC8vIFRoaXMgc2VjdGlvbiBpcyBvbmx5IHJlbGV2YW50IGZvciBzaWduZWQgbG9uZ3MgYW5kIGlzIGRlcml2ZWQgZnJvbSB0aGVcbiAgICAvLyBjbG9zdXJlIGxpYnJhcnkgYXMgYSB3aG9sZS5cbiAgICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKSB7XG4gICAgICBpZiAoZGl2aXNvci5lcShPTkUpIHx8IGRpdmlzb3IuZXEoTkVHX09ORSkpXG4gICAgICAgIHJldHVybiBNSU5fVkFMVUU7ICAvLyByZWNhbGwgdGhhdCAtTUlOX1ZBTFVFID09IE1JTl9WQUxVRVxuICAgICAgZWxzZSBpZiAoZGl2aXNvci5lcShNSU5fVkFMVUUpKVxuICAgICAgICByZXR1cm4gT05FO1xuICAgICAgZWxzZSB7XG4gICAgICAgIC8vIEF0IHRoaXMgcG9pbnQsIHdlIGhhdmUgfG90aGVyfCA+PSAyLCBzbyB8dGhpcy9vdGhlcnwgPCB8TUlOX1ZBTFVFfC5cbiAgICAgICAgdmFyIGhhbGZUaGlzID0gdGhpcy5zaHIoMSk7XG4gICAgICAgIGFwcHJveCA9IGhhbGZUaGlzLmRpdihkaXZpc29yKS5zaGwoMSk7XG4gICAgICAgIGlmIChhcHByb3guZXEoWkVSTykpIHtcbiAgICAgICAgICByZXR1cm4gZGl2aXNvci5pc05lZ2F0aXZlKCkgPyBPTkUgOiBORUdfT05FO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlbSA9IHRoaXMuc3ViKGRpdmlzb3IubXVsKGFwcHJveCkpO1xuICAgICAgICAgIHJlcyA9IGFwcHJveC5hZGQocmVtLmRpdihkaXZpc29yKSk7XG4gICAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZGl2aXNvci5lcShNSU5fVkFMVUUpKVxuICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XG4gICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XG4gICAgICBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpXG4gICAgICAgIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yLm5lZygpKTtcbiAgICAgIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yKS5uZWcoKTtcbiAgICB9IGVsc2UgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKVxuICAgICAgcmV0dXJuIHRoaXMuZGl2KGRpdmlzb3IubmVnKCkpLm5lZygpO1xuICAgIHJlcyA9IFpFUk87XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhlIGFsZ29yaXRobSBiZWxvdyBoYXMgbm90IGJlZW4gbWFkZSBmb3IgdW5zaWduZWQgbG9uZ3MuIEl0J3MgdGhlcmVmb3JlXG4gICAgLy8gcmVxdWlyZWQgdG8gdGFrZSBzcGVjaWFsIGNhcmUgb2YgdGhlIE1TQiBwcmlvciB0byBydW5uaW5nIGl0LlxuICAgIGlmICghZGl2aXNvci51bnNpZ25lZClcbiAgICAgIGRpdmlzb3IgPSBkaXZpc29yLnRvVW5zaWduZWQoKTtcbiAgICBpZiAoZGl2aXNvci5ndCh0aGlzKSlcbiAgICAgIHJldHVybiBVWkVSTztcbiAgICBpZiAoZGl2aXNvci5ndCh0aGlzLnNocnUoMSkpKSAvLyAxNSA+Pj4gMSA9IDcgOyB3aXRoIGRpdmlzb3IgPSA4IDsgdHJ1ZVxuICAgICAgcmV0dXJuIFVPTkU7XG4gICAgcmVzID0gVVpFUk87XG4gIH1cblxuICAvLyBSZXBlYXQgdGhlIGZvbGxvd2luZyB1bnRpbCB0aGUgcmVtYWluZGVyIGlzIGxlc3MgdGhhbiBvdGhlcjogIGZpbmQgYVxuICAvLyBmbG9hdGluZy1wb2ludCB0aGF0IGFwcHJveGltYXRlcyByZW1haW5kZXIgLyBvdGhlciAqZnJvbSBiZWxvdyosIGFkZCB0aGlzXG4gIC8vIGludG8gdGhlIHJlc3VsdCwgYW5kIHN1YnRyYWN0IGl0IGZyb20gdGhlIHJlbWFpbmRlci4gIEl0IGlzIGNyaXRpY2FsIHRoYXRcbiAgLy8gdGhlIGFwcHJveGltYXRlIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgcmVhbCB2YWx1ZSBzbyB0aGF0IHRoZVxuICAvLyByZW1haW5kZXIgbmV2ZXIgYmVjb21lcyBuZWdhdGl2ZS5cbiAgcmVtID0gdGhpcztcbiAgd2hpbGUgKHJlbS5ndGUoZGl2aXNvcikpIHtcbiAgICAvLyBBcHByb3hpbWF0ZSB0aGUgcmVzdWx0IG9mIGRpdmlzaW9uLiBUaGlzIG1heSBiZSBhIGxpdHRsZSBncmVhdGVyIG9yXG4gICAgLy8gc21hbGxlciB0aGFuIHRoZSBhY3R1YWwgdmFsdWUuXG4gICAgYXBwcm94ID0gTWF0aC5tYXgoMSwgTWF0aC5mbG9vcihyZW0udG9OdW1iZXIoKSAvIGRpdmlzb3IudG9OdW1iZXIoKSkpO1xuXG4gICAgLy8gV2Ugd2lsbCB0d2VhayB0aGUgYXBwcm94aW1hdGUgcmVzdWx0IGJ5IGNoYW5naW5nIGl0IGluIHRoZSA0OC10aCBkaWdpdCBvclxuICAgIC8vIHRoZSBzbWFsbGVzdCBub24tZnJhY3Rpb25hbCBkaWdpdCwgd2hpY2hldmVyIGlzIGxhcmdlci5cbiAgICB2YXIgbG9nMiA9IE1hdGguY2VpbChNYXRoLmxvZyhhcHByb3gpIC8gTWF0aC5MTjIpLFxuICAgICAgZGVsdGEgPSAobG9nMiA8PSA0OCkgPyAxIDogcG93X2RibCgyLCBsb2cyIC0gNDgpLFxuXG4gICAgICAvLyBEZWNyZWFzZSB0aGUgYXBwcm94aW1hdGlvbiB1bnRpbCBpdCBpcyBzbWFsbGVyIHRoYW4gdGhlIHJlbWFpbmRlci4gIE5vdGVcbiAgICAgIC8vIHRoYXQgaWYgaXQgaXMgdG9vIGxhcmdlLCB0aGUgcHJvZHVjdCBvdmVyZmxvd3MgYW5kIGlzIG5lZ2F0aXZlLlxuICAgICAgYXBwcm94UmVzID0gZnJvbU51bWJlcihhcHByb3gpLFxuICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcbiAgICB3aGlsZSAoYXBwcm94UmVtLmlzTmVnYXRpdmUoKSB8fCBhcHByb3hSZW0uZ3QocmVtKSkge1xuICAgICAgYXBwcm94IC09IGRlbHRhO1xuICAgICAgYXBwcm94UmVzID0gZnJvbU51bWJlcihhcHByb3gsIHRoaXMudW5zaWduZWQpO1xuICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcbiAgICB9XG5cbiAgICAvLyBXZSBrbm93IHRoZSBhbnN3ZXIgY2FuJ3QgYmUgemVyby4uLiBhbmQgYWN0dWFsbHksIHplcm8gd291bGQgY2F1c2VcbiAgICAvLyBpbmZpbml0ZSByZWN1cnNpb24gc2luY2Ugd2Ugd291bGQgbWFrZSBubyBwcm9ncmVzcy5cbiAgICBpZiAoYXBwcm94UmVzLmlzWmVybygpKVxuICAgICAgYXBwcm94UmVzID0gT05FO1xuXG4gICAgcmVzID0gcmVzLmFkZChhcHByb3hSZXMpO1xuICAgIHJlbSA9IHJlbS5zdWIoYXBwcm94UmVtKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBkaXZpZGVkIGJ5IHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZGl2aWRlfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcbiAqIEByZXR1cm5zIHshTG9uZ30gUXVvdGllbnRcbiAqL1xuTG9uZ1Byb3RvdHlwZS5kaXYgPSBMb25nUHJvdG90eXBlLmRpdmlkZTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxuICovXG5Mb25nUHJvdG90eXBlLm1vZHVsbyA9IGZ1bmN0aW9uIG1vZHVsbyhkaXZpc29yKSB7XG4gIGlmICghaXNMb25nKGRpdmlzb3IpKVxuICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XG5cbiAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XG4gIGlmICh3YXNtKSB7XG4gICAgdmFyIGxvdyA9ICh0aGlzLnVuc2lnbmVkID8gd2FzbVtcInJlbV91XCJdIDogd2FzbVtcInJlbV9zXCJdKShcbiAgICAgIHRoaXMubG93LFxuICAgICAgdGhpcy5oaWdoLFxuICAgICAgZGl2aXNvci5sb3csXG4gICAgICBkaXZpc29yLmhpZ2hcbiAgICApO1xuICAgIHJldHVybiBmcm9tQml0cyhsb3csIHdhc21bXCJnZXRfaGlnaFwiXSgpLCB0aGlzLnVuc2lnbmVkKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLnN1Yih0aGlzLmRpdihkaXZpc29yKS5tdWwoZGl2aXNvcikpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNtb2R1bG99LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcbiAqL1xuTG9uZ1Byb3RvdHlwZS5tb2QgPSBMb25nUHJvdG90eXBlLm1vZHVsbztcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNtb2R1bG99LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcbiAqL1xuTG9uZ1Byb3RvdHlwZS5yZW0gPSBMb25nUHJvdG90eXBlLm1vZHVsbztcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIE5PVCBvZiB0aGlzIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmdQcm90b3R5cGUubm90ID0gZnVuY3Rpb24gbm90KCkge1xuICByZXR1cm4gZnJvbUJpdHMofnRoaXMubG93LCB+dGhpcy5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBjb3VudCBsZWFkaW5nIHplcm9zIG9mIHRoaXMgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshbnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmNvdW50TGVhZGluZ1plcm9zID0gZnVuY3Rpb24gY291bnRMZWFkaW5nWmVyb3MoKSB7XG4gIHJldHVybiB0aGlzLmhpZ2ggPyBNYXRoLmNsejMyKHRoaXMuaGlnaCkgOiBNYXRoLmNsejMyKHRoaXMubG93KSArIDMyO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IGxlYWRpbmcgemVyb3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY291bnRMZWFkaW5nWmVyb3N9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfVxuICogQHJldHVybnMgeyFudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUuY2x6ID0gTG9uZ1Byb3RvdHlwZS5jb3VudExlYWRpbmdaZXJvcztcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IHRyYWlsaW5nIHplcm9zIG9mIHRoaXMgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshbnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmNvdW50VHJhaWxpbmdaZXJvcyA9IGZ1bmN0aW9uIGNvdW50VHJhaWxpbmdaZXJvcygpIHtcbiAgcmV0dXJuIHRoaXMubG93ID8gY3R6MzIodGhpcy5sb3cpIDogY3R6MzIodGhpcy5oaWdoKSArIDMyO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IHRyYWlsaW5nIHplcm9zLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2NvdW50VHJhaWxpbmdaZXJvc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IW51bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5jdHogPSBMb25nUHJvdG90eXBlLmNvdW50VHJhaWxpbmdaZXJvcztcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIEFORCBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqL1xuTG9uZ1Byb3RvdHlwZS5hbmQgPSBmdW5jdGlvbiBhbmQob3RoZXIpIHtcbiAgaWYgKCFpc0xvbmcob3RoZXIpKVxuICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcbiAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93ICYgb3RoZXIubG93LCB0aGlzLmhpZ2ggJiBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYml0d2lzZSBPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqL1xuTG9uZ1Byb3RvdHlwZS5vciA9IGZ1bmN0aW9uIG9yKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSlcbiAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyB8IG90aGVyLmxvdywgdGhpcy5oaWdoIHwgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgWE9SIG9mIHRoaXMgTG9uZyBhbmQgdGhlIGdpdmVuIG9uZS5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xuICogQHJldHVybnMgeyFMb25nfVxuICovXG5Mb25nUHJvdG90eXBlLnhvciA9IGZ1bmN0aW9uIHhvcihvdGhlcikge1xuICBpZiAoIWlzTG9uZyhvdGhlcikpXG4gICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgXiBvdGhlci5sb3csIHRoaXMuaGlnaCBeIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgc2hpZnRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hpZnRMZWZ0ID0gZnVuY3Rpb24gc2hpZnRMZWZ0KG51bUJpdHMpIHtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSlcbiAgICBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xuICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKVxuICAgIHJldHVybiB0aGlzO1xuICBlbHNlIGlmIChudW1CaXRzIDwgMzIpXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IDw8IG51bUJpdHMsICh0aGlzLmhpZ2ggPDwgbnVtQml0cykgfCAodGhpcy5sb3cgPj4+ICgzMiAtIG51bUJpdHMpKSwgdGhpcy51bnNpZ25lZCk7XG4gIGVsc2VcbiAgICByZXR1cm4gZnJvbUJpdHMoMCwgdGhpcy5sb3cgPDwgKG51bUJpdHMgLSAzMiksIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgc2hpZnRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0TGVmdH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNobCA9IExvbmdQcm90b3R5cGUuc2hpZnRMZWZ0O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hpZnRSaWdodCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHQobnVtQml0cykge1xuICBpZiAoaXNMb25nKG51bUJpdHMpKVxuICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XG4gIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApXG4gICAgcmV0dXJuIHRoaXM7XG4gIGVsc2UgaWYgKG51bUJpdHMgPCAzMilcbiAgICByZXR1cm4gZnJvbUJpdHMoKHRoaXMubG93ID4+PiBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPDwgKDMyIC0gbnVtQml0cykpLCB0aGlzLmhpZ2ggPj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XG4gIGVsc2VcbiAgICByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoID4+IChudW1CaXRzIC0gMzIpLCB0aGlzLmhpZ2ggPj0gMCA/IDAgOiAtMSwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0UmlnaHR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaHIgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQ7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGxvZ2ljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkID0gZnVuY3Rpb24gc2hpZnRSaWdodFVuc2lnbmVkKG51bUJpdHMpIHtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gIGlmIChudW1CaXRzIDwgMzIpIHJldHVybiBmcm9tQml0cygodGhpcy5sb3cgPj4+IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA8PCAoMzIgLSBudW1CaXRzKSksIHRoaXMuaGlnaCA+Pj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XG4gIGlmIChudW1CaXRzID09PSAzMikgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCwgMCwgdGhpcy51bnNpZ25lZCk7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2ggPj4+IChudW1CaXRzIC0gMzIpLCAwLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGxvZ2ljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0UmlnaHRVbnNpZ25lZH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNocnUgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hyX3UgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgcm90YXRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gUm90YXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUucm90YXRlTGVmdCA9IGZ1bmN0aW9uIHJvdGF0ZUxlZnQobnVtQml0cykge1xuICB2YXIgYjtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gIGlmIChudW1CaXRzID09PSAzMikgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCwgdGhpcy5sb3csIHRoaXMudW5zaWduZWQpO1xuICBpZiAobnVtQml0cyA8IDMyKSB7XG4gICAgYiA9ICgzMiAtIG51bUJpdHMpO1xuICAgIHJldHVybiBmcm9tQml0cygoKHRoaXMubG93IDw8IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA+Pj4gYikpLCAoKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gYikpLCB0aGlzLnVuc2lnbmVkKTtcbiAgfVxuICBudW1CaXRzIC09IDMyO1xuICBiID0gKDMyIC0gbnVtQml0cyk7XG4gIHJldHVybiBmcm9tQml0cygoKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gYikpLCAoKHRoaXMubG93IDw8IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA+Pj4gYikpLCB0aGlzLnVuc2lnbmVkKTtcbn1cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHJvdGF0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNyb3RhdGVMZWZ0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gUm90YXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUucm90bCA9IExvbmdQcm90b3R5cGUucm90YXRlTGVmdDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgcm90YXRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJvdGF0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnJvdGF0ZVJpZ2h0ID0gZnVuY3Rpb24gcm90YXRlUmlnaHQobnVtQml0cykge1xuICB2YXIgYjtcbiAgaWYgKGlzTG9uZyhudW1CaXRzKSkgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMCkgcmV0dXJuIHRoaXM7XG4gIGlmIChudW1CaXRzID09PSAzMikgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCwgdGhpcy5sb3csIHRoaXMudW5zaWduZWQpO1xuICBpZiAobnVtQml0cyA8IDMyKSB7XG4gICAgYiA9ICgzMiAtIG51bUJpdHMpO1xuICAgIHJldHVybiBmcm9tQml0cygoKHRoaXMuaGlnaCA8PCBiKSB8ICh0aGlzLmxvdyA+Pj4gbnVtQml0cykpLCAoKHRoaXMubG93IDw8IGIpIHwgKHRoaXMuaGlnaCA+Pj4gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcbiAgfVxuICBudW1CaXRzIC09IDMyO1xuICBiID0gKDMyIC0gbnVtQml0cyk7XG4gIHJldHVybiBmcm9tQml0cygoKHRoaXMubG93IDw8IGIpIHwgKHRoaXMuaGlnaCA+Pj4gbnVtQml0cykpLCAoKHRoaXMuaGlnaCA8PCBiKSB8ICh0aGlzLmxvdyA+Pj4gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcbn1cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHJvdGF0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjcm90YXRlUmlnaHR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBSb3RhdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5yb3RyID0gTG9uZ1Byb3RvdHlwZS5yb3RhdGVSaWdodDtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gc2lnbmVkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnRvU2lnbmVkID0gZnVuY3Rpb24gdG9TaWduZWQoKSB7XG4gIGlmICghdGhpcy51bnNpZ25lZClcbiAgICByZXR1cm4gdGhpcztcbiAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93LCB0aGlzLmhpZ2gsIGZhbHNlKTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIHVuc2lnbmVkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFMb25nfSBVbnNpZ25lZCBsb25nXG4gKi9cbkxvbmdQcm90b3R5cGUudG9VbnNpZ25lZCA9IGZ1bmN0aW9uIHRvVW5zaWduZWQoKSB7XG4gIGlmICh0aGlzLnVuc2lnbmVkKVxuICAgIHJldHVybiB0aGlzO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgdHJ1ZSk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IGxlIFdoZXRoZXIgbGl0dGxlIG9yIGJpZyBlbmRpYW4sIGRlZmF1bHRzIHRvIGJpZyBlbmRpYW5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshQXJyYXkuPG51bWJlcj59IEJ5dGUgcmVwcmVzZW50YXRpb25cbiAqL1xuTG9uZ1Byb3RvdHlwZS50b0J5dGVzID0gZnVuY3Rpb24gdG9CeXRlcyhsZSkge1xuICByZXR1cm4gbGUgPyB0aGlzLnRvQnl0ZXNMRSgpIDogdGhpcy50b0J5dGVzQkUoKTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBsaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAqL1xuTG9uZ1Byb3RvdHlwZS50b0J5dGVzTEUgPSBmdW5jdGlvbiB0b0J5dGVzTEUoKSB7XG4gIHZhciBoaSA9IHRoaXMuaGlnaCxcbiAgICBsbyA9IHRoaXMubG93O1xuICByZXR1cm4gW1xuICAgIGxvICYgMHhmZixcbiAgICBsbyA+Pj4gOCAmIDB4ZmYsXG4gICAgbG8gPj4+IDE2ICYgMHhmZixcbiAgICBsbyA+Pj4gMjQsXG4gICAgaGkgJiAweGZmLFxuICAgIGhpID4+PiA4ICYgMHhmZixcbiAgICBoaSA+Pj4gMTYgJiAweGZmLFxuICAgIGhpID4+PiAyNFxuICBdO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshQXJyYXkuPG51bWJlcj59IEJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvblxuICovXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXNCRSA9IGZ1bmN0aW9uIHRvQnl0ZXNCRSgpIHtcbiAgdmFyIGhpID0gdGhpcy5oaWdoLFxuICAgIGxvID0gdGhpcy5sb3c7XG4gIHJldHVybiBbXG4gICAgaGkgPj4+IDI0LFxuICAgIGhpID4+PiAxNiAmIDB4ZmYsXG4gICAgaGkgPj4+IDggJiAweGZmLFxuICAgIGhpICYgMHhmZixcbiAgICBsbyA+Pj4gMjQsXG4gICAgbG8gPj4+IDE2ICYgMHhmZixcbiAgICBsbyA+Pj4gOCAmIDB4ZmYsXG4gICAgbG8gJiAweGZmXG4gIF07XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBMb25nIGZyb20gaXRzIGJ5dGUgcmVwcmVzZW50YXRpb24uXG4gKiBAcGFyYW0geyFBcnJheS48bnVtYmVyPn0gYnl0ZXMgQnl0ZSByZXByZXNlbnRhdGlvblxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHBhcmFtIHtib29sZWFuPX0gbGUgV2hldGhlciBsaXR0bGUgb3IgYmlnIGVuZGlhbiwgZGVmYXVsdHMgdG8gYmlnIGVuZGlhblxuICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tQnl0ZXMgPSBmdW5jdGlvbiBmcm9tQnl0ZXMoYnl0ZXMsIHVuc2lnbmVkLCBsZSkge1xuICByZXR1cm4gbGUgPyBMb25nLmZyb21CeXRlc0xFKGJ5dGVzLCB1bnNpZ25lZCkgOiBMb25nLmZyb21CeXRlc0JFKGJ5dGVzLCB1bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBMb25nIGZyb20gaXRzIGxpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEByZXR1cm5zIHtMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbUJ5dGVzTEUgPSBmdW5jdGlvbiBmcm9tQnl0ZXNMRShieXRlcywgdW5zaWduZWQpIHtcbiAgcmV0dXJuIG5ldyBMb25nKFxuICAgIGJ5dGVzWzBdIHxcbiAgICBieXRlc1sxXSA8PCA4IHxcbiAgICBieXRlc1syXSA8PCAxNiB8XG4gICAgYnl0ZXNbM10gPDwgMjQsXG4gICAgYnl0ZXNbNF0gfFxuICAgIGJ5dGVzWzVdIDw8IDggfFxuICAgIGJ5dGVzWzZdIDw8IDE2IHxcbiAgICBieXRlc1s3XSA8PCAyNCxcbiAgICB1bnNpZ25lZFxuICApO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgTG9uZyBmcm9tIGl0cyBiaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXG4gKiBAcGFyYW0geyFBcnJheS48bnVtYmVyPn0gYnl0ZXMgQmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcmV0dXJucyB7TG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21CeXRlc0JFID0gZnVuY3Rpb24gZnJvbUJ5dGVzQkUoYnl0ZXMsIHVuc2lnbmVkKSB7XG4gIHJldHVybiBuZXcgTG9uZyhcbiAgICBieXRlc1s0XSA8PCAyNCB8XG4gICAgYnl0ZXNbNV0gPDwgMTYgfFxuICAgIGJ5dGVzWzZdIDw8IDggfFxuICAgIGJ5dGVzWzddLFxuICAgIGJ5dGVzWzBdIDw8IDI0IHxcbiAgICBieXRlc1sxXSA8PCAxNiB8XG4gICAgYnl0ZXNbMl0gPDwgOCB8XG4gICAgYnl0ZXNbM10sXG4gICAgdW5zaWduZWRcbiAgKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IExvbmc7XG4iLCAiLy8gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgdGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyLCBkbyBub3QgbW9kaWZ5XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycywgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvbiAqL1xuXG5leHBvcnQgZW51bSBBcmdUeXBlIHtcbiAgSU5QVVQgPSAwLFxuICBPVVRQVVQgPSAxLFxufVxuIiwgIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5TSVpFX1BSRUZJWF9MRU5HVEggPSBleHBvcnRzLkZJTEVfSURFTlRJRklFUl9MRU5HVEggPSBleHBvcnRzLlNJWkVPRl9JTlQgPSBleHBvcnRzLlNJWkVPRl9TSE9SVCA9IHZvaWQgMDtcbmV4cG9ydHMuU0laRU9GX1NIT1JUID0gMjtcbmV4cG9ydHMuU0laRU9GX0lOVCA9IDQ7XG5leHBvcnRzLkZJTEVfSURFTlRJRklFUl9MRU5HVEggPSA0O1xuZXhwb3J0cy5TSVpFX1BSRUZJWF9MRU5HVEggPSA0O1xuIiwgIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5pc0xpdHRsZUVuZGlhbiA9IGV4cG9ydHMuZmxvYXQ2NCA9IGV4cG9ydHMuZmxvYXQzMiA9IGV4cG9ydHMuaW50MzIgPSB2b2lkIDA7XG5leHBvcnRzLmludDMyID0gbmV3IEludDMyQXJyYXkoMik7XG5leHBvcnRzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KGV4cG9ydHMuaW50MzIuYnVmZmVyKTtcbmV4cG9ydHMuZmxvYXQ2NCA9IG5ldyBGbG9hdDY0QXJyYXkoZXhwb3J0cy5pbnQzMi5idWZmZXIpO1xuZXhwb3J0cy5pc0xpdHRsZUVuZGlhbiA9IG5ldyBVaW50MTZBcnJheShuZXcgVWludDhBcnJheShbMSwgMF0pLmJ1ZmZlcilbMF0gPT09IDE7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkVuY29kaW5nID0gdm9pZCAwO1xudmFyIEVuY29kaW5nO1xuKGZ1bmN0aW9uIChFbmNvZGluZykge1xuICAgIEVuY29kaW5nW0VuY29kaW5nW1wiVVRGOF9CWVRFU1wiXSA9IDFdID0gXCJVVEY4X0JZVEVTXCI7XG4gICAgRW5jb2RpbmdbRW5jb2RpbmdbXCJVVEYxNl9TVFJJTkdcIl0gPSAyXSA9IFwiVVRGMTZfU1RSSU5HXCI7XG59KShFbmNvZGluZyB8fCAoZXhwb3J0cy5FbmNvZGluZyA9IEVuY29kaW5nID0ge30pKTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQnl0ZUJ1ZmZlciA9IHZvaWQgMDtcbmNvbnN0IGNvbnN0YW50c19qc18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzLmpzXCIpO1xuY29uc3QgdXRpbHNfanNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xuY29uc3QgZW5jb2RpbmdfanNfMSA9IHJlcXVpcmUoXCIuL2VuY29kaW5nLmpzXCIpO1xuY2xhc3MgQnl0ZUJ1ZmZlciB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IEJ5dGVCdWZmZXIgd2l0aCBhIGdpdmVuIGFycmF5IG9mIGJ5dGVzIChgVWludDhBcnJheWApXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoYnl0ZXNfKSB7XG4gICAgICAgIHRoaXMuYnl0ZXNfID0gYnl0ZXNfO1xuICAgICAgICB0aGlzLnBvc2l0aW9uXyA9IDA7XG4gICAgICAgIHRoaXMudGV4dF9kZWNvZGVyXyA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW5kIGFsbG9jYXRlIGEgbmV3IEJ5dGVCdWZmZXIgd2l0aCBhIGdpdmVuIHNpemUuXG4gICAgICovXG4gICAgc3RhdGljIGFsbG9jYXRlKGJ5dGVfc2l6ZSkge1xuICAgICAgICByZXR1cm4gbmV3IEJ5dGVCdWZmZXIobmV3IFVpbnQ4QXJyYXkoYnl0ZV9zaXplKSk7XG4gICAgfVxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLnBvc2l0aW9uXyA9IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdW5kZXJseWluZyBgVWludDhBcnJheWAuXG4gICAgICovXG4gICAgYnl0ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ5dGVzXztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBidWZmZXIncyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBwb3NpdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb25fO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGJ1ZmZlcidzIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uKHBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMucG9zaXRpb25fID0gcG9zaXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYnVmZmVyJ3MgY2FwYWNpdHkuXG4gICAgICovXG4gICAgY2FwYWNpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ5dGVzXy5sZW5ndGg7XG4gICAgfVxuICAgIHJlYWRJbnQ4KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkVWludDgob2Zmc2V0KSA8PCAyNCA+PiAyNDtcbiAgICB9XG4gICAgcmVhZFVpbnQ4KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ieXRlc19bb2Zmc2V0XTtcbiAgICB9XG4gICAgcmVhZEludDE2KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkVWludDE2KG9mZnNldCkgPDwgMTYgPj4gMTY7XG4gICAgfVxuICAgIHJlYWRVaW50MTYob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ5dGVzX1tvZmZzZXRdIHwgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPDwgODtcbiAgICB9XG4gICAgcmVhZEludDMyKG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ieXRlc19bb2Zmc2V0XSB8IHRoaXMuYnl0ZXNfW29mZnNldCArIDFdIDw8IDggfCB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAyXSA8PCAxNiB8IHRoaXMuYnl0ZXNfW29mZnNldCArIDNdIDw8IDI0O1xuICAgIH1cbiAgICByZWFkVWludDMyKG9mZnNldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkSW50MzIob2Zmc2V0KSA+Pj4gMDtcbiAgICB9XG4gICAgcmVhZEludDY0KG9mZnNldCkge1xuICAgICAgICByZXR1cm4gQmlnSW50LmFzSW50Tig2NCwgQmlnSW50KHRoaXMucmVhZFVpbnQzMihvZmZzZXQpKSArIChCaWdJbnQodGhpcy5yZWFkVWludDMyKG9mZnNldCArIDQpKSA8PCBCaWdJbnQoMzIpKSk7XG4gICAgfVxuICAgIHJlYWRVaW50NjQob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBCaWdJbnQuYXNVaW50Tig2NCwgQmlnSW50KHRoaXMucmVhZFVpbnQzMihvZmZzZXQpKSArIChCaWdJbnQodGhpcy5yZWFkVWludDMyKG9mZnNldCArIDQpKSA8PCBCaWdJbnQoMzIpKSk7XG4gICAgfVxuICAgIHJlYWRGbG9hdDMyKG9mZnNldCkge1xuICAgICAgICB1dGlsc19qc18xLmludDMyWzBdID0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgICAgICAgcmV0dXJuIHV0aWxzX2pzXzEuZmxvYXQzMlswXTtcbiAgICB9XG4gICAgcmVhZEZsb2F0NjQob2Zmc2V0KSB7XG4gICAgICAgIHV0aWxzX2pzXzEuaW50MzJbdXRpbHNfanNfMS5pc0xpdHRsZUVuZGlhbiA/IDAgOiAxXSA9IHRoaXMucmVhZEludDMyKG9mZnNldCk7XG4gICAgICAgIHV0aWxzX2pzXzEuaW50MzJbdXRpbHNfanNfMS5pc0xpdHRsZUVuZGlhbiA/IDEgOiAwXSA9IHRoaXMucmVhZEludDMyKG9mZnNldCArIDQpO1xuICAgICAgICByZXR1cm4gdXRpbHNfanNfMS5mbG9hdDY0WzBdO1xuICAgIH1cbiAgICB3cml0ZUludDgob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgfVxuICAgIHdyaXRlVWludDgob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgfVxuICAgIHdyaXRlSW50MTYob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbiAgICB9XG4gICAgd3JpdGVVaW50MTYob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbiAgICB9XG4gICAgd3JpdGVJbnQzMihvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPSB2YWx1ZSA+PiA4O1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAyXSA9IHZhbHVlID4+IDE2O1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAzXSA9IHZhbHVlID4+IDI0O1xuICAgIH1cbiAgICB3cml0ZVVpbnQzMihvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYnl0ZXNfW29mZnNldF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPSB2YWx1ZSA+PiA4O1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAyXSA9IHZhbHVlID4+IDE2O1xuICAgICAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAzXSA9IHZhbHVlID4+IDI0O1xuICAgIH1cbiAgICB3cml0ZUludDY0KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCwgTnVtYmVyKEJpZ0ludC5hc0ludE4oMzIsIHZhbHVlKSkpO1xuICAgICAgICB0aGlzLndyaXRlSW50MzIob2Zmc2V0ICsgNCwgTnVtYmVyKEJpZ0ludC5hc0ludE4oMzIsIHZhbHVlID4+IEJpZ0ludCgzMikpKSk7XG4gICAgfVxuICAgIHdyaXRlVWludDY0KG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy53cml0ZVVpbnQzMihvZmZzZXQsIE51bWJlcihCaWdJbnQuYXNVaW50TigzMiwgdmFsdWUpKSk7XG4gICAgICAgIHRoaXMud3JpdGVVaW50MzIob2Zmc2V0ICsgNCwgTnVtYmVyKEJpZ0ludC5hc1VpbnROKDMyLCB2YWx1ZSA+PiBCaWdJbnQoMzIpKSkpO1xuICAgIH1cbiAgICB3cml0ZUZsb2F0MzIob2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICB1dGlsc19qc18xLmZsb2F0MzJbMF0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy53cml0ZUludDMyKG9mZnNldCwgdXRpbHNfanNfMS5pbnQzMlswXSk7XG4gICAgfVxuICAgIHdyaXRlRmxvYXQ2NChvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIHV0aWxzX2pzXzEuZmxvYXQ2NFswXSA9IHZhbHVlO1xuICAgICAgICB0aGlzLndyaXRlSW50MzIob2Zmc2V0LCB1dGlsc19qc18xLmludDMyW3V0aWxzX2pzXzEuaXNMaXR0bGVFbmRpYW4gPyAwIDogMV0pO1xuICAgICAgICB0aGlzLndyaXRlSW50MzIob2Zmc2V0ICsgNCwgdXRpbHNfanNfMS5pbnQzMlt1dGlsc19qc18xLmlzTGl0dGxlRW5kaWFuID8gMSA6IDBdKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBmaWxlIGlkZW50aWZpZXIuICAgQmVoYXZpb3IgaXMgdW5kZWZpbmVkIGZvciBGbGF0QnVmZmVycyB3aG9zZVxuICAgICAqIHNjaGVtYSBkb2VzIG5vdCBpbmNsdWRlIGEgZmlsZV9pZGVudGlmaWVyIChsaWtlbHkgcG9pbnRzIGF0IHBhZGRpbmcgb3IgdGhlXG4gICAgICogc3RhcnQgb2YgYSB0aGUgcm9vdCB2dGFibGUpLlxuICAgICAqL1xuICAgIGdldEJ1ZmZlcklkZW50aWZpZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLmJ5dGVzXy5sZW5ndGggPCB0aGlzLnBvc2l0aW9uXyArIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgK1xuICAgICAgICAgICAgY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogQnl0ZUJ1ZmZlciBpcyB0b28gc2hvcnQgdG8gY29udGFpbiBhbiBpZGVudGlmaWVyLicpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHQgPSBcIlwiO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5yZWFkSW50OCh0aGlzLnBvc2l0aW9uXyArIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgKyBpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTG9vayB1cCBhIGZpZWxkIGluIHRoZSB2dGFibGUsIHJldHVybiBhbiBvZmZzZXQgaW50byB0aGUgb2JqZWN0LCBvciAwIGlmIHRoZVxuICAgICAqIGZpZWxkIGlzIG5vdCBwcmVzZW50LlxuICAgICAqL1xuICAgIF9fb2Zmc2V0KGJiX3BvcywgdnRhYmxlX29mZnNldCkge1xuICAgICAgICBjb25zdCB2dGFibGUgPSBiYl9wb3MgLSB0aGlzLnJlYWRJbnQzMihiYl9wb3MpO1xuICAgICAgICByZXR1cm4gdnRhYmxlX29mZnNldCA8IHRoaXMucmVhZEludDE2KHZ0YWJsZSkgPyB0aGlzLnJlYWRJbnQxNih2dGFibGUgKyB2dGFibGVfb2Zmc2V0KSA6IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgYW55IFRhYmxlLWRlcml2ZWQgdHlwZSB0byBwb2ludCB0byB0aGUgdW5pb24gYXQgdGhlIGdpdmVuIG9mZnNldC5cbiAgICAgKi9cbiAgICBfX3VuaW9uKHQsIG9mZnNldCkge1xuICAgICAgICB0LmJiX3BvcyA9IG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCk7XG4gICAgICAgIHQuYmIgPSB0aGlzO1xuICAgICAgICByZXR1cm4gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgSmF2YVNjcmlwdCBzdHJpbmcgZnJvbSBVVEYtOCBkYXRhIHN0b3JlZCBpbnNpZGUgdGhlIEZsYXRCdWZmZXIuXG4gICAgICogVGhpcyBhbGxvY2F0ZXMgYSBuZXcgc3RyaW5nIGFuZCBjb252ZXJ0cyB0byB3aWRlIGNoYXJzIHVwb24gZWFjaCBhY2Nlc3MuXG4gICAgICpcbiAgICAgKiBUbyBhdm9pZCB0aGUgY29udmVyc2lvbiB0byBzdHJpbmcsIHBhc3MgRW5jb2RpbmcuVVRGOF9CWVRFUyBhcyB0aGVcbiAgICAgKiBcIm9wdGlvbmFsRW5jb2RpbmdcIiBhcmd1bWVudC4gVGhpcyBpcyB1c2VmdWwgZm9yIGF2b2lkaW5nIGNvbnZlcnNpb24gd2hlblxuICAgICAqIHRoZSBkYXRhIHdpbGwganVzdCBiZSBwYWNrYWdlZCBiYWNrIHVwIGluIGFub3RoZXIgRmxhdEJ1ZmZlciBsYXRlciBvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvZmZzZXRcbiAgICAgKiBAcGFyYW0gb3B0X2VuY29kaW5nIERlZmF1bHRzIHRvIFVURjE2X1NUUklOR1xuICAgICAqL1xuICAgIF9fc3RyaW5nKG9mZnNldCwgb3B0X2VuY29kaW5nKSB7XG4gICAgICAgIG9mZnNldCArPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgICAgICBjb25zdCBsZW5ndGggPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVDtcbiAgICAgICAgY29uc3QgdXRmOGJ5dGVzID0gdGhpcy5ieXRlc18uc3ViYXJyYXkob2Zmc2V0LCBvZmZzZXQgKyBsZW5ndGgpO1xuICAgICAgICBpZiAob3B0X2VuY29kaW5nID09PSBlbmNvZGluZ19qc18xLkVuY29kaW5nLlVURjhfQllURVMpXG4gICAgICAgICAgICByZXR1cm4gdXRmOGJ5dGVzO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50ZXh0X2RlY29kZXJfLmRlY29kZSh1dGY4Ynl0ZXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgdW5pb25zIHRoYXQgY2FuIGNvbnRhaW4gc3RyaW5nIGFzIGl0cyBtZW1iZXIsIGlmIGEgVGFibGUtZGVyaXZlZCB0eXBlIHRoZW4gaW5pdGlhbGl6ZSBpdCxcbiAgICAgKiBpZiBhIHN0cmluZyB0aGVuIHJldHVybiBhIG5ldyBvbmVcbiAgICAgKlxuICAgICAqIFdBUk5JTkc6IHN0cmluZ3MgYXJlIGltbXV0YWJsZSBpbiBKUyBzbyB3ZSBjYW4ndCBjaGFuZ2UgdGhlIHN0cmluZyB0aGF0IHRoZSB1c2VyIGdhdmUgdXMsIHRoaXNcbiAgICAgKiBtYWtlcyB0aGUgYmVoYXZpb3VyIG9mIF9fdW5pb25fd2l0aF9zdHJpbmcgZGlmZmVyZW50IGNvbXBhcmVkIHRvIF9fdW5pb25cbiAgICAgKi9cbiAgICBfX3VuaW9uX3dpdGhfc3RyaW5nKG8sIG9mZnNldCkge1xuICAgICAgICBpZiAodHlwZW9mIG8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fX3N0cmluZyhvZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9fdW5pb24obywgb2Zmc2V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmUgdGhlIHJlbGF0aXZlIG9mZnNldCBzdG9yZWQgYXQgXCJvZmZzZXRcIlxuICAgICAqL1xuICAgIF9faW5kaXJlY3Qob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHN0YXJ0IG9mIGRhdGEgb2YgYSB2ZWN0b3Igd2hvc2Ugb2Zmc2V0IGlzIHN0b3JlZCBhdCBcIm9mZnNldFwiIGluIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIF9fdmVjdG9yKG9mZnNldCkge1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgdGhpcy5yZWFkSW50MzIob2Zmc2V0KSArIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQ7IC8vIGRhdGEgc3RhcnRzIGFmdGVyIHRoZSBsZW5ndGhcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBsZW5ndGggb2YgYSB2ZWN0b3Igd2hvc2Ugb2Zmc2V0IGlzIHN0b3JlZCBhdCBcIm9mZnNldFwiIGluIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIF9fdmVjdG9yX2xlbihvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZEludDMyKG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCkpO1xuICAgIH1cbiAgICBfX2hhc19pZGVudGlmaWVyKGlkZW50KSB7XG4gICAgICAgIGlmIChpZGVudC5sZW5ndGggIT0gY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogZmlsZSBpZGVudGlmaWVyIG11c3QgYmUgbGVuZ3RoICcgK1xuICAgICAgICAgICAgICAgIGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoaWRlbnQuY2hhckNvZGVBdChpKSAhPSB0aGlzLnJlYWRJbnQ4KHRoaXMucG9zaXRpb24oKSArIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgKyBpKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gZm9yIGdlbmVyYXRpbmcgbGlzdCBmb3Igb2JqIGFwaVxuICAgICAqL1xuICAgIGNyZWF0ZVNjYWxhckxpc3QobGlzdEFjY2Vzc29yLCBsaXN0TGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHJldCA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RMZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgY29uc3QgdmFsID0gbGlzdEFjY2Vzc29yKGkpO1xuICAgICAgICAgICAgaWYgKHZhbCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldC5wdXNoKHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gZm9yIGdlbmVyYXRpbmcgbGlzdCBmb3Igb2JqIGFwaVxuICAgICAqIEBwYXJhbSBsaXN0QWNjZXNzb3IgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIGFuIGluZGV4IGFuZCByZXR1cm4gZGF0YSBhdCB0aGF0IGluZGV4XG4gICAgICogQHBhcmFtIGxpc3RMZW5ndGggbGlzdExlbmd0aFxuICAgICAqIEBwYXJhbSByZXMgcmVzdWx0IGxpc3RcbiAgICAgKi9cbiAgICBjcmVhdGVPYmpMaXN0KGxpc3RBY2Nlc3NvciwgbGlzdExlbmd0aCkge1xuICAgICAgICBjb25zdCByZXQgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0TGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IGxpc3RBY2Nlc3NvcihpKTtcbiAgICAgICAgICAgIGlmICh2YWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXQucHVzaCh2YWwudW5wYWNrKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxufVxuZXhwb3J0cy5CeXRlQnVmZmVyID0gQnl0ZUJ1ZmZlcjtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQnVpbGRlciA9IHZvaWQgMDtcbmNvbnN0IGJ5dGVfYnVmZmVyX2pzXzEgPSByZXF1aXJlKFwiLi9ieXRlLWJ1ZmZlci5qc1wiKTtcbmNvbnN0IGNvbnN0YW50c19qc18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzLmpzXCIpO1xuY2xhc3MgQnVpbGRlciB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgRmxhdEJ1ZmZlckJ1aWxkZXIuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0X2luaXRpYWxfc2l6ZSkge1xuICAgICAgICAvKiogTWluaW11bSBhbGlnbm1lbnQgZW5jb3VudGVyZWQgc28gZmFyLiAqL1xuICAgICAgICB0aGlzLm1pbmFsaWduID0gMTtcbiAgICAgICAgLyoqIFRoZSB2dGFibGUgZm9yIHRoZSBjdXJyZW50IHRhYmxlLiAqL1xuICAgICAgICB0aGlzLnZ0YWJsZSA9IG51bGw7XG4gICAgICAgIC8qKiBUaGUgYW1vdW50IG9mIGZpZWxkcyB3ZSdyZSBhY3R1YWxseSB1c2luZy4gKi9cbiAgICAgICAgdGhpcy52dGFibGVfaW5fdXNlID0gMDtcbiAgICAgICAgLyoqIFdoZXRoZXIgd2UgYXJlIGN1cnJlbnRseSBzZXJpYWxpemluZyBhIHRhYmxlLiAqL1xuICAgICAgICB0aGlzLmlzTmVzdGVkID0gZmFsc2U7XG4gICAgICAgIC8qKiBTdGFydGluZyBvZmZzZXQgb2YgdGhlIGN1cnJlbnQgc3RydWN0L3RhYmxlLiAqL1xuICAgICAgICB0aGlzLm9iamVjdF9zdGFydCA9IDA7XG4gICAgICAgIC8qKiBMaXN0IG9mIG9mZnNldHMgb2YgYWxsIHZ0YWJsZXMuICovXG4gICAgICAgIHRoaXMudnRhYmxlcyA9IFtdO1xuICAgICAgICAvKiogRm9yIHRoZSBjdXJyZW50IHZlY3RvciBiZWluZyBidWlsdC4gKi9cbiAgICAgICAgdGhpcy52ZWN0b3JfbnVtX2VsZW1zID0gMDtcbiAgICAgICAgLyoqIEZhbHNlIG9taXRzIGRlZmF1bHQgdmFsdWVzIGZyb20gdGhlIHNlcmlhbGl6ZWQgZGF0YSAqL1xuICAgICAgICB0aGlzLmZvcmNlX2RlZmF1bHRzID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RyaW5nX21hcHMgPSBudWxsO1xuICAgICAgICB0aGlzLnRleHRfZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICAgICAgICBsZXQgaW5pdGlhbF9zaXplO1xuICAgICAgICBpZiAoIW9wdF9pbml0aWFsX3NpemUpIHtcbiAgICAgICAgICAgIGluaXRpYWxfc2l6ZSA9IDEwMjQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpbml0aWFsX3NpemUgPSBvcHRfaW5pdGlhbF9zaXplO1xuICAgICAgICB9XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7Qnl0ZUJ1ZmZlcn1cbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYmIgPSBieXRlX2J1ZmZlcl9qc18xLkJ5dGVCdWZmZXIuYWxsb2NhdGUoaW5pdGlhbF9zaXplKTtcbiAgICAgICAgdGhpcy5zcGFjZSA9IGluaXRpYWxfc2l6ZTtcbiAgICB9XG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuYmIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5zcGFjZSA9IHRoaXMuYmIuY2FwYWNpdHkoKTtcbiAgICAgICAgdGhpcy5taW5hbGlnbiA9IDE7XG4gICAgICAgIHRoaXMudnRhYmxlID0gbnVsbDtcbiAgICAgICAgdGhpcy52dGFibGVfaW5fdXNlID0gMDtcbiAgICAgICAgdGhpcy5pc05lc3RlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLm9iamVjdF9zdGFydCA9IDA7XG4gICAgICAgIHRoaXMudnRhYmxlcyA9IFtdO1xuICAgICAgICB0aGlzLnZlY3Rvcl9udW1fZWxlbXMgPSAwO1xuICAgICAgICB0aGlzLmZvcmNlX2RlZmF1bHRzID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RyaW5nX21hcHMgPSBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbiBvcmRlciB0byBzYXZlIHNwYWNlLCBmaWVsZHMgdGhhdCBhcmUgc2V0IHRvIHRoZWlyIGRlZmF1bHQgdmFsdWVcbiAgICAgKiBkb24ndCBnZXQgc2VyaWFsaXplZCBpbnRvIHRoZSBidWZmZXIuIEZvcmNpbmcgZGVmYXVsdHMgcHJvdmlkZXMgYVxuICAgICAqIHdheSB0byBtYW51YWxseSBkaXNhYmxlIHRoaXMgb3B0aW1pemF0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIGZvcmNlRGVmYXVsdHMgdHJ1ZSBhbHdheXMgc2VyaWFsaXplcyBkZWZhdWx0IHZhbHVlc1xuICAgICAqL1xuICAgIGZvcmNlRGVmYXVsdHMoZm9yY2VEZWZhdWx0cykge1xuICAgICAgICB0aGlzLmZvcmNlX2RlZmF1bHRzID0gZm9yY2VEZWZhdWx0cztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBCeXRlQnVmZmVyIHJlcHJlc2VudGluZyB0aGUgRmxhdEJ1ZmZlci4gT25seSBjYWxsIHRoaXMgYWZ0ZXIgeW91J3ZlXG4gICAgICogY2FsbGVkIGZpbmlzaCgpLiBUaGUgYWN0dWFsIGRhdGEgc3RhcnRzIGF0IHRoZSBCeXRlQnVmZmVyJ3MgY3VycmVudCBwb3NpdGlvbixcbiAgICAgKiBub3QgbmVjZXNzYXJpbHkgYXQgMC5cbiAgICAgKi9cbiAgICBkYXRhQnVmZmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5iYjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBieXRlcyByZXByZXNlbnRpbmcgdGhlIEZsYXRCdWZmZXIuIE9ubHkgY2FsbCB0aGlzIGFmdGVyIHlvdSd2ZVxuICAgICAqIGNhbGxlZCBmaW5pc2goKS5cbiAgICAgKi9cbiAgICBhc1VpbnQ4QXJyYXkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJiLmJ5dGVzKCkuc3ViYXJyYXkodGhpcy5iYi5wb3NpdGlvbigpLCB0aGlzLmJiLnBvc2l0aW9uKCkgKyB0aGlzLm9mZnNldCgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJlcGFyZSB0byB3cml0ZSBhbiBlbGVtZW50IG9mIGBzaXplYCBhZnRlciBgYWRkaXRpb25hbF9ieXRlc2AgaGF2ZSBiZWVuXG4gICAgICogd3JpdHRlbiwgZS5nLiBpZiB5b3Ugd3JpdGUgYSBzdHJpbmcsIHlvdSBuZWVkIHRvIGFsaWduIHN1Y2ggdGhlIGludCBsZW5ndGhcbiAgICAgKiBmaWVsZCBpcyBhbGlnbmVkIHRvIDQgYnl0ZXMsIGFuZCB0aGUgc3RyaW5nIGRhdGEgZm9sbG93cyBpdCBkaXJlY3RseS4gSWYgYWxsXG4gICAgICogeW91IG5lZWQgdG8gZG8gaXMgYWxpZ25tZW50LCBgYWRkaXRpb25hbF9ieXRlc2Agd2lsbCBiZSAwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNpemUgVGhpcyBpcyB0aGUgb2YgdGhlIG5ldyBlbGVtZW50IHRvIHdyaXRlXG4gICAgICogQHBhcmFtIGFkZGl0aW9uYWxfYnl0ZXMgVGhlIHBhZGRpbmcgc2l6ZVxuICAgICAqL1xuICAgIHByZXAoc2l6ZSwgYWRkaXRpb25hbF9ieXRlcykge1xuICAgICAgICAvLyBUcmFjayB0aGUgYmlnZ2VzdCB0aGluZyB3ZSd2ZSBldmVyIGFsaWduZWQgdG8uXG4gICAgICAgIGlmIChzaXplID4gdGhpcy5taW5hbGlnbikge1xuICAgICAgICAgICAgdGhpcy5taW5hbGlnbiA9IHNpemU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmluZCB0aGUgYW1vdW50IG9mIGFsaWdubWVudCBuZWVkZWQgc3VjaCB0aGF0IGBzaXplYCBpcyBwcm9wZXJseVxuICAgICAgICAvLyBhbGlnbmVkIGFmdGVyIGBhZGRpdGlvbmFsX2J5dGVzYFxuICAgICAgICBjb25zdCBhbGlnbl9zaXplID0gKCh+KHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRoaXMuc3BhY2UgKyBhZGRpdGlvbmFsX2J5dGVzKSkgKyAxKSAmIChzaXplIC0gMSk7XG4gICAgICAgIC8vIFJlYWxsb2NhdGUgdGhlIGJ1ZmZlciBpZiBuZWVkZWQuXG4gICAgICAgIHdoaWxlICh0aGlzLnNwYWNlIDwgYWxpZ25fc2l6ZSArIHNpemUgKyBhZGRpdGlvbmFsX2J5dGVzKSB7XG4gICAgICAgICAgICBjb25zdCBvbGRfYnVmX3NpemUgPSB0aGlzLmJiLmNhcGFjaXR5KCk7XG4gICAgICAgICAgICB0aGlzLmJiID0gQnVpbGRlci5ncm93Qnl0ZUJ1ZmZlcih0aGlzLmJiKTtcbiAgICAgICAgICAgIHRoaXMuc3BhY2UgKz0gdGhpcy5iYi5jYXBhY2l0eSgpIC0gb2xkX2J1Zl9zaXplO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGFkKGFsaWduX3NpemUpO1xuICAgIH1cbiAgICBwYWQoYnl0ZV9zaXplKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZV9zaXplOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMuYmIud3JpdGVJbnQ4KC0tdGhpcy5zcGFjZSwgMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgd3JpdGVJbnQ4KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVJbnQ4KHRoaXMuc3BhY2UgLT0gMSwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUludDE2KHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmIud3JpdGVJbnQxNih0aGlzLnNwYWNlIC09IDIsIHZhbHVlKTtcbiAgICB9XG4gICAgd3JpdGVJbnQzMih2YWx1ZSkge1xuICAgICAgICB0aGlzLmJiLndyaXRlSW50MzIodGhpcy5zcGFjZSAtPSA0LCB2YWx1ZSk7XG4gICAgfVxuICAgIHdyaXRlSW50NjQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5iYi53cml0ZUludDY0KHRoaXMuc3BhY2UgLT0gOCwgdmFsdWUpO1xuICAgIH1cbiAgICB3cml0ZUZsb2F0MzIodmFsdWUpIHtcbiAgICAgICAgdGhpcy5iYi53cml0ZUZsb2F0MzIodGhpcy5zcGFjZSAtPSA0LCB2YWx1ZSk7XG4gICAgfVxuICAgIHdyaXRlRmxvYXQ2NCh2YWx1ZSkge1xuICAgICAgICB0aGlzLmJiLndyaXRlRmxvYXQ2NCh0aGlzLnNwYWNlIC09IDgsIHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGBpbnQ4YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBpbnQ4YCB0byBhZGQgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBhZGRJbnQ4KHZhbHVlKSB7XG4gICAgICAgIHRoaXMucHJlcCgxLCAwKTtcbiAgICAgICAgdGhpcy53cml0ZUludDgodmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gYGludDE2YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBpbnQxNmAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkSW50MTYodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDIsIDApO1xuICAgICAgICB0aGlzLndyaXRlSW50MTYodmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gYGludDMyYCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBpbnQzMmAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkSW50MzIodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDQsIDApO1xuICAgICAgICB0aGlzLndyaXRlSW50MzIodmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gYGludDY0YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGBpbnQ2NGAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkSW50NjQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDgsIDApO1xuICAgICAgICB0aGlzLndyaXRlSW50NjQodmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBgZmxvYXQzMmAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gICAgICogQHBhcmFtIHZhbHVlIFRoZSBgZmxvYXQzMmAgdG8gYWRkIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgYWRkRmxvYXQzMih2YWx1ZSkge1xuICAgICAgICB0aGlzLnByZXAoNCwgMCk7XG4gICAgICAgIHRoaXMud3JpdGVGbG9hdDMyKHZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgYGZsb2F0NjRgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYGZsb2F0NjRgIHRvIGFkZCB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGFkZEZsb2F0NjQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5wcmVwKDgsIDApO1xuICAgICAgICB0aGlzLndyaXRlRmxvYXQ2NCh2YWx1ZSk7XG4gICAgfVxuICAgIGFkZEZpZWxkSW50OCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnQ4KHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZEludDE2KHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEludDE2KHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZEludDMyKHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEludDMyKHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZEludDY0KHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT09IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRJbnQ2NCh2YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkRmllbGRGbG9hdDMyKHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEZsb2F0MzIodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZEZpZWxkRmxvYXQ2NCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRGbG9hdDY0KHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRGaWVsZE9mZnNldCh2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hZGRPZmZzZXQodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0cnVjdHMgYXJlIHN0b3JlZCBpbmxpbmUsIHNvIG5vdGhpbmcgYWRkaXRpb25hbCBpcyBiZWluZyBhZGRlZC4gYGRgIGlzIGFsd2F5cyAwLlxuICAgICAqL1xuICAgIGFkZEZpZWxkU3RydWN0KHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5uZXN0ZWQodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0cnVjdHVyZXMgYXJlIGFsd2F5cyBzdG9yZWQgaW5saW5lLCB0aGV5IG5lZWQgdG8gYmUgY3JlYXRlZCByaWdodFxuICAgICAqIHdoZXJlIHRoZXkncmUgdXNlZC4gIFlvdSdsbCBnZXQgdGhpcyBhc3NlcnRpb24gZmFpbHVyZSBpZiB5b3VcbiAgICAgKiBjcmVhdGVkIGl0IGVsc2V3aGVyZS5cbiAgICAgKi9cbiAgICBuZXN0ZWQob2JqKSB7XG4gICAgICAgIGlmIChvYmogIT0gdGhpcy5vZmZzZXQoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmxhdEJ1ZmZlcnM6IHN0cnVjdCBtdXN0IGJlIHNlcmlhbGl6ZWQgaW5saW5lLicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNob3VsZCBub3QgYmUgY3JlYXRpbmcgYW55IG90aGVyIG9iamVjdCwgc3RyaW5nIG9yIHZlY3RvclxuICAgICAqIHdoaWxlIGFuIG9iamVjdCBpcyBiZWluZyBjb25zdHJ1Y3RlZFxuICAgICAqL1xuICAgIG5vdE5lc3RlZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNOZXN0ZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZsYXRCdWZmZXJzOiBvYmplY3Qgc2VyaWFsaXphdGlvbiBtdXN0IG5vdCBiZSBuZXN0ZWQuJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBjdXJyZW50IHZ0YWJsZSBhdCBgdm9mZnNldGAgdG8gdGhlIGN1cnJlbnQgbG9jYXRpb24gaW4gdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBzbG90KHZvZmZzZXQpIHtcbiAgICAgICAgaWYgKHRoaXMudnRhYmxlICE9PSBudWxsKVxuICAgICAgICAgICAgdGhpcy52dGFibGVbdm9mZnNldF0gPSB0aGlzLm9mZnNldCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBPZmZzZXQgcmVsYXRpdmUgdG8gdGhlIGVuZCBvZiB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIG9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRoaXMuc3BhY2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERvdWJsZXMgdGhlIHNpemUgb2YgdGhlIGJhY2tpbmcgQnl0ZUJ1ZmZlciBhbmQgY29waWVzIHRoZSBvbGQgZGF0YSB0b3dhcmRzXG4gICAgICogdGhlIGVuZCBvZiB0aGUgbmV3IGJ1ZmZlciAoc2luY2Ugd2UgYnVpbGQgdGhlIGJ1ZmZlciBiYWNrd2FyZHMpLlxuICAgICAqXG4gICAgICogQHBhcmFtIGJiIFRoZSBjdXJyZW50IGJ1ZmZlciB3aXRoIHRoZSBleGlzdGluZyBkYXRhXG4gICAgICogQHJldHVybnMgQSBuZXcgYnl0ZSBidWZmZXIgd2l0aCB0aGUgb2xkIGRhdGEgY29waWVkXG4gICAgICogdG8gaXQuIFRoZSBkYXRhIGlzIGxvY2F0ZWQgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyLlxuICAgICAqXG4gICAgICogdWludDhBcnJheS5zZXQoKSBmb3JtYWxseSB0YWtlcyB7QXJyYXk8bnVtYmVyPnxBcnJheUJ1ZmZlclZpZXd9LCBzbyB0byBwYXNzXG4gICAgICogaXQgYSB1aW50OEFycmF5IHdlIG5lZWQgdG8gc3VwcHJlc3MgdGhlIHR5cGUgY2hlY2s6XG4gICAgICogQHN1cHByZXNzIHtjaGVja1R5cGVzfVxuICAgICAqL1xuICAgIHN0YXRpYyBncm93Qnl0ZUJ1ZmZlcihiYikge1xuICAgICAgICBjb25zdCBvbGRfYnVmX3NpemUgPSBiYi5jYXBhY2l0eSgpO1xuICAgICAgICAvLyBFbnN1cmUgd2UgZG9uJ3QgZ3JvdyBiZXlvbmQgd2hhdCBmaXRzIGluIGFuIGludC5cbiAgICAgICAgaWYgKG9sZF9idWZfc2l6ZSAmIDB4QzAwMDAwMDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IGNhbm5vdCBncm93IGJ1ZmZlciBiZXlvbmQgMiBnaWdhYnl0ZXMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3X2J1Zl9zaXplID0gb2xkX2J1Zl9zaXplIDw8IDE7XG4gICAgICAgIGNvbnN0IG5iYiA9IGJ5dGVfYnVmZmVyX2pzXzEuQnl0ZUJ1ZmZlci5hbGxvY2F0ZShuZXdfYnVmX3NpemUpO1xuICAgICAgICBuYmIuc2V0UG9zaXRpb24obmV3X2J1Zl9zaXplIC0gb2xkX2J1Zl9zaXplKTtcbiAgICAgICAgbmJiLmJ5dGVzKCkuc2V0KGJiLmJ5dGVzKCksIG5ld19idWZfc2l6ZSAtIG9sZF9idWZfc2l6ZSk7XG4gICAgICAgIHJldHVybiBuYmI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZHMgb24gb2Zmc2V0LCByZWxhdGl2ZSB0byB3aGVyZSBpdCB3aWxsIGJlIHdyaXR0ZW4uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBvZmZzZXQgdG8gYWRkLlxuICAgICAqL1xuICAgIGFkZE9mZnNldChvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5wcmVwKGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQsIDApOyAvLyBFbnN1cmUgYWxpZ25tZW50IGlzIGFscmVhZHkgZG9uZS5cbiAgICAgICAgdGhpcy53cml0ZUludDMyKHRoaXMub2Zmc2V0KCkgLSBvZmZzZXQgKyBjb25zdGFudHNfanNfMS5TSVpFT0ZfSU5UKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgZW5jb2RpbmcgYSBuZXcgb2JqZWN0IGluIHRoZSBidWZmZXIuICBVc2VycyB3aWxsIG5vdCB1c3VhbGx5IG5lZWQgdG9cbiAgICAgKiBjYWxsIHRoaXMgZGlyZWN0bHkuIFRoZSBGbGF0QnVmZmVycyBjb21waWxlciB3aWxsIGdlbmVyYXRlIGhlbHBlciBtZXRob2RzXG4gICAgICogdGhhdCBjYWxsIHRoaXMgbWV0aG9kIGludGVybmFsbHkuXG4gICAgICovXG4gICAgc3RhcnRPYmplY3QobnVtZmllbGRzKSB7XG4gICAgICAgIHRoaXMubm90TmVzdGVkKCk7XG4gICAgICAgIGlmICh0aGlzLnZ0YWJsZSA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnZ0YWJsZSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudnRhYmxlX2luX3VzZSA9IG51bWZpZWxkcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1maWVsZHM7IGkrKykge1xuICAgICAgICAgICAgdGhpcy52dGFibGVbaV0gPSAwOyAvLyBUaGlzIHdpbGwgcHVzaCBhZGRpdGlvbmFsIGVsZW1lbnRzIGFzIG5lZWRlZFxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaXNOZXN0ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLm9iamVjdF9zdGFydCA9IHRoaXMub2Zmc2V0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmlzaCBvZmYgd3JpdGluZyB0aGUgb2JqZWN0IHRoYXQgaXMgdW5kZXIgY29uc3RydWN0aW9uLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIG9mZnNldCB0byB0aGUgb2JqZWN0IGluc2lkZSBgZGF0YUJ1ZmZlcmBcbiAgICAgKi9cbiAgICBlbmRPYmplY3QoKSB7XG4gICAgICAgIGlmICh0aGlzLnZ0YWJsZSA9PSBudWxsIHx8ICF0aGlzLmlzTmVzdGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXRCdWZmZXJzOiBlbmRPYmplY3QgY2FsbGVkIHdpdGhvdXQgc3RhcnRPYmplY3QnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkZEludDMyKDApO1xuICAgICAgICBjb25zdCB2dGFibGVsb2MgPSB0aGlzLm9mZnNldCgpO1xuICAgICAgICAvLyBUcmltIHRyYWlsaW5nIHplcm9lcy5cbiAgICAgICAgbGV0IGkgPSB0aGlzLnZ0YWJsZV9pbl91c2UgLSAxO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHlcbiAgICAgICAgZm9yICg7IGkgPj0gMCAmJiB0aGlzLnZ0YWJsZVtpXSA9PSAwOyBpLS0pIHsgfVxuICAgICAgICBjb25zdCB0cmltbWVkX3NpemUgPSBpICsgMTtcbiAgICAgICAgLy8gV3JpdGUgb3V0IHRoZSBjdXJyZW50IHZ0YWJsZS5cbiAgICAgICAgZm9yICg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAvLyBPZmZzZXQgcmVsYXRpdmUgdG8gdGhlIHN0YXJ0IG9mIHRoZSB0YWJsZS5cbiAgICAgICAgICAgIHRoaXMuYWRkSW50MTYodGhpcy52dGFibGVbaV0gIT0gMCA/IHZ0YWJsZWxvYyAtIHRoaXMudnRhYmxlW2ldIDogMCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhbmRhcmRfZmllbGRzID0gMjsgLy8gVGhlIGZpZWxkcyBiZWxvdzpcbiAgICAgICAgdGhpcy5hZGRJbnQxNih2dGFibGVsb2MgLSB0aGlzLm9iamVjdF9zdGFydCk7XG4gICAgICAgIGNvbnN0IGxlbiA9ICh0cmltbWVkX3NpemUgKyBzdGFuZGFyZF9maWVsZHMpICogY29uc3RhbnRzX2pzXzEuU0laRU9GX1NIT1JUO1xuICAgICAgICB0aGlzLmFkZEludDE2KGxlbik7XG4gICAgICAgIC8vIFNlYXJjaCBmb3IgYW4gZXhpc3RpbmcgdnRhYmxlIHRoYXQgbWF0Y2hlcyB0aGUgY3VycmVudCBvbmUuXG4gICAgICAgIGxldCBleGlzdGluZ192dGFibGUgPSAwO1xuICAgICAgICBjb25zdCB2dDEgPSB0aGlzLnNwYWNlO1xuICAgICAgICBvdXRlcl9sb29wOiBmb3IgKGkgPSAwOyBpIDwgdGhpcy52dGFibGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB2dDIgPSB0aGlzLmJiLmNhcGFjaXR5KCkgLSB0aGlzLnZ0YWJsZXNbaV07XG4gICAgICAgICAgICBpZiAobGVuID09IHRoaXMuYmIucmVhZEludDE2KHZ0MikpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gY29uc3RhbnRzX2pzXzEuU0laRU9GX1NIT1JUOyBqIDwgbGVuOyBqICs9IGNvbnN0YW50c19qc18xLlNJWkVPRl9TSE9SVCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5iYi5yZWFkSW50MTYodnQxICsgaikgIT0gdGhpcy5iYi5yZWFkSW50MTYodnQyICsgaikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyX2xvb3A7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXhpc3RpbmdfdnRhYmxlID0gdGhpcy52dGFibGVzW2ldO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChleGlzdGluZ192dGFibGUpIHtcbiAgICAgICAgICAgIC8vIEZvdW5kIGEgbWF0Y2g6XG4gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGN1cnJlbnQgdnRhYmxlLlxuICAgICAgICAgICAgdGhpcy5zcGFjZSA9IHRoaXMuYmIuY2FwYWNpdHkoKSAtIHZ0YWJsZWxvYztcbiAgICAgICAgICAgIC8vIFBvaW50IHRhYmxlIHRvIGV4aXN0aW5nIHZ0YWJsZS5cbiAgICAgICAgICAgIHRoaXMuYmIud3JpdGVJbnQzMih0aGlzLnNwYWNlLCBleGlzdGluZ192dGFibGUgLSB2dGFibGVsb2MpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gTm8gbWF0Y2g6XG4gICAgICAgICAgICAvLyBBZGQgdGhlIGxvY2F0aW9uIG9mIHRoZSBjdXJyZW50IHZ0YWJsZSB0byB0aGUgbGlzdCBvZiB2dGFibGVzLlxuICAgICAgICAgICAgdGhpcy52dGFibGVzLnB1c2godGhpcy5vZmZzZXQoKSk7XG4gICAgICAgICAgICAvLyBQb2ludCB0YWJsZSB0byBjdXJyZW50IHZ0YWJsZS5cbiAgICAgICAgICAgIHRoaXMuYmIud3JpdGVJbnQzMih0aGlzLmJiLmNhcGFjaXR5KCkgLSB2dGFibGVsb2MsIHRoaXMub2Zmc2V0KCkgLSB2dGFibGVsb2MpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaXNOZXN0ZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHZ0YWJsZWxvYztcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluYWxpemUgYSBidWZmZXIsIHBvaXRpbmcgdG8gdGhlIGdpdmVuIGByb290X3RhYmxlYC5cbiAgICAgKi9cbiAgICBmaW5pc2gocm9vdF90YWJsZSwgb3B0X2ZpbGVfaWRlbnRpZmllciwgb3B0X3NpemVfcHJlZml4KSB7XG4gICAgICAgIGNvbnN0IHNpemVfcHJlZml4ID0gb3B0X3NpemVfcHJlZml4ID8gY29uc3RhbnRzX2pzXzEuU0laRV9QUkVGSVhfTEVOR1RIIDogMDtcbiAgICAgICAgaWYgKG9wdF9maWxlX2lkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVfaWRlbnRpZmllciA9IG9wdF9maWxlX2lkZW50aWZpZXI7XG4gICAgICAgICAgICB0aGlzLnByZXAodGhpcy5taW5hbGlnbiwgY29uc3RhbnRzX2pzXzEuU0laRU9GX0lOVCArXG4gICAgICAgICAgICAgICAgY29uc3RhbnRzX2pzXzEuRklMRV9JREVOVElGSUVSX0xFTkdUSCArIHNpemVfcHJlZml4KTtcbiAgICAgICAgICAgIGlmIChmaWxlX2lkZW50aWZpZXIubGVuZ3RoICE9IGNvbnN0YW50c19qc18xLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGbGF0QnVmZmVyczogZmlsZSBpZGVudGlmaWVyIG11c3QgYmUgbGVuZ3RoICcgK1xuICAgICAgICAgICAgICAgICAgICBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBjb25zdGFudHNfanNfMS5GSUxFX0lERU5USUZJRVJfTEVOR1RIIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLndyaXRlSW50OChmaWxlX2lkZW50aWZpZXIuY2hhckNvZGVBdChpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcmVwKHRoaXMubWluYWxpZ24sIGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQgKyBzaXplX3ByZWZpeCk7XG4gICAgICAgIHRoaXMuYWRkT2Zmc2V0KHJvb3RfdGFibGUpO1xuICAgICAgICBpZiAoc2l6ZV9wcmVmaXgpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkSW50MzIodGhpcy5iYi5jYXBhY2l0eSgpIC0gdGhpcy5zcGFjZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5iYi5zZXRQb3NpdGlvbih0aGlzLnNwYWNlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluYWxpemUgYSBzaXplIHByZWZpeGVkIGJ1ZmZlciwgcG9pbnRpbmcgdG8gdGhlIGdpdmVuIGByb290X3RhYmxlYC5cbiAgICAgKi9cbiAgICBmaW5pc2hTaXplUHJlZml4ZWQocm9vdF90YWJsZSwgb3B0X2ZpbGVfaWRlbnRpZmllcikge1xuICAgICAgICB0aGlzLmZpbmlzaChyb290X3RhYmxlLCBvcHRfZmlsZV9pZGVudGlmaWVyLCB0cnVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhpcyBjaGVja3MgYSByZXF1aXJlZCBmaWVsZCBoYXMgYmVlbiBzZXQgaW4gYSBnaXZlbiB0YWJsZSB0aGF0IGhhc1xuICAgICAqIGp1c3QgYmVlbiBjb25zdHJ1Y3RlZC5cbiAgICAgKi9cbiAgICByZXF1aXJlZEZpZWxkKHRhYmxlLCBmaWVsZCkge1xuICAgICAgICBjb25zdCB0YWJsZV9zdGFydCA9IHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRhYmxlO1xuICAgICAgICBjb25zdCB2dGFibGVfc3RhcnQgPSB0YWJsZV9zdGFydCAtIHRoaXMuYmIucmVhZEludDMyKHRhYmxlX3N0YXJ0KTtcbiAgICAgICAgY29uc3Qgb2sgPSBmaWVsZCA8IHRoaXMuYmIucmVhZEludDE2KHZ0YWJsZV9zdGFydCkgJiZcbiAgICAgICAgICAgIHRoaXMuYmIucmVhZEludDE2KHZ0YWJsZV9zdGFydCArIGZpZWxkKSAhPSAwO1xuICAgICAgICAvLyBJZiB0aGlzIGZhaWxzLCB0aGUgY2FsbGVyIHdpbGwgc2hvdyB3aGF0IGZpZWxkIG5lZWRzIHRvIGJlIHNldC5cbiAgICAgICAgaWYgKCFvaykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmxhdEJ1ZmZlcnM6IGZpZWxkICcgKyBmaWVsZCArICcgbXVzdCBiZSBzZXQnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCBhIG5ldyBhcnJheS92ZWN0b3Igb2Ygb2JqZWN0cy4gIFVzZXJzIHVzdWFsbHkgd2lsbCBub3QgY2FsbFxuICAgICAqIHRoaXMgZGlyZWN0bHkuIFRoZSBGbGF0QnVmZmVycyBjb21waWxlciB3aWxsIGNyZWF0ZSBhIHN0YXJ0L2VuZFxuICAgICAqIG1ldGhvZCBmb3IgdmVjdG9yIHR5cGVzIGluIGdlbmVyYXRlZCBjb2RlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVsZW1fc2l6ZSBUaGUgc2l6ZSBvZiBlYWNoIGVsZW1lbnQgaW4gdGhlIGFycmF5XG4gICAgICogQHBhcmFtIG51bV9lbGVtcyBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBhcnJheVxuICAgICAqIEBwYXJhbSBhbGlnbm1lbnQgVGhlIGFsaWdubWVudCBvZiB0aGUgYXJyYXlcbiAgICAgKi9cbiAgICBzdGFydFZlY3RvcihlbGVtX3NpemUsIG51bV9lbGVtcywgYWxpZ25tZW50KSB7XG4gICAgICAgIHRoaXMubm90TmVzdGVkKCk7XG4gICAgICAgIHRoaXMudmVjdG9yX251bV9lbGVtcyA9IG51bV9lbGVtcztcbiAgICAgICAgdGhpcy5wcmVwKGNvbnN0YW50c19qc18xLlNJWkVPRl9JTlQsIGVsZW1fc2l6ZSAqIG51bV9lbGVtcyk7XG4gICAgICAgIHRoaXMucHJlcChhbGlnbm1lbnQsIGVsZW1fc2l6ZSAqIG51bV9lbGVtcyk7IC8vIEp1c3QgaW4gY2FzZSBhbGlnbm1lbnQgPiBpbnQuXG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmlzaCBvZmYgdGhlIGNyZWF0aW9uIG9mIGFuIGFycmF5IGFuZCBhbGwgaXRzIGVsZW1lbnRzLiBUaGUgYXJyYXkgbXVzdCBiZVxuICAgICAqIGNyZWF0ZWQgd2l0aCBgc3RhcnRWZWN0b3JgLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIG9mZnNldCBhdCB3aGljaCB0aGUgbmV3bHkgY3JlYXRlZCBhcnJheVxuICAgICAqIHN0YXJ0cy5cbiAgICAgKi9cbiAgICBlbmRWZWN0b3IoKSB7XG4gICAgICAgIHRoaXMud3JpdGVJbnQzMih0aGlzLnZlY3Rvcl9udW1fZWxlbXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5vZmZzZXQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRW5jb2RlIHRoZSBzdHJpbmcgYHNgIGluIHRoZSBidWZmZXIgdXNpbmcgVVRGLTguIElmIHRoZSBzdHJpbmcgcGFzc2VkIGhhc1xuICAgICAqIGFscmVhZHkgYmVlbiBzZWVuLCB3ZSByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgYWxyZWFkeSB3cml0dGVuIHN0cmluZ1xuICAgICAqXG4gICAgICogQHBhcmFtIHMgVGhlIHN0cmluZyB0byBlbmNvZGVcbiAgICAgKiBAcmV0dXJuIFRoZSBvZmZzZXQgaW4gdGhlIGJ1ZmZlciB3aGVyZSB0aGUgZW5jb2RlZCBzdHJpbmcgc3RhcnRzXG4gICAgICovXG4gICAgY3JlYXRlU2hhcmVkU3RyaW5nKHMpIHtcbiAgICAgICAgaWYgKCFzKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuc3RyaW5nX21hcHMpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyaW5nX21hcHMgPSBuZXcgTWFwKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RyaW5nX21hcHMuaGFzKHMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdHJpbmdfbWFwcy5nZXQocyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5jcmVhdGVTdHJpbmcocyk7XG4gICAgICAgIHRoaXMuc3RyaW5nX21hcHMuc2V0KHMsIG9mZnNldCk7XG4gICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVuY29kZSB0aGUgc3RyaW5nIGBzYCBpbiB0aGUgYnVmZmVyIHVzaW5nIFVURi04LiBJZiBhIFVpbnQ4QXJyYXkgaXMgcGFzc2VkXG4gICAgICogaW5zdGVhZCBvZiBhIHN0cmluZywgaXQgaXMgYXNzdW1lZCB0byBjb250YWluIHZhbGlkIFVURi04IGVuY29kZWQgZGF0YS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzIFRoZSBzdHJpbmcgdG8gZW5jb2RlXG4gICAgICogQHJldHVybiBUaGUgb2Zmc2V0IGluIHRoZSBidWZmZXIgd2hlcmUgdGhlIGVuY29kZWQgc3RyaW5nIHN0YXJ0c1xuICAgICAqL1xuICAgIGNyZWF0ZVN0cmluZyhzKSB7XG4gICAgICAgIGlmIChzID09PSBudWxsIHx8IHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHV0Zjg7XG4gICAgICAgIGlmIChzIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgICAgICAgdXRmOCA9IHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB1dGY4ID0gdGhpcy50ZXh0X2VuY29kZXIuZW5jb2RlKHMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWRkSW50OCgwKTtcbiAgICAgICAgdGhpcy5zdGFydFZlY3RvcigxLCB1dGY4Lmxlbmd0aCwgMSk7XG4gICAgICAgIHRoaXMuYmIuc2V0UG9zaXRpb24odGhpcy5zcGFjZSAtPSB1dGY4Lmxlbmd0aCk7XG4gICAgICAgIHRoaXMuYmIuYnl0ZXMoKS5zZXQodXRmOCwgdGhpcy5zcGFjZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVuZFZlY3RvcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBieXRlIHZlY3Rvci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2IFRoZSBieXRlcyB0byBhZGRcbiAgICAgKiBAcmV0dXJucyBUaGUgb2Zmc2V0IGluIHRoZSBidWZmZXIgd2hlcmUgdGhlIGJ5dGUgdmVjdG9yIHN0YXJ0c1xuICAgICAqL1xuICAgIGNyZWF0ZUJ5dGVWZWN0b3Iodikge1xuICAgICAgICBpZiAodiA9PT0gbnVsbCB8fCB2ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhcnRWZWN0b3IoMSwgdi5sZW5ndGgsIDEpO1xuICAgICAgICB0aGlzLmJiLnNldFBvc2l0aW9uKHRoaXMuc3BhY2UgLT0gdi5sZW5ndGgpO1xuICAgICAgICB0aGlzLmJiLmJ5dGVzKCkuc2V0KHYsIHRoaXMuc3BhY2UpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbmRWZWN0b3IoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gcGFjayBhbiBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIG9mZnNldCBvZiBvYmpcbiAgICAgKi9cbiAgICBjcmVhdGVPYmplY3RPZmZzZXQob2JqKSB7XG4gICAgICAgIGlmIChvYmogPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU3RyaW5nKG9iaik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqLnBhY2sodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gcGFjayBhIGxpc3Qgb2Ygb2JqZWN0XG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBsaXN0IG9mIG9mZnNldHMgb2YgZWFjaCBub24gbnVsbCBvYmplY3RcbiAgICAgKi9cbiAgICBjcmVhdGVPYmplY3RPZmZzZXRMaXN0KGxpc3QpIHtcbiAgICAgICAgY29uc3QgcmV0ID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgY29uc3QgdmFsID0gbGlzdFtpXTtcbiAgICAgICAgICAgIGlmICh2YWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXQucHVzaCh0aGlzLmNyZWF0ZU9iamVjdE9mZnNldCh2YWwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZsYXRCdWZmZXJzOiBBcmd1bWVudCBmb3IgY3JlYXRlT2JqZWN0T2Zmc2V0TGlzdCBjYW5ub3QgY29udGFpbiBudWxsLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIGNyZWF0ZVN0cnVjdE9mZnNldExpc3QobGlzdCwgc3RhcnRGdW5jKSB7XG4gICAgICAgIHN0YXJ0RnVuYyh0aGlzLCBsaXN0Lmxlbmd0aCk7XG4gICAgICAgIHRoaXMuY3JlYXRlT2JqZWN0T2Zmc2V0TGlzdChsaXN0LnNsaWNlKCkucmV2ZXJzZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5kVmVjdG9yKCk7XG4gICAgfVxufVxuZXhwb3J0cy5CdWlsZGVyID0gQnVpbGRlcjtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQnl0ZUJ1ZmZlciA9IGV4cG9ydHMuQnVpbGRlciA9IGV4cG9ydHMuRW5jb2RpbmcgPSBleHBvcnRzLmlzTGl0dGxlRW5kaWFuID0gZXhwb3J0cy5mbG9hdDY0ID0gZXhwb3J0cy5mbG9hdDMyID0gZXhwb3J0cy5pbnQzMiA9IGV4cG9ydHMuU0laRV9QUkVGSVhfTEVOR1RIID0gZXhwb3J0cy5GSUxFX0lERU5USUZJRVJfTEVOR1RIID0gZXhwb3J0cy5TSVpFT0ZfSU5UID0gZXhwb3J0cy5TSVpFT0ZfU0hPUlQgPSB2b2lkIDA7XG52YXIgY29uc3RhbnRzX2pzXzEgPSByZXF1aXJlKFwiLi9jb25zdGFudHMuanNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJTSVpFT0ZfU0hPUlRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbnN0YW50c19qc18xLlNJWkVPRl9TSE9SVDsgfSB9KTtcbnZhciBjb25zdGFudHNfanNfMiA9IHJlcXVpcmUoXCIuL2NvbnN0YW50cy5qc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlNJWkVPRl9JTlRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbnN0YW50c19qc18yLlNJWkVPRl9JTlQ7IH0gfSk7XG52YXIgY29uc3RhbnRzX2pzXzMgPSByZXF1aXJlKFwiLi9jb25zdGFudHMuanNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJGSUxFX0lERU5USUZJRVJfTEVOR1RIXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdGFudHNfanNfMy5GSUxFX0lERU5USUZJRVJfTEVOR1RIOyB9IH0pO1xudmFyIGNvbnN0YW50c19qc180ID0gcmVxdWlyZShcIi4vY29uc3RhbnRzLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiU0laRV9QUkVGSVhfTEVOR1RIXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdGFudHNfanNfNC5TSVpFX1BSRUZJWF9MRU5HVEg7IH0gfSk7XG52YXIgdXRpbHNfanNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiaW50MzJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHV0aWxzX2pzXzEuaW50MzI7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJmbG9hdDMyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB1dGlsc19qc18xLmZsb2F0MzI7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJmbG9hdDY0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB1dGlsc19qc18xLmZsb2F0NjQ7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpc0xpdHRsZUVuZGlhblwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdXRpbHNfanNfMS5pc0xpdHRsZUVuZGlhbjsgfSB9KTtcbnZhciBlbmNvZGluZ19qc18xID0gcmVxdWlyZShcIi4vZW5jb2RpbmcuanNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJFbmNvZGluZ1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZW5jb2RpbmdfanNfMS5FbmNvZGluZzsgfSB9KTtcbnZhciBidWlsZGVyX2pzXzEgPSByZXF1aXJlKFwiLi9idWlsZGVyLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQnVpbGRlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYnVpbGRlcl9qc18xLkJ1aWxkZXI7IH0gfSk7XG52YXIgYnl0ZV9idWZmZXJfanNfMSA9IHJlcXVpcmUoXCIuL2J5dGUtYnVmZmVyLmpzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQnl0ZUJ1ZmZlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gYnl0ZV9idWZmZXJfanNfMS5CeXRlQnVmZmVyOyB9IH0pO1xuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblxuaW1wb3J0ICogYXMgZmxhdGJ1ZmZlcnMgZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQgeyBBcmdUeXBlIH0gZnJvbSAnLi4vLi4vb25ueHJ1bnRpbWUvZmJzL2FyZy10eXBlLmpzJztcblxuZXhwb3J0IGNsYXNzIEFyZ1R5cGVBbmRJbmRleCB7XG4gIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIGJiX3BvcyA9IDA7XG4gIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogQXJnVHlwZUFuZEluZGV4IHtcbiAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgdGhpcy5iYiA9IGJiO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGdldFJvb3RBc0FyZ1R5cGVBbmRJbmRleChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogQXJnVHlwZUFuZEluZGV4KTogQXJnVHlwZUFuZEluZGV4IHtcbiAgICByZXR1cm4gKG9iaiB8fCBuZXcgQXJnVHlwZUFuZEluZGV4KCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzQXJnVHlwZUFuZEluZGV4KGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/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+IDI7XHJcbiAgICAgICAgICAgICAgICB0ID0gYztcclxuICAgICAgICAgICAgICAgIGogPSAzO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSAodCAmIDMpIDw8IDYgfCBjO1xyXG4gICAgICAgICAgICAgICAgaiA9IDA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoaiA9PT0gMSlcclxuICAgICAgICB0aHJvdyBFcnJvcihpbnZhbGlkRW5jb2RpbmcpO1xyXG4gICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFwcGVhcnMgdG8gYmUgYmFzZTY0IGVuY29kZWQuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU3RyaW5nIHRvIHRlc3RcclxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBwcm9iYWJseSBiYXNlNjQgZW5jb2RlZCwgb3RoZXJ3aXNlIGZhbHNlXHJcbiAqL1xyXG5iYXNlNjQudGVzdCA9IGZ1bmN0aW9uIHRlc3Qoc3RyaW5nKSB7XHJcbiAgICByZXR1cm4gL14oPzpbQS1aYS16MC05Ky9dezR9KSooPzpbQS1aYS16MC05Ky9dezJ9PT18W0EtWmEtejAtOSsvXXszfT0pPyQvLnRlc3Qoc3RyaW5nKTtcclxufTtcclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcclxuXHJcbi8qKlxyXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IGV2ZW50IGVtaXR0ZXIgaW5zdGFuY2UuXHJcbiAqIEBjbGFzc2Rlc2MgQSBtaW5pbWFsIGV2ZW50IGVtaXR0ZXIuXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKi9cclxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVnaXN0ZXJlZCBsaXN0ZW5lcnMuXHJcbiAgICAgKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsKj59XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB0aGlzLl9saXN0ZW5lcnMgPSB7fTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lci5cclxuICogQHBhcmFtIHtzdHJpbmd9IGV2dCBFdmVudCBuYW1lXHJcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGZuIExpc3RlbmVyXHJcbiAqIEBwYXJhbSB7Kn0gW2N0eF0gTGlzdGVuZXIgY29udGV4dFxyXG4gKiBAcmV0dXJucyB7dXRpbC5FdmVudEVtaXR0ZXJ9IGB0aGlzYFxyXG4gKi9cclxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKGV2dCwgZm4sIGN0eCkge1xyXG4gICAgKHRoaXMuX2xpc3RlbmVyc1tldnRdIHx8ICh0aGlzLl9saXN0ZW5lcnNbZXZ0XSA9IFtdKSkucHVzaCh7XHJcbiAgICAgICAgZm4gIDogZm4sXHJcbiAgICAgICAgY3R4IDogY3R4IHx8IHRoaXNcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogUmVtb3ZlcyBhbiBldmVudCBsaXN0ZW5lciBvciBhbnkgbWF0Y2hpbmcgbGlzdGVuZXJzIGlmIGFyZ3VtZW50cyBhcmUgb21pdHRlZC5cclxuICogQHBhcmFtIHtzdHJpbmd9IFtldnRdIEV2ZW50IG5hbWUuIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBpZiBvbWl0dGVkLlxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBbZm5dIExpc3RlbmVyIHRvIHJlbW92ZS4gUmVtb3ZlcyBhbGwgbGlzdGVuZXJzIG9mIGBldnRgIGlmIG9taXR0ZWQuXHJcbiAqIEByZXR1cm5zIHt1dGlsLkV2ZW50RW1pdHRlcn0gYHRoaXNgXHJcbiAqL1xyXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIG9mZihldnQsIGZuKSB7XHJcbiAgICBpZiAoZXZ0ID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzID0ge307XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBpZiAoZm4gPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzW2V2dF0gPSBbXTtcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVyc1tldnRdO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7KVxyXG4gICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyc1tpXS5mbiA9PT0gZm4pXHJcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpLCAxKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICArK2k7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogRW1pdHMgYW4gZXZlbnQgYnkgY2FsbGluZyBpdHMgbGlzdGVuZXJzIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBldnQgRXZlbnQgbmFtZVxyXG4gKiBAcGFyYW0gey4uLip9IGFyZ3MgQXJndW1lbnRzXHJcbiAqIEByZXR1cm5zIHt1dGlsLkV2ZW50RW1pdHRlcn0gYHRoaXNgXHJcbiAqL1xyXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiBlbWl0KGV2dCkge1xyXG4gICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVyc1tldnRdO1xyXG4gICAgaWYgKGxpc3RlbmVycykge1xyXG4gICAgICAgIHZhciBhcmdzID0gW10sXHJcbiAgICAgICAgICAgIGkgPSAxO1xyXG4gICAgICAgIGZvciAoOyBpIDwgYXJndW1lbnRzLmxlbmd0aDspXHJcbiAgICAgICAgICAgIGFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XHJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7KVxyXG4gICAgICAgICAgICBsaXN0ZW5lcnNbaV0uZm4uYXBwbHkobGlzdGVuZXJzW2krK10uY3R4LCBhcmdzKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG59O1xyXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoZmFjdG9yeSk7XHJcblxyXG4vKipcclxuICogUmVhZHMgLyB3cml0ZXMgZmxvYXRzIC8gZG91YmxlcyBmcm9tIC8gdG8gYnVmZmVycy5cclxuICogQG5hbWUgdXRpbC5mbG9hdFxyXG4gKiBAbmFtZXNwYWNlXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFdyaXRlcyBhIDMyIGJpdCBmbG9hdCB0byBhIGJ1ZmZlciB1c2luZyBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQud3JpdGVGbG9hdExFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsIFZhbHVlIHRvIHdyaXRlXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFRhcmdldCBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBUYXJnZXQgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSAzMiBiaXQgZmxvYXQgdG8gYSBidWZmZXIgdXNpbmcgYmlnIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LndyaXRlRmxvYXRCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogUmVhZHMgYSAzMiBiaXQgZmxvYXQgZnJvbSBhIGJ1ZmZlciB1c2luZyBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQucmVhZEZsb2F0TEVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFNvdXJjZSBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBTb3VyY2UgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIGEgMzIgYml0IGZsb2F0IGZyb20gYSBidWZmZXIgdXNpbmcgYmlnIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWRGbG9hdEJFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgU291cmNlIGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSA2NCBiaXQgZG91YmxlIHRvIGEgYnVmZmVyIHVzaW5nIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC53cml0ZURvdWJsZUxFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsIFZhbHVlIHRvIHdyaXRlXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFRhcmdldCBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBUYXJnZXQgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSA2NCBiaXQgZG91YmxlIHRvIGEgYnVmZmVyIHVzaW5nIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC53cml0ZURvdWJsZUJFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsIFZhbHVlIHRvIHdyaXRlXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFRhcmdldCBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBUYXJnZXQgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBhIDY0IGJpdCBkb3VibGUgZnJvbSBhIGJ1ZmZlciB1c2luZyBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQucmVhZERvdWJsZUxFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgU291cmNlIGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBhIDY0IGJpdCBkb3VibGUgZnJvbSBhIGJ1ZmZlciB1c2luZyBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQucmVhZERvdWJsZUJFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgU291cmNlIGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gKi9cclxuXHJcbi8vIEZhY3RvcnkgZnVuY3Rpb24gZm9yIHRoZSBwdXJwb3NlIG9mIG5vZGUtYmFzZWQgdGVzdGluZyBpbiBtb2RpZmllZCBnbG9iYWwgZW52aXJvbm1lbnRzXHJcbmZ1bmN0aW9uIGZhY3RvcnkoZXhwb3J0cykge1xyXG5cclxuICAgIC8vIGZsb2F0OiB0eXBlZCBhcnJheVxyXG4gICAgaWYgKHR5cGVvZiBGbG9hdDMyQXJyYXkgIT09IFwidW5kZWZpbmVkXCIpIChmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIGYzMiA9IG5ldyBGbG9hdDMyQXJyYXkoWyAtMCBdKSxcclxuICAgICAgICAgICAgZjhiID0gbmV3IFVpbnQ4QXJyYXkoZjMyLmJ1ZmZlciksXHJcbiAgICAgICAgICAgIGxlICA9IGY4YlszXSA9PT0gMTI4O1xyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZUZsb2F0X2YzMl9jcHkodmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmMzJbMF0gPSB2YWw7XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgICAgXSA9IGY4YlswXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDFdID0gZjhiWzFdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMl0gPSBmOGJbMl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAzXSA9IGY4YlszXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRmxvYXRfZjMyX3Jldih2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGYzMlswXSA9IHZhbDtcclxuICAgICAgICAgICAgYnVmW3BvcyAgICBdID0gZjhiWzNdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMV0gPSBmOGJbMl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAyXSA9IGY4YlsxXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDNdID0gZjhiWzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLndyaXRlRmxvYXRMRSA9IGxlID8gd3JpdGVGbG9hdF9mMzJfY3B5IDogd3JpdGVGbG9hdF9mMzJfcmV2O1xyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZUZsb2F0QkUgPSBsZSA/IHdyaXRlRmxvYXRfZjMyX3JldiA6IHdyaXRlRmxvYXRfZjMyX2NweTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZEZsb2F0X2YzMl9jcHkoYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjhiWzBdID0gYnVmW3BvcyAgICBdO1xyXG4gICAgICAgICAgICBmOGJbMV0gPSBidWZbcG9zICsgMV07XHJcbiAgICAgICAgICAgIGY4YlsyXSA9IGJ1Zltwb3MgKyAyXTtcclxuICAgICAgICAgICAgZjhiWzNdID0gYnVmW3BvcyArIDNdO1xyXG4gICAgICAgICAgICByZXR1cm4gZjMyWzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZEZsb2F0X2YzMl9yZXYoYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjhiWzNdID0gYnVmW3BvcyAgICBdO1xyXG4gICAgICAgICAgICBmOGJbMl0gPSBidWZbcG9zICsgMV07XHJcbiAgICAgICAgICAgIGY4YlsxXSA9IGJ1Zltwb3MgKyAyXTtcclxuICAgICAgICAgICAgZjhiWzBdID0gYnVmW3BvcyArIDNdO1xyXG4gICAgICAgICAgICByZXR1cm4gZjMyWzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLnJlYWRGbG9hdExFID0gbGUgPyByZWFkRmxvYXRfZjMyX2NweSA6IHJlYWRGbG9hdF9mMzJfcmV2O1xyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRmxvYXRCRSA9IGxlID8gcmVhZEZsb2F0X2YzMl9yZXYgOiByZWFkRmxvYXRfZjMyX2NweTtcclxuXHJcbiAgICAvLyBmbG9hdDogaWVlZTc1NFxyXG4gICAgfSkoKTsgZWxzZSAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRmxvYXRfaWVlZTc1NCh3cml0ZVVpbnQsIHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgdmFyIHNpZ24gPSB2YWwgPCAwID8gMSA6IDA7XHJcbiAgICAgICAgICAgIGlmIChzaWduKVxyXG4gICAgICAgICAgICAgICAgdmFsID0gLXZhbDtcclxuICAgICAgICAgICAgaWYgKHZhbCA9PT0gMClcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgxIC8gdmFsID4gMCA/IC8qIHBvc2l0aXZlICovIDAgOiAvKiBuZWdhdGl2ZSAwICovIDIxNDc0ODM2NDgsIGJ1ZiwgcG9zKTtcclxuICAgICAgICAgICAgZWxzZSBpZiAoaXNOYU4odmFsKSlcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgyMTQzMjg5MzQ0LCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbCA+IDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpIC8vICstSW5maW5pdHlcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IDIxMzkwOTUwNDApID4+PiAwLCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbCA8IDEuMTc1NDk0MzUwODIyMjg3NWUtMzgpIC8vIGRlbm9ybWFsXHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoKHNpZ24gPDwgMzEgfCBNYXRoLnJvdW5kKHZhbCAvIDEuNDAxMjk4NDY0MzI0ODE3ZS00NSkpID4+PiAwLCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdmFyIGV4cG9uZW50ID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWwpIC8gTWF0aC5MTjIpLFxyXG4gICAgICAgICAgICAgICAgICAgIG1hbnRpc3NhID0gTWF0aC5yb3VuZCh2YWwgKiBNYXRoLnBvdygyLCAtZXhwb25lbnQpICogODM4ODYwOCkgJiA4Mzg4NjA3O1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgZXhwb25lbnQgKyAxMjcgPDwgMjMgfCBtYW50aXNzYSkgPj4+IDAsIGJ1ZiwgcG9zKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZUZsb2F0TEUgPSB3cml0ZUZsb2F0X2llZWU3NTQuYmluZChudWxsLCB3cml0ZVVpbnRMRSk7XHJcbiAgICAgICAgZXhwb3J0cy53cml0ZUZsb2F0QkUgPSB3cml0ZUZsb2F0X2llZWU3NTQuYmluZChudWxsLCB3cml0ZVVpbnRCRSk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWRGbG9hdF9pZWVlNzU0KHJlYWRVaW50LCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICB2YXIgdWludCA9IHJlYWRVaW50KGJ1ZiwgcG9zKSxcclxuICAgICAgICAgICAgICAgIHNpZ24gPSAodWludCA+PiAzMSkgKiAyICsgMSxcclxuICAgICAgICAgICAgICAgIGV4cG9uZW50ID0gdWludCA+Pj4gMjMgJiAyNTUsXHJcbiAgICAgICAgICAgICAgICBtYW50aXNzYSA9IHVpbnQgJiA4Mzg4NjA3O1xyXG4gICAgICAgICAgICByZXR1cm4gZXhwb25lbnQgPT09IDI1NVxyXG4gICAgICAgICAgICAgICAgPyBtYW50aXNzYVxyXG4gICAgICAgICAgICAgICAgPyBOYU5cclxuICAgICAgICAgICAgICAgIDogc2lnbiAqIEluZmluaXR5XHJcbiAgICAgICAgICAgICAgICA6IGV4cG9uZW50ID09PSAwIC8vIGRlbm9ybWFsXHJcbiAgICAgICAgICAgICAgICA/IHNpZ24gKiAxLjQwMTI5ODQ2NDMyNDgxN2UtNDUgKiBtYW50aXNzYVxyXG4gICAgICAgICAgICAgICAgOiBzaWduICogTWF0aC5wb3coMiwgZXhwb25lbnQgLSAxNTApICogKG1hbnRpc3NhICsgODM4ODYwOCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBleHBvcnRzLnJlYWRGbG9hdExFID0gcmVhZEZsb2F0X2llZWU3NTQuYmluZChudWxsLCByZWFkVWludExFKTtcclxuICAgICAgICBleHBvcnRzLnJlYWRGbG9hdEJFID0gcmVhZEZsb2F0X2llZWU3NTQuYmluZChudWxsLCByZWFkVWludEJFKTtcclxuXHJcbiAgICB9KSgpO1xyXG5cclxuICAgIC8vIGRvdWJsZTogdHlwZWQgYXJyYXlcclxuICAgIGlmICh0eXBlb2YgRmxvYXQ2NEFycmF5ICE9PSBcInVuZGVmaW5lZFwiKSAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBmNjQgPSBuZXcgRmxvYXQ2NEFycmF5KFstMF0pLFxyXG4gICAgICAgICAgICBmOGIgPSBuZXcgVWludDhBcnJheShmNjQuYnVmZmVyKSxcclxuICAgICAgICAgICAgbGUgID0gZjhiWzddID09PSAxMjg7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRG91YmxlX2Y2NF9jcHkodmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmNjRbMF0gPSB2YWw7XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgICAgXSA9IGY4YlswXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDFdID0gZjhiWzFdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMl0gPSBmOGJbMl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAzXSA9IGY4YlszXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDRdID0gZjhiWzRdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNV0gPSBmOGJbNV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA2XSA9IGY4Yls2XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDddID0gZjhiWzddO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gd3JpdGVEb3VibGVfZjY0X3Jldih2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY2NFswXSA9IHZhbDtcclxuICAgICAgICAgICAgYnVmW3BvcyAgICBdID0gZjhiWzddO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMV0gPSBmOGJbNl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAyXSA9IGY4Yls1XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDNdID0gZjhiWzRdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNF0gPSBmOGJbM107XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA1XSA9IGY4YlsyXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDZdID0gZjhiWzFdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgN10gPSBmOGJbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVEb3VibGVMRSA9IGxlID8gd3JpdGVEb3VibGVfZjY0X2NweSA6IHdyaXRlRG91YmxlX2Y2NF9yZXY7XHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLndyaXRlRG91YmxlQkUgPSBsZSA/IHdyaXRlRG91YmxlX2Y2NF9yZXYgOiB3cml0ZURvdWJsZV9mNjRfY3B5O1xyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRG91YmxlX2Y2NF9jcHkoYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjhiWzBdID0gYnVmW3BvcyAgICBdO1xyXG4gICAgICAgICAgICBmOGJbMV0gPSBidWZbcG9zICsgMV07XHJcbiAgICAgICAgICAgIGY4YlsyXSA9IGJ1Zltwb3MgKyAyXTtcclxuICAgICAgICAgICAgZjhiWzNdID0gYnVmW3BvcyArIDNdO1xyXG4gICAgICAgICAgICBmOGJbNF0gPSBidWZbcG9zICsgNF07XHJcbiAgICAgICAgICAgIGY4Yls1XSA9IGJ1Zltwb3MgKyA1XTtcclxuICAgICAgICAgICAgZjhiWzZdID0gYnVmW3BvcyArIDZdO1xyXG4gICAgICAgICAgICBmOGJbN10gPSBidWZbcG9zICsgN107XHJcbiAgICAgICAgICAgIHJldHVybiBmNjRbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRG91YmxlX2Y2NF9yZXYoYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjhiWzddID0gYnVmW3BvcyAgICBdO1xyXG4gICAgICAgICAgICBmOGJbNl0gPSBidWZbcG9zICsgMV07XHJcbiAgICAgICAgICAgIGY4Yls1XSA9IGJ1Zltwb3MgKyAyXTtcclxuICAgICAgICAgICAgZjhiWzRdID0gYnVmW3BvcyArIDNdO1xyXG4gICAgICAgICAgICBmOGJbM10gPSBidWZbcG9zICsgNF07XHJcbiAgICAgICAgICAgIGY4YlsyXSA9IGJ1Zltwb3MgKyA1XTtcclxuICAgICAgICAgICAgZjhiWzFdID0gYnVmW3BvcyArIDZdO1xyXG4gICAgICAgICAgICBmOGJbMF0gPSBidWZbcG9zICsgN107XHJcbiAgICAgICAgICAgIHJldHVybiBmNjRbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMucmVhZERvdWJsZUxFID0gbGUgPyByZWFkRG91YmxlX2Y2NF9jcHkgOiByZWFkRG91YmxlX2Y2NF9yZXY7XHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLnJlYWREb3VibGVCRSA9IGxlID8gcmVhZERvdWJsZV9mNjRfcmV2IDogcmVhZERvdWJsZV9mNjRfY3B5O1xyXG5cclxuICAgIC8vIGRvdWJsZTogaWVlZTc1NFxyXG4gICAgfSkoKTsgZWxzZSAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRG91YmxlX2llZWU3NTQod3JpdGVVaW50LCBvZmYwLCBvZmYxLCB2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIHZhciBzaWduID0gdmFsIDwgMCA/IDEgOiAwO1xyXG4gICAgICAgICAgICBpZiAoc2lnbilcclxuICAgICAgICAgICAgICAgIHZhbCA9IC12YWw7XHJcbiAgICAgICAgICAgIGlmICh2YWwgPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgwLCBidWYsIHBvcyArIG9mZjApO1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KDEgLyB2YWwgPiAwID8gLyogcG9zaXRpdmUgKi8gMCA6IC8qIG5lZ2F0aXZlIDAgKi8gMjE0NzQ4MzY0OCwgYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc05hTih2YWwpKSB7XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMCwgYnVmLCBwb3MgKyBvZmYwKTtcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgyMTQ2OTU5MzYwLCBidWYsIHBvcyArIG9mZjEpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbCA+IDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4KSB7IC8vICstSW5maW5pdHlcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgwLCBidWYsIHBvcyArIG9mZjApO1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgMjE0NjQzNTA3MikgPj4+IDAsIGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbWFudGlzc2E7XHJcbiAgICAgICAgICAgICAgICBpZiAodmFsIDwgMi4yMjUwNzM4NTg1MDcyMDE0ZS0zMDgpIHsgLy8gZGVub3JtYWxcclxuICAgICAgICAgICAgICAgICAgICBtYW50aXNzYSA9IHZhbCAvIDVlLTMyNDtcclxuICAgICAgICAgICAgICAgICAgICB3cml0ZVVpbnQobWFudGlzc2EgPj4+IDAsIGJ1ZiwgcG9zICsgb2ZmMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgbWFudGlzc2EgLyA0Mjk0OTY3Mjk2KSA+Pj4gMCwgYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGV4cG9uZW50ID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWwpIC8gTWF0aC5MTjIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChleHBvbmVudCA9PT0gMTAyNClcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwb25lbnQgPSAxMDIzO1xyXG4gICAgICAgICAgICAgICAgICAgIG1hbnRpc3NhID0gdmFsICogTWF0aC5wb3coMiwgLWV4cG9uZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB3cml0ZVVpbnQobWFudGlzc2EgKiA0NTAzNTk5NjI3MzcwNDk2ID4+PiAwLCBidWYsIHBvcyArIG9mZjApO1xyXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IGV4cG9uZW50ICsgMTAyMyA8PCAyMCB8IG1hbnRpc3NhICogMTA0ODU3NiAmIDEwNDg1NzUpID4+PiAwLCBidWYsIHBvcyArIG9mZjEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBleHBvcnRzLndyaXRlRG91YmxlTEUgPSB3cml0ZURvdWJsZV9pZWVlNzU0LmJpbmQobnVsbCwgd3JpdGVVaW50TEUsIDAsIDQpO1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVEb3VibGVCRSA9IHdyaXRlRG91YmxlX2llZWU3NTQuYmluZChudWxsLCB3cml0ZVVpbnRCRSwgNCwgMCk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWREb3VibGVfaWVlZTc1NChyZWFkVWludCwgb2ZmMCwgb2ZmMSwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgdmFyIGxvID0gcmVhZFVpbnQoYnVmLCBwb3MgKyBvZmYwKSxcclxuICAgICAgICAgICAgICAgIGhpID0gcmVhZFVpbnQoYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgdmFyIHNpZ24gPSAoaGkgPj4gMzEpICogMiArIDEsXHJcbiAgICAgICAgICAgICAgICBleHBvbmVudCA9IGhpID4+PiAyMCAmIDIwNDcsXHJcbiAgICAgICAgICAgICAgICBtYW50aXNzYSA9IDQyOTQ5NjcyOTYgKiAoaGkgJiAxMDQ4NTc1KSArIGxvO1xyXG4gICAgICAgICAgICByZXR1cm4gZXhwb25lbnQgPT09IDIwNDdcclxuICAgICAgICAgICAgICAgID8gbWFudGlzc2FcclxuICAgICAgICAgICAgICAgID8gTmFOXHJcbiAgICAgICAgICAgICAgICA6IHNpZ24gKiBJbmZpbml0eVxyXG4gICAgICAgICAgICAgICAgOiBleHBvbmVudCA9PT0gMCAvLyBkZW5vcm1hbFxyXG4gICAgICAgICAgICAgICAgPyBzaWduICogNWUtMzI0ICogbWFudGlzc2FcclxuICAgICAgICAgICAgICAgIDogc2lnbiAqIE1hdGgucG93KDIsIGV4cG9uZW50IC0gMTA3NSkgKiAobWFudGlzc2EgKyA0NTAzNTk5NjI3MzcwNDk2KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGV4cG9ydHMucmVhZERvdWJsZUxFID0gcmVhZERvdWJsZV9pZWVlNzU0LmJpbmQobnVsbCwgcmVhZFVpbnRMRSwgMCwgNCk7XHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRG91YmxlQkUgPSByZWFkRG91YmxlX2llZWU3NTQuYmluZChudWxsLCByZWFkVWludEJFLCA0LCAwKTtcclxuXHJcbiAgICB9KSgpO1xyXG5cclxuICAgIHJldHVybiBleHBvcnRzO1xyXG59XHJcblxyXG4vLyB1aW50IGhlbHBlcnNcclxuXHJcbmZ1bmN0aW9uIHdyaXRlVWludExFKHZhbCwgYnVmLCBwb3MpIHtcclxuICAgIGJ1Zltwb3MgICAgXSA9ICB2YWwgICAgICAgICYgMjU1O1xyXG4gICAgYnVmW3BvcyArIDFdID0gIHZhbCA+Pj4gOCAgJiAyNTU7XHJcbiAgICBidWZbcG9zICsgMl0gPSAgdmFsID4+PiAxNiAmIDI1NTtcclxuICAgIGJ1Zltwb3MgKyAzXSA9ICB2YWwgPj4+IDI0O1xyXG59XHJcblxyXG5mdW5jdGlvbiB3cml0ZVVpbnRCRSh2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICBidWZbcG9zICAgIF0gPSAgdmFsID4+PiAyNDtcclxuICAgIGJ1Zltwb3MgKyAxXSA9ICB2YWwgPj4+IDE2ICYgMjU1O1xyXG4gICAgYnVmW3BvcyArIDJdID0gIHZhbCA+Pj4gOCAgJiAyNTU7XHJcbiAgICBidWZbcG9zICsgM10gPSAgdmFsICAgICAgICAmIDI1NTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVhZFVpbnRMRShidWYsIHBvcykge1xyXG4gICAgcmV0dXJuIChidWZbcG9zICAgIF1cclxuICAgICAgICAgIHwgYnVmW3BvcyArIDFdIDw8IDhcclxuICAgICAgICAgIHwgYnVmW3BvcyArIDJdIDw8IDE2XHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAzXSA8PCAyNCkgPj4+IDA7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlYWRVaW50QkUoYnVmLCBwb3MpIHtcclxuICAgIHJldHVybiAoYnVmW3BvcyAgICBdIDw8IDI0XHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAxXSA8PCAxNlxyXG4gICAgICAgICAgfCBidWZbcG9zICsgMl0gPDwgOFxyXG4gICAgICAgICAgfCBidWZbcG9zICsgM10pID4+PiAwO1xyXG59XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcclxubW9kdWxlLmV4cG9ydHMgPSBpbnF1aXJlO1xyXG5cclxuLyoqXHJcbiAqIFJlcXVpcmVzIGEgbW9kdWxlIG9ubHkgaWYgYXZhaWxhYmxlLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlTmFtZSBNb2R1bGUgdG8gcmVxdWlyZVxyXG4gKiBAcmV0dXJucyB7P09iamVjdH0gUmVxdWlyZWQgbW9kdWxlIGlmIGF2YWlsYWJsZSBhbmQgbm90IGVtcHR5LCBvdGhlcndpc2UgYG51bGxgXHJcbiAqL1xyXG5mdW5jdGlvbiBpbnF1aXJlKG1vZHVsZU5hbWUpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgdmFyIG1vZCA9IGV2YWwoXCJxdWlyZVwiLnJlcGxhY2UoL14vLFwicmVcIikpKG1vZHVsZU5hbWUpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWV2YWxcclxuICAgICAgICBpZiAobW9kICYmIChtb2QubGVuZ3RoIHx8IE9iamVjdC5rZXlzKG1vZCkubGVuZ3RoKSlcclxuICAgICAgICAgICAgcmV0dXJuIG1vZDtcclxuICAgIH0gY2F0Y2ggKGUpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZW1wdHlcclxuICAgIHJldHVybiBudWxsO1xyXG59XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcclxuXHJcbi8qKlxyXG4gKiBBIG1pbmltYWwgVVRGOCBpbXBsZW1lbnRhdGlvbiBmb3IgbnVtYmVyIGFycmF5cy5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQG5hbWVzcGFjZVxyXG4gKi9cclxudmFyIHV0ZjggPSBleHBvcnRzO1xyXG5cclxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIFVURjggYnl0ZSBsZW5ndGggb2YgYSBzdHJpbmcuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU3RyaW5nXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEJ5dGUgbGVuZ3RoXHJcbiAqL1xyXG51dGY4Lmxlbmd0aCA9IGZ1bmN0aW9uIHV0ZjhfbGVuZ3RoKHN0cmluZykge1xyXG4gICAgdmFyIGxlbiA9IDAsXHJcbiAgICAgICAgYyA9IDA7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7ICsraSkge1xyXG4gICAgICAgIGMgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcclxuICAgICAgICBpZiAoYyA8IDEyOClcclxuICAgICAgICAgICAgbGVuICs9IDE7XHJcbiAgICAgICAgZWxzZSBpZiAoYyA8IDIwNDgpXHJcbiAgICAgICAgICAgIGxlbiArPSAyO1xyXG4gICAgICAgIGVsc2UgaWYgKChjICYgMHhGQzAwKSA9PT0gMHhEODAwICYmIChzdHJpbmcuY2hhckNvZGVBdChpICsgMSkgJiAweEZDMDApID09PSAweERDMDApIHtcclxuICAgICAgICAgICAgKytpO1xyXG4gICAgICAgICAgICBsZW4gKz0gNDtcclxuICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgbGVuICs9IDM7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGVuO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIFVURjggYnl0ZXMgYXMgYSBzdHJpbmcuXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIFNvdXJjZSBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFNvdXJjZSBzdGFydFxyXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIFNvdXJjZSBlbmRcclxuICogQHJldHVybnMge3N0cmluZ30gU3RyaW5nIHJlYWRcclxuICovXHJcbnV0ZjgucmVhZCA9IGZ1bmN0aW9uIHV0ZjhfcmVhZChidWZmZXIsIHN0YXJ0LCBlbmQpIHtcclxuICAgIHZhciBsZW4gPSBlbmQgLSBzdGFydDtcclxuICAgIGlmIChsZW4gPCAxKVxyXG4gICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgdmFyIHBhcnRzID0gbnVsbCxcclxuICAgICAgICBjaHVuayA9IFtdLFxyXG4gICAgICAgIGkgPSAwLCAvLyBjaGFyIG9mZnNldFxyXG4gICAgICAgIHQ7ICAgICAvLyB0ZW1wb3JhcnlcclxuICAgIHdoaWxlIChzdGFydCA8IGVuZCkge1xyXG4gICAgICAgIHQgPSBidWZmZXJbc3RhcnQrK107XHJcbiAgICAgICAgaWYgKHQgPCAxMjgpXHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSB0O1xyXG4gICAgICAgIGVsc2UgaWYgKHQgPiAxOTEgJiYgdCA8IDIyNClcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9ICh0ICYgMzEpIDw8IDYgfCBidWZmZXJbc3RhcnQrK10gJiA2MztcclxuICAgICAgICBlbHNlIGlmICh0ID4gMjM5ICYmIHQgPCAzNjUpIHtcclxuICAgICAgICAgICAgdCA9ICgodCAmIDcpIDw8IDE4IHwgKGJ1ZmZlcltzdGFydCsrXSAmIDYzKSA8PCAxMiB8IChidWZmZXJbc3RhcnQrK10gJiA2MykgPDwgNiB8IGJ1ZmZlcltzdGFydCsrXSAmIDYzKSAtIDB4MTAwMDA7XHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSAweEQ4MDAgKyAodCA+PiAxMCk7XHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSAweERDMDAgKyAodCAmIDEwMjMpO1xyXG4gICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICBjaHVua1tpKytdID0gKHQgJiAxNSkgPDwgMTIgfCAoYnVmZmVyW3N0YXJ0KytdICYgNjMpIDw8IDYgfCBidWZmZXJbc3RhcnQrK10gJiA2MztcclxuICAgICAgICBpZiAoaSA+IDgxOTEpIHtcclxuICAgICAgICAgICAgKHBhcnRzIHx8IChwYXJ0cyA9IFtdKSkucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2h1bmspKTtcclxuICAgICAgICAgICAgaSA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHBhcnRzKSB7XHJcbiAgICAgICAgaWYgKGkpXHJcbiAgICAgICAgICAgIHBhcnRzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rLnNsaWNlKDAsIGkpKSk7XHJcbiAgICAgICAgcmV0dXJuIHBhcnRzLmpvaW4oXCJcIik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rLnNsaWNlKDAsIGkpKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSBzdHJpbmcgYXMgVVRGOCBieXRlcy5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTb3VyY2Ugc3RyaW5nXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIERlc3RpbmF0aW9uIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IERlc3RpbmF0aW9uIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBCeXRlcyB3cml0dGVuXHJcbiAqL1xyXG51dGY4LndyaXRlID0gZnVuY3Rpb24gdXRmOF93cml0ZShzdHJpbmcsIGJ1ZmZlciwgb2Zmc2V0KSB7XHJcbiAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgYzEsIC8vIGNoYXJhY3RlciAxXHJcbiAgICAgICAgYzI7IC8vIGNoYXJhY3RlciAyXHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7ICsraSkge1xyXG4gICAgICAgIGMxID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgaWYgKGMxIDwgMTI4KSB7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMTtcclxuICAgICAgICB9IGVsc2UgaWYgKGMxIDwgMjA0OCkge1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gNiAgICAgICB8IDE5MjtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxICAgICAgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgfSBlbHNlIGlmICgoYzEgJiAweEZDMDApID09PSAweEQ4MDAgJiYgKChjMiA9IHN0cmluZy5jaGFyQ29kZUF0KGkgKyAxKSkgJiAweEZDMDApID09PSAweERDMDApIHtcclxuICAgICAgICAgICAgYzEgPSAweDEwMDAwICsgKChjMSAmIDB4MDNGRikgPDwgMTApICsgKGMyICYgMHgwM0ZGKTtcclxuICAgICAgICAgICAgKytpO1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gMTggICAgICB8IDI0MDtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+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/IDcgOiA4XG4gICAgICAgICA6IHBhcnQyIDwgMTI4ID8gOSA6IDEwO1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbnZhciB1dGlsID0gZXhwb3J0cztcblxuLy8gdXNlZCB0byByZXR1cm4gYSBQcm9taXNlIHdoZXJlIGNhbGxiYWNrIGlzIG9taXR0ZWRcbnV0aWwuYXNQcm9taXNlID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2FzcHJvbWlzZVwiKTtcblxuLy8gY29udmVydHMgdG8gLyBmcm9tIGJhc2U2NCBlbmNvZGVkIHN0cmluZ3NcbnV0aWwuYmFzZTY0ID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2Jhc2U2NFwiKTtcblxuLy8gYmFzZSBjbGFzcyBvZiBycGMuU2VydmljZVxudXRpbC5FdmVudEVtaXR0ZXIgPSByZXF1aXJlKFwiQHByb3RvYnVmanMvZXZlbnRlbWl0dGVyXCIpO1xuXG4vLyBmbG9hdCBoYW5kbGluZyBhY2Nyb3NzIGJyb3dzZXJzXG51dGlsLmZsb2F0ID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2Zsb2F0XCIpO1xuXG4vLyByZXF1aXJlcyBtb2R1bGVzIG9wdGlvbmFsbHkgYW5kIGhpZGVzIHRoZSBjYWxsIGZyb20gYnVuZGxlcnNcbnV0aWwuaW5xdWlyZSA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9pbnF1aXJlXCIpO1xuXG4vLyBjb252ZXJ0cyB0byAvIGZyb20gdXRmOCBlbmNvZGVkIHN0cmluZ3NcbnV0aWwudXRmOCA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy91dGY4XCIpO1xuXG4vLyBwcm92aWRlcyBhIG5vZGUtbGlrZSBidWZmZXIgcG9vbCBpbiB0aGUgYnJvd3NlclxudXRpbC5wb29sID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL3Bvb2xcIik7XG5cbi8vIHV0aWxpdHkgdG8gd29yayB3aXRoIHRoZSBsb3cgYW5kIGhpZ2ggYml0cyBvZiBhIDY0IGJpdCB2YWx1ZVxudXRpbC5Mb25nQml0cyA9IHJlcXVpcmUoXCIuL2xvbmdiaXRzXCIpO1xuXG4vKipcbiAqIFdoZXRoZXIgcnVubmluZyB3aXRoaW4gbm9kZSBvciBub3QuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHR5cGUge2Jvb2xlYW59XG4gKi9cbnV0aWwuaXNOb2RlID0gQm9vbGVhbih0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiXG4gICAgICAgICAgICAgICAgICAgJiYgZ2xvYmFsXG4gICAgICAgICAgICAgICAgICAgJiYgZ2xvYmFsLnByb2Nlc3NcbiAgICAgICAgICAgICAgICAgICAmJiBnbG9iYWwucHJvY2Vzcy52ZXJzaW9uc1xuICAgICAgICAgICAgICAgICAgICYmIGdsb2JhbC5wcm9jZXNzLnZlcnNpb25zLm5vZGUpO1xuXG4vKipcbiAqIEdsb2JhbCBvYmplY3QgcmVmZXJlbmNlLlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbnV0aWwuZ2xvYmFsID0gdXRpbC5pc05vZGUgJiYgZ2xvYmFsXG4gICAgICAgICAgIHx8IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93XG4gICAgICAgICAgIHx8IHR5cGVvZiBzZWxmICAgIT09IFwidW5kZWZpbmVkXCIgJiYgc2VsZlxuICAgICAgICAgICB8fCB0aGlzOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWludmFsaWQtdGhpc1xuXG4vKipcbiAqIEFuIGltbXVhYmxlIGVtcHR5IGFycmF5LlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtBcnJheS48Kj59XG4gKiBAY29uc3RcbiAqL1xudXRpbC5lbXB0eUFycmF5ID0gT2JqZWN0LmZyZWV6ZSA/IE9iamVjdC5mcmVlemUoW10pIDogLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gW107IC8vIHVzZWQgb24gcHJvdG90eXBlc1xuXG4vKipcbiAqIEFuIGltbXV0YWJsZSBlbXB0eSBvYmplY3QuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQGNvbnN0XG4gKi9cbnV0aWwuZW1wdHlPYmplY3QgPSBPYmplY3QuZnJlZXplID8gT2JqZWN0LmZyZWV6ZSh7fSkgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB7fTsgLy8gdXNlZCBvbiBwcm90b3R5cGVzXG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhbiBpbnRlZ2VyLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGFuIGludGVnZXJcbiAqL1xudXRpbC5pc0ludGVnZXIgPSBOdW1iZXIuaXNJbnRlZ2VyIHx8IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIGZ1bmN0aW9uIGlzSW50ZWdlcih2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgaXNGaW5pdGUodmFsdWUpICYmIE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZTtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIHN0cmluZy5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgdmFsdWUgaXMgYSBzdHJpbmdcbiAqL1xudXRpbC5pc1N0cmluZyA9IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiB8fCB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZztcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIG5vbi1udWxsIG9iamVjdC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgdmFsdWUgaXMgYSBub24tbnVsbCBvYmplY3RcbiAqL1xudXRpbC5pc09iamVjdCA9IGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIjtcbn07XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgcHJvcGVydHkgb24gYSBtZXNzYWdlIGlzIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudC5cbiAqIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIHV0aWwuaXNTZXR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFBsYWluIG9iamVjdCBvciBtZXNzYWdlIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcCBQcm9wZXJ0eSBuYW1lXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudCwgb3RoZXJ3aXNlIGBmYWxzZWBcbiAqL1xudXRpbC5pc3NldCA9XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgcHJvcGVydHkgb24gYSBtZXNzYWdlIGlzIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogUGxhaW4gb2JqZWN0IG9yIG1lc3NhZ2UgaW5zdGFuY2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIFByb3BlcnR5IG5hbWVcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgY29uc2lkZXJlZCB0byBiZSBwcmVzZW50LCBvdGhlcndpc2UgYGZhbHNlYFxuICovXG51dGlsLmlzU2V0ID0gZnVuY3Rpb24gaXNTZXQob2JqLCBwcm9wKSB7XG4gICAgdmFyIHZhbHVlID0gb2JqW3Byb3BdO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIG9iai5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXEsIG5vLXByb3RvdHlwZS1idWlsdGluc1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiIHx8IChBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLmxlbmd0aCA6IE9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGgpID4gMDtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG4vKipcbiAqIEFueSBjb21wYXRpYmxlIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIFRoaXMgaXMgYSBtaW5pbWFsIHN0YW5kLWFsb25lIGRlZmluaXRpb24gb2YgYSBCdWZmZXIgaW5zdGFuY2UuIFRoZSBhY3R1YWwgdHlwZSBpcyB0aGF0IGV4cG9ydGVkIGJ5IG5vZGUncyB0eXBpbmdzLlxuICogQGludGVyZmFjZSBCdWZmZXJcbiAqIEBleHRlbmRzIFVpbnQ4QXJyYXlcbiAqL1xuXG4vKipcbiAqIE5vZGUncyBCdWZmZXIgY2xhc3MgaWYgYXZhaWxhYmxlLlxuICogQHR5cGUge0NvbnN0cnVjdG9yPEJ1ZmZlcj59XG4gKi9cbnV0aWwuQnVmZmVyID0gKGZ1bmN0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHZhciBCdWZmZXIgPSB1dGlsLmlucXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO1xuICAgICAgICAvLyByZWZ1c2UgdG8gdXNlIG5vbi1ub2RlIGJ1ZmZlcnMgaWYgbm90IGV4cGxpY2l0bHkgYXNzaWduZWQgKHBlcmYgcmVhc29ucyk6XG4gICAgICAgIHJldHVybiBCdWZmZXIucHJvdG90eXBlLnV0ZjhXcml0ZSA/IEJ1ZmZlciA6IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIG51bGw7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59KSgpO1xuXG4vLyBJbnRlcm5hbCBhbGlhcyBvZiBvciBwb2x5ZnVsbCBmb3IgQnVmZmVyLmZyb20uXG51dGlsLl9CdWZmZXJfZnJvbSA9IG51bGw7XG5cbi8vIEludGVybmFsIGFsaWFzIG9mIG9yIHBvbHlmaWxsIGZvciBCdWZmZXIuYWxsb2NVbnNhZmUuXG51dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmUgPSBudWxsO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgYnVmZmVyIG9mIHdoYXRldmVyIHR5cGUgc3VwcG9ydGVkIGJ5IHRoZSBlbnZpcm9ubWVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfG51bWJlcltdfSBbc2l6ZU9yQXJyYXk9MF0gQnVmZmVyIHNpemUgb3IgbnVtYmVyIGFycmF5XG4gKiBAcmV0dXJucyB7VWludDhBcnJheXxCdWZmZXJ9IEJ1ZmZlclxuICovXG51dGlsLm5ld0J1ZmZlciA9IGZ1bmN0aW9uIG5ld0J1ZmZlcihzaXplT3JBcnJheSkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgcmV0dXJuIHR5cGVvZiBzaXplT3JBcnJheSA9PT0gXCJudW1iZXJcIlxuICAgICAgICA/IHV0aWwuQnVmZmVyXG4gICAgICAgICAgICA/IHV0aWwuX0J1ZmZlcl9hbGxvY1Vuc2FmZShzaXplT3JBcnJheSlcbiAgICAgICAgICAgIDogbmV3IHV0aWwuQXJyYXkoc2l6ZU9yQXJyYXkpXG4gICAgICAgIDogdXRpbC5CdWZmZXJcbiAgICAgICAgICAgID8gdXRpbC5fQnVmZmVyX2Zyb20oc2l6ZU9yQXJyYXkpXG4gICAgICAgICAgICA6IHR5cGVvZiBVaW50OEFycmF5ID09PSBcInVuZGVmaW5lZFwiXG4gICAgICAgICAgICAgICAgPyBzaXplT3JBcnJheVxuICAgICAgICAgICAgICAgIDogbmV3IFVpbnQ4QXJyYXkoc2l6ZU9yQXJyYXkpO1xufTtcblxuLyoqXG4gKiBBcnJheSBpbXBsZW1lbnRhdGlvbiB1c2VkIGluIHRoZSBicm93c2VyLiBgVWludDhBcnJheWAgaWYgc3VwcG9ydGVkLCBvdGhlcndpc2UgYEFycmF5YC5cbiAqIEB0eXBlIHtDb25zdHJ1Y3RvcjxVaW50OEFycmF5Pn1cbiAqL1xudXRpbC5BcnJheSA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSBcInVuZGVmaW5lZFwiID8gVWludDhBcnJheSAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyA6IEFycmF5O1xuXG4vKipcbiAqIEFueSBjb21wYXRpYmxlIExvbmcgaW5zdGFuY2UuXG4gKiBUaGlzIGlzIGEgbWluaW1hbCBzdGFuZC1hbG9uZSBkZWZpbml0aW9uIG9mIGEgTG9uZyBpbnN0YW5jZS4gVGhlIGFjdHVhbCB0eXBlIGlzIHRoYXQgZXhwb3J0ZWQgYnkgbG9uZy5qcy5cbiAqIEBpbnRlcmZhY2UgTG9uZ1xuICogQHByb3BlcnR5IHtudW1iZXJ9IGxvdyBMb3cgYml0c1xuICogQHByb3BlcnR5IHtudW1iZXJ9IGhpZ2ggSGlnaCBiaXRzXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90XG4gKi9cblxuLyoqXG4gKiBMb25nLmpzJ3MgTG9uZyBjbGFzcyBpZiBhdmFpbGFibGUuXG4gKiBAdHlwZSB7Q29uc3RydWN0b3I8TG9uZz59XG4gKi9cbnV0aWwuTG9uZyA9IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHV0aWwuZ2xvYmFsLmRjb2RlSU8gJiYgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gdXRpbC5nbG9iYWwuZGNvZGVJTy5Mb25nXG4gICAgICAgICB8fCAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB1dGlsLmdsb2JhbC5Mb25nXG4gICAgICAgICB8fCB1dGlsLmlucXVpcmUoXCJsb25nXCIpO1xuXG4vKipcbiAqIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIHRvIHZlcmlmeSAyIGJpdCAoYGJvb2xgKSBtYXAga2V5cy5cbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5rZXkyUmUgPSAvXnRydWV8ZmFsc2V8MHwxJC87XG5cbi8qKlxuICogUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gdmVyaWZ5IDMyIGJpdCAoYGludDMyYCBldGMuKSBtYXAga2V5cy5cbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5rZXkzMlJlID0gL14tPyg/OjB8WzEtOV1bMC05XSopJC87XG5cbi8qKlxuICogUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gdmVyaWZ5IDY0IGJpdCAoYGludDY0YCBldGMuKSBtYXAga2V5cy5cbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5rZXk2NFJlID0gL14oPzpbXFxcXHgwMC1cXFxceGZmXXs4fXwtPyg/OjB8WzEtOV1bMC05XSopKSQvO1xuXG4vKipcbiAqIENvbnZlcnRzIGEgbnVtYmVyIG9yIGxvbmcgdG8gYW4gOCBjaGFyYWN0ZXJzIGxvbmcgaGFzaCBzdHJpbmcuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyB7c3RyaW5nfSBIYXNoXG4gKi9cbnV0aWwubG9uZ1RvSGFzaCA9IGZ1bmN0aW9uIGxvbmdUb0hhc2godmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgPyB1dGlsLkxvbmdCaXRzLmZyb20odmFsdWUpLnRvSGFzaCgpXG4gICAgICAgIDogdXRpbC5Mb25nQml0cy56ZXJvSGFzaDtcbn07XG5cbi8qKlxuICogQ29udmVydHMgYW4gOCBjaGFyYWN0ZXJzIGxvbmcgaGFzaCBzdHJpbmcgdG8gYSBsb25nIG9yIG51bWJlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoIEhhc2hcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Vuc2lnbmVkPWZhbHNlXSBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdFxuICogQHJldHVybnMge0xvbmd8bnVtYmVyfSBPcmlnaW5hbCB2YWx1ZVxuICovXG51dGlsLmxvbmdGcm9tSGFzaCA9IGZ1bmN0aW9uIGxvbmdGcm9tSGFzaChoYXNoLCB1bnNpZ25lZCkge1xuICAgIHZhciBiaXRzID0gdXRpbC5Mb25nQml0cy5mcm9tSGFzaChoYXNoKTtcbiAgICBpZiAodXRpbC5Mb25nKVxuICAgICAgICByZXR1cm4gdXRpbC5Mb25nLmZyb21CaXRzKGJpdHMubG8sIGJpdHMuaGksIHVuc2lnbmVkKTtcbiAgICByZXR1cm4gYml0cy50b051bWJlcihCb29sZWFuKHVuc2lnbmVkKSk7XG59O1xuXG4vKipcbiAqIE1lcmdlcyB0aGUgcHJvcGVydGllcyBvZiB0aGUgc291cmNlIG9iamVjdCBpbnRvIHRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gZHN0IERlc3RpbmF0aW9uIG9iamVjdFxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gc3JjIFNvdXJjZSBvYmplY3RcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lmTm90U2V0PWZhbHNlXSBNZXJnZXMgb25seSBpZiB0aGUga2V5IGlzIG5vdCBhbHJlYWR5IHNldFxuICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBEZXN0aW5hdGlvbiBvYmplY3RcbiAqL1xuZnVuY3Rpb24gbWVyZ2UoZHN0LCBzcmMsIGlmTm90U2V0KSB7IC8vIHVzZWQgYnkgY29udmVydGVyc1xuICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhzcmMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgIGlmIChkc3Rba2V5c1tpXV0gPT09IHVuZGVmaW5lZCB8fCAhaWZOb3RTZXQpXG4gICAgICAgICAgICBkc3Rba2V5c1tpXV0gPSBzcmNba2V5c1tpXV07XG4gICAgcmV0dXJuIGRzdDtcbn1cblxudXRpbC5tZXJnZSA9IG1lcmdlO1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgYSBzdHJpbmcgdG8gbG93ZXIgY2FzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHtzdHJpbmd9IENvbnZlcnRlZCBzdHJpbmdcbiAqL1xudXRpbC5sY0ZpcnN0ID0gZnVuY3Rpb24gbGNGaXJzdChzdHIpIHtcbiAgICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgc3RyLnN1YnN0cmluZygxKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGN1c3RvbSBlcnJvciBjb25zdHJ1Y3Rvci5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBFcnJvciBuYW1lXG4gKiBAcmV0dXJucyB7Q29uc3RydWN0b3I8RXJyb3I+fSBDdXN0b20gZXJyb3IgY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gbmV3RXJyb3IobmFtZSkge1xuXG4gICAgZnVuY3Rpb24gQ3VzdG9tRXJyb3IobWVzc2FnZSwgcHJvcGVydGllcykge1xuXG4gICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDdXN0b21FcnJvcikpXG4gICAgICAgICAgICByZXR1cm4gbmV3IEN1c3RvbUVycm9yKG1lc3NhZ2UsIHByb3BlcnRpZXMpO1xuXG4gICAgICAgIC8vIEVycm9yLmNhbGwodGhpcywgbWVzc2FnZSk7XG4gICAgICAgIC8vIF4ganVzdCByZXR1cm5zIGEgbmV3IGVycm9yIGluc3RhbmNlIGJlY2F1c2UgdGhlIGN0b3IgY2FuIGJlIGNhbGxlZCBhcyBhIGZ1bmN0aW9uXG5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwibWVzc2FnZVwiLCB7IGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtZXNzYWdlOyB9IH0pO1xuXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkgLy8gbm9kZVxuICAgICAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgQ3VzdG9tRXJyb3IpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJzdGFja1wiLCB7IHZhbHVlOiBuZXcgRXJyb3IoKS5zdGFjayB8fCBcIlwiIH0pO1xuXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgbWVyZ2UodGhpcywgcHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgQ3VzdG9tRXJyb3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFcnJvci5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgICAgIHZhbHVlOiBDdXN0b21FcnJvcixcbiAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIG5hbWU6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkgeyByZXR1cm4gbmFtZTsgfSxcbiAgICAgICAgICAgIHNldDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAvLyBjb25maWd1cmFibGU6IGZhbHNlIHdvdWxkIGFjY3VyYXRlbHkgcHJlc2VydmUgdGhlIGJlaGF2aW9yIG9mXG4gICAgICAgICAgICAvLyB0aGUgb3JpZ2luYWwsIGJ1dCBJJ20gZ3Vlc3NpbmcgdGhhdCB3YXMgbm90IGludGVudGlvbmFsLlxuICAgICAgICAgICAgLy8gRm9yIGFuIGFjdHVhbCBlcnJvciBzdWJjbGFzcywgdGhpcyBwcm9wZXJ0eSB3b3VsZFxuICAgICAgICAgICAgLy8gYmUgY29uZmlndXJhYmxlLlxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICB0b1N0cmluZzoge1xuICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKCkgeyByZXR1cm4gdGhpcy5uYW1lICsgXCI6IFwiICsgdGhpcy5tZXNzYWdlOyB9LFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiBDdXN0b21FcnJvcjtcbn1cblxudXRpbC5uZXdFcnJvciA9IG5ld0Vycm9yO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgcHJvdG9jb2wgZXJyb3IuXG4gKiBAY2xhc3NkZXNjIEVycm9yIHN1YmNsYXNzIGluZGljYXRpbmcgYSBwcm90b2NvbCBzcGVjaWZjIGVycm9yLlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEBleHRlbmRzIEVycm9yXG4gKiBAdGVtcGxhdGUgVCBleHRlbmRzIE1lc3NhZ2U8VD5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgRXJyb3IgbWVzc2FnZVxuICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gW3Byb3BlcnRpZXNdIEFkZGl0aW9uYWwgcHJvcGVydGllc1xuICogQGV4YW1wbGVcbiAqIHRyeSB7XG4gKiAgICAgTXlNZXNzYWdlLmRlY29kZShzb21lQnVmZmVyKTsgLy8gdGhyb3dzIGlmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICogfSBjYXRjaCAoZSkge1xuICogICAgIGlmIChlIGluc3RhbmNlb2YgUHJvdG9jb2xFcnJvciAmJiBlLmluc3RhbmNlKVxuICogICAgICAgICBjb25zb2xlLmxvZyhcImRlY29kZWQgc28gZmFyOiBcIiArIEpTT04uc3RyaW5naWZ5KGUuaW5zdGFuY2UpKTtcbiAqIH1cbiAqL1xudXRpbC5Qcm90b2NvbEVycm9yID0gbmV3RXJyb3IoXCJQcm90b2NvbEVycm9yXCIpO1xuXG4vKipcbiAqIFNvIGZhciBkZWNvZGVkIG1lc3NhZ2UgaW5zdGFuY2UuXG4gKiBAbmFtZSB1dGlsLlByb3RvY29sRXJyb3IjaW5zdGFuY2VcbiAqIEB0eXBlIHtNZXNzYWdlPFQ+fVxuICovXG5cbi8qKlxuICogQSBPbmVPZiBnZXR0ZXIgYXMgcmV0dXJuZWQgYnkge0BsaW5rIHV0aWwub25lT2ZHZXR0ZXJ9LlxuICogQHR5cGVkZWYgT25lT2ZHZXR0ZXJcbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfSBTZXQgZmllbGQgbmFtZSwgaWYgYW55XG4gKi9cblxuLyoqXG4gKiBCdWlsZHMgYSBnZXR0ZXIgZm9yIGEgb25lb2YncyBwcmVzZW50IGZpZWxkIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBmaWVsZE5hbWVzIEZpZWxkIG5hbWVzXG4gKiBAcmV0dXJucyB7T25lT2ZHZXR0ZXJ9IFVuYm91bmQgZ2V0dGVyXG4gKi9cbnV0aWwub25lT2ZHZXR0ZXIgPSBmdW5jdGlvbiBnZXRPbmVPZihmaWVsZE5hbWVzKSB7XG4gICAgdmFyIGZpZWxkTWFwID0ge307XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWVsZE5hbWVzLmxlbmd0aDsgKytpKVxuICAgICAgICBmaWVsZE1hcFtmaWVsZE5hbWVzW2ldXSA9IDE7XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gU2V0IGZpZWxkIG5hbWUsIGlmIGFueVxuICAgICAqIEB0aGlzIE9iamVjdFxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpLCBpID0ga2V5cy5sZW5ndGggLSAxOyBpID4gLTE7IC0taSlcbiAgICAgICAgICAgIGlmIChmaWVsZE1hcFtrZXlzW2ldXSA9PT0gMSAmJiB0aGlzW2tleXNbaV1dICE9PSB1bmRlZmluZWQgJiYgdGhpc1trZXlzW2ldXSAhPT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5c1tpXTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBBIE9uZU9mIHNldHRlciBhcyByZXR1cm5lZCBieSB7QGxpbmsgdXRpbC5vbmVPZlNldHRlcn0uXG4gKiBAdHlwZWRlZiBPbmVPZlNldHRlclxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSB2YWx1ZSBGaWVsZCBuYW1lXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICovXG5cbi8qKlxuICogQnVpbGRzIGEgc2V0dGVyIGZvciBhIG9uZW9mJ3MgcHJlc2VudCBmaWVsZCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gZmllbGROYW1lcyBGaWVsZCBuYW1lc1xuICogQHJldHVybnMge09uZU9mU2V0dGVyfSBVbmJvdW5kIHNldHRlclxuICovXG51dGlsLm9uZU9mU2V0dGVyID0gZnVuY3Rpb24gc2V0T25lT2YoZmllbGROYW1lcykge1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgRmllbGQgbmFtZVxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gICAgICogQHRoaXMgT2JqZWN0XG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZmllbGROYW1lcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgIGlmIChmaWVsZE5hbWVzW2ldICE9PSBuYW1lKVxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzW2ZpZWxkTmFtZXNbaV1dO1xuICAgIH07XG59O1xuXG4vKipcbiAqIERlZmF1bHQgY29udmVyc2lvbiBvcHRpb25zIHVzZWQgZm9yIHtAbGluayBNZXNzYWdlI3RvSlNPTn0gaW1wbGVtZW50YXRpb25zLlxuICpcbiAqIFRoZXNlIG9wdGlvbnMgYXJlIGNsb3NlIHRvIHByb3RvMydzIEpTT04gbWFwcGluZyB3aXRoIHRoZSBleGNlcHRpb24gdGhhdCBpbnRlcm5hbCB0eXBlcyBsaWtlIEFueSBhcmUgaGFuZGxlZCBqdXN0IGxpa2UgbWVzc2FnZXMuIE1vcmUgcHJlY2lzZWx5OlxuICpcbiAqIC0gTG9uZ3MgYmVjb21lIHN0cmluZ3NcbiAqIC0gRW51bXMgYmVjb21lIHN0cmluZyBrZXlzXG4gKiAtIEJ5dGVzIGJlY29tZSBiYXNlNjQgZW5jb2RlZCBzdHJpbmdzXG4gKiAtIChTdWItKU1lc3NhZ2VzIGJlY29tZSBwbGFpbiBvYmplY3RzXG4gKiAtIE1hcHMgYmVjb21lIHBsYWluIG9iamVjdHMgd2l0aCBhbGwgc3RyaW5nIGtleXNcbiAqIC0gUmVwZWF0ZWQgZmllbGRzIGJlY29tZSBhcnJheXNcbiAqIC0gTmFOIGFuZCBJbmZpbml0eSBmb3IgZmxvYXQgYW5kIGRvdWJsZSBmaWVsZHMgYmVjb21lIHN0cmluZ3NcbiAqXG4gKiBAdHlwZSB7SUNvbnZlcnNpb25PcHRpb25zfVxuICogQHNlZSBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzL2RvY3MvcHJvdG8zP2hsPWVuI2pzb25cbiAqL1xudXRpbC50b0pTT05PcHRpb25zID0ge1xuICAgIGxvbmdzOiBTdHJpbmcsXG4gICAgZW51bXM6IFN0cmluZyxcbiAgICBieXRlczogU3RyaW5nLFxuICAgIGpzb246IHRydWVcbn07XG5cbi8vIFNldHMgdXAgYnVmZmVyIHV0aWxpdHkgYWNjb3JkaW5nIHRvIHRoZSBlbnZpcm9ubWVudCAoY2FsbGVkIGluIGluZGV4LW1pbmltYWwpXG51dGlsLl9jb25maWd1cmUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgQnVmZmVyID0gdXRpbC5CdWZmZXI7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKCFCdWZmZXIpIHtcbiAgICAgICAgdXRpbC5fQnVmZmVyX2Zyb20gPSB1dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmUgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGJlY2F1c2Ugbm9kZSA0LnggYnVmZmVycyBhcmUgaW5jb21wYXRpYmxlICYgaW1tdXRhYmxlXG4gICAgLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vZGNvZGVJTy9wcm90b2J1Zi5qcy9wdWxsLzY2NVxuICAgIHV0aWwuX0J1ZmZlcl9mcm9tID0gQnVmZmVyLmZyb20gIT09IFVpbnQ4QXJyYXkuZnJvbSAmJiBCdWZmZXIuZnJvbSB8fFxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBmdW5jdGlvbiBCdWZmZXJfZnJvbSh2YWx1ZSwgZW5jb2RpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlLCBlbmNvZGluZyk7XG4gICAgICAgIH07XG4gICAgdXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlID0gQnVmZmVyLmFsbG9jVW5zYWZlIHx8XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGZ1bmN0aW9uIEJ1ZmZlcl9hbGxvY1Vuc2FmZShzaXplKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihzaXplKTtcbiAgICAgICAgfTtcbn07XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRlcjtcblxudmFyIHV0aWwgICAgICA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcblxudmFyIEJ1ZmZlcldyaXRlcjsgLy8gY3ljbGljXG5cbnZhciBMb25nQml0cyAgPSB1dGlsLkxvbmdCaXRzLFxuICAgIGJhc2U2NCAgICA9IHV0aWwuYmFzZTY0LFxuICAgIHV0ZjggICAgICA9IHV0aWwudXRmODtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IHdyaXRlciBvcGVyYXRpb24gaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFNjaGVkdWxlZCB3cml0ZXIgb3BlcmF0aW9uLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosIFVpbnQ4QXJyYXksIG51bWJlcil9IGZuIEZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gVmFsdWUgYnl0ZSBsZW5ndGhcbiAqIEBwYXJhbSB7Kn0gdmFsIFZhbHVlIHRvIHdyaXRlXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIE9wKGZuLCBsZW4sIHZhbCkge1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdG8gY2FsbC5cbiAgICAgKiBAdHlwZSB7ZnVuY3Rpb24oVWludDhBcnJheSwgbnVtYmVyLCAqKX1cbiAgICAgKi9cbiAgICB0aGlzLmZuID0gZm47XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBieXRlIGxlbmd0aC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMubGVuID0gbGVuO1xuXG4gICAgLyoqXG4gICAgICogTmV4dCBvcGVyYXRpb24uXG4gICAgICogQHR5cGUge1dyaXRlci5PcHx1bmRlZmluZWR9XG4gICAgICovXG4gICAgdGhpcy5uZXh0ID0gdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVmFsdWUgdG8gd3JpdGUuXG4gICAgICogQHR5cGUgeyp9XG4gICAgICovXG4gICAgdGhpcy52YWwgPSB2YWw7IC8vIHR5cGUgdmFyaWVzXG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBub29wKCkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1lbXB0eS1mdW5jdGlvblxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgd3JpdGVyIHN0YXRlIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBDb3BpZWQgd3JpdGVyIHN0YXRlLlxuICogQG1lbWJlcm9mIFdyaXRlclxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1dyaXRlcn0gd3JpdGVyIFdyaXRlciB0byBjb3B5IHN0YXRlIGZyb21cbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gU3RhdGUod3JpdGVyKSB7XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IGhlYWQuXG4gICAgICogQHR5cGUge1dyaXRlci5PcH1cbiAgICAgKi9cbiAgICB0aGlzLmhlYWQgPSB3cml0ZXIuaGVhZDtcblxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgdGFpbC5cbiAgICAgKiBAdHlwZSB7V3JpdGVyLk9wfVxuICAgICAqL1xuICAgIHRoaXMudGFpbCA9IHdyaXRlci50YWlsO1xuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBidWZmZXIgbGVuZ3RoLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sZW4gPSB3cml0ZXIubGVuO1xuXG4gICAgLyoqXG4gICAgICogTmV4dCBzdGF0ZS5cbiAgICAgKiBAdHlwZSB7U3RhdGV8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLm5leHQgPSB3cml0ZXIuc3RhdGVzO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgd3JpdGVyIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBXaXJlIGZvcm1hdCB3cml0ZXIgdXNpbmcgYFVpbnQ4QXJyYXlgIGlmIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGBBcnJheWAuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gV3JpdGVyKCkge1xuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBsZW5ndGguXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxlbiA9IDA7XG5cbiAgICAvKipcbiAgICAgKiBPcGVyYXRpb25zIGhlYWQuXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICB0aGlzLmhlYWQgPSBuZXcgT3Aobm9vcCwgMCwgMCk7XG5cbiAgICAvKipcbiAgICAgKiBPcGVyYXRpb25zIHRhaWxcbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIHRoaXMudGFpbCA9IHRoaXMuaGVhZDtcblxuICAgIC8qKlxuICAgICAqIExpbmtlZCBmb3JrZWQgc3RhdGVzLlxuICAgICAqIEB0eXBlIHtPYmplY3R8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLnN0YXRlcyA9IG51bGw7XG5cbiAgICAvLyBXaGVuIGEgdmFsdWUgaXMgd3JpdHRlbiwgdGhlIHdyaXRlciBjYWxjdWxhdGVzIGl0cyBieXRlIGxlbmd0aCBhbmQgcHV0cyBpdCBpbnRvIGEgbGlua2VkXG4gICAgLy8gbGlzdCBvZiBvcGVyYXRpb25zIHRvIHBlcmZvcm0gd2hlbiBmaW5pc2goKSBpcyBjYWxsZWQuIFRoaXMgYm90aCBhbGxvd3MgdXMgdG8gYWxsb2NhdGVcbiAgICAvLyBidWZmZXJzIG9mIHRoZSBleGFjdCByZXF1aXJlZCBzaXplIGFuZCByZWR1Y2VzIHRoZSBhbW91bnQgb2Ygd29yayB3ZSBoYXZlIHRvIGRvIGNvbXBhcmVkXG4gICAgLy8gdG8gZmlyc3QgY2FsY3VsYXRpbmcgb3ZlciBvYmplY3RzIGFuZCB0aGVuIGVuY29kaW5nIG92ZXIgb2JqZWN0cy4gSW4gb3VyIGNhc2UsIHRoZSBlbmNvZGluZ1xuICAgIC8vIHBhcnQgaXMganVzdCBhIGxpbmtlZCBsaXN0IHdhbGsgY2FsbGluZyBvcGVyYXRpb25zIHdpdGggYWxyZWFkeSBwcmVwYXJlZCB2YWx1ZXMuXG59XG5cbnZhciBjcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gICAgcmV0dXJuIHV0aWwuQnVmZmVyXG4gICAgICAgID8gZnVuY3Rpb24gY3JlYXRlX2J1ZmZlcl9zZXR1cCgpIHtcbiAgICAgICAgICAgIHJldHVybiAoV3JpdGVyLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZV9idWZmZXIoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJXcml0ZXIoKTtcbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgIH1cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgOiBmdW5jdGlvbiBjcmVhdGVfYXJyYXkoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFdyaXRlcigpO1xuICAgICAgICB9O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHdyaXRlci5cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0J1ZmZlcldyaXRlcnxXcml0ZXJ9IEEge0BsaW5rIEJ1ZmZlcldyaXRlcn0gd2hlbiBCdWZmZXJzIGFyZSBzdXBwb3J0ZWQsIG90aGVyd2lzZSBhIHtAbGluayBXcml0ZXJ9XG4gKi9cbldyaXRlci5jcmVhdGUgPSBjcmVhdGUoKTtcblxuLyoqXG4gKiBBbGxvY2F0ZXMgYSBidWZmZXIgb2YgdGhlIHNwZWNpZmllZCBzaXplLlxuICogQHBhcmFtIHtudW1iZXJ9IHNpemUgQnVmZmVyIHNpemVcbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBCdWZmZXJcbiAqL1xuV3JpdGVyLmFsbG9jID0gZnVuY3Rpb24gYWxsb2Moc2l6ZSkge1xuICAgIHJldHVybiBuZXcgdXRpbC5BcnJheShzaXplKTtcbn07XG5cbi8vIFVzZSBVaW50OEFycmF5IGJ1ZmZlciBwb29sIGluIHRoZSBicm93c2VyLCBqdXN0IGxpa2Ugbm9kZSBkb2VzIHdpdGggYnVmZmVyc1xuLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbmlmICh1dGlsLkFycmF5ICE9PSBBcnJheSlcbiAgICBXcml0ZXIuYWxsb2MgPSB1dGlsLnBvb2woV3JpdGVyLmFsbG9jLCB1dGlsLkFycmF5LnByb3RvdHlwZS5zdWJhcnJheSk7XG5cbi8qKlxuICogUHVzaGVzIGEgbmV3IG9wZXJhdGlvbiB0byB0aGUgcXVldWUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFVpbnQ4QXJyYXksIG51bWJlciwgKil9IGZuIEZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gVmFsdWUgYnl0ZSBsZW5ndGhcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHByaXZhdGVcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5fcHVzaCA9IGZ1bmN0aW9uIHB1c2goZm4sIGxlbiwgdmFsKSB7XG4gICAgdGhpcy50YWlsID0gdGhpcy50YWlsLm5leHQgPSBuZXcgT3AoZm4sIGxlbiwgdmFsKTtcbiAgICB0aGlzLmxlbiArPSBsZW47XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUJ5dGUodmFsLCBidWYsIHBvcykge1xuICAgIGJ1Zltwb3NdID0gdmFsICYgMjU1O1xufVxuXG5mdW5jdGlvbiB3cml0ZVZhcmludDMyKHZhbCwgYnVmLCBwb3MpIHtcbiAgICB3aGlsZSAodmFsID4gMTI3KSB7XG4gICAgICAgIGJ1Zltwb3MrK10gPSB2YWwgJiAxMjcgfCAxMjg7XG4gICAgICAgIHZhbCA+Pj49IDc7XG4gICAgfVxuICAgIGJ1Zltwb3NdID0gdmFsO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgdmFyaW50IHdyaXRlciBvcGVyYXRpb24gaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFNjaGVkdWxlZCB2YXJpbnQgd3JpdGVyIG9wZXJhdGlvbi5cbiAqIEBleHRlbmRzIE9wXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gVmFsdWUgYnl0ZSBsZW5ndGhcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gVmFyaW50T3AobGVuLCB2YWwpIHtcbiAgICB0aGlzLmxlbiA9IGxlbjtcbiAgICB0aGlzLm5leHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy52YWwgPSB2YWw7XG59XG5cblZhcmludE9wLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoT3AucHJvdG90eXBlKTtcblZhcmludE9wLnByb3RvdHlwZS5mbiA9IHdyaXRlVmFyaW50MzI7XG5cbi8qKlxuICogV3JpdGVzIGFuIHVuc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUudWludDMyID0gZnVuY3Rpb24gd3JpdGVfdWludDMyKHZhbHVlKSB7XG4gICAgLy8gaGVyZSwgdGhlIGNhbGwgdG8gdGhpcy5wdXNoIGhhcyBiZWVuIGlubGluZWQgYW5kIGEgdmFyaW50IHNwZWNpZmljIE9wIHN1YmNsYXNzIGlzIHVzZWQuXG4gICAgLy8gdWludDMyIGlzIGJ5IGZhciB0aGUgbW9zdCBmcmVxdWVudGx5IHVzZWQgb3BlcmF0aW9uIGFuZCBiZW5lZml0cyBzaWduaWZpY2FudGx5IGZyb20gdGhpcy5cbiAgICB0aGlzLmxlbiArPSAodGhpcy50YWlsID0gdGhpcy50YWlsLm5leHQgPSBuZXcgVmFyaW50T3AoXG4gICAgICAgICh2YWx1ZSA9IHZhbHVlID4+PiAwKVxuICAgICAgICAgICAgICAgIDwgMTI4ICAgICAgID8gMVxuICAgICAgICA6IHZhbHVlIDwgMTYzODQgICAgID8gMlxuICAgICAgICA6IHZhbHVlIDwgMjA5NzE1MiAgID8gM1xuICAgICAgICA6IHZhbHVlIDwgMjY4NDM1NDU2ID8gNFxuICAgICAgICA6ICAgICAgICAgICAgICAgICAgICAgNSxcbiAgICB2YWx1ZSkpLmxlbjtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5pbnQzMiA9IGZ1bmN0aW9uIHdyaXRlX2ludDMyKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlIDwgMFxuICAgICAgICA/IHRoaXMuX3B1c2god3JpdGVWYXJpbnQ2NCwgMTAsIExvbmdCaXRzLmZyb21OdW1iZXIodmFsdWUpKSAvLyAxMCBieXRlcyBwZXIgc3BlY1xuICAgICAgICA6IHRoaXMudWludDMyKHZhbHVlKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgMzIgYml0IHZhbHVlIGFzIGEgdmFyaW50LCB6aWctemFnIGVuY29kZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnNpbnQzMiA9IGZ1bmN0aW9uIHdyaXRlX3NpbnQzMih2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLnVpbnQzMigodmFsdWUgPDwgMSBeIHZhbHVlID4+IDMxKSA+Pj4gMCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZVZhcmludDY0KHZhbCwgYnVmLCBwb3MpIHtcbiAgICB3aGlsZSAodmFsLmhpKSB7XG4gICAgICAgIGJ1Zltwb3MrK10gPSB2YWwubG8gJiAxMjcgfCAxMjg7XG4gICAgICAgIHZhbC5sbyA9ICh2YWwubG8gPj4+IDcgfCB2YWwuaGkgPDwgMjUpID4+PiAwO1xuICAgICAgICB2YWwuaGkgPj4+PSA3O1xuICAgIH1cbiAgICB3aGlsZSAodmFsLmxvID4gMTI3KSB7XG4gICAgICAgIGJ1Zltwb3MrK10gPSB2YWwubG8gJiAxMjcgfCAxMjg7XG4gICAgICAgIHZhbC5sbyA9IHZhbC5sbyA+Pj4gNztcbiAgICB9XG4gICAgYnVmW3BvcysrXSA9IHZhbC5sbztcbn1cblxuLyoqXG4gKiBXcml0ZXMgYW4gdW5zaWduZWQgNjQgYml0IHZhbHVlIGFzIGEgdmFyaW50LlxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUudWludDY0ID0gZnVuY3Rpb24gd3JpdGVfdWludDY0KHZhbHVlKSB7XG4gICAgdmFyIGJpdHMgPSBMb25nQml0cy5mcm9tKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZVZhcmludDY0LCBiaXRzLmxlbmd0aCgpLCBiaXRzKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDY0IGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUuaW50NjQgPSBXcml0ZXIucHJvdG90eXBlLnVpbnQ2NDtcblxuLyoqXG4gKiBXcml0ZXMgYSBzaWduZWQgNjQgYml0IHZhbHVlIGFzIGEgdmFyaW50LCB6aWctemFnIGVuY29kZWQuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgdmFsdWVgIGlzIGEgc3RyaW5nIGFuZCBubyBsb25nIGxpYnJhcnkgaXMgcHJlc2VudC5cbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5zaW50NjQgPSBmdW5jdGlvbiB3cml0ZV9zaW50NjQodmFsdWUpIHtcbiAgICB2YXIgYml0cyA9IExvbmdCaXRzLmZyb20odmFsdWUpLnp6RW5jb2RlKCk7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2god3JpdGVWYXJpbnQ2NCwgYml0cy5sZW5ndGgoKSwgYml0cyk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIGJvb2xpc2ggdmFsdWUgYXMgYSB2YXJpbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5ib29sID0gZnVuY3Rpb24gd3JpdGVfYm9vbCh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHdyaXRlQnl0ZSwgMSwgdmFsdWUgPyAxIDogMCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUZpeGVkMzIodmFsLCBidWYsIHBvcykge1xuICAgIGJ1Zltwb3MgICAgXSA9ICB2YWwgICAgICAgICAmIDI1NTtcbiAgICBidWZbcG9zICsgMV0gPSAgdmFsID4+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+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgbGVuZ3RoKTtcblxuICAgIHRoaXMucG9zICs9IGxlbmd0aDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmJ1ZikpIC8vIHBsYWluIGFycmF5XG4gICAgICAgIHJldHVybiB0aGlzLmJ1Zi5zbGljZShzdGFydCwgZW5kKTtcblxuICAgIGlmIChzdGFydCA9PT0gZW5kKSB7IC8vIGZpeCBmb3IgSUUgMTAvV2luOCBhbmQgb3RoZXJzJyBzdWJhcnJheSByZXR1cm5pbmcgYXJyYXkgb2Ygc2l6ZSAxXG4gICAgICAgIHZhciBuYXRpdmVCdWZmZXIgPSB1dGlsLkJ1ZmZlcjtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUJ1ZmZlclxuICAgICAgICAgICAgPyBuYXRpdmVCdWZmZXIuYWxsb2MoMClcbiAgICAgICAgICAgIDogbmV3IHRoaXMuYnVmLmNvbnN0cnVjdG9yKDApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2xpY2UuY2FsbCh0aGlzLmJ1Ziwgc3RhcnQsIGVuZCk7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgc3RyaW5nIHByZWNlZWRlZCBieSBpdHMgYnl0ZSBsZW5ndGggYXMgYSB2YXJpbnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuc3RyaW5nID0gZnVuY3Rpb24gcmVhZF9zdHJpbmcoKSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy5ieXRlcygpO1xuICAgIHJldHVybiB1dGY4LnJlYWQoYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCk7XG59O1xuXG4vKipcbiAqIFNraXBzIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzIGlmIHNwZWNpZmllZCwgb3RoZXJ3aXNlIHNraXBzIGEgdmFyaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIExlbmd0aCBpZiBrbm93biwgb3RoZXJ3aXNlIGEgdmFyaW50IGlzIGFzc3VtZWRcbiAqIEByZXR1cm5zIHtSZWFkZXJ9IGB0aGlzYFxuICovXG5SZWFkZXIucHJvdG90eXBlLnNraXAgPSBmdW5jdGlvbiBza2lwKGxlbmd0aCkge1xuICAgIGlmICh0eXBlb2YgbGVuZ3RoID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAodGhpcy5wb3MgKyBsZW5ndGggPiB0aGlzLmxlbilcbiAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB0aGlzLnBvcyArPSBsZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5sZW4pXG4gICAgICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMpO1xuICAgICAgICB9IHdoaWxlICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSAmIDEyOCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTa2lwcyB0aGUgbmV4dCBlbGVtZW50IG9mIHRoZSBzcGVjaWZpZWQgd2lyZSB0eXBlLlxuICogQHBhcmFtIHtudW1iZXJ9IHdpcmVUeXBlIFdpcmUgdHlwZSByZWNlaXZlZFxuICogQHJldHVybnMge1JlYWRlcn0gYHRoaXNgXG4gKi9cblJlYWRlci5wcm90b3R5cGUuc2tpcFR5cGUgPSBmdW5jdGlvbih3aXJlVHlwZSkge1xuICAgIHN3aXRjaCAod2lyZVR5cGUpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgdGhpcy5za2lwKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgdGhpcy5za2lwKDgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIHRoaXMuc2tpcCh0aGlzLnVpbnQzMigpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICB3aGlsZSAoKHdpcmVUeXBlID0gdGhpcy51aW50MzIoKSAmIDcpICE9PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5za2lwVHlwZSh3aXJlVHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgdGhpcy5za2lwKDQpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiaW52YWxpZCB3aXJlIHR5cGUgXCIgKyB3aXJlVHlwZSArIFwiIGF0IG9mZnNldCBcIiArIHRoaXMucG9zKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5SZWFkZXIuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uKEJ1ZmZlclJlYWRlcl8pIHtcbiAgICBCdWZmZXJSZWFkZXIgPSBCdWZmZXJSZWFkZXJfO1xuICAgIFJlYWRlci5jcmVhdGUgPSBjcmVhdGUoKTtcbiAgICBCdWZmZXJSZWFkZXIuX2NvbmZpZ3VyZSgpO1xuXG4gICAgdmFyIGZuID0gdXRpbC5Mb25nID8gXCJ0b0xvbmdcIiA6IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIFwidG9OdW1iZXJcIjtcbiAgICB1dGlsLm1lcmdlKFJlYWRlci5wcm90b3R5cGUsIHtcblxuICAgICAgICBpbnQ2NDogZnVuY3Rpb24gcmVhZF9pbnQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkTG9uZ1ZhcmludC5jYWxsKHRoaXMpW2ZuXShmYWxzZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdWludDY0OiBmdW5jdGlvbiByZWFkX3VpbnQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkTG9uZ1ZhcmludC5jYWxsKHRoaXMpW2ZuXSh0cnVlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBzaW50NjQ6IGZ1bmN0aW9uIHJlYWRfc2ludDY0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlYWRMb25nVmFyaW50LmNhbGwodGhpcykuenpEZWNvZGUoKVtmbl0oZmFsc2UpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpeGVkNjQ6IGZ1bmN0aW9uIHJlYWRfZml4ZWQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkRml4ZWQ2NC5jYWxsKHRoaXMpW2ZuXSh0cnVlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBzZml4ZWQ2NDogZnVuY3Rpb24gcmVhZF9zZml4ZWQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkRml4ZWQ2NC5jYWxsKHRoaXMpW2ZuXShmYWxzZSk7XG4gICAgICAgIH1cblxuICAgIH0pO1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gQnVmZmVyUmVhZGVyO1xuXG4vLyBleHRlbmRzIFJlYWRlclxudmFyIFJlYWRlciA9IHJlcXVpcmUoXCIuL3JlYWRlclwiKTtcbihCdWZmZXJSZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShSZWFkZXIucHJvdG90eXBlKSkuY29uc3RydWN0b3IgPSBCdWZmZXJSZWFkZXI7XG5cbnZhciB1dGlsID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgYnVmZmVyIHJlYWRlciBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgV2lyZSBmb3JtYXQgcmVhZGVyIHVzaW5nIG5vZGUgYnVmZmVycy5cbiAqIEBleHRlbmRzIFJlYWRlclxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyIEJ1ZmZlciB0byByZWFkIGZyb21cbiAqL1xuZnVuY3Rpb24gQnVmZmVyUmVhZGVyKGJ1ZmZlcikge1xuICAgIFJlYWRlci5jYWxsKHRoaXMsIGJ1ZmZlcik7XG5cbiAgICAvKipcbiAgICAgKiBSZWFkIGJ1ZmZlci5cbiAgICAgKiBAbmFtZSBCdWZmZXJSZWFkZXIjYnVmXG4gICAgICogQHR5cGUge0J1ZmZlcn1cbiAgICAgKi9cbn1cblxuQnVmZmVyUmVhZGVyLl9jb25maWd1cmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAodXRpbC5CdWZmZXIpXG4gICAgICAgIEJ1ZmZlclJlYWRlci5wcm90b3R5cGUuX3NsaWNlID0gdXRpbC5CdWZmZXIucHJvdG90eXBlLnNsaWNlO1xufTtcblxuXG4vKipcbiAqIEBvdmVycmlkZVxuICovXG5CdWZmZXJSZWFkZXIucHJvdG90eXBlLnN0cmluZyA9IGZ1bmN0aW9uIHJlYWRfc3RyaW5nX2J1ZmZlcigpIHtcbiAgICB2YXIgbGVuID0gdGhpcy51aW50MzIoKTsgLy8gbW9kaWZpZXMgcG9zXG4gICAgcmV0dXJuIHRoaXMuYnVmLnV0ZjhTbGljZVxuICAgICAgICA/IHRoaXMuYnVmLnV0ZjhTbGljZSh0aGlzLnBvcywgdGhpcy5wb3MgPSBNYXRoLm1pbih0aGlzLnBvcyArIGxlbiwgdGhpcy5sZW4pKVxuICAgICAgICA6IHRoaXMuYnVmLnRvU3RyaW5nKFwidXRmLThcIiwgdGhpcy5wb3MsIHRoaXMucG9zID0gTWF0aC5taW4odGhpcy5wb3MgKyBsZW4sIHRoaXMubGVuKSk7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgc2VxdWVuY2Ugb2YgYnl0ZXMgcHJlY2VlZGVkIGJ5IGl0cyBsZW5ndGggYXMgYSB2YXJpbnQuXG4gKiBAbmFtZSBCdWZmZXJSZWFkZXIjYnl0ZXNcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0J1ZmZlcn0gVmFsdWUgcmVhZFxuICovXG5cbkJ1ZmZlclJlYWRlci5fY29uZmlndXJlKCk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IFNlcnZpY2U7XG5cbnZhciB1dGlsID0gcmVxdWlyZShcIi4uL3V0aWwvbWluaW1hbFwiKTtcblxuLy8gRXh0ZW5kcyBFdmVudEVtaXR0ZXJcbihTZXJ2aWNlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUodXRpbC5FdmVudEVtaXR0ZXIucHJvdG90eXBlKSkuY29uc3RydWN0b3IgPSBTZXJ2aWNlO1xuXG4vKipcbiAqIEEgc2VydmljZSBtZXRob2QgY2FsbGJhY2sgYXMgdXNlZCBieSB7QGxpbmsgcnBjLlNlcnZpY2VNZXRob2R8U2VydmljZU1ldGhvZH0uXG4gKlxuICogRGlmZmVycyBmcm9tIHtAbGluayBSUENJbXBsQ2FsbGJhY2t9IGluIHRoYXQgaXQgaXMgYW4gYWN0dWFsIGNhbGxiYWNrIG9mIGEgc2VydmljZSBtZXRob2Qgd2hpY2ggbWF5IG5vdCByZXR1cm4gYHJlc3BvbnNlID0gbnVsbGAuXG4gKiBAdHlwZWRlZiBycGMuU2VydmljZU1ldGhvZENhbGxiYWNrXG4gKiBAdGVtcGxhdGUgVFJlcyBleHRlbmRzIE1lc3NhZ2U8VFJlcz5cbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7RXJyb3J8bnVsbH0gZXJyb3IgRXJyb3IsIGlmIGFueVxuICogQHBhcmFtIHtUUmVzfSBbcmVzcG9uc2VdIFJlc3BvbnNlIG1lc3NhZ2VcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKi9cblxuLyoqXG4gKiBBIHNlcnZpY2UgbWV0aG9kIHBhcnQgb2YgYSB7QGxpbmsgcnBjLlNlcnZpY2V9IGFzIGNyZWF0ZWQgYnkge0BsaW5rIFNlcnZpY2UuY3JlYXRlfS5cbiAqIEB0eXBlZGVmIHJwYy5TZXJ2aWNlTWV0aG9kXG4gKiBAdGVtcGxhdGUgVFJlcSBleHRlbmRzIE1lc3NhZ2U8VFJlcT5cbiAqIEB0ZW1wbGF0ZSBUUmVzIGV4dGVuZHMgTWVzc2FnZTxUUmVzPlxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtUUmVxfFByb3BlcnRpZXM8VFJlcT59IHJlcXVlc3QgUmVxdWVzdCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdFxuICogQHBhcmFtIHtycGMuU2VydmljZU1ldGhvZENhbGxiYWNrPFRSZXM+fSBbY2FsbGJhY2tdIE5vZGUtc3R5bGUgY2FsbGJhY2sgY2FsbGVkIHdpdGggdGhlIGVycm9yLCBpZiBhbnksIGFuZCB0aGUgcmVzcG9uc2UgbWVzc2FnZVxuICogQHJldHVybnMge1Byb21pc2U8TWVzc2FnZTxUUmVzPj59IFByb21pc2UgaWYgYGNhbGxiYWNrYCBoYXMgYmVlbiBvbWl0dGVkLCBvdGhlcndpc2UgYHVuZGVmaW5lZGBcbiAqL1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgUlBDIHNlcnZpY2UgaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIEFuIFJQQyBzZXJ2aWNlIGFzIHJldHVybmVkIGJ5IHtAbGluayBTZXJ2aWNlI2NyZWF0ZX0uXG4gKiBAZXhwb3J0cyBycGMuU2VydmljZVxuICogQGV4dGVuZHMgdXRpbC5FdmVudEVtaXR0ZXJcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtSUENJbXBsfSBycGNJbXBsIFJQQyBpbXBsZW1lbnRhdGlvblxuICogQHBhcmFtIHtib29sZWFufSBbcmVxdWVzdERlbGltaXRlZD1mYWxzZV0gV2hldGhlciByZXF1ZXN0cyBhcmUgbGVuZ3RoLWRlbGltaXRlZFxuICogQHBhcmFtIHtib29sZWFufSBbcmVzcG9uc2VEZWxpbWl0ZWQ9ZmFsc2VdIFdoZXRoZXIgcmVzcG9uc2VzIGFyZSBsZW5ndGgtZGVsaW1pdGVkXG4gKi9cbmZ1bmN0aW9uIFNlcnZpY2UocnBjSW1wbCwgcmVxdWVzdERlbGltaXRlZCwgcmVzcG9uc2VEZWxpbWl0ZWQpIHtcblxuICAgIGlmICh0eXBlb2YgcnBjSW1wbCAhPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJycGNJbXBsIG11c3QgYmUgYSBmdW5jdGlvblwiKTtcblxuICAgIHV0aWwuRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgICAvKipcbiAgICAgKiBSUEMgaW1wbGVtZW50YXRpb24uIEJlY29tZXMgYG51bGxgIG9uY2UgdGhlIHNlcnZpY2UgaXMgZW5kZWQuXG4gICAgICogQHR5cGUge1JQQ0ltcGx8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLnJwY0ltcGwgPSBycGNJbXBsO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciByZXF1ZXN0cyBhcmUgbGVuZ3RoLWRlbGltaXRlZC5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLnJlcXVlc3REZWxpbWl0ZWQgPSBCb29sZWFuKHJlcXVlc3REZWxpbWl0ZWQpO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciByZXNwb25zZXMgYXJlIGxlbmd0aC1kZWxpbWl0ZWQuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5yZXNwb25zZURlbGltaXRlZCA9IEJvb2xlYW4ocmVzcG9uc2VEZWxpbWl0ZWQpO1xufVxuXG4vKipcbiAqIENhbGxzIGEgc2VydmljZSBtZXRob2QgdGhyb3VnaCB7QGxpbmsgcnBjLlNlcnZpY2UjcnBjSW1wbHxycGNJbXBsfS5cbiAqIEBwYXJhbSB7TWV0aG9kfHJwYy5TZXJ2aWNlTWV0aG9kPFRSZXEsVFJlcz59IG1ldGhvZCBSZWZsZWN0ZWQgb3Igc3RhdGljIG1ldGhvZFxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxUUmVxPn0gcmVxdWVzdEN0b3IgUmVxdWVzdCBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxUUmVzPn0gcmVzcG9uc2VDdG9yIFJlc3BvbnNlIGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1RSZXF8UHJvcGVydGllczxUUmVxPn0gcmVxdWVzdCBSZXF1ZXN0IG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0XG4gKiBAcGFyYW0ge3JwYy5TZXJ2aWNlTWV0aG9kQ2FsbGJhY2s8VFJlcz59IGNhbGxiYWNrIFNlcnZpY2UgY2FsbGJhY2tcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKiBAdGVtcGxhdGUgVFJlcSBleHRlbmRzIE1lc3NhZ2U8VFJlcT5cbiAqIEB0ZW1wbGF0ZSBUUmVzIGV4dGVuZHMgTWVzc2FnZTxUUmVzPlxuICovXG5TZXJ2aWNlLnByb3RvdHlwZS5ycGNDYWxsID0gZnVuY3Rpb24gcnBjQ2FsbChtZXRob2QsIHJlcXVlc3RDdG9yLCByZXNwb25zZUN0b3IsIHJlcXVlc3QsIGNhbGxiYWNrKSB7XG5cbiAgICBpZiAoIXJlcXVlc3QpXG4gICAgICAgIHRocm93IFR5cGVFcnJvcihcInJlcXVlc3QgbXVzdCBiZSBzcGVjaWZpZWRcIik7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgaWYgKCFjYWxsYmFjaylcbiAgICAgICAgcmV0dXJuIHV0aWwuYXNQcm9taXNlKHJwY0NhbGwsIHNlbGYsIG1ldGhvZCwgcmVxdWVzdEN0b3IsIHJlc3BvbnNlQ3RvciwgcmVxdWVzdCk7XG5cbiAgICBpZiAoIXNlbGYucnBjSW1wbCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjYWxsYmFjayhFcnJvcihcImFscmVhZHkgZW5kZWRcIikpOyB9LCAwKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gc2VsZi5ycGNJbXBsKFxuICAgICAgICAgICAgbWV0aG9kLFxuICAgICAgICAgICAgcmVxdWVzdEN0b3Jbc2VsZi5yZXF1ZXN0RGVsaW1pdGVkID8gXCJlbmNvZGVEZWxpbWl0ZWRcIiA6IFwiZW5jb2RlXCJdKHJlcXVlc3QpLmZpbmlzaCgpLFxuICAgICAgICAgICAgZnVuY3Rpb24gcnBjQ2FsbGJhY2soZXJyLCByZXNwb25zZSkge1xuXG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnIsIG1ldGhvZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmVuZCgvKiBlbmRlZEJ5UlBDICovIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghKHJlc3BvbnNlIGluc3RhbmNlb2YgcmVzcG9uc2VDdG9yKSkge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZUN0b3Jbc2VsZi5yZXNwb25zZURlbGltaXRlZCA/IFwiZGVjb2RlRGVsaW1pdGVkXCIgOiBcImRlY29kZVwiXShyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgZXJyLCBtZXRob2QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzZWxmLmVtaXQoXCJkYXRhXCIsIHJlc3BvbnNlLCBtZXRob2QpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCByZXNwb25zZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHNlbGYuZW1pdChcImVycm9yXCIsIGVyciwgbWV0aG9kKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgY2FsbGJhY2soZXJyKTsgfSwgMCk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxufTtcblxuLyoqXG4gKiBFbmRzIHRoaXMgc2VydmljZSBhbmQgZW1pdHMgdGhlIGBlbmRgIGV2ZW50LlxuICogQHBhcmFtIHtib29sZWFufSBbZW5kZWRCeVJQQz1mYWxzZV0gV2hldGhlciB0aGUgc2VydmljZSBoYXMgYmVlbiBlbmRlZCBieSB0aGUgUlBDIGltcGxlbWVudGF0aW9uLlxuICogQHJldHVybnMge3JwYy5TZXJ2aWNlfSBgdGhpc2BcbiAqL1xuU2VydmljZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gZW5kKGVuZGVkQnlSUEMpIHtcbiAgICBpZiAodGhpcy5ycGNJbXBsKSB7XG4gICAgICAgIGlmICghZW5kZWRCeVJQQykgLy8gc2lnbmFsIGVuZCB0byBycGNJbXBsXG4gICAgICAgICAgICB0aGlzLnJwY0ltcGwobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgICAgIHRoaXMucnBjSW1wbCA9IG51bGw7XG4gICAgICAgIHRoaXMuZW1pdChcImVuZFwiKS5vZmYoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuIiwgIlwidXNlIHN0cmljdFwiO1xuXG4vKipcbiAqIFN0cmVhbWluZyBSUEMgaGVscGVycy5cbiAqIEBuYW1lc3BhY2VcbiAqL1xudmFyIHJwYyA9IGV4cG9ydHM7XG5cbi8qKlxuICogUlBDIGltcGxlbWVudGF0aW9uIHBhc3NlZCB0byB7QGxpbmsgU2VydmljZSNjcmVhdGV9IHBlcmZvcm1pbmcgYSBzZXJ2aWNlIHJlcXVlc3Qgb24gbmV0d29yayBsZXZlbCwgaS5lLiBieSB1dGlsaXppbmcgaHR0cCByZXF1ZXN0cyBvciB3ZWJzb2NrZXRzLlxuICogQHR5cGVkZWYgUlBDSW1wbFxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtNZXRob2R8cnBjLlNlcnZpY2VNZXRob2Q8TWVzc2FnZTx7fT4sTWVzc2FnZTx7fT4+fSBtZXRob2QgUmVmbGVjdGVkIG9yIHN0YXRpYyBtZXRob2QgYmVpbmcgY2FsbGVkXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHJlcXVlc3REYXRhIFJlcXVlc3QgZGF0YVxuICogQHBhcmFtIHtSUENJbXBsQ2FsbGJhY2t9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICogQGV4YW1wbGVcbiAqIGZ1bmN0aW9uIHJwY0ltcGwobWV0aG9kLCByZXF1ZXN0RGF0YSwgY2FsbGJhY2spIHtcbiAqICAgICBpZiAocHJvdG9idWYudXRpbC5sY0ZpcnN0KG1ldGhvZC5uYW1lKSAhPT0gXCJteU1ldGhvZFwiKSAvLyBjb21wYXRpYmxlIHdpdGggc3RhdGljIGNvZGVcbiAqICAgICAgICAgdGhyb3cgRXJyb3IoXCJubyBzdWNoIG1ldGhvZFwiKTtcbiAqICAgICBhc3luY2hyb25vdXNseU9idGFpbkFSZXNwb25zZShyZXF1ZXN0RGF0YSwgZnVuY3Rpb24oZXJyLCByZXNwb25zZURhdGEpIHtcbiAqICAgICAgICAgY2FsbGJhY2soZXJyLCByZXNwb25zZURhdGEpO1xuICogICAgIH0pO1xuICogfVxuICovXG5cbi8qKlxuICogTm9kZS1zdHlsZSBjYWxsYmFjayBhcyB1c2VkIGJ5IHtAbGluayBSUENJbXBsfS5cbiAqIEB0eXBlZGVmIFJQQ0ltcGxDYWxsYmFja1xuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtFcnJvcnxudWxsfSBlcnJvciBFcnJvciwgaWYgYW55LCBvdGhlcndpc2UgYG51bGxgXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl8bnVsbH0gW3Jlc3BvbnNlXSBSZXNwb25zZSBkYXRhIG9yIGBudWxsYCB0byBzaWduYWwgZW5kIG9mIHN0cmVhbSwgaWYgdGhlcmUgaGFzbid0IGJlZW4gYW4gZXJyb3JcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKi9cblxucnBjLlNlcnZpY2UgPSByZXF1aXJlKFwiLi9ycGMvc2VydmljZVwiKTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0ge307XG5cbi8qKlxuICogTmFtZWQgcm9vdHMuXG4gKiBUaGlzIGlzIHdoZXJlIHBianMgc3RvcmVzIGdlbmVyYXRlZCBzdHJ1Y3R1cmVzICh0aGUgb3B0aW9uIGAtciwgLS1yb290YCBzcGVjaWZpZXMgYSBuYW1lKS5cbiAqIENhbiBhbHNvIGJlIHVzZWQgbWFudWFsbHkgdG8gbWFrZSByb290cyBhdmFpbGFibGUgYWNyb3NzIG1vZHVsZXMuXG4gKiBAbmFtZSByb290c1xuICogQHR5cGUge09iamVjdC48c3RyaW5nLFJvb3Q+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+IHN0cmluZykge1xuICBpZiAoIWV4cHIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodHlwZW9mIG1zZyA9PT0gJ3N0cmluZycgPyBtc2cgOiBtc2coKSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEFycmF5VXRpbCB7XG4gIC8qKlxuICAgKiBWZXJpZmllcyBpZiAyIGlucHV0IGFycmF5cyBjb250YWluIHRoZSBzYW1lIGVsZW1lbnRzLlxuICAgKiBAcGFyYW0gbjEgQXJyYXkgMVxuICAgKiBAcGFyYW0gbjIgQXJyYXkgMlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZXNlIDIgYXJlIGVxdWFsXG4gICAqL1xuICBzdGF0aWMgYXJyYXlzRXF1YWwoXG4gICAgbjE6XG4gICAgICB8IHJlYWRvbmx5IG51bWJlcltdXG4gICAgICB8IEludDhBcnJheVxuICAgICAgfCBVaW50OEFycmF5XG4gICAgICB8IEludDE2QXJyYXlcbiAgICAgIHwgVWludDE2QXJyYXlcbiAgICAgIHwgSW50MzJBcnJheVxuICAgICAgfCBVaW50MzJBcnJheVxuICAgICAgfCBVaW50OENsYW1wZWRBcnJheVxuICAgICAgfCBGbG9hdDMyQXJyYXlcbiAgICAgIHwgRmxvYXQ2NEFycmF5LFxuICAgIG4yOlxuICAgICAgfCByZWFkb25seSBudW1iZXJbXVxuICAgICAgfCBJbnQ4QXJyYXlcbiAgICAgIHwgVWludDhBcnJheVxuICAgICAgfCBJbnQxNkFycmF5XG4gICAgICB8IFVpbnQxNkFycmF5XG4gICAgICB8IEludDMyQXJyYXlcbiAgICAgIHwgVWludDMyQXJyYXlcbiAgICAgIHwgVWludDhDbGFtcGVkQXJyYXlcbiAgICAgIHwgRmxvYXQzMkFycmF5XG4gICAgICB8IEZsb2F0NjRBcnJheSxcbiAgKSB7XG4gICAgaWYgKG4xLmxlbmd0aCAhPT0gbjIubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChuMVtpXSAhPT0gbjJbaV0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTWF0TXVsVXRpbCB7XG4gIC8qKlxuICAgKiBGaXggdGhlIGlucHV0IHNoYXBlcyBmb3IgTWF0TXVsIG9wZXJhdGlvbiBpZiB0aGV5IG5lZWQgZml4aW5nXG4gICAqIEBwYXJhbSBkaW1zQSBUaGUgc2hhcGUgb2YgdGVuc29yIEEuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gZGltc0IgVGhlIHNoYXBlIG9mIHRlbnNvciBCLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHJldHVybnMgQSB0dXBsZSBjb250YWluaW5nIHRoZSBwcmVwcm9jZXNzZWQgaW5wdXQgc2hhcGVzIGFzIHJlcXVpcmVkIGJ5IE9OTlggc3BlY2lmaWNhdGlvbnNcbiAgICovXG4gIHN0YXRpYyBwcmVwcm9jZXNzSW5wdXRTaGFwZXMoXG4gICAgZGltc0E6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbXNCOiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogW3JlYWRvbmx5IG51bWJlcltdLCByZWFkb25seSBudW1iZXJbXV0ge1xuICAgIC8vIElmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyAxLUQsIGl0IGlzIHByb21vdGVkIHRvIGEgbWF0cml4IGJ5IHByZXBlbmRpbmdcbiAgICAvLyBhIDEgdG8gaXRzIGRpbWVuc2lvbnMuIEFmdGVyIG1hdHJpeCBtdWx0aXBsaWNhdGlvbiB0aGUgcHJlcGVuZGVkIDEgaXNcbiAgICAvLyByZW1vdmVkLlxuICAgIGNvbnN0IGEgPSBkaW1zQS5sZW5ndGggPT09IDEgPyBbMSwgZGltc0FbMF1dIDogZGltc0E7XG5cbiAgICAvLyBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIDEtRCwgaXQgaXMgcHJvbW90ZWQgdG8gYSBtYXRyaXggYnkgYXBwZW5kaW5nXG4gICAgLy8gYSAxIHRvIGl0cyBkaW1lbnNpb25zLiBBZnRlciBtYXRyaXggbXVsdGlwbGljYXRpb24gdGhlIGFwcGVuZGVkIDEgaXNcbiAgICAvLyByZW1vdmVkLlxuICAgIGNvbnN0IGIgPSBkaW1zQi5sZW5ndGggPT09IDEgPyBbZGltc0JbMF0sIDFdIDogZGltc0I7XG5cbiAgICByZXR1cm4gW2EsIGJdO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpeCB0aGUgb3V0cHV0IHNoYXBlIGNvbXB1dGVkIGZvciBNYXRNdWwgb3BlcmF0aW9uIGlmIGl0IG5lZWRzIGZpeGluZ1xuICAgKiBAcGFyYW0gb3V0cHV0U2hhcGUgVGhlIGNvbXB1dGVkIG91dHB1dFNoYXBlLiBTaG91bGQgYmUgYW4gYXJyYXkgKGF0bGVhc3Qgb2YgbGVuZ3RoIDIpIG9mIHBvc2l0aXZlIGludGVnZXJzLlxuICAgKiBUaGlzIHdpbGwgYmUgbXV0YXRlZC5cbiAgICogQHBhcmFtIGFSYW5rIFRoZSByYW5rIG9mIHRlbnNvciBBLlxuICAgKiBAcGFyYW0gYlJhbmsgVGhlIHJhbmsgb2YgdGVuc29yIEIuXG4gICAqL1xuICBzdGF0aWMgcG9zdHByb2Nlc3NPdXRwdXRTaGFwZShvdXRwdXRTaGFwZTogbnVtYmVyW10sIGFSYW5rOiBudW1iZXIsIGJSYW5rOiBudW1iZXIpIHtcbiAgICAvLyBSZW1vdmUgcHJlcGVuZGVkIGRpbWVuc2lvbiBpZiBmaXJzdCBpbnB1dCBpcyAxZFxuICAgIGlmIChhUmFuayA9PT0gMSkge1xuICAgICAgLy8gb3V0cHV0U2hhcGUgPSBvdXRwdXRTaGFwZS5zbGljZSgwLCBvdXRwdXRTaGFwZS5sZW5ndGggLSAyKS5jb25jYXQob3V0cHV0U2hhcGUuc2xpY2Uob3V0cHV0U2hhcGUubGVuZ3RoIC0gMSkpO1xuICAgICAgb3V0cHV0U2hhcGUuc3BsaWNlKG91dHB1dFNoYXBlLmxlbmd0aCAtIDIsIDEpO1xuICAgIH1cbiAgICAvLyBSZW1vdmUgYXBwZW5kZWQgZGltZW5zaW9uIGlmIHNlY29uZCBpbnB1dCBpcyAxZFxuICAgIGlmIChiUmFuayA9PT0gMSkge1xuICAgICAgb3V0cHV0U2hhcGUucG9wKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgc2hhcGUgd2hlbiBtYXRyaXggbXVsdGlwbGljYXRpb25cbiAgICogQHBhcmFtIGEgVGhlIHNoYXBlIG9mIHRlbnNvciBBLiBTaG91bGQgYmUgYSB0dXBsZSBvZiAyIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBiIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQi4gU2hvdWxkIGJlIGEgdHVwbGUgb2YgMiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcmV0dXJucyBUaGUgZXhwZWN0ZWQgc2hhcGUgb2YgdGhlIHJlc3VsdCwgb3IgdW5kZWZpbmVkIGlmIE4vQVxuICAgKi9cbiAgc3RhdGljIGNhbGNNYXRNdWxTaGFwZShhOiBbbnVtYmVyLCBudW1iZXJdLCBiOiBbbnVtYmVyLCBudW1iZXJdKTogW251bWJlciwgbnVtYmVyXSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGFbMV0gIT09IGJbMF0gPyB1bmRlZmluZWQgOiBbYVswXSwgYlsxXV07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEJyb2FkY2FzdFV0aWwge1xuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZSB3aGVuIGJyb2FkY2FzdGluZyAyIHRlbnNvcnNcbiAgICogQHBhcmFtIGEgVGhlIHNoYXBlIG9mIHRlbnNvciBBLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGIgVGhlIHNoYXBlIG9mIHRlbnNvciBCLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGlzTWF0TXVsIFdoZXRoZXIgdGhlIG9wZXJhdGlvbiBpcyBNYXRNdWxcbiAgICogQHJldHVybnMgVGhlIGV4cGVjdGVkIHNoYXBlIG9mIHRoZSByZXN1bHQsIG9yIHVuZGVmaW5lZCBpZiBOL0FcbiAgICovXG4gIHN0YXRpYyBjYWxjU2hhcGUoXG4gICAgYWRpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGJkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBpc01hdE11bCA9IGZhbHNlLFxuICApOiByZWFkb25seSBudW1iZXJbXSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgYXJhbmsgPSBhZGltcy5sZW5ndGg7XG4gICAgY29uc3QgYnJhbmsgPSBiZGltcy5sZW5ndGg7XG4gICAgaWYgKGFyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gYmRpbXM7XG4gICAgfVxuICAgIGlmIChicmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIGFkaW1zO1xuICAgIH1cbiAgICBjb25zdCBjcmFuayA9IE1hdGgubWF4KGFkaW1zLmxlbmd0aCwgYmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBjZGltcyA9IG5ldyBBcnJheTxudW1iZXI+KGNyYW5rKTtcblxuICAgIC8vIGNhbGN1bGF0ZSB0aGUgbGFzdCAyIGRpbWVuc2lvbiBpZiBpdCBpcyBNYXRNdWxcbiAgICBpZiAoaXNNYXRNdWwpIHtcbiAgICAgIGlmIChhcmFuayA8IDIgfHwgYnJhbmsgPCAyKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBjb25zdCBjU2hhcGVNYXRNdWwgPSBNYXRNdWxVdGlsLmNhbGNNYXRNdWxTaGFwZShcbiAgICAgICAgW2FkaW1zW2FyYW5rIC0gMl0sIGFkaW1zW2FyYW5rIC0gMV1dLFxuICAgICAgICBbYmRpbXNbYnJhbmsgLSAyXSwgYmRpbXNbYnJhbmsgLSAxXV0sXG4gICAgICApO1xuICAgICAgaWYgKGNTaGFwZU1hdE11bCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBbY2RpbXNbY3JhbmsgLSAyXSwgY2RpbXNbY3JhbmsgLSAxXV0gPSBjU2hhcGVNYXRNdWw7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IGlzTWF0TXVsID8gMyA6IDE7IGkgPD0gY3Jhbms7IGkrKykge1xuICAgICAgY29uc3QgYUxlbiA9IGFyYW5rIC0gaSA8IDAgPyAxIDogYWRpbXNbYXJhbmsgLSBpXTtcbiAgICAgIGNvbnN0IGJMZW4gPSBicmFuayAtIGkgPCAwID8gMSA6IGJkaW1zW2JyYW5rIC0gaV07XG5cbiAgICAgIGlmIChhTGVuICE9PSBiTGVuICYmIGFMZW4gPiAxICYmIGJMZW4gPiAxKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBjZGltc1tjcmFuayAtIGldID0gTWF0aC5tYXgoYUxlbiwgYkxlbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNkaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIEdpdmVuIHRoZSBpbmRpY2VzIG9mIGEgYnJvYWRjYXN0ZWQgdGVuc29yLCBjYWxjdWxhdGUgdGhlIG9yaWdpbmFsIGluZGljZXNcbiAgICogQHBhcmFtIGJyb2FkY2FzdGVkSW5kaWNlcyBUaGUgZ2l2ZW4gaW5kaWNlcyBvZiB0aGUgYnJvYWRjYXN0ZWQgdGVuc29yLlxuICAgKiBAcGFyYW0gb3JpZ2luYWxTaGFwZSBUaGUgb3JpZ2luYWwgc2hhcGUgb2YgdGhlIHRlbnNvciBiZWZvcmUgYnJvYWRjYXNcbiAgICogQHJldHVybnMgVGhlIGNhbGN1bGF0ZWQgaW5kaWNlcyB0aGF0IG1hcHMgdG8gdGhlIG9yaWdpbmFsIHRlbnNvci5cbiAgICovXG4gIHN0YXRpYyBpbmRleChicm9hZGNhc3RlZEluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdLCBvcmlnaW5hbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgICAvLyBOT1RFIDE6IHdlIGFzc3VtZSB0aGUgcGFyYW1ldGVyIGJyb2FkY2FzdGVkSW5kaWNlcyBpcyB2YWxpZC4gaWUuIGl0IHNob3VsZCBoYXZlIHRoZSBzYW1lXG4gICAgLy8gbGVuZ3RoIGFzIHRoZSBicm9hZGNhc3RlZCBzaGFwZSwgYW5kIGZvciBlYWNoIGRpbWVuc2lvbiB0aGUgaW5kZXggc2hvdWxkXG4gICAgLy8gbm90IGJlIG91dCBvZiByYW5nZS5cbiAgICBjb25zdCBvcmlnaW5hbEluZGljZXMgPSBuZXcgQXJyYXkob3JpZ2luYWxTaGFwZS5sZW5ndGgpO1xuICAgIEJyb2FkY2FzdFV0aWwuZmlsbEluZGV4KGJyb2FkY2FzdGVkSW5kaWNlcywgb3JpZ2luYWxTaGFwZSwgb3JpZ2luYWxJbmRpY2VzKTtcbiAgICByZXR1cm4gb3JpZ2luYWxJbmRpY2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdpdmVuIHRoZSBpbmRpY2VzIG9mIGEgYnJvYWRjYXN0ZWQgdGVuc29yLCBjYWxjdWxhdGUgdGhlIG9yaWdpbmFsIGluZGljZXNcbiAgICogQHBhcmFtIGJyb2FkY2FzdGVkSW5kaWNlcyBUaGUgZ2l2ZW4gaW5kaWNlcyBvZiB0aGUgYnJvYWRjYXN0ZWQgdGVuc29yLlxuICAgKiBAcGFyYW0gb3JpZ2luYWxTaGFwZSBUaGUgb3JpZ2luYWwgc2hhcGUgb2YgdGhlIHRlbnNvciBiZWZvcmUgYnJvYWRjYXN0XG4gICAqIEBwYXJhbSBvcmlnaW5hbEluZGljZXMgVGhlIG1hcHBpbmcgb2YgYnJvYWRjYXN0ZWRJbmRpY2VzIHRvIHRoZSBvcmlnaW5hbEluZGljZXMgKG91dHB1dCBwYXJhbWV0ZXIgLSB3aWxsIGJlXG4gICAqICAgICBtdXRhdGVkKS5cbiAgICovXG4gIHN0YXRpYyBmaWxsSW5kZXgoYnJvYWRjYXN0ZWRJbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSwgb3JpZ2luYWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIG9yaWdpbmFsSW5kaWNlczogbnVtYmVyW10pIHtcbiAgICAvLyBOT1RFIDE6IHdlIGFzc3VtZSB0aGUgcGFyYW1ldGVyIGJyb2FkY2FzdGVkSW5kaWNlcyBpcyB2YWxpZC4gaWUuIGl0IHNob3VsZCBoYXZlIHRoZSBzYW1lIGxlbmd0aCBhcyB0aGVcbiAgICAvLyBicm9hZGNhc3RlZCBzaGFwZSwgYW5kIGZvciBlYWNoIGRpbWVuc2lvbiB0aGUgaW5kZXggc2hvdWxkIG5vdCBiZSBvdXQgb2YgcmFuZ2UuXG4gICAgLy8gTk9URSAyOiB3ZSBhc3N1bWUgdGhlIHBhcmFtZXRlciBvcmlnaW5hbEluZGljZXMgaGFzIHRoZSBzYW1lIGxlbmd0aCBhcyB0aGUgb3JpZ2luYWxTaGFwZVxuICAgIGNvbnN0IGRpbU9mZnNldCA9IGJyb2FkY2FzdGVkSW5kaWNlcy5sZW5ndGggLSBvcmlnaW5hbFNoYXBlLmxlbmd0aDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yaWdpbmFsU2hhcGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9yaWdpbmFsSW5kaWNlc1tpXSA9IGJyb2FkY2FzdGVkSW5kaWNlc1tkaW1PZmZzZXQgKyBpXSAlIG9yaWdpbmFsU2hhcGVbaV07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gdGhlIGJyb2FkY2FzdGluZyBvcGVyYXRpb24gb24gdGhlIHNwZWNpZmljIG9wZXJhdG9yXG4gICAqIEBwYXJhbSBhIFRoZSBpbnB1dCB0ZW5zb3IgQVxuICAgKiBAcGFyYW0gYiBUaGUgaW5wdXQgdGVuc29yIEJcbiAgICogQHBhcmFtIG9wIFRoZSBvcGVyYXRvciBsYW1iZGEgZnVuY3Rpb25cbiAgICogQHBhcmFtIGlucGxhY2UgV2hldGhlciB0byB3cml0ZSB0aGUgcmVzdWx0IGJhY2sgdG8gQS5cbiAgICogQHJldHVybnMgVGhlIHJlc3VsdCB0ZW5zb3IsIG9yIHVuZGVmaW5lZCBpZiBpbnB1dCBub3QgYnJvYWRjYXN0YWJsZS5cbiAgICovXG4gIHN0YXRpYyBjYWxjKFxuICAgIGE6IFRlbnNvcixcbiAgICBiOiBUZW5zb3IsXG4gICAgb3A6IChhOiBzdHJpbmcgfCBudW1iZXIsIGI6IHN0cmluZyB8IG51bWJlcikgPT4gc3RyaW5nIHwgbnVtYmVyLFxuICAgIGlucGxhY2U6IGJvb2xlYW4sXG4gICAgcmVzdWx0VHlwZT86IFRlbnNvci5EYXRhVHlwZSxcbiAgKTogVGVuc29yIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBvdXRwdXRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGEuZGltcywgYi5kaW1zKTtcblxuICAgIGlmIChvdXRwdXRTaGFwZSkge1xuICAgICAgaWYgKGlucGxhY2UgJiYgIVNoYXBlVXRpbC5hcmVFcXVhbChvdXRwdXRTaGFwZSwgYS5kaW1zKSkge1xuICAgICAgICAvLyBCIGlzIG5vdCBicm9hZGNhc3RhYmxlIHRvIEEsIGZhaWxlZCB0byBjYWxjdWxhdGUgaW5wbGFjZS5cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgICAgIGNvbnN0IGMgPSBpbnBsYWNlID8gYSA6IG5ldyBUZW5zb3Iob3V0cHV0U2hhcGUsIHJlc3VsdFR5cGUgfHwgYS50eXBlKTtcblxuICAgICAgLy8gYm90aCBpbnB1dHMgYXJlIHNjYWxhcnNcbiAgICAgIGlmIChvdXRwdXRTaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgYy5zZXQoW10sIG9wKGEuZ2V0KFtdKSBhcyBudW1iZXIsIGIuZ2V0KFtdKSBhcyBudW1iZXIpKTtcbiAgICAgIH1cblxuICAgICAgLy8gYXRsZWFzdCBvbmUgaW5wdXQgaXMgYSBub24tc2NhbGFyXG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0EgPSBuZXcgQXJyYXkoYS5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0IgPSBuZXcgQXJyYXkoYi5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGxldCB2YWxBOiBzdHJpbmcgfCBudW1iZXIgPSAwO1xuICAgICAgICBsZXQgdmFsQjogc3RyaW5nIHwgbnVtYmVyID0gMDtcbiAgICAgICAgbGV0IGlzQVNjYWxhciA9IGZhbHNlO1xuICAgICAgICBsZXQgaXNCU2NhbGFyID0gZmFsc2U7XG4gICAgICAgIGlmIChhLmRpbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdmFsQSA9IGEuZ2V0KFtdKSBhcyBudW1iZXI7XG4gICAgICAgICAgaXNBU2NhbGFyID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYi5kaW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHZhbEIgPSBiLmdldChbXSkgYXMgbnVtYmVyO1xuICAgICAgICAgIGlzQlNjYWxhciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc3Q6IG51bWJlcjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgICAgICAvLyB0cmF2ZXJzYWwgaW5kaWNlc1xuICAgICAgICAgIHJlc3QgPSBpO1xuICAgICAgICAgIGZvciAobGV0IGogPSBvdXRwdXRTaGFwZS5sZW5ndGggLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgICAgICAgb3V0cHV0SW5kaWNlc1tqXSA9IHJlc3QgJSBvdXRwdXRTaGFwZVtqXTtcbiAgICAgICAgICAgIHJlc3QgPSBNYXRoLmZsb29yKHJlc3QgLyBvdXRwdXRTaGFwZVtqXSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFpc0FTY2FsYXIpIHtcbiAgICAgICAgICAgIC8vIG1hcCBvdXRwdXRJbmRpY2VzICh3aGljaCBpcyBhY3R1YWxseSBicm9hZGNhc3RlZCkgdG8gdGhlIG9yaWdpbmFsSW5kaWNlc1xuICAgICAgICAgICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgob3V0cHV0SW5kaWNlcywgYS5kaW1zLCBvcmlnaW5hbEluZGljZXNBKTtcbiAgICAgICAgICAgIHZhbEEgPSBhLmdldChvcmlnaW5hbEluZGljZXNBKSBhcyBudW1iZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghaXNCU2NhbGFyKSB7XG4gICAgICAgICAgICBCcm9hZGNhc3RVdGlsLmZpbGxJbmRleChvdXRwdXRJbmRpY2VzLCBiLmRpbXMsIG9yaWdpbmFsSW5kaWNlc0IpO1xuICAgICAgICAgICAgdmFsQiA9IGIuZ2V0KG9yaWdpbmFsSW5kaWNlc0IpIGFzIG51bWJlcjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjLnNldChvdXRwdXRJbmRpY2VzLCBvcCh2YWxBLCB2YWxCKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgaWYgYSBzaGFwZSBpcyB1bmlkaXJlY3Rpb25hbCBicm9hZGNhc3RhYmxlIHRvIGFub3RoZXIgc2hhcGVcbiAgICogQHBhcmFtIHNoYXBlIFRoZSBpbnB1dCBzaGFwZVxuICAgKiBAcGFyYW0gZmluYWxTaGFwZSBUaGUgZGVzaXJlZCBzaGFwZSBhZnRlciBicm9hZGNhc3RpbmdcbiAgICovXG4gIHN0YXRpYyBpc1ZhbGlkQnJvYWRjYXN0KHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZmluYWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBib29sZWFuIHtcbiAgICAvLyBhbGlnbiBzaGFwZSB0byB0aGUgcmlnaHRcbiAgICBjb25zdCBpbnB1dFJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgZmluYWxSYW5rID0gZmluYWxTaGFwZS5sZW5ndGg7XG4gICAgaWYgKGlucHV0UmFuayA+IGZpbmFsUmFuaykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBpbnB1dFJhbms7IGkrKykge1xuICAgICAgaWYgKHNoYXBlW2lucHV0UmFuayAtIGldICE9PSAxICYmIHNoYXBlW2lucHV0UmFuayAtIGldICE9PSBmaW5hbFNoYXBlW2ZpbmFsUmFuayAtIGldKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIHRoZSBicm9hZGNhc3RlZCBkaW1zIGluIGlucHV0IHNoYXBlIGJhc2VkIG9uIHRoZSBnaXZlbiBvdXRwdXQgc2hhcGUuXG4gICAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIG9ubHkgcmV0dXJucyB0aGUgYnJvYWRjYXN0ZWQgZGltcy5cbiAgICogQHBhcmFtIGlucHV0U2hhcGUgVGhlIGlucHV0IHNoYXBlXG4gICAqIEBwYXJhbSBvdXRwdXRTaGFwZSBUaGUgb3V0cHV0IHNoYXBlXG4gICAqIEByZXR1cm5zIFRoZSBicm9hZGNhc3RlZCBkaW1zIGluIGlucHV0IHNoYXBlLlxuICAgKi9cbiAgc3RhdGljIGdldEJyb2FkY2FzdERpbXMoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgICBjb25zdCBpblJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBkaW1zOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5SYW5rOyBpKyspIHtcbiAgICAgIGNvbnN0IGRpbSA9IGluUmFuayAtIDEgLSBpO1xuICAgICAgY29uc3QgYSA9IGlucHV0U2hhcGVbZGltXSB8fCAxO1xuICAgICAgY29uc3QgYiA9IG91dHB1dFNoYXBlW291dHB1dFNoYXBlLmxlbmd0aCAtIDEgLSBpXSB8fCAxO1xuICAgICAgaWYgKGIgPiAxICYmIGEgPT09IDEpIHtcbiAgICAgICAgZGltcy51bnNoaWZ0KGRpbSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkaW1zO1xuICB9XG59XG5cbi8vIGNvcHkgYXJyYXkgaGVscGVyXG4vLyBtaW1pY3MgbWVtY3B5IGFzIG11Y2ggYXMgcG9zc2libGVcbmV4cG9ydCBmdW5jdGlvbiBhcnJheUNvcHlIZWxwZXIoXG4gIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgc291cmNlOiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICB0YXJnZXRJbmRleDogbnVtYmVyLFxuICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICBibG9ja1NpemU6IG51bWJlcixcbikge1xuICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gIH1cbiAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICB9XG5cbiAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBHZW1tVXRpbCB7XG4gIC8vIHdpbGwgbWFrZSBzdXJlIGlucHV0IHNoYXBlcyBhcmUgY29tcGF0aWJsZSBmb3IgdGhpcyBvcFxuICAvLyBhbmQgcmV0dXJuIGJhY2sgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgaW4gdGhlIGZvcm0gb2YgYSB0dXBsZVxuICAvLyB3aWxsIHRocm93IGV4Y2VwdGlvbiBpZiB0aGUgaW5wdXQgc2hhcGVzIGFyZSBub3QgY29tcGF0aWJsZVxuICBzdGF0aWMgZ2V0U2hhcGVPZkdlbW1SZXN1bHQoXG4gICAgbGVmdFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICB0cmFuc0xlZnQ6IGJvb2xlYW4sXG4gICAgcmlnaHRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgdHJhbnNSaWdodDogYm9vbGVhbixcbiAgICBiaWFzU2hhcGU/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChsZWZ0U2hhcGUubGVuZ3RoICE9PSAyIHx8IHJpZ2h0U2hhcGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NoYXBlIG5lZWQgdG8gYmUgb2Ygc2l6ZSAyJyk7XG4gICAgfVxuXG4gICAgbGV0IE06IG51bWJlcjtcbiAgICBsZXQgSzogbnVtYmVyO1xuICAgIGxldCBOOiBudW1iZXI7XG5cbiAgICBpZiAodHJhbnNMZWZ0KSB7XG4gICAgICBNID0gbGVmdFNoYXBlWzFdO1xuICAgICAgSyA9IGxlZnRTaGFwZVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgTSA9IGxlZnRTaGFwZVswXTtcbiAgICAgIEsgPSBsZWZ0U2hhcGVbMV07XG4gICAgfVxuXG4gICAgbGV0IGtEaW0gPSAtMTtcblxuICAgIGlmICh0cmFuc1JpZ2h0KSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVswXTtcbiAgICAgIGtEaW0gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVsxXTtcbiAgICAgIGtEaW0gPSAwO1xuICAgIH1cblxuICAgIGlmIChyaWdodFNoYXBlW2tEaW1dICE9PSBLKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RpbWVuc2lvbiBtaXNtYXRjaCcpO1xuICAgIH1cblxuICAgIGlmIChNIDw9IDAgfHwgTiA8PSAwIHx8IEsgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNoYXBlIHNwZWNpZmllZCcpO1xuICAgIH1cblxuICAgIGlmIChiaWFzU2hhcGUgJiYgIUJyb2FkY2FzdFV0aWwuaXNWYWxpZEJyb2FkY2FzdChiaWFzU2hhcGUsIFtNLCBOXSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ2VtbTogaW52YWxpZCBiaWFzIHNoYXBlIGZvciBicm9hZGNhc3QnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW00sIE4sIEtdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQcm90b1V0aWwge1xuICBzdGF0aWMgdGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odHlwZVByb3RvOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHwgb3J0RmJzLlRlbnNvckRhdGFUeXBlKTogVGVuc29yLkRhdGFUeXBlIHtcbiAgICBzd2l0Y2ggKHR5cGVQcm90bykge1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgICAgIHJldHVybiAnaW50OCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgICAgIHJldHVybiAndWludDgnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgICAgIHJldHVybiAnYm9vbCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY6XG4gICAgICAgIHJldHVybiAnaW50MTYnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICAgICAgcmV0dXJuICd1aW50MTYnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyOlxuICAgICAgICByZXR1cm4gJ2ludDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICAgIHJldHVybiAndWludDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuICdmbG9hdDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgICAgIHJldHVybiAnZmxvYXQ2NCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gJ3N0cmluZyc7XG5cbiAgICAgIC8vIEZvciBJTlQ2NC9VSU5UNjQsIHJlZHVjZSB0aGVpciB2YWx1ZSB0byAzMi1iaXRzLlxuICAgICAgLy8gU2hvdWxkIHRocm93IGV4Y2VwdGlvbiB3aGVuIG92ZXJmbG93XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgICAgIHJldHVybiAnaW50MzInO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgICAgcmV0dXJuICd1aW50MzInO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHtvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlW3R5cGVQcm90b119YCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtKHR5cGU6IHN0cmluZyk6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4O1xuICAgICAgY2FzZSAnYm9vbCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2O1xuICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2O1xuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjtcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjtcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDtcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU7XG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5TVFJJTkc7XG4gICAgICBjYXNlICdpbnQ2NCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0O1xuICAgICAgY2FzZSAndWludDY0JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0O1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHt0eXBlfWApO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB0ZW5zb3JEaW1zRnJvbVByb3RvKGRpbXM6IEFycmF5PG51bWJlciB8IExvbmc+KTogbnVtYmVyW10ge1xuICAgIC8vIGdldCByaWQgb2YgTG9uZyB0eXBlIGZvciBkaW1zXG4gICAgcmV0dXJuIGRpbXMubWFwKChkKSA9PiAoTG9uZy5pc0xvbmcoZCkgPyBkLnRvTnVtYmVyKCkgOiBkKSk7XG4gIH1cblxuICBzdGF0aWMgdGVuc29yVmFsdWVUeXBlRnJvbVByb3RvKHZhbHVlVHlwZTogb25ueC5UeXBlUHJvdG8uSVRlbnNvcik6IEdyYXBoLlZhbHVlVHlwZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRlbnNvclR5cGU6IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byh2YWx1ZVR5cGUuZWxlbVR5cGUhKSxcbiAgICAgIHNoYXBlOiB7IGRpbXM6IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKHZhbHVlVHlwZS5zaGFwZSEuZGltIS5tYXAoKGQpID0+IGQuZGltVmFsdWUhKSkgfSxcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHRlbnNvckRpbXNGcm9tT1JURm9ybWF0KHRlbnNvcjogb3J0RmJzLlRlbnNvcikge1xuICAgIGNvbnN0IGRpbXMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRlbnNvci5kaW1zTGVuZ3RoKCk7IGkrKykge1xuICAgICAgZGltcy5wdXNoKExvbmdVdGlsLmxvbmdUb051bWJlcih0ZW5zb3IuZGltcyhpKSEpKTtcbiAgICB9XG4gICAgcmV0dXJuIGRpbXM7XG4gIH1cblxuICBzdGF0aWMgdGVuc29yQXR0cmlidXRlc0Zyb21PUlRGb3JtYXQobm9kZTogb3J0RmJzLk5vZGUpIHtcbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2RlLmF0dHJpYnV0ZXNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBhdHRyaWJ1dGVzLnB1c2gobm9kZS5hdHRyaWJ1dGVzKGkpISk7XG4gICAgfVxuICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBMb25nVXRpbCB7XG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHRvIGdldCBhIG51bWJlciBmcm9tIGxvbmcgdHlwZSBvZiBkYXRhIGZvciBhdHRyaWJ1dGUsIGRpbSwgYW5kIGlyIHZlcnNpb24sXG4gIC8vIHdoaWNoIHZhbHVlcyBhcmUgc2lnbmVkIGludGVnZXJzLlxuICAvLyBUbyBtYWtlIGl0IG1vcmUgZ2VuZXJpYywgYWRkIGFuIG9wdGlvbmFsIHBhcmFtZXRlciB0byBjb252ZXJ0IHRvIGEgdW5zaWduZWQgbnVtYmVyLlxuICBzdGF0aWMgbG9uZ1RvTnVtYmVyKG46IExvbmcgfCBiaWdpbnQgfCBudW1iZXIpIHtcbiAgICBpZiAoTG9uZy5pc0xvbmcobikpIHtcbiAgICAgIHJldHVybiBuLnRvTnVtYmVyKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbiA9PT0gJ2JpZ2ludCcpIHtcbiAgICAgIHJldHVybiBOdW1iZXIobik7XG4gICAgfVxuICAgIHJldHVybiBuO1xuICB9XG4gIHN0YXRpYyBpc0xvbmcobjogdW5rbm93bikge1xuICAgIHJldHVybiBMb25nLmlzTG9uZyhuKSB8fCB0eXBlb2YgbiA9PT0gJ2JpZ2ludCc7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNoYXBlVXRpbCB7XG4gIHN0YXRpYyBzaXplKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgMCwgZGltcy5sZW5ndGgpO1xuICB9XG5cbiAgLy8gYGF4aXNgIGluY2x1c2l2ZVxuICBzdGF0aWMgc2l6ZUZyb21EaW1lbnNpb24oZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAwIHx8IGF4aXMgPiBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGRpbWVuc2lvbiBvZiAke2F4aXN9IGZvciBzaXplRnJvbURpbWVuc2lvbiBhcyBUZW5zb3IgaGFzICR7ZGltcy5sZW5ndGh9IGRpbWVuc2lvbnMuYCk7XG4gICAgfVxuICAgIHJldHVybiBTaGFwZVV0aWwuZ2V0U2l6ZUZyb21EaW1lbnNpb25SYW5nZShkaW1zLCBheGlzLCBkaW1zLmxlbmd0aCk7XG4gIH1cblxuICAvLyBgYXhpc2AgZXhjbHVzaXZlXG4gIHN0YXRpYyBzaXplVG9EaW1lbnNpb24oZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAwIHx8IGF4aXMgPiBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGRpbWVuc2lvbiBvZiAke2F4aXN9IGZvciBzaXplVG9EaW1lbnNpb24gYXMgVGVuc29yIGhhcyAke2RpbXMubGVuZ3RofSBkaW1lbnNpb25zLmApO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgMCwgYXhpcyk7XG4gIH1cblxuICBzdGF0aWMgZ2V0U2l6ZUZyb21EaW1lbnNpb25SYW5nZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBzaXplID0gMTtcbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgLy8gc2FmZXR5IGNoZWNrIGFzIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBtdWx0aXBsZSBvdGhlciBtZXRob2RzIHJlcXVpcmluZyBzaXplLlxuICAgICAgLy8gc2l6ZSBjYW5ub3QgYmUgMCBvciBuZWdhdGl2ZS5cbiAgICAgIGlmIChkaW1zW2ldIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgICAgJ2Nhbm5vdCBnZXQgdmFsaWQgc2l6ZSBmcm9tIHNwZWNpZmllZCBkaW1lbnNpb24gcmFuZ2UuIE1vc3QgbGlrZWx5IHRoZSByYW5nZSBjb250YWlucyAwIG9yIG5lZ2F0aXZlIHZhbHVlcyBpbiB0aGVtLicsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBzaXplICo9IGRpbXNbaV07XG4gICAgfVxuICAgIHJldHVybiBzaXplO1xuICB9XG5cbiAgc3RhdGljIGNvbXB1dGVTdHJpZGVzKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IHJhbmsgPSBkaW1zLmxlbmd0aDtcbiAgICBpZiAocmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH0gZWxzZSBpZiAocmFuayA9PT0gMSkge1xuICAgICAgcmV0dXJuIFsxXTtcbiAgICB9XG4gICAgY29uc3Qgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAxXSA9IDE7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBkaW1zW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBkaW1zW2kgKyAxXTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cmlkZXM7XG4gIH1cblxuICBzdGF0aWMgdHJhbnNwb3NlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IGNvcHkgPSBkaW1zLnNsaWNlKCk7XG4gICAgcmV0dXJuIGNvcHkucmV2ZXJzZSgpO1xuICB9XG5cbiAgc3RhdGljIGluZGljZXNUb09mZnNldChpbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM/OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGF4aXMgPSBpbmRpY2VzLmxlbmd0aDtcbiAgICB9XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBheGlzOyArK2kpIHtcbiAgICAgIG9mZnNldCArPSBzdHJpZGVzW2ldICogaW5kaWNlc1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBvZmZzZXRUb0luZGljZXMob2Zmc2V0OiBudW1iZXIsIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IHJhbmsgPSBzdHJpZGVzLmxlbmd0aDtcbiAgICBpZiAocmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH0gZWxzZSBpZiAocmFuayA9PT0gMSkge1xuICAgICAgcmV0dXJuIFtvZmZzZXQgKiBzdHJpZGVzWzBdXTtcbiAgICB9XG4gICAgY29uc3QgaW5kaWNlczogbnVtYmVyW10gPSBuZXcgQXJyYXkoc3RyaWRlcy5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGggLSAxOyArK2kpIHtcbiAgICAgIGluZGljZXNbaV0gPSBNYXRoLmZsb29yKG9mZnNldCAvIHN0cmlkZXNbaV0pO1xuICAgICAgb2Zmc2V0IC09IGluZGljZXNbaV0gKiBzdHJpZGVzW2ldO1xuICAgIH1cbiAgICBpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gPSBvZmZzZXQ7XG4gICAgcmV0dXJuIGluZGljZXM7XG4gIH1cblxuICAvKipcbiAgICogbm9ybWFpbHplIGF4aXMgb2YgcmFuZ2UgWy1yLCByKSBpbnRvIFswLCByKS5cbiAgICovXG4gIHN0YXRpYyBub3JtYWxpemVBeGlzKGF4aXM6IG51bWJlciwgdGVuc29yUmFuazogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoYXhpcyA8IC10ZW5zb3JSYW5rICYmIGF4aXMgPj0gdGVuc29yUmFuaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bnN1cHBvcnRlZCBheGlzIGZvciB0aGlzIG9wZXJhdGlvbi4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGF4aXMgPCAwID8gYXhpcyArIHRlbnNvclJhbmsgOiBheGlzO1xuICB9XG5cbiAgc3RhdGljIG5vcm1hbGl6ZUF4ZXMoYXhlczogcmVhZG9ubHkgbnVtYmVyW10sIHRlbnNvclJhbms6IG51bWJlcik6IG51bWJlcltdIHtcbiAgICByZXR1cm4gYXhlcy5tYXAoKHgpID0+IHRoaXMubm9ybWFsaXplQXhpcyh4LCB0ZW5zb3JSYW5rKSk7XG4gIH1cblxuICAvLyBJbmNyZW1lbnQgYW4gaW5kZXggaW50byBhIHRlbnNvciAoaW4gbGV4aWNvZ3JhcGhpY1xuICAvLyBvcmRlcmluZyksIHdyYXBwaW5nIGFyb3VuZCB0aGUgc3BlY2lmaWVkIHVwcGVyX2JvdW5kLlxuICAvKipcbiAgICogSW5jcmVtZW50IGFuIGluZGV4IGludG8gYSB0ZW5zb3IgKGluIGxleGljb2dyYXBoaWMgb3JkZXJpbmcpLCB3cmFwcGluZyBhcm91bmQgdGhlIHNwZWNpZmllZCB1cHBlcl9ib3VuZC5cbiAgICogQHBhcmFtIGluZGV4IEdpdmVuIGluZGV4IHRvIGluY3JlbWVudCAoV2lsbCBiZSBtdXRhdGVkKVxuICAgKiBAcGFyYW0gZGltcyBUaGUgZGltZW5zaW9ucyBvZiB0aGUgdGVuc29yIGZvciB3aGljaCB0aGUgZ2l2ZW4gaW5kZXggY29ycmVzcG9uZHMgdG9cbiAgICogQHBhcmFtIGF4aXNUb0luY3JlbWVudE9uIFRoZSAxLWluZGV4ZWQgYXhpcyB0byBpbmNyZW1lbnQgb24uIElmIHVuZGVmaW5lZCwgYXhpc1RvSW5jcmVtZW50T24gPT0gcmFua1xuICAgKi9cbiAgc3RhdGljIGluY3JlbWVudEluZGV4KGluZGV4OiBudW1iZXJbXSwgZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXNUb0luY3JlbWVudE9uPzogbnVtYmVyKSB7XG4gICAgaWYgKGRpbXMubGVuZ3RoID09PSAwIHx8IGluZGV4Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbmRleCBpbmNyZW1lbnRpbmcgdW5zdXBwb3J0ZWQgZm9yIHNjYWxhciBUZW5zb3InKTtcbiAgICB9XG4gICAgaWYgKGF4aXNUb0luY3JlbWVudE9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGF4aXNUb0luY3JlbWVudE9uID0gZGltcy5sZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChheGlzVG9JbmNyZW1lbnRPbiA8PSAwIHx8IGF4aXNUb0luY3JlbWVudE9uID4gZGltcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbmNvcnJlY3QgYXhpcyB0byBpbmNyZW1lbnQgb24nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGxldCBrID0gYXhpc1RvSW5jcmVtZW50T24gLSAxOyBrID49IDA7IC0taykge1xuICAgICAgaW5kZXhba10rKztcbiAgICAgIGlmIChpbmRleFtrXSA8IGRpbXNba10pIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpbmRleFtrXSA9IDA7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEgbmV3IGRpbWVuc2lvbnMgYXJyYXkgYmFzZWQgb24gdGhlIHZhbHVlcyBpbiB0aGUgJ29yaWdpbmFsRGltZW5zaW9ucycgYW5kICdzaGFwZScgYXJyYXlcbiAgICogVXNlZCBpbiBSZXNoYXBlXG4gICAqIEBwYXJhbSBvcmlnaW5hbERpbXMgT3JpZ2luYWwgU2hhcGUgYXJyYXlcbiAgICogQHBhcmFtIHNoYXBlSGludHMgYXJyYXkgY29udGFpbmluZyB2YWx1ZXMgdG8gY29tcHV0ZSB0aGUgbmV3IGRpbWVuc2lvbnNcbiAgICogRm9yIGV4YW1wbGU6XG4gICAqIG9yaWdpbmFsRGltcyA9IFsyLDJdIGFuZCBzaGFwZUhpbnRzID0gWzAsLTFdIHdpbGwgcmV0dXJuIFsyLDJdXG4gICAqIG9yaWdpbmFsRGltcyA9IFsyLDJdIGFuZCBzaGFwZUhpbnRzID0gWzRdIHdpbGwgcmV0dXJuIFs0XVxuICAgKiBvcmlnaW5hbERpbXMgPSBbMiwyXSBhbmQgc2hhcGVIaW50cyA9IFs1XSB3aWxsIHRocm93IGFuIGV4Y2VwdGlvblxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL09wZXJhdG9ycy5tZCNSZXNoYXBlXG4gICAqL1xuXG4gIHN0YXRpYyBjYWxjdWxhdGVSZXNoYXBlZERpbXMob3JpZ2luYWxEaW1zOiByZWFkb25seSBudW1iZXJbXSwgc2hhcGVIaW50czogQXJyYXlMaWtlPG51bWJlcj4pOiBudW1iZXJbXSB7XG4gICAgLy8gcmVzaGFwZSB0byBhIFNjYWxhciBUZW5zb3JcbiAgICBpZiAoc2hhcGVIaW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChvcmlnaW5hbERpbXMubGVuZ3RoID09PSAwIHx8IFNoYXBlVXRpbC5zaXplKG9yaWdpbmFsRGltcykgPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgcmVzaGFwZSB0byBhIHNjYWxhciBUZW5zb3InKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBuRGltcyA9IHNoYXBlSGludHMubGVuZ3RoO1xuICAgIGNvbnN0IHJlc2hhcGVkRGltcyA9IG5ldyBBcnJheTxudW1iZXI+KG5EaW1zKTtcbiAgICBsZXQgdW5rbm93bkRpbWVuc2lvbiA9IC0xO1xuICAgIGxldCBuZXdUZW5zb3JTaXplID0gMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5EaW1zOyBpKyspIHtcbiAgICAgIGlmIChzaGFwZUhpbnRzW2ldIDwgLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhIGRpbWVuc2lvbiBpbiBzaGFwZSBoaW50cyBjYW5ub3QgYmUgbGVzcyB0aGFuIC0xJyk7XG4gICAgICB9XG4gICAgICBpZiAoc2hhcGVIaW50c1tpXSA9PT0gLTEpIHtcbiAgICAgICAgaWYgKHVua25vd25EaW1lbnNpb24gIT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhdCBtb3N0IG9uZSBkaW1lbnNpb24gaW4gc2hhcGUgaGludHMgY2FuIGJlIC0xJyk7XG4gICAgICAgIH1cbiAgICAgICAgdW5rbm93bkRpbWVuc2lvbiA9IGk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoc2hhcGVIaW50c1tpXSA9PT0gMCkge1xuICAgICAgICAgIGlmIChpID49IG9yaWdpbmFsRGltcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIGRpbWVuc2lvbiB3aXRoIHZhbHVlIHplcm8gZXhjZWVkcyB0aGUgZGltZW5zaW9uIHNpemUgb2YgdGhlIGlucHV0IHRlbnNvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXNoYXBlZERpbXNbaV0gPSBvcmlnaW5hbERpbXNbaV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzaGFwZWREaW1zW2ldID0gc2hhcGVIaW50c1tpXTtcbiAgICAgICAgfVxuICAgICAgICBuZXdUZW5zb3JTaXplICo9IHJlc2hhcGVkRGltc1tpXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBvbGRUZW5zb3JTaXplID0gU2hhcGVVdGlsLnNpemUob3JpZ2luYWxEaW1zKTtcbiAgICBpZiAodW5rbm93bkRpbWVuc2lvbiAhPT0gLTEpIHtcbiAgICAgIGlmIChvbGRUZW5zb3JTaXplICUgbmV3VGVuc29yU2l6ZSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYHRoZSBpbnB1dCB0ZW5zb3IgY2Fubm90IGJlIHJlc2hhcGVkIHRvIHRoZSByZXF1ZXN0ZWQgc2hhcGUuIElucHV0IHNoYXBlOiBbJHtcbiAgICAgICAgICAgIG9yaWdpbmFsRGltc1xuICAgICAgICAgIH1dIE91dHB1dCBzaGFwZTogWyR7c2hhcGVIaW50c31dYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJlc2hhcGVkRGltc1t1bmtub3duRGltZW5zaW9uXSA9IG9sZFRlbnNvclNpemUgLyBuZXdUZW5zb3JTaXplO1xuICAgIH1cbiAgICAvLyB2YWxpZGF0ZSBzaXplcyBmcm9tIG9yaWdpbmFsRGltcyBhbmQgcmVzaGFwZWREaW1zIG1hdGNoXG4gICAgZWxzZSB7XG4gICAgICBpZiAobmV3VGVuc29yU2l6ZSAhPT0gb2xkVGVuc29yU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJyZXNoYXBlZERpbXMgYW5kIG9yaWdpbmFsRGltcyBkb24ndCBoYXZlIG1hdGNoaW5nIHNpemVzXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzaGFwZWREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIFNvcnRzIGEgZ2l2ZW4gYXJyYXkgYmFzZWQgb24gdGhlIGluZGljZXMgaW4gdGhlIFBlcm0gYXJyYXlcbiAgICogVXNlZCBpbiBUcmFuc3Bvc2VcbiAgICogQHBhcmFtIGEgQXJyYXkgdG8gYmUgc29ydGVkIHN1Y2ggYXMgZGltcyBvciBzdHJpZGVzXG4gICAqIEBwYXJhbSBwZXJtIFBlcm0gZ2l2ZW47IGlmIG51bGwgYSB3aWxsIGJlIHJldmVyc2VkXG4gICAqL1xuICBzdGF0aWMgc29ydEJhc2VkT25QZXJtKGE6IHJlYWRvbmx5IG51bWJlcltdLCBwZXJtPzogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgaWYgKHBlcm0pIHtcbiAgICAgIHJldHVybiBwZXJtLm1hcCgodikgPT4gYVt2XSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBhLnNsaWNlKCkucmV2ZXJzZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQYWRzIGEgZ2l2ZW4gc2hhcGUgYWNjb3JkaW5nIHRvIHRoZSBwYWRkaW5nIHZhbHVlc1xuICAgKiBAcGFyYW0gZGltcyBzaGFwZSBvZiB0aGUgVGVuc29yIHRvIGJlIHBhZGRlZFxuICAgKiBAcGFyYW0gcGFkIHBhZCB2YWx1ZXNcbiAgICovXG4gIHN0YXRpYyBwYWRTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgcGFkOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gZGltcy5sZW5ndGg7XG4gICAgcmV0dXJuIGRpbXMubWFwKCh2LCBpKSA9PiB2ICsgcGFkW2ldICsgcGFkW2kgKyByYW5rXSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBpZiB0aGUgdHdvIHNoYXBlcyBhcmUgaWRlbnRpY2FsXG4gICAqIEBwYXJhbSBzaGFwZTFcbiAgICogQHBhcmFtIHNoYXBlMlxuICAgKi9cbiAgc3RhdGljIGFyZUVxdWFsKHNoYXBlMTogcmVhZG9ubHkgbnVtYmVyW10sIHNoYXBlMjogcmVhZG9ubHkgbnVtYmVyW10pOiBib29sZWFuIHtcbiAgICBpZiAoc2hhcGUxLmxlbmd0aCAhPT0gc2hhcGUyLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gc2hhcGUxLmV2ZXJ5KCh2LCBpKSA9PiB2ID09PSBzaGFwZTJbaV0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBpZiB0aGUgZ2l2ZW4gYGRpbXNgIG9yIGBzaGFwZWAgaXMgdmFsaWQgaW4gT05OWC5qcyBjb250ZXh0IGFuZCByZXR1cm5zIGRhdGEgc2l6ZVxuICAgKiBAcGFyYW0gZGltcyAtIGlucHV0IGBkaW1zYCB0aGF0IG5lZWRzIHRvIGJlIGNoZWNrZWRcbiAgICovXG4gIHN0YXRpYyB2YWxpZGF0ZURpbXNBbmRDYWxjU2l6ZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgaWYgKGRpbXMubGVuZ3RoID4gNikge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignT25seSByYW5rIDAgdG8gNiBpcyBzdXBwb3J0ZWQgZm9yIHRlbnNvciBzaGFwZS4nKTtcbiAgICB9XG4gICAgbGV0IHNpemUgPSAxO1xuICAgIGZvciAoY29uc3QgbiBvZiBkaW1zKSB7XG4gICAgICBpZiAoIU51bWJlci5pc0ludGVnZXIobikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBzaGFwZTogJHtufSBpcyBub3QgYW4gaW50ZWdlcmApO1xuICAgICAgfVxuICAgICAgaWYgKG4gPCAwIHx8IG4gPiAyMTQ3NDgzNjQ3KSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgc2hhcGU6IGxlbmd0aCAke259IGlzIG5vdCBhbGxvd2VkYCk7XG4gICAgICB9XG4gICAgICBzaXplICo9IG47XG4gICAgfVxuICAgIHJldHVybiBzaXplO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgdGhlIHNoYXBlIG9mIG91dHB1dCB0ZW5zb3IgeSA9IGZsYXR0ZW4oeCwgYXhpcylcbiAgICogQHBhcmFtIGRpbXMgLSBzaGFwZSBvZiBpbnB1dCB0ZW5zb3JcbiAgICogQHBhcmFtIGF4aXMgLSBmbGF0dGVuIGF4aXMsIGluIHRoZSByYW5nZSBbLXIsIHJdXG4gICAqL1xuICBzdGF0aWMgZmxhdHRlblNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzOiBudW1iZXIpOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgaWYgKGF4aXMgPCAwKSB7XG4gICAgICBheGlzICs9IGRpbXMubGVuZ3RoO1xuICAgIH1cbiAgICBjb25zdCB0b3RhbCA9IGRpbXMucmVkdWNlKCh4LCB5KSA9PiB4ICogeSwgMSk7XG4gICAgY29uc3QgcmlnaHQgPSBkaW1zLnNsaWNlKGF4aXMpLnJlZHVjZSgoeCwgeSkgPT4geCAqIHksIDEpO1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBbdG90YWwgLyByaWdodCwgcmlnaHRdO1xuXG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyB0aGUgc2hhcGUgb2Ygb3V0cHV0IHRlbnNvciB5ID0gc3F1ZWV6ZSh4LCBheGVzKVxuICAgKiBAcGFyYW0gZGltcyAtIHNoYXBlIG9mIGlucHV0IHRlbnNvclxuICAgKiBAcGFyYW0gYXhlcyAtIHNxdWVlemUgYXhlc1xuICAgKi9cbiAgc3RhdGljIHNxdWVlemVTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhlczogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cbiAgICAvLyBzYW5pdHkgY2hlY2tcbiAgICBheGVzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4ZXMoYXhlcywgZGltcy5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpblNxdWVlemVMaXN0ID0gYXhlcy5pbmRleE9mKGkpID49IDA7XG4gICAgICBpZiAoaW5TcXVlZXplTGlzdCAmJiBkaW1zW2ldICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignc3F1ZWV6ZSBhbiBheGlzIG9mIHNpemUgZGlmZmVyZW50IHRoYW4gMScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoKGF4ZXMubGVuZ3RoID09PSAwICYmIGRpbXNbaV0gPiAxKSB8fCAoYXhlcy5sZW5ndGggPiAwICYmICFpblNxdWVlemVMaXN0KSkge1xuICAgICAgICBvdXRwdXREaW1zLnB1c2goZGltc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyB0aGUgc2hhcGUgb2Ygb3V0cHV0IHRlbnNvciB5ID0gdW5zcXVlZXplKHgsIGF4ZXMpXG4gICAqIEBwYXJhbSBkaW1zIC0gc2hhcGUgb2YgaW5wdXQgdGVuc29yXG4gICAqIEBwYXJhbSBheGVzIC0gdW5zcXVlZXplIGF4ZXNcbiAgICovXG4gIHN0YXRpYyB1bnNxdWVlemVTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhlczogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IG5ldyBBcnJheTxudW1iZXI+KGRpbXMubGVuZ3RoICsgYXhlcy5sZW5ndGgpO1xuXG4gICAgLy8gaW5pdGlhbGl6ZSB0aGUgYXJyYXkgZWxlbWVudHMgdG8gMFxuICAgIG91dHB1dERpbXMuZmlsbCgwKTtcblxuICAgIC8vIHNldCBhbGwgYXhlcyBpbmRpY2VzIHRvIDEgaW4gb3V0cHV0RGltcyBhbmQgY2hlY2sgZm9yIGR1cGxpY2F0ZXNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF4ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhheGVzW2ldLCBvdXRwdXREaW1zLmxlbmd0aCk7XG4gICAgICBpZiAoYXhpcyA+PSBvdXRwdXREaW1zLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCInYXhlcycgaGFzIGFuIG91dCBvZiByYW5nZSBheGlzXCIpO1xuICAgICAgfVxuICAgICAgaWYgKG91dHB1dERpbXNbYXhpc10gIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiJ2F4ZXMnIGhhcyBhIGR1cGxpY2F0ZSBheGlzXCIpO1xuICAgICAgfVxuXG4gICAgICBvdXRwdXREaW1zW2F4aXNdID0gMTtcbiAgICB9XG5cbiAgICAvLyBmaWxsIGluIHRoZSB6ZXJvIGVudHJpZXMgb2Ygb3V0cHV0RGltcyB3aXRoIHRoZSBpbnB1dCB0ZW5zb3IncyBzaGFwZVxuICAgIGxldCBpbnB1dERpbXNJdGVyYXRvciA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXREaW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAob3V0cHV0RGltc1tpXSA9PT0gMCkge1xuICAgICAgICBvdXRwdXREaW1zW2ldID0gZGltc1tpbnB1dERpbXNJdGVyYXRvcisrXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzYW5pdHkgY2hlY2sgYXNzZXJ0aW9uLiAnaW5wdXREaW1zSXRlcmF0b3InXG4gICAgLy8gc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSBsZW5ndGggb2YgJ2RpbXMnXG4gICAgaWYgKGlucHV0RGltc0l0ZXJhdG9yICE9PSBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgdW5zcXVlZXplZCBkaW1lbnNpb24gY291bGQgbm90IGJlIGVzdGFibGlzaGVkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cbn1cblxuLy8gYnVuY2ggb2YgaGVscGVyIG1ldGhvZHMgdGhhdCBkbyBhIHZhcmlldHkgb2YgbWF0aCBvcGVyYXRpb25zXG5leHBvcnQgY2xhc3MgTWF0aFV0aWwge1xuICAvLyB5ID0gKHgqeCkgKyB5XG4gIHN0YXRpYyBzcXIoXG4gICAgdGFyZ2V0OiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHNvdXJjZTogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICB0YXJnZXRJbmRleDogbnVtYmVyLFxuICAgIHNvdXJjZUluZGV4OiBudW1iZXIsXG4gICAgYmxvY2tTaXplOiBudW1iZXIsXG4gICkge1xuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdICs9IE1hdGgucG93KHNvdXJjZVtzb3VyY2VJbmRleCArIG9mZnNldF0sIDIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHkgPSBheCArIHlcbiAgc3RhdGljIGF4cHkoXG4gICAgdGFyZ2V0OiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHNvdXJjZTogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICB0YXJnZXRJbmRleDogbnVtYmVyLFxuICAgIHNvdXJjZUluZGV4OiBudW1iZXIsXG4gICAgYmxvY2tTaXplOiBudW1iZXIsXG4gICAgYWxwaGE6IG51bWJlcixcbiAgKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gKz0gYWxwaGEgKiBzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdO1xuICAgIH1cbiAgfVxuXG4gIC8vIHkgPSBwb3coeCwgYilcbiAgc3RhdGljIHBvd3goXG4gICAgdGFyZ2V0OiBudW1iZXJbXSB8IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIHNvdXJjZTogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICB0YXJnZXRJbmRleDogbnVtYmVyLFxuICAgIHNvdXJjZUluZGV4OiBudW1iZXIsXG4gICAgYmxvY2tTaXplOiBudW1iZXIsXG4gICAgYjogbnVtYmVyLFxuICApIHtcbiAgICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlSW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0SW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBpbmRpY2VzIHRvIGJlIGNvcGllZCBhcmUgb3V0c2lkZSBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXQgYXJyYXkgaXMgdG9vIHNtYWxsIHRvIGhvbGQgcmVzdWx0Jyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgICAgdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSA9IE1hdGgucG93KHNvdXJjZVtzb3VyY2VJbmRleCArIG9mZnNldF0sIGIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHkgPSB4ICogeVxuICBzdGF0aWMgbXVsKFxuICAgIHRhcmdldDogbnVtYmVyW10gfCBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICBzb3VyY2U6IG51bWJlcltdIHwgVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGFyZ2V0SW5kZXg6IG51bWJlcixcbiAgICBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyLFxuICApIHtcbiAgICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlSW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0SW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBpbmRpY2VzIHRvIGJlIGNvcGllZCBhcmUgb3V0c2lkZSBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXQgYXJyYXkgaXMgdG9vIHNtYWxsIHRvIGhvbGQgcmVzdWx0Jyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgICAgdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSA9IHNvdXJjZVtzb3VyY2VJbmRleCArIG9mZnNldF0gKiB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU3BsaXRVdGlsIHtcbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgbmV3IFNoYXBlcyBmcm9tIGV4aXN0aW5nIG9uZSBhbmQgdGhlIHNwbGl0cyBnaXZlbiBhbG9uZyB0aGUgYXhpcyBwcm92aWRlc1xuICAgKiBAcGFyYW0gZGltcyBTaGFwZSBvZiB0aGUgVGVuc29yIHRvIGJlIHNwbGl0dGVkIGludG8gdHdvIG9yIG1vcmUgU2hhcGVzXG4gICAqIEBwYXJhbSBheGlzIFRoZSBkaW1lbnNpb24gYWxvbmcgd2hpY2ggdGhlIFRlbnNvciB3aWxsIGJlIHNwbGl0XG4gICAqIEBwYXJhbSBzcGxpdHMgT2Zmc2V0cyBmb3IgdGhlIHN0YXJ0IG9mIGVhY2ggc3BsaXRcbiAgICovXG4gIHN0YXRpYyBzcGxpdFNoYXBlKFxuICAgIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGF4aXM6IG51bWJlcixcbiAgICBzcGxpdDogbnVtYmVyW10sXG4gICAgbnVtT3V0cHV0cz86IG51bWJlcixcbiAgKTogW251bWJlcltdW10sIG51bWJlcltdXSB7XG4gICAgaWYgKHNwbGl0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKCFudW1PdXRwdXRzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5lZWQgdG8ga25vdyBudW1iZXIgb2Ygb3V0cHV0cyB3aGVuIHRoZSAnc3BsaXQnIGF0dHJpYnV0ZSBpcyBub3Qgc3BlY2lmaWVkXCIpO1xuICAgICAgfVxuICAgICAgU3BsaXRVdGlsLmRldGVybWluZVNwbGl0KGRpbXNbYXhpc10sIG51bU91dHB1dHMsIHNwbGl0KTtcbiAgICB9XG5cbiAgICBjb25zdCBzaGFwZXM6IG51bWJlcltdW10gPSBbXTtcbiAgICBjb25zdCBvZmZzZXRzID0gWzBdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3BsaXQubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChpICE9PSAwKSB7XG4gICAgICAgIG9mZnNldHMucHVzaChvZmZzZXRzW2kgLSAxXSArIHNwbGl0W2kgLSAxXSk7XG4gICAgICB9XG4gICAgICBjb25zdCBzaGFwZSA9IGRpbXMuc2xpY2UoKTtcbiAgICAgIHNoYXBlW2F4aXNdID0gc3BsaXRbaV07XG4gICAgICBzaGFwZXMucHVzaChzaGFwZSk7XG4gICAgfVxuICAgIHJldHVybiBbc2hhcGVzLCBvZmZzZXRzXTtcbiAgfVxuXG4gIHN0YXRpYyBkZXRlcm1pbmVTcGxpdChudW1FbGVtZW50c0Fsb25nQXhpczogbnVtYmVyLCBudW1PdXRwdXRzOiBudW1iZXIsIHNwbGl0OiBudW1iZXJbXSkge1xuICAgIC8vIElmICdzcGxpdCcgaXMgbm90IHNwZWNpZmllZCBieSB0aGUgdXNlciwgd2UgbmVlZCB0byBwYXJ0aXRpb24gdGhlIG51bWJlciBvZiBlbGVtZW50cyBlcXVhbGx5IGFtb25nIHRoZSBvdXRwdXRzXG4gICAgaWYgKG51bUVsZW1lbnRzQWxvbmdBeGlzICUgbnVtT3V0cHV0cyAhPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3Qgc3BsaXQgdGVuc29yIHRvIGVxdWFsIHNpemVkIHBhcnRzJyk7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtT3V0cHV0czsgKytpKSB7XG4gICAgICBzcGxpdC5wdXNoKG51bUVsZW1lbnRzQWxvbmdBeGlzIC8gbnVtT3V0cHV0cyk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBSZWR1Y2VVdGlsIHtcbiAgLyoqXG4gICAqIFBlcmZvcm0gcmVkdWNlIG9wZXJhdGlvbnMgb24gdGhlIHNwZWNpZmljIG9wZXJhdG9yXG4gICAqIEBwYXJhbSBhIElucHV0IHRlbnNvciBkYXRhXG4gICAqIEBwYXJhbSBheGVzIFRoZSBkaW1lbnNpb25zIGFsb25nIHdoaWNoIHRoZSBUZW5zb3Igd2lsbCBiZSByZWR1Y2VkXG4gICAqIEBwYXJhbSBrZWVwZGltcyBJZiBzZXQgdG8gdHJ1ZSwgdGhlIGF4ZXMgd2hpY2ggYXJlIHJlZHVjZWQgYXJlIGxlZnQgaW4gdGhlXG4gICAqICAgIHJlc3VsdCBhcyBkaW1lbnNpb25zIHdpdGggc2l6ZSBvbmUuXG4gICAqIEBwYXJhbSBvcDEgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgb24gZWFjaCBlbGVtZW50IGluIHRoZSB0ZW5zb3JcbiAgICogQHBhcmFtIG9wMiBUaGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZCBiZXR3ZWVuIGVsZW1lbnRzIGluIHRoZSB0ZW5zb3JcbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlKFxuICAgIGE6IFRlbnNvcixcbiAgICBheGVzOiBudW1iZXJbXSxcbiAgICBrZWVwZGltczogYm9vbGVhbixcbiAgICBvcDE6IChiOiBudW1iZXIpID0+IG51bWJlcixcbiAgICBvcDI6IChhOiBudW1iZXIsIGI6IG51bWJlcikgPT4gbnVtYmVyLFxuICApOiBUZW5zb3Ige1xuICAgIGNvbnN0IGRpbXMgPSBhLmRpbXMuc2xpY2UoMCk7XG4gICAgLy8gaWYgYXhlcyBpcyBub3Qgc2V0LCBwZXJmb3JtIHJlZHVjZSBvbiBhbGwgYXhlc1xuICAgIGlmIChheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZGltcy5mb3JFYWNoKChfZCwgaW5kKSA9PiBheGVzLnB1c2goaW5kKSk7XG4gICAgfVxuICAgIC8vIGdldCBhIHRlbXBvcmFyeSBicm9hZGNhc3RhYmxlIG91dHB1dCBzaGFwZVxuICAgIGNvbnN0IG91dHB1dERpbXMgPSBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VTaGFwZShkaW1zLCBheGVzLCB0cnVlKTtcblxuICAgIC8vIGxvb3AgdGhyb3VnaCB0aGUgb3V0cHV0IGFuZCBjYWxjdWxhdGUgcmVzdWx0IG9uZSBieSBvbmVcbiAgICBjb25zdCBzaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0RGltcyk7XG4gICAgY29uc3QgeSA9IG5ldyBUZW5zb3Iob3V0cHV0RGltcywgYS50eXBlKTtcbiAgICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKG91dHB1dERpbXMpO1xuICAgIGNvbnN0IGlucHV0U3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhkaW1zKTtcbiAgICBjb25zdCBpbmRpY2VzWSA9IG5ldyBBcnJheShkaW1zLmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGljZXMgPSBTaGFwZVV0aWwub2Zmc2V0VG9JbmRpY2VzKGksIHN0cmlkZXMpO1xuICAgICAgLy8gbWFwIGluZGV4XG4gICAgICBCcm9hZGNhc3RVdGlsLmZpbGxJbmRleChpbmRpY2VzLCBkaW1zLCBpbmRpY2VzWSk7XG4gICAgICB5LnNldChcbiAgICAgICAgaW5kaWNlcyxcbiAgICAgICAgUmVkdWNlVXRpbC5jYWxjUmVkdWNlQnlBeGlzKFxuICAgICAgICAgIGEubnVtYmVyRGF0YSxcbiAgICAgICAgICBheGVzLFxuICAgICAgICAgIGRpbXMsXG4gICAgICAgICAgMCxcbiAgICAgICAgICBTaGFwZVV0aWwuaW5kaWNlc1RvT2Zmc2V0KGluZGljZXNZLCBpbnB1dFN0cmlkZXMpLFxuICAgICAgICAgIG9wMSxcbiAgICAgICAgICBvcDIsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChrZWVwZGltcykge1xuICAgICAgcmV0dXJuIHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGtlZXBkaW1zID09IDAsIGNhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgc2hhcGVcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKFxuICAgICAgICBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VTaGFwZShkaW1zLCBheGVzLCBrZWVwZGltcyksXG4gICAgICAgIHkudHlwZSxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHkuZGF0YSxcbiAgICAgICAgeS5kYXRhSWQsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIHJlZHVjZSBvcGVyYXRpb25zIG9uIHRoZSBzcGVjaWZpYyBvcGVyYXRvciBvbiBzcGVjaWZpYyBheGVzXG4gICAqIEBwYXJhbSBhIElucHV0IHRlbnNvciBkYXRhXG4gICAqIEBwYXJhbSBheGVzIFRoZSBkaW1lbnNpb25zIGFsb25nIHdoaWNoIHRoZSBUZW5zb3Igd2lsbCBiZSByZWR1Y2VkXG4gICAqIEBwYXJhbSBkaW1zIFRoZSBpbnB1dCBkaW1lbnNpb24uXG4gICAqIEBwYXJhbSBjdXJBeGlzSW5kIEluZGV4IGluIGF4ZXMgc3BlY2lmeWluZyB0aGUgY3VycmVudCBkaW1lbnNpb24gYWxvbmdcbiAgICogICAgICB3aGljaCB0aGUgdGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0gcG9zIFRoZSBjdXJyZW50IGluZGV4IG9mIGVsZW1lbnQgdG8gcGVyZm9ybSBvcGVyYXRpb25cbiAgICogQHBhcmFtIG9wMSBUaGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZCBvbiBlYWNoIGVsZW1lbnQgaW4gdGhlIHRlbnNvclxuICAgKiBAcGFyYW0gb3AyIFRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkIGJldHdlZW4gZWxlbWVudHMgaW4gdGhlIHRlbnNvclxuICAgKi9cbiAgc3RhdGljIGNhbGNSZWR1Y2VCeUF4aXMoXG4gICAgaW5wdXQ6IFRlbnNvci5OdW1iZXJUeXBlLFxuICAgIGF4ZXM6IG51bWJlcltdLFxuICAgIGRpbXM6IG51bWJlcltdLFxuICAgIGN1ckF4aXNJbmQ6IG51bWJlcixcbiAgICBwb3M6IG51bWJlcixcbiAgICBvcDE6IChiOiBudW1iZXIpID0+IG51bWJlcixcbiAgICBvcDI6IChhOiBudW1iZXIsIGI6IG51bWJlcikgPT4gbnVtYmVyLFxuICApOiBudW1iZXIge1xuICAgIGxldCByZXMgPSAwO1xuICAgIGlmIChjdXJBeGlzSW5kID49IGF4ZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gb3AxKGlucHV0W3Bvc10pO1xuICAgIH1cbiAgICBjb25zdCBheGlzID0gYXhlc1tjdXJBeGlzSW5kXTtcbiAgICBjb25zdCBzdGVwID0gYXhpcyA+PSBkaW1zLmxlbmd0aCA/IDEgOiBTaGFwZVV0aWwuc2l6ZShkaW1zLnNsaWNlKGF4aXMgKyAxKSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1zW2F4aXNdOyBpKyspIHtcbiAgICAgIHJlcyA9XG4gICAgICAgIGkgPT09IDBcbiAgICAgICAgICA/IFJlZHVjZVV0aWwuY2FsY1JlZHVjZUJ5QXhpcyhpbnB1dCwgYXhlcywgZGltcywgY3VyQXhpc0luZCArIDEsIHBvcywgb3AxLCBvcDIpXG4gICAgICAgICAgOiBvcDIocmVzLCBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VCeUF4aXMoaW5wdXQsIGF4ZXMsIGRpbXMsIGN1ckF4aXNJbmQgKyAxLCBwb3MsIG9wMSwgb3AyKSk7XG4gICAgICBwb3MgKz0gc3RlcDtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlIG9mIGEgcmVkdWNlIG9wZXJhdGlvblxuICAgKiBAcGFyYW0gZGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvblxuICAgKiBAcGFyYW0gYXhlcyBUaGUgZGltZW5zaW9ucyBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0ga2VlcGRpbXMgSWYgc2V0IHRvIHRydWUsIHRoZSBheGVzIHdoaWNoIGFyZSByZWR1Y2VkIGFyZSBsZWZ0IGluIHRoZVxuICAgKiAgICByZXN1bHQgYXMgZGltZW5zaW9ucyB3aXRoIHNpemUgb25lLlxuICAgKi9cbiAgc3RhdGljIGNhbGNSZWR1Y2VTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhlczogcmVhZG9ubHkgbnVtYmVyW10sIGtlZXBEaW1zOiBib29sZWFuKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBkaW1zLnNsaWNlKCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBheGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoa2VlcERpbXMpIHtcbiAgICAgICAgb3V0cHV0RGltc1theGVzW2ldXSA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXREaW1zW2F4ZXNbaV1dID0gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dERpbXMuZmlsdGVyKChkaW0pID0+IGRpbSAhPT0gMCk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBvb2xDb252VXRpbCB7XG4gIC8qKlxuICAgKiBBZGp1c3QgdGhlIGtlcm5lbCwgc3RyaWRlcywgcGFkcyB0byBjb3JyZWN0IHJhbmsuIFNldCB0byBkZWZhdWx0IHZhbHVlIGlmIG5vdCBwcmVzZW50XG4gICAqIEBwYXJhbSBpc0dsb2JhbE9wZXJhdG9yIElmIHRydWUsIHBlcmZvcm0gZ2xvYmFsIHBvb2xpbmcuXG4gICAqIEBwYXJhbSBpbnB1dERpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb24uXG4gICAqIEBwYXJhbSBrZXJuZWxTaGFwZSBUaGUgc2l6ZSBvZiB0aGUga2VybmVsIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIHN0cmlkZXMgU3RyaWRlIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGRpbGF0aW9ucyBEaWxhdGlvbiBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqL1xuICBzdGF0aWMgYWRqdXN0UG9vbEF0dHJpYnV0ZXMoXG4gICAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICApIHtcbiAgICBpZiAoIWlzR2xvYmFsT3BlcmF0b3IgJiYga2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dERpbXMubGVuZ3RoIC0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Ygc3BlY2lmaWVkIGtlcm5lbCBzaGFwZXMgc2hvdWxkIGJlIDIgbGVzcyB0aGFuIGxlbmd0aCBvZiBpbnB1dCBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKGlzR2xvYmFsT3BlcmF0b3IpIHtcbiAgICAgIC8vIGFkanVzdCBrZXJuZWwgc2hhcGUgdG8gY292ZXIgdGhlIGlucHV0IGRpbXNcbiAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGlucHV0RGltcy5sZW5ndGggLSAyOyBkaW0rKykge1xuICAgICAgICBpZiAoZGltID49IGtlcm5lbFNoYXBlLmxlbmd0aCkge1xuICAgICAgICAgIGtlcm5lbFNoYXBlLnB1c2goaW5wdXREaW1zW2RpbSArIDJdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBrZXJuZWxTaGFwZVtkaW1dID0gaW5wdXREaW1zW2RpbSArIDJdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRqdXN0IHN0cmlkZXMgbGVuZ3RoIHRvIG1hdGNoIGtlcm5lbCBzaGFwZSBsZW5ndGhcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGg7IGRpbSsrKSB7XG4gICAgICBpZiAoZGltIDwgc3RyaWRlcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHN0cmlkZXNbZGltXSA8IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmlkZXMgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cmlkZXMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGp1c3QgZGlsYXRpb24gdmFsdWVcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGg7IGRpbSsrKSB7XG4gICAgICBpZiAoZGltIDwgZGlsYXRpb25zLmxlbmd0aCkge1xuICAgICAgICBpZiAoZGlsYXRpb25zW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkaWxhdGlvbnMgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpbGF0aW9ucy5wdXNoKDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkanVzdCBwYWRzIGxlbmd0aCB0byBtYXRjaCAyICoga2VybmVsIHNoYXBlIGxlbmd0aFxuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aCAqIDI7IGRpbSsrKSB7XG4gICAgICBpZiAoZGltIDwgcGFkcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHBhZHNbZGltXSA8IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhZCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFkcy5wdXNoKDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNhbml0eSBjaGVja3MgZm9yIHZhbHVlcyBpbiBrZXJuZWwgc2hhcGVzIGFuZCBwYWRzXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGtlcm5lbFNoYXBlW2RpbV0gPD0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2tlcm5lbCBzaGFwZXMgbmVlZCB0byBiZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFkc1tkaW1dID49IGtlcm5lbFNoYXBlW2RpbV0gfHwgcGFkc1tkaW0gKyBrZXJuZWxTaGFwZS5sZW5ndGhdID49IGtlcm5lbFNoYXBlW2RpbV0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYWRzIHNob3VsZCBiZSBzbWFsbGVyIHRoYW4ga2VybmVsJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gYWRqdXN0IHBhZCB2YWx1ZXMgYmFzZWQgb24gJ2F1dG9QYWQnIGF0dHJpYnV0ZVxuICBzdGF0aWMgYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKSB7XG4gICAgaWYgKCFhdXRvUGFkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHBhZHMubGVuZ3RoICE9PSAyICogKGlucHV0RGltcy5sZW5ndGggLSAyKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2YgcGFkcyBzaG91bGQgYmUgdHdpY2UgdGhlIGxlbmd0aCBvZiBkYXRhIGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAoc3RyaWRlcy5sZW5ndGggIT09IGlucHV0RGltcy5sZW5ndGggLSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBzdHJpZGVzIHNob3VsZCBiZSB0aGUgbGVuZ3RoIG9mIGRhdGEgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChrZXJuZWxTaGFwZS5sZW5ndGggIT09IGlucHV0RGltcy5sZW5ndGggLSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBrZXJuZWwgc2hhcGVzIHNob3VsZCBiZSB0aGUgbGVuZ3RoIG9mIGRhdGEgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGlucHV0RGltcy5sZW5ndGggLSAyOyBkaW0rKykge1xuICAgICAgUG9vbENvbnZVdGlsLmFkanVzdFBhZEFuZFJldHVyblNoYXBlKFxuICAgICAgICBpbnB1dERpbXNbZGltICsgMl0sXG4gICAgICAgIHN0cmlkZXNbZGltXSxcbiAgICAgICAgZGlsYXRpb25zW2RpbV0sXG4gICAgICAgIGtlcm5lbFNoYXBlW2RpbV0sXG4gICAgICAgIHBhZHMsXG4gICAgICAgIGRpbSxcbiAgICAgICAgZGltICsgaW5wdXREaW1zLmxlbmd0aCAtIDIsXG4gICAgICAgIGF1dG9QYWQsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIG91dHB1dCBzaGFwZSBmb3IgUG9vbCBvcHMgYmFzZWQgb24gaW5wdXQgYXR0cmlidXRlcy4gKFNob3VsZCBiZSB1c2VkIG9ubHkgZm9yIFBvb2wgb3BzKVxuICAgKiBAcGFyYW0gaXNHbG9iYWxPcGVyYXRvciBJZiB0cnVlLCBwZXJmb3JtIGdsb2JhbCBwb29saW5nLlxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzBdLmRpbXMpXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBkaWxhdGlvbnMgRGlsYXRpb24gYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBhdXRvUGFkIERFUFJFQ0FURUQgYXR0cmlidXRlIHN1cHBvcnRlZCBmb3IgbGVnYWN5IG1vZGVscy4gU3BlY2lmaWVzIGhvdyB0byBpbXBsaWNpdGx5IGNhbGN1bGF0ZSBwYWRzIGluIGVhY2hcbiAgICogICAgIGRpbWVuc2lvbi4gQ2FuIHRha2UgdmFsdWVzIE5PVFNFVCwgU0FNRV9VUFBFUiwgU0FNRV9MT1dFUiwgb3IgVkFMSUQuXG4gICAqL1xuICBzdGF0aWMgY29tcHV0ZVBvb2xPdXRwdXRTaGFwZShcbiAgICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgc3RyaWRlczogbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKTogbnVtYmVyW10ge1xuICAgIGlmIChpbnB1dERpbXMubGVuZ3RoIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hhcGUgbXVzdCBiZSBvZiBzaXplIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJhdGNoIHNpemUgYW5kIG51bWJlciBvZiBjaGFubmVscyBvZiBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW2lucHV0RGltc1swXSwgaW5wdXREaW1zWzFdXTtcblxuICAgIFBvb2xDb252VXRpbC5jb21wdXRlU2hhcGVIZWxwZXIoXG4gICAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICAgICAgaW5wdXREaW1zLFxuICAgICAgb3V0cHV0RGltcyxcbiAgICAgIHN0cmlkZXMsXG4gICAgICBkaWxhdGlvbnMsXG4gICAgICBrZXJuZWxTaGFwZSxcbiAgICAgIHBhZHMsXG4gICAgICBhdXRvUGFkLFxuICAgICk7XG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBvdXRwdXQgc2hhcGUgZm9yIENvbnYgb3AgYmFzZWQgb24gaW5wdXQgYXR0cmlidXRlcy4gKFNob3VsZCBiZSB1c2VkIG9ubHkgZm9yIENvbnYgb3ApXG4gICAqIEBwYXJhbSBpbnB1dERpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb24uIChpbnB1dHNbMF0uZGltcylcbiAgICogQHBhcmFtIGZpbHRlckRpbXMgVGhlIGZpbHRlciB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzFdLmRpbXMpXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBrZXJuZWxTaGFwZSBUaGUgc2l6ZSBvZiB0aGUga2VybmVsIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIHBhZHMgUGFkZGluZyBmb3IgdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGF1dG9QYWQgREVQUkVDQVRFRCBhdHRyaWJ1dGUgc3VwcG9ydGVkIGZvciBsZWdhY3kgbW9kZWxzLiBTcGVjaWZpZXMgaG93IHRvIGltcGxpY2l0bHkgY2FsY3VsYXRlIHBhZHMgaW4gZWFjaFxuICAgKiAgICAgZGltZW5zaW9uLiBDYW4gdGFrZSB2YWx1ZXMgTk9UU0VULCBTQU1FX1VQUEVSLCBTQU1FX0xPV0VSLCBvciBWQUxJRC5cbiAgICovXG4gIHN0YXRpYyBjb21wdXRlQ29udk91dHB1dFNoYXBlKFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZmlsdGVyRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgc3RyaWRlczogbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKTogbnVtYmVyW10ge1xuICAgIGlmIChpbnB1dERpbXMubGVuZ3RoIDw9IDAgfHwgZmlsdGVyRGltcy5sZW5ndGggPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciBkaW1zIG9yIGludmFsaWQgZmlsdGVyIHRlbnNvciBkaW1zJyk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJhdGNoIHNpemUgYW5kIG51bWJlciBvZiBjaGFubmVscyBvZiBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW2lucHV0RGltc1swXSwgZmlsdGVyRGltc1swXV07XG5cbiAgICBQb29sQ29udlV0aWwuY29tcHV0ZVNoYXBlSGVscGVyKGZhbHNlLCBpbnB1dERpbXMsIG91dHB1dERpbXMsIHN0cmlkZXMsIGRpbGF0aW9ucywga2VybmVsU2hhcGUsIHBhZHMsIGF1dG9QYWQpO1xuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLy8gd2lsbCBjb21wdXRlIG91dHB1dCBzaGFwZXMgZm9yIGRhdGEgZGltZW5zaW9ucyBPTkxZIChpLmUuKSBubyBiYXRjaCBzaXplIGFuZCBjaGFubmVsc1xuICAvLyBjYWxsZWQgYnkgY29tcHV0ZVBvb2xPdXRwdXRTaGFwZSgpIGFuZCBjb21wdXRlQ29udk91dHB1dFNoYXBlKClcbiAgLy8gYWRqdXN0IHBhZHMgYmFzZWQgb24gJ2F1dG9QYWQnIGF0dHJpYnV0ZSBwcmlvciB0byBzaGFwZSBjb21wdXRhdGlvblxuICBwcml2YXRlIHN0YXRpYyBjb21wdXRlU2hhcGVIZWxwZXIoXG4gICAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIG91dHB1dERpbXM6IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICkge1xuICAgIGlmIChpc0dsb2JhbE9wZXJhdG9yKSB7XG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKDEpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKFxuICAgICAgICAgIFBvb2xDb252VXRpbC5hZGp1c3RQYWRBbmRSZXR1cm5TaGFwZShcbiAgICAgICAgICAgIGlucHV0RGltc1tkaW0gKyAyXSxcbiAgICAgICAgICAgIHN0cmlkZXNbZGltXSxcbiAgICAgICAgICAgIGRpbGF0aW9uc1tkaW1dLFxuICAgICAgICAgICAga2VybmVsU2hhcGVbZGltXSxcbiAgICAgICAgICAgIHBhZHMsXG4gICAgICAgICAgICBkaW0sXG4gICAgICAgICAgICBkaW0gKyBpbnB1dERpbXMubGVuZ3RoIC0gMixcbiAgICAgICAgICAgIGF1dG9QYWQsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBoZWxwZXIgZm9yIGNvbXB1dGVTaGFwZUhlbHBlcigpIGFuZCBhZGp1c3RQYWRzQmFzZWRPbkF1dG9QYWQoKVxuICAvLyBhZGp1c3RzIHBhZCB2YWx1ZSBmb3IgZ2l2ZW4gJ2F1dG9QYWQnIHN0cmluZyBhbmQgY29tcHV0ZXMgb3V0cHV0IHNoYXBlIGFsb25nIGEgcGFydGljdWxhciBkaW1lbnNpb25cbiAgcHJpdmF0ZSBzdGF0aWMgYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgaW5TaXplOiBudW1iZXIsXG4gICAgc3RyaWRlOiBudW1iZXIsXG4gICAgZGlsYXRpb246IG51bWJlcixcbiAgICBrZXJuZWw6IG51bWJlcixcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBwYWRIZWFkSW5kZXg6IG51bWJlcixcbiAgICBwYWRUYWlsSW5kZXg6IG51bWJlcixcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApOiBudW1iZXIge1xuICAgIGNvbnN0IGRrZXJuZWwgPSBkaWxhdGlvbiAqIChrZXJuZWwgLSAxKSArIDE7XG4gICAgaWYgKGF1dG9QYWQgJiYgYXV0b1BhZCAhPT0gJ05PVFNFVCcpIHtcbiAgICAgIHN3aXRjaCAoYXV0b1BhZCkge1xuICAgICAgICBjYXNlICdWQUxJRCc6XG4gICAgICAgICAgcGFkc1twYWRIZWFkSW5kZXhdID0gMDtcbiAgICAgICAgICBwYWRzW3BhZFRhaWxJbmRleF0gPSAwO1xuICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKChpblNpemUgLSBka2VybmVsKSAvIHN0cmlkZSArIDEpO1xuICAgICAgICBjYXNlICdTQU1FX0xPV0VSJzpcbiAgICAgICAgY2FzZSAnU0FNRV9VUFBFUic6XG4gICAgICAgICAgaWYgKGRpbGF0aW9uICE9PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbGF0aW9uIG5vdCBzdXBwb3J0ZWQgZm9yIFNBTUVfVVBQRVIgb3IgU0FNRV9MT1dFUicpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBsZWdhY3lUYXJnZXRTaXplID0gKGluU2l6ZSArIHN0cmlkZSAtIDEpIC8gc3RyaWRlO1xuICAgICAgICAgICAgY29uc3QgcGFkTmVlZGVkID0gKGxlZ2FjeVRhcmdldFNpemUgLSAxKSAqIHN0cmlkZSArIGtlcm5lbCAtIGluU2l6ZTtcbiAgICAgICAgICAgIHBhZHNbcGFkSGVhZEluZGV4XSA9IGF1dG9QYWQgPT09ICdTQU1FX0xPV0VSJyA/IE1hdGguZmxvb3IoKHBhZE5lZWRlZCArIDEpIC8gMikgOiBNYXRoLmZsb29yKHBhZE5lZWRlZCAvIDIpO1xuICAgICAgICAgICAgcGFkc1twYWRUYWlsSW5kZXhdID0gcGFkTmVlZGVkIC0gcGFkc1twYWRIZWFkSW5kZXhdO1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKGluU2l6ZSArIHBhZE5lZWRlZCAtIGtlcm5lbCkgLyBzdHJpZGUgKyAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBBdXRvUGFkIHR5cGUnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKGluU2l6ZSArIHBhZHNbcGFkSGVhZEluZGV4XSArIHBhZHNbcGFkVGFpbEluZGV4XSAtIGRrZXJuZWwpIC8gc3RyaWRlICsgMSk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBNSU5fQ0xJUCA9IC0zLjQwMjgyMzQ2NjM4NTI4ODZlMzg7XG5leHBvcnQgY29uc3QgTUFYX0NMSVAgPSAzLjQwMjgyMzQ2NjM4NTI4ODZlMzg7XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVVdGY4U3RyaW5nKGJ1ZmZlcjogVWludDhBcnJheSk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoYnVmZmVyKTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3VpZCB9IGZyb20gJ2d1aWQtdHlwZXNjcmlwdCc7XG5pbXBvcnQgTG9uZyBmcm9tICdsb25nJztcblxuaW1wb3J0ICogYXMgb3J0RmJzIGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7IG9ubnggfSBmcm9tICcuL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueCc7XG5pbXBvcnQgeyBkZWNvZGVVdGY4U3RyaW5nLCBQcm90b1V0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBUZW5zb3Ige1xuICBleHBvcnQgaW50ZXJmYWNlIERhdGFUeXBlTWFwIHtcbiAgICBib29sOiBVaW50OEFycmF5O1xuICAgIGZsb2F0MzI6IEZsb2F0MzJBcnJheTtcbiAgICBmbG9hdDY0OiBGbG9hdDY0QXJyYXk7XG4gICAgc3RyaW5nOiBzdHJpbmdbXTtcbiAgICBpbnQ4OiBJbnQ4QXJyYXk7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgaW50MTY6IEludDE2QXJyYXk7XG4gICAgdWludDE2OiBVaW50MTZBcnJheTtcbiAgICBpbnQzMjogSW50MzJBcnJheTtcbiAgICB1aW50MzI6IFVpbnQzMkFycmF5O1xuICAgIGludDY0OiBCaWdJbnQ2NEFycmF5O1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgRGF0YVR5cGUgPSBrZXlvZiBEYXRhVHlwZU1hcDtcblxuICBleHBvcnQgdHlwZSBTdHJpbmdUeXBlID0gVGVuc29yLkRhdGFUeXBlTWFwWydzdHJpbmcnXTtcbiAgZXhwb3J0IHR5cGUgQm9vbGVhblR5cGUgPSBUZW5zb3IuRGF0YVR5cGVNYXBbJ2Jvb2wnXTtcbiAgZXhwb3J0IHR5cGUgSW50ZWdlclR5cGUgPVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWydpbnQ4J11cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsndWludDgnXVxuICAgIHwgVGVuc29yLkRhdGFUeXBlTWFwWydpbnQxNiddXG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ3VpbnQxNiddXG4gICAgfCBUZW5zb3IuRGF0YVR5cGVNYXBbJ2ludDMyJ11cbiAgICB8IFRlbnNvci5EYXRhVHlwZU1hcFsndWludDMyJ107XG4gIGV4cG9ydCB0eXBlIEZsb2F0VHlwZSA9IFRlbnNvci5EYXRhVHlwZU1hcFsnZmxvYXQzMiddIHwgVGVuc29yLkRhdGFUeXBlTWFwWydmbG9hdDY0J107XG4gIGV4cG9ydCB0eXBlIE51bWJlclR5cGUgPSBCb29sZWFuVHlwZSB8IEludGVnZXJUeXBlIHwgRmxvYXRUeXBlO1xuXG4gIGV4cG9ydCB0eXBlIElkID0gR3VpZDtcbn1cblxudHlwZSBUZW5zb3JEYXRhID0gVGVuc29yLkRhdGFUeXBlTWFwW1RlbnNvci5EYXRhVHlwZV07XG5cbnR5cGUgRGF0YVByb3ZpZGVyID0gKGlkOiBUZW5zb3IuSWQpID0+IFRlbnNvckRhdGE7XG50eXBlIEFzeW5jRGF0YVByb3ZpZGVyID0gKGlkOiBUZW5zb3IuSWQpID0+IFByb21pc2U8VGVuc29yRGF0YT47XG5cbmV4cG9ydCBjbGFzcyBUZW5zb3Ige1xuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIHRlbnNvciBkYXRhXG4gICAqL1xuICBnZXQgZGF0YSgpOiBUZW5zb3JEYXRhIHtcbiAgICBpZiAodGhpcy5jYWNoZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhUHJvdmlkZXIhKHRoaXMuZGF0YUlkKTtcbiAgICAgIGlmIChkYXRhLmxlbmd0aCAhPT0gdGhpcy5zaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTGVuZ3RoIG9mIGRhdGEgcHJvdmlkZWQgYnkgdGhlIERhdGEgUHJvdmlkZXIgaXMgaW5jb25zaXN0ZW50IHdpdGggdGhlIGRpbXMgb2YgdGhpcyBUZW5zb3IuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmNhY2hlID0gZGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGU7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIHN0cmluZyB0ZW5zb3IgZGF0YS4gU2hvdWxkIG9ubHkgdXNlIHdoZW4gdHlwZSBpcyBTVFJJTkdcbiAgICovXG4gIGdldCBzdHJpbmdEYXRhKCkge1xuICAgIGlmICh0aGlzLnR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIHR5cGUgaXMgbm90IHN0cmluZycpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmRhdGEgYXMgVGVuc29yLlN0cmluZ1R5cGU7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIGludGVnZXIgdGVuc29yIGRhdGEuIFNob3VsZCBvbmx5IHVzZSB3aGVuIHR5cGUgaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6IChVSU5UOCwgSU5UOCwgVUlOVDE2LFxuICAgKiBJTlQxNiwgSU5UMzIsIFVJTlQzMiwgQk9PTClcbiAgICovXG4gIGdldCBpbnRlZ2VyRGF0YSgpIHtcbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhIGFzIFRlbnNvci5JbnRlZ2VyVHlwZTtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZGF0YSB0eXBlIGlzIG5vdCBpbnRlZ2VyICh1aW50OCwgaW50OCwgdWludDE2LCBpbnQxNiwgaW50MzIsIHVpbnQzMiwgYm9vbCknKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIGZsb2F0IHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nOiAoRkxPQVQsIERPVUJMRSlcbiAgICovXG4gIGdldCBmbG9hdERhdGEoKSB7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEgYXMgVGVuc29yLkZsb2F0VHlwZTtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZGF0YSB0eXBlIGlzIG5vdCBmbG9hdCAoZmxvYXQzMiwgZmxvYXQ2NCknKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIG51bWJlciB0ZW5zb3IgZGF0YS4gU2hvdWxkIG9ubHkgdXNlIHdoZW4gdHlwZSBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzogKFVJTlQ4LCBJTlQ4LCBVSU5UMTYsXG4gICAqIElOVDE2LCBJTlQzMiwgVUlOVDMyLCBCT09MLCBGTE9BVCwgRE9VQkxFKVxuICAgKi9cbiAgZ2V0IG51bWJlckRhdGEoKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB0aGlzLmRhdGEgYXMgVGVuc29yLk51bWJlclR5cGU7XG4gICAgfVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3R5cGUgY2Fubm90IGJlIG5vbi1udW1iZXIgKHN0cmluZyknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdmFsdWUgb2YgYW4gZWxlbWVudCBhdCB0aGUgZ2l2ZW4gaW5kaWNlc1xuICAgKi9cbiAgZ2V0KGluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yLkRhdGFUeXBlTWFwW1RlbnNvci5EYXRhVHlwZV1bbnVtYmVyXSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVtTaGFwZVV0aWwuaW5kaWNlc1RvT2Zmc2V0KGluZGljZXMsIHRoaXMuc3RyaWRlcyldO1xuICB9XG5cbiAgLyoqXG4gICAqIHNldCB2YWx1ZSBvZiBhbiBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRpY2VzXG4gICAqL1xuICBzZXQoaW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIHZhbHVlOiBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXVtudW1iZXJdKSB7XG4gICAgdGhpcy5kYXRhW1NoYXBlVXRpbC5pbmRpY2VzVG9PZmZzZXQoaW5kaWNlcywgdGhpcy5zdHJpZGVzKV0gPSB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgdGVuc29yIGRhdGEgYXN5bmNocm9ub3VzbHlcbiAgICovXG4gIGFzeW5jIGdldERhdGEoKTogUHJvbWlzZTxUZW5zb3JEYXRhPiB7XG4gICAgaWYgKHRoaXMuY2FjaGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5jYWNoZSA9IGF3YWl0IHRoaXMuYXN5bmNEYXRhUHJvdmlkZXIhKHRoaXMuZGF0YUlkKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGU7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHRlbnNvclxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNpemU6IG51bWJlcjtcblxuICBwcml2YXRlIF9zdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbiAgLyoqXG4gICAqIGdldCB0aGUgc3RyaWRlcyBmb3IgZWFjaCBkaW1lbnNpb25cbiAgICovXG4gIGdldCBzdHJpZGVzKCk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAoIXRoaXMuX3N0cmlkZXMpIHtcbiAgICAgIHRoaXMuX3N0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXModGhpcy5kaW1zKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N0cmlkZXM7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICAgKiBnZXQgdGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvclxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICAvKipcbiAgICAgKiBnZXQgdGhlIHR5cGUgb2YgdGhlIHRlbnNvclxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0eXBlOiBUZW5zb3IuRGF0YVR5cGUsXG4gICAgcHJpdmF0ZSBkYXRhUHJvdmlkZXI/OiBEYXRhUHJvdmlkZXIsXG4gICAgcHJpdmF0ZSBhc3luY0RhdGFQcm92aWRlcj86IEFzeW5jRGF0YVByb3ZpZGVyLFxuICAgIHByaXZhdGUgY2FjaGU/OiBUZW5zb3JEYXRhLFxuICAgIC8qKlxuICAgICAqIGdldCB0aGUgZGF0YSBJRCB0aGF0IHVzZWQgdG8gbWFwIHRvIGEgdGVuc29yIGRhdGFcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZGF0YUlkOiBHdWlkID0gR3VpZC5jcmVhdGUoKSxcbiAgKSB7XG4gICAgdGhpcy5zaXplID0gU2hhcGVVdGlsLnZhbGlkYXRlRGltc0FuZENhbGNTaXplKGRpbXMpO1xuICAgIGNvbnN0IHNpemUgPSB0aGlzLnNpemU7XG4gICAgY29uc3QgZW1wdHkgPSBkYXRhUHJvdmlkZXIgPT09IHVuZGVmaW5lZCAmJiBhc3luY0RhdGFQcm92aWRlciA9PT0gdW5kZWZpbmVkICYmIGNhY2hlID09PSB1bmRlZmluZWQ7XG5cbiAgICBpZiAoY2FjaGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGNhY2hlLmxlbmd0aCAhPT0gc2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIklucHV0IGRpbXMgZG9lc24ndCBtYXRjaCBkYXRhIGxlbmd0aC5cIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAoY2FjaGUgIT09IHVuZGVmaW5lZCAmJiAoIUFycmF5LmlzQXJyYXkoY2FjaGUpIHx8ICFjYWNoZS5ldmVyeSgoaSkgPT4gdHlwZW9mIGkgPT09ICdzdHJpbmcnKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignY2FjaGUgc2hvdWxkIGJlIGEgc3RyaW5nIGFycmF5Jyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbXB0eSkge1xuICAgICAgICB0aGlzLmNhY2hlID0gbmV3IEFycmF5PHN0cmluZz4oc2l6ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChjYWNoZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gZGF0YXZpZXdDb25zdHJ1Y3Rvcih0eXBlKTtcbiAgICAgICAgaWYgKCEoY2FjaGUgaW5zdGFuY2VvZiBjb25zdHJ1Y3RvcikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBjYWNoZSBzaG91bGQgYmUgdHlwZSAke2NvbnN0cnVjdG9yLm5hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGVtcHR5KSB7XG4gICAgICAgIGNvbnN0IGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcihzaXplICogc2l6ZW9mKHR5cGUpKTtcbiAgICAgICAgdGhpcy5jYWNoZSA9IGNyZWF0ZVZpZXcoYnVmLCB0eXBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IG5ldyBUZW5zb3IgZnJvbSBhIE9OTlggVGVuc29yIG9iamVjdFxuICAgKiBAcGFyYW0gdGVuc29yUHJvdG8gdGhlIE9OTlggVGVuc29yXG4gICAqL1xuICBzdGF0aWMgZnJvbVByb3RvKHRlbnNvclByb3RvOiBvbm54LklUZW5zb3JQcm90byk6IFRlbnNvciB7XG4gICAgaWYgKCF0ZW5zb3JQcm90bykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgY29uc3RydWN0IFZhbHVlIGZyb20gYW4gZW1wdHkgdGVuc29yJyk7XG4gICAgfVxuICAgIGNvbnN0IHR5cGUgPSBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odGVuc29yUHJvdG8uZGF0YVR5cGUhKTtcbiAgICBjb25zdCBkaW1zID0gUHJvdG9VdGlsLnRlbnNvckRpbXNGcm9tUHJvdG8odGVuc29yUHJvdG8uZGltcyEpO1xuXG4gICAgY29uc3QgdmFsdWUgPSBuZXcgVGVuc29yKGRpbXMsIHR5cGUpO1xuXG4gICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBXaGVuIGl0J3MgU1RSSU5HIHR5cGUsIHRoZSB2YWx1ZSBzaG91bGQgYWx3YXlzIGJlIHN0b3JlZCBpbiBmaWVsZFxuICAgICAgLy8gJ3N0cmluZ0RhdGEnXG4gICAgICB0ZW5zb3JQcm90by5zdHJpbmdEYXRhIS5mb3JFYWNoKChzdHIsIGkpID0+IHtcbiAgICAgICAgdmFsdWUuZGF0YVtpXSA9IGRlY29kZVV0ZjhTdHJpbmcoc3RyKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0ZW5zb3JQcm90by5yYXdEYXRhICYmXG4gICAgICB0eXBlb2YgdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoID4gMFxuICAgICkge1xuICAgICAgLy8gTk9UIGNvbnNpZGVyaW5nIHNlZ21lbnQgZm9yIG5vdyAoSU1QT1JUQU5UKVxuXG4gICAgICAvLyBwb3B1bGF0ZSB2YWx1ZSBmcm9tIHJhd0RhdGFcbiAgICAgIGNvbnN0IGRhdGFEZXN0ID0gdmFsdWUuZGF0YTtcbiAgICAgIGNvbnN0IGRhdGFTb3VyY2UgPSBuZXcgRGF0YVZpZXcoXG4gICAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEuYnVmZmVyLFxuICAgICAgICB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVPZmZzZXQsXG4gICAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCxcbiAgICAgICk7XG4gICAgICBjb25zdCBlbGVtZW50U2l6ZSA9IHNpemVvZlByb3RvKHRlbnNvclByb3RvLmRhdGFUeXBlISk7XG4gICAgICBjb25zdCBsZW5ndGggPSB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGggLyBlbGVtZW50U2l6ZTtcblxuICAgICAgaWYgKHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCAlIGVsZW1lbnRTaXplICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBidWZmZXIgbGVuZ3RoJyk7XG4gICAgICB9XG4gICAgICBpZiAoZGF0YURlc3QubGVuZ3RoICE9PSBsZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdidWZmZXIgbGVuZ3RoIG1pc21hdGNoJyk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgbiA9IHJlYWRQcm90byhkYXRhU291cmNlLCB0ZW5zb3JQcm90by5kYXRhVHlwZSEsIGkgKiBlbGVtZW50U2l6ZSk7XG4gICAgICAgIGRhdGFEZXN0W2ldID0gbjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcG9wdWxhdGUgdmFsdWUgZnJvbSBhcnJheVxuICAgICAgbGV0IGFycmF5OiBBcnJheTxudW1iZXIgfCBMb25nPjtcbiAgICAgIHN3aXRjaCAodGVuc29yUHJvdG8uZGF0YVR5cGUpIHtcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkZMT0FUOlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8uZmxvYXREYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyOlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4OlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MOlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8uaW50MzJEYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8uaW50NjREYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkRPVUJMRTpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLmRvdWJsZURhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyOlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0OlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8udWludDY0RGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIHJ1biBoZXJlXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bnNwZWNpZmljIGVycm9yJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhcnJheSA9PT0gbnVsbCB8fCBhcnJheSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIHBvcHVsYXRlIGRhdGEgZnJvbSBhIHRlbnNvcnByb3RvIHZhbHVlJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRhdGEgPSB2YWx1ZS5kYXRhO1xuICAgICAgaWYgKGRhdGEubGVuZ3RoICE9PSBhcnJheS5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhcnJheSBsZW5ndGggbWlzbWF0Y2gnKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gYXJyYXlbaV07XG4gICAgICAgIGlmIChMb25nLmlzTG9uZyhlbGVtZW50KSkge1xuICAgICAgICAgIGRhdGFbaV0gPSBsb25nVG9OdW1iZXIoZWxlbWVudCwgdGVuc29yUHJvdG8uZGF0YVR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRhdGFbaV0gPSBlbGVtZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBuZXcgVGVuc29yIGZyb20gcmF3IGRhdGFcbiAgICogQHBhcmFtIGRhdGEgdGhlIHJhdyBkYXRhIG9iamVjdC4gU2hvdWxkIGJlIGEgc3RyaW5nIGFycmF5IGZvciAnc3RyaW5nJyB0ZW5zb3IsIGFuZCB0aGUgY29ycmVzcG9uZGluZyB0eXBlZCBhcnJheVxuICAgKiBmb3Igb3RoZXIgdHlwZXMgb2YgdGVuc29yLlxuICAgKiBAcGFyYW0gZGltcyB0aGUgZGltZW5zaW9ucyBvZiB0aGUgdGVuc29yXG4gICAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRoZSB0ZW5zb3JcbiAgICovXG4gIHN0YXRpYyBmcm9tRGF0YShkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXSwgZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHR5cGU6IFRlbnNvci5EYXRhVHlwZSkge1xuICAgIHJldHVybiBuZXcgVGVuc29yKGRpbXMsIHR5cGUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBkYXRhKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tT3J0VGVuc29yKG9ydFRlbnNvcjogb3J0RmJzLlRlbnNvcikge1xuICAgIGlmICghb3J0VGVuc29yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBjb25zdHJ1Y3QgVmFsdWUgZnJvbSBhbiBlbXB0eSB0ZW5zb3InKTtcbiAgICB9XG4gICAgY29uc3QgZGltcyA9IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbU9SVEZvcm1hdChvcnRUZW5zb3IpO1xuICAgIGNvbnN0IHR5cGUgPSBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8ob3J0VGVuc29yLmRhdGFUeXBlKCkpO1xuXG4gICAgY29uc3QgdmFsdWUgPSBuZXcgVGVuc29yKGRpbXMsIHR5cGUpO1xuXG4gICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBXaGVuIGl0J3MgU1RSSU5HIHR5cGUsIHRoZSB2YWx1ZSBzaG91bGQgYWx3YXlzIGJlIHN0b3JlZCBpbiBmaWVsZFxuICAgICAgLy8gJ3N0cmluZ0RhdGEnXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ydFRlbnNvci5zdHJpbmdEYXRhTGVuZ3RoKCk7IGkrKykge1xuICAgICAgICB2YWx1ZS5kYXRhW2ldID0gb3J0VGVuc29yLnN0cmluZ0RhdGEoaSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIG9ydFRlbnNvci5yYXdEYXRhQXJyYXkoKSAmJlxuICAgICAgdHlwZW9mIG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkgPT09ICdudW1iZXInICYmXG4gICAgICBvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpID4gMFxuICAgICkge1xuICAgICAgLy8gTk9UIGNvbnNpZGVyaW5nIHNlZ21lbnQgZm9yIG5vdyAoSU1QT1JUQU5UKVxuXG4gICAgICAvLyBwb3B1bGF0ZSB2YWx1ZSBmcm9tIHJhd0RhdGFcbiAgICAgIGNvbnN0IGRhdGFEZXN0ID0gdmFsdWUuZGF0YTtcbiAgICAgIGNvbnN0IGRhdGFTb3VyY2UgPSBuZXcgRGF0YVZpZXcoXG4gICAgICAgIG9ydFRlbnNvci5yYXdEYXRhQXJyYXkoKSEuYnVmZmVyLFxuICAgICAgICBvcnRUZW5zb3IucmF3RGF0YUFycmF5KCkhLmJ5dGVPZmZzZXQsXG4gICAgICAgIG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCksXG4gICAgICApO1xuICAgICAgY29uc3QgZWxlbWVudFNpemUgPSBzaXplb2ZQcm90byhvcnRUZW5zb3IuZGF0YVR5cGUoKSk7XG4gICAgICBjb25zdCBsZW5ndGggPSBvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpIC8gZWxlbWVudFNpemU7XG5cbiAgICAgIGlmIChvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpICUgZWxlbWVudFNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJ1ZmZlciBsZW5ndGgnKTtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhRGVzdC5sZW5ndGggIT09IGxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1ZmZlciBsZW5ndGggbWlzbWF0Y2gnKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBuID0gcmVhZFByb3RvKGRhdGFTb3VyY2UsIG9ydFRlbnNvci5kYXRhVHlwZSgpLCBpICogZWxlbWVudFNpemUpO1xuICAgICAgICBkYXRhRGVzdFtpXSA9IG47XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaXplb2YodHlwZTogVGVuc29yLkRhdGFUeXBlKTogbnVtYmVyIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnYm9vbCc6XG4gICAgY2FzZSAnaW50OCc6XG4gICAgY2FzZSAndWludDgnOlxuICAgICAgcmV0dXJuIDE7XG4gICAgY2FzZSAnaW50MTYnOlxuICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICByZXR1cm4gMjtcbiAgICBjYXNlICdpbnQzMic6XG4gICAgY2FzZSAndWludDMyJzpcbiAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIHJldHVybiA0O1xuICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgcmV0dXJuIDg7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY2Fubm90IGNhbGN1bGF0ZSBzaXplb2YoKSBvbiB0eXBlICR7dHlwZX1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaXplb2ZQcm90byh0eXBlOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHwgb3J0RmJzLlRlbnNvckRhdGFUeXBlKTogbnVtYmVyIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4OlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4OlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MOlxuICAgICAgcmV0dXJuIDE7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY6XG4gICAgICByZXR1cm4gMjtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICByZXR1cm4gNDtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkRPVUJMRTpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0OlxuICAgICAgcmV0dXJuIDg7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY2Fubm90IGNhbGN1bGF0ZSBzaXplb2YoKSBvbiB0eXBlICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlXX1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVWaWV3KGRhdGFCdWZmZXI6IEFycmF5QnVmZmVyLCB0eXBlOiBUZW5zb3IuRGF0YVR5cGUpIHtcbiAgcmV0dXJuIG5ldyAoZGF0YXZpZXdDb25zdHJ1Y3Rvcih0eXBlKSkoZGF0YUJ1ZmZlcik7XG59XG5cbmZ1bmN0aW9uIGRhdGF2aWV3Q29uc3RydWN0b3IodHlwZTogVGVuc29yLkRhdGFUeXBlKSB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2Jvb2wnOlxuICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIHJldHVybiBVaW50OEFycmF5O1xuICAgIGNhc2UgJ2ludDgnOlxuICAgICAgcmV0dXJuIEludDhBcnJheTtcbiAgICBjYXNlICdpbnQxNic6XG4gICAgICByZXR1cm4gSW50MTZBcnJheTtcbiAgICBjYXNlICd1aW50MTYnOlxuICAgICAgcmV0dXJuIFVpbnQxNkFycmF5O1xuICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgIHJldHVybiBJbnQzMkFycmF5O1xuICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICByZXR1cm4gVWludDMyQXJyYXk7XG4gICAgY2FzZSAnaW50NjQnOlxuICAgICAgcmV0dXJuIEJpZ0ludDY0QXJyYXk7XG4gICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICByZXR1cm4gRmxvYXQzMkFycmF5O1xuICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgcmV0dXJuIEZsb2F0NjRBcnJheTtcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gc2hvdWxkIG5ldmVyIHJ1biB0byBoZXJlXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3BlY2lmaWVkIGVycm9yJyk7XG4gIH1cbn1cblxuLy8gY29udmVydCBhIGxvbmcgbnVtYmVyIHRvIGEgMzItYml0IGludGVnZXIgKGNhc3QtZG93bilcbmZ1bmN0aW9uIGxvbmdUb051bWJlcihpOiBMb25nLCB0eXBlOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHwgb3J0RmJzLlRlbnNvckRhdGFUeXBlKTogbnVtYmVyIHtcbiAgLy8gSU5UNjQsIFVJTlQzMiwgVUlOVDY0XG4gIGlmICh0eXBlID09PSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0IHx8IHR5cGUgPT09IG9ydEZicy5UZW5zb3JEYXRhVHlwZS5JTlQ2NCkge1xuICAgIGlmIChpLmdyZWF0ZXJUaGFuT3JFcXVhbCgyMTQ3NDgzNjQ4KSB8fCBpLmxlc3NUaGFuKC0yMTQ3NDgzNjQ4KSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW50NjQgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChcbiAgICB0eXBlID09PSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMiB8fFxuICAgIHR5cGUgPT09IG9ydEZicy5UZW5zb3JEYXRhVHlwZS5VSU5UMzIgfHxcbiAgICB0eXBlID09PSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NCB8fFxuICAgIHR5cGUgPT09IG9ydEZicy5UZW5zb3JEYXRhVHlwZS5VSU5UNjRcbiAgKSB7XG4gICAgaWYgKGkuZ3JlYXRlclRoYW5PckVxdWFsKDQyOTQ5NjcyOTYpIHx8IGkubGVzc1RoYW4oMCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3VpbnQ2NCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYG5vdCBhIExPTkcgdHlwZTogJHtvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlW3R5cGVdfWApO1xuICB9XG5cbiAgcmV0dXJuIGkudG9OdW1iZXIoKTtcbn1cblxuLy8gcmVhZCBvbmUgdmFsdWUgZnJvbSBUZW5zb3JQcm90b1xuZnVuY3Rpb24gcmVhZFByb3RvKFxuICB2aWV3OiBEYXRhVmlldyxcbiAgdHlwZTogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZSB8IG9ydEZicy5UZW5zb3JEYXRhVHlwZSxcbiAgYnl0ZU9mZnNldDogbnVtYmVyLFxuKTogbnVtYmVyIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4OlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0VWludDgoYnl0ZU9mZnNldCk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgICByZXR1cm4gdmlldy5nZXRJbnQ4KGJ5dGVPZmZzZXQpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY6XG4gICAgICByZXR1cm4gdmlldy5nZXRVaW50MTYoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2OlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0SW50MTYoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkZMT0FUOlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0RmxvYXQzMihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI6XG4gICAgICByZXR1cm4gdmlldy5nZXRJbnQzMihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyOlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDpcbiAgICAgIHJldHVybiBsb25nVG9OdW1iZXIoXG4gICAgICAgIExvbmcuZnJvbUJpdHModmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSksIHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQgKyA0LCB0cnVlKSwgZmFsc2UpLFxuICAgICAgICB0eXBlLFxuICAgICAgKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0RmxvYXQ2NChieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0OlxuICAgICAgcmV0dXJuIGxvbmdUb051bWJlcihcbiAgICAgICAgTG9uZy5mcm9tQml0cyh2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0LCB0cnVlKSwgdmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCArIDQsIHRydWUpLCB0cnVlKSxcbiAgICAgICAgdHlwZSxcbiAgICAgICk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY2Fubm90IHJlYWQgZnJvbSBEYXRhVmlldyBmb3IgdHlwZSAke29ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVbdHlwZV19YCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLyoqXG4gKiByZXByZXNlbnQgYSB2ZXJzaW9uIGlycmVsZXZhbnQgYWJzdHJhY3Rpb24gb2YgZm9yIEdMU0wgc291cmNlIGNvZGVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHbHNsIHtcbiAgcmVhZG9ubHkgdmVyc2lvbjogc3RyaW5nO1xuICByZWFkb25seSBhdHRyaWJ1dGU6IHN0cmluZztcbiAgcmVhZG9ubHkgdmFyeWluZ1ZlcnRleDogc3RyaW5nO1xuICByZWFkb25seSB2YXJ5aW5nRnJhZzogc3RyaW5nO1xuICByZWFkb25seSB0ZXh0dXJlMkQ6IHN0cmluZztcbiAgcmVhZG9ubHkgb3V0cHV0OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG91dHB1dERlY2xhcmF0aW9uOiBzdHJpbmc7XG59XG5cbmNvbnN0IEdMU0xfRVNfMl8wOiBHbHNsID0ge1xuICB2ZXJzaW9uOiAnJyxcbiAgYXR0cmlidXRlOiAnYXR0cmlidXRlJyxcbiAgdmFyeWluZ1ZlcnRleDogJ3ZhcnlpbmcnLFxuICB2YXJ5aW5nRnJhZzogJ3ZhcnlpbmcnLFxuICB0ZXh0dXJlMkQ6ICd0ZXh0dXJlMkQnLFxuICBvdXRwdXQ6ICdnbF9GcmFnQ29sb3InLFxuICBvdXRwdXREZWNsYXJhdGlvbjogJycsXG59O1xuY29uc3QgR0xTTF9FU18zXzA6IEdsc2wgPSB7XG4gIHZlcnNpb246ICcjdmVyc2lvbiAzMDAgZXMnLFxuICBhdHRyaWJ1dGU6ICdpbicsXG4gIHZhcnlpbmdWZXJ0ZXg6ICdvdXQnLFxuICB2YXJ5aW5nRnJhZzogJ2luJyxcbiAgdGV4dHVyZTJEOiAndGV4dHVyZScsXG4gIG91dHB1dDogJ291dHB1dENvbG9yJyxcbiAgb3V0cHV0RGVjbGFyYXRpb246ICdvdXQgdmVjNCBvdXRwdXRDb2xvcjsnLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEdsc2wodmVyc2lvbjogMSB8IDIpIHtcbiAgcmV0dXJuIHZlcnNpb24gPT09IDEgPyBHTFNMX0VTXzJfMCA6IEdMU0xfRVNfM18wO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVydGV4U2hhZGVyU291cmNlKHZlcnNpb246IDEgfCAyKTogc3RyaW5nIHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2wodmVyc2lvbik7XG4gIHJldHVybiBgJHtnbHNsLnZlcnNpb259XG4gICAgICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7XG4gICAgICAke2dsc2wuYXR0cmlidXRlfSB2ZWMzIHBvc2l0aW9uO1xuICAgICAgJHtnbHNsLmF0dHJpYnV0ZX0gdmVjMiB0ZXh0dXJlQ29vcmQ7XG5cbiAgICAgICR7Z2xzbC52YXJ5aW5nVmVydGV4fSB2ZWMyIFRleENvb3JkcztcblxuICAgICAgdm9pZCBtYWluKClcbiAgICAgIHtcbiAgICAgICAgICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDEuMCk7XG4gICAgICAgICAgVGV4Q29vcmRzID0gdGV4dHVyZUNvb3JkO1xuICAgICAgfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGcmFnU2hhZGVyUHJlYW1ibGUodmVyc2lvbjogMSB8IDIpOiBzdHJpbmcge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbCh2ZXJzaW9uKTtcbiAgcmV0dXJuIGAke2dsc2wudmVyc2lvbn1cbiAgICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7XG4gICAgcHJlY2lzaW9uIGhpZ2hwIGludDtcbiAgICBwcmVjaXNpb24gaGlnaHAgc2FtcGxlcjJEO1xuICAgICR7Z2xzbC52YXJ5aW5nRnJhZ30gdmVjMiBUZXhDb29yZHM7XG4gICAgJHtnbHNsLm91dHB1dERlY2xhcmF0aW9ufVxuICAgIGNvbnN0IHZlYzIgaGFsZkNSID0gdmVjMigwLjUsIDAuNSk7XG5cbiAgICAvLyBDdXN0b20gdmVjdG9yIHR5cGVzIHRvIGhhbmRsZSBoaWdoZXIgZGltZW5hbGl0aWVzLlxuICAgIHN0cnVjdCBpdmVjNVxuICAgIHtcbiAgICAgIGludCB4O1xuICAgICAgaW50IHk7XG4gICAgICBpbnQgejtcbiAgICAgIGludCB3O1xuICAgICAgaW50IHU7XG4gICAgfTtcblxuICAgIHN0cnVjdCBpdmVjNlxuICAgIHtcbiAgICAgIGludCB4O1xuICAgICAgaW50IHk7XG4gICAgICBpbnQgejtcbiAgICAgIGludCB3O1xuICAgICAgaW50IHU7XG4gICAgICBpbnQgdjtcbiAgICB9O1xuXG4gICAgaW50IGltb2QoaW50IHgsIGludCB5KSB7XG4gICAgICByZXR1cm4geCAtIHkgKiAoeCAvIHkpO1xuICAgIH1cblxuICAgIGA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWZhdWx0RnJhZ1NoYWRlck1haW4odmVyc2lvbjogMSB8IDIsIG91dHB1dFNoYXBlTGVuZ3RoOiBudW1iZXIpOiBzdHJpbmcge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbCh2ZXJzaW9uKTtcbiAgcmV0dXJuIGBcbiAgdm9pZCBtYWluKCkge1xuICAgIGludCBpbmRpY2VzWyR7b3V0cHV0U2hhcGVMZW5ndGh9XTtcbiAgICB0b1ZlYyhUZXhDb29yZHMsIGluZGljZXMpO1xuICAgIHZlYzQgcmVzdWx0ID0gdmVjNChwcm9jZXNzKGluZGljZXMpKTtcbiAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgfVxuICBgO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuXG4vKipcbiAqIExheW91dCBpbmZvIGlzIHVzZWQgZm9yIG1hcHBpbmcgbi1kaW1lbnNpb25hbCBhcnJheSB0byAyRCB0ZXh0dXJlc1xuICogVGhlIGxheW91dCBpcyBjcmVhdGVkIGJ5IHRoZSBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kgYmFzZWQgb25cbiAqIHRoZSBUZW5zb3IncyBkaW1lbnNpb25zIGFuZCBzdHJpZGVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZUxheW91dCB7XG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICAvKipcbiAgICogc3BlY2lmeSB0aGUgbnVtYmVyIG9mIHZhbHVlIHRoYXQgZW5jb2RlZCBpbiBhIHNpbmdsZSBwaXhlbFxuICAgKi9cbiAgY2hhbm5lbHM6IDEgfCAyIHwgMyB8IDQ7XG4gIC8qKlxuICAgKiB3aGV0aGVyIGluIHBhY2tlZCBtb2RlIG9yIG5vdFxuICAgKi9cbiAgaXNQYWNrZWQ/OiBib29sZWFuO1xuICAvKipcbiAgICogdGhlIG5vcm1hbGl6ZWQgc2hhcGVcbiAgICovXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgLyoqXG4gICAqIHRoZSBzdHJpZGUgb2YgZWFjaCBkaW1lbnNpb25zLCBjYWxjdWxhdGVkIGFjY29yZGluZyB0byBzaGFwZVxuICAgKi9cbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG4gIC8qKlxuICAgKiB0aGUgb3JpZ2luYWwgc2hhcGUoZGltcykgb2YgdGhlIGNvcnJlc3BvbmRpbmcgdGVuc29yXG4gICAqL1xuICB1bnBhY2tlZFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcblxuICByZXZlcnNlZFdIPzogYm9vbGVhbjtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZURhdGEgZXh0ZW5kcyBUZXh0dXJlTGF5b3V0IHtcbiAgdGVuc29yOiBUZW5zb3I7XG4gIHRleHR1cmU6IFdlYkdMVGV4dHVyZTtcbn1cblxuZXhwb3J0IGVudW0gVGV4dHVyZVR5cGUge1xuICB1bnBhY2tlZCwgLy8gPC0tIG5vcm1hbCB1bnBhY2tlZCB0ZXh0dXJlXG4gIHVucGFja2VkUmV2ZXJzZWQsIC8vIDwtLSB1bnBhY2tlZCB0ZXh0dXJlIHVzZWQgaW4gb2xkIE9OTlguanMgaW1wbGVtZW50YXRpb24gKGRlcHJlY2F0ZWQpXG4gIHBhY2tlZCwgLy8gPC0tIG5vcm1hbCBwYWNrZWQgdGV4dHVyZVxuICBkb3dubG9hZFVpbnQ4QXNGbG9hdCwgLy8gPC0tIE9OTFkgdXNlZCBpbiB0ZXh0dXJlIGRvd25sb2FkaW5nIGZvciBpT1MgZGV2aWNlc1xuICBwYWNrZWRMYXN0RGltZW5zaW9uLCAvLyA8LS0gT05MWSB1c2VkIGluIG9sZCBPTk5YLmpzIENvbnYgaW1wbGVtZW50YXRpb24gZm9yIGlucHV0IFcgKGRlcHJlY2F0ZWQpXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29ySW5mbyB7XG4gIGlkPzogVGVuc29yLklkO1xuICBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcbiAgdHlwZTogVGVuc29yLkRhdGFUeXBlO1xuICB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbVZhcmlhYmxlIHtcbiAgdHlwZTogJ2Zsb2F0JyB8ICdpbnQnO1xuICBuYW1lOiBzdHJpbmc7XG4gIGFycmF5TGVuZ3RoPzogbnVtYmVyO1xuICBkYXRhOiBudW1iZXIgfCBudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBBIHNldCBvZiBtZXRhZGF0YSBvZiBhIHNoYWRlciBwcm9ncmFtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiB0aGUgbmFtZSBvZiB0aGUgcHJvZ3JhbS4gdXNlZCBmb3IgZGVidWdnaW5nIGFuZCBwcm9maWxpbmdcbiAgICovXG4gIG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIHRleHR1cmUgdHlwZXMgZm9yIGVhY2ggaW5wdXRcbiAgICovXG4gIGlucHV0VHlwZXM6IFRleHR1cmVUeXBlW107XG4gIC8qKlxuICAgKiBuYW1lcyBvZiBlYWNoIGlucHV0XG4gICAqL1xuICBpbnB1dE5hbWVzOiBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIGFuIG9wdGlvbmFsIHN0cmluZyBhcyBhIGNhY2hlIGhpbnQgaW4gdGhlIGFydGlmYWN0IGNhY2hlXG4gICAqL1xuICBjYWNoZUhpbnQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBQcm9ncmFtSW5mb0xvYWRlciBhbGxvd3NcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtSW5mb0xvYWRlciBleHRlbmRzIFByb2dyYW1NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBhIGZ1bmN0aW9uIHRvIGdldCB0aGUgcHJvZ3JhbSBpbmZvXG4gICAqL1xuICBnZXQoKTogUHJvZ3JhbUluZm87XG59XG5cbi8qKlxuICogQSBzZXQgb2YgZGF0YSB0aGF0IHJlcHJlc2VudCBhIHNoYWRlciBwcm9ncmFtXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbUluZm8gZXh0ZW5kcyBQcm9ncmFtTWV0YWRhdGEge1xuICAvKipcbiAgICogaW5mb3JtYXRpb24gb2YgdW5pZm9ybSB2YXJpYWJsZXNcbiAgICovXG4gIHZhcmlhYmxlcz86IFByb2dyYW1WYXJpYWJsZVtdO1xuICAvKipcbiAgICogdGVuc29yIGluZm8gZm9yIG91dHB1dFxuICAgKi9cbiAgb3V0cHV0OiBUZW5zb3JJbmZvO1xuICAvKipcbiAgICogdGhlIHNoYWRlcidzIHByb2Nlc3Npbmcgc291cmNlIGNvZGVcbiAgICovXG4gIHNoYWRlclNvdXJjZTogc3RyaW5nO1xuICAvKipcbiAgICogd2hldGhlciB0aGUgc2hhZGVyIHNvdXJjZSBjb250YWlucyBhIGN1c3RvbWl6ZWQgbWFpbiBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvblxuICAgKi9cbiAgaGFzTWFpbj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmFyaWFibGVJbmZvIHtcbiAgdHlwZTogJ2Zsb2F0JyB8ICdpbnQnO1xuICBuYW1lOiBzdHJpbmc7XG4gIGFycmF5TGVuZ3RoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1WYXJpYWJsZSB7XG4gIHR5cGU6ICdmbG9hdCcgfCAnaW50JztcbiAgbmFtZTogc3RyaW5nO1xuICBhcnJheUxlbmd0aD86IG51bWJlcjtcbiAgZGF0YTogbnVtYmVyIHwgbnVtYmVyW107XG59XG5cbi8qKlxuICogSW5mb3JtYXRpb24gb2YgdW5pZm9ybXMgdGhhdCBzaGFkZXIgdXNlc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZvcm1JbmZvIHtcbiAgdHlwZTogJ3NhbXBsZXIyRCcgfCBWYXJpYWJsZUluZm9bJ3R5cGUnXTtcbiAgbmFtZTogc3RyaW5nO1xuICBhcnJheUxlbmd0aD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVbmlmb3JtTG9jYXRpb24gZXh0ZW5kcyBVbmlmb3JtSW5mbyB7XG4gIGxvY2F0aW9uOiBXZWJHTFVuaWZvcm1Mb2NhdGlvbjtcbn1cblxuLyoqXG4gKiBBcnRpZmFjdCBpcyB0aGUgcmVzdWx0IG9mIGNvbXBpbGF0aW9uXG4gKiBJdCBkb2VzIG5vdCBjb250YWluIGlucHV0IG9mIG91dHB1dCBkYXRhXG4gKiBIb3dldmVyIGFueXRoaW5nIHRoYXQgY291bGQgYmUgcnVuIGFzIGEgXCJwcm9ncmFtXCJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcnRpZmFjdCB7XG4gIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbztcbiAgcHJvZ3JhbTogV2ViR0xQcm9ncmFtO1xuICB1bmlmb3JtTG9jYXRpb25zOiBVbmlmb3JtTG9jYXRpb25bXTtcbiAgYXR0cmliTG9jYXRpb25zOiB7IHBvc2l0aW9uOiBudW1iZXI7IHRleHR1cmVDb29yZDogbnVtYmVyIH07XG59XG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgQXJ0aWZhY3Qge1xuICB0eXBlIFVuaWZvcm1Mb2NhdGlvbnMgPSBBcnRpZmFjdFsndW5pZm9ybUxvY2F0aW9ucyddO1xuICB0eXBlIEF0dHJpYkxvY2F0aW9ucyA9IEFydGlmYWN0WydhdHRyaWJMb2NhdGlvbnMnXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVbmlmb3JtRGF0YSB7XG4gIFtuYW1lOiBzdHJpbmddOiBudW1iZXIgfCBudW1iZXJbXTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vLi4vdXRpbCc7XG4vKipcbiAqIEdpdmVuIGEgbm9uIFJHQkEgc2hhcGUgY2FsY3VsYXRlIHRoZSBSIHZlcnNpb25cbiAqIEl0IGlzIGFzc3VtZWQgdGhhdCB0aGUgZGltZW5zaW9ucyBhcmUgbXVsdGlwbGVzIG9mIGdpdmVuIGNoYW5uZWxzXG4gKiBOT1RFOiBpdCBpcyBhbHdheXMgdGhlIGxhc3QgZGltIHRoYXQgZ2V0cyBwYWNrZWQuXG4gKiBAcGFyYW0gdW5wYWNrZWRTaGFwZSBvcmlnaW5hbCBzaGFwZSB0byBjcmVhdGUgYSBwYWNrZWQgdmVyc2lvbiBmcm9tXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWNrZWRTaGFwZSh1bnBhY2tlZFNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgY29uc3QgbGVuID0gdW5wYWNrZWRTaGFwZS5sZW5ndGg7XG4gIHJldHVybiB1bnBhY2tlZFNoYXBlLnNsaWNlKDAsIGxlbiAtIDEpLmNvbmNhdCh1bnBhY2tlZFNoYXBlW2xlbiAtIDFdIC8gNCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXBlYXRlZFRyeShcbiAgY2hlY2tGbjogKCkgPT4gYm9vbGVhbixcbiAgZGVsYXlGbiA9IChfY291bnRlcjogbnVtYmVyKSA9PiAwLFxuICBtYXhDb3VudGVyPzogbnVtYmVyLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgbGV0IHRyeUNvdW50ID0gMDtcblxuICAgIGNvbnN0IHRyeUZuID0gKCkgPT4ge1xuICAgICAgaWYgKGNoZWNrRm4oKSkge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdHJ5Q291bnQrKztcblxuICAgICAgY29uc3QgbmV4dEJhY2tvZmYgPSBkZWxheUZuKHRyeUNvdW50KTtcblxuICAgICAgaWYgKG1heENvdW50ZXIgIT0gbnVsbCAmJiB0cnlDb3VudCA+PSBtYXhDb3VudGVyKSB7XG4gICAgICAgIHJlamVjdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZXRUaW1lb3V0KHRyeUZuLCBuZXh0QmFja29mZik7XG4gICAgfTtcblxuICAgIHRyeUZuKCk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyB0aGUgZnVuY3Rpb24gbmFtZSBmcm9tIGFuIGlucHV0IHNhbXBsZXIgbmFtZS5cbiAqIEBwYXJhbSBzYW1wbGVyTmFtZSBOYW1lIG9mIHRoZSBzYW1wbGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lKHNhbXBsZXJOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICBhc3NlcnQodHlwZW9mIHNhbXBsZXJOYW1lICE9PSAndW5kZWZpbmVkJyAmJiBzYW1wbGVyTmFtZS5sZW5ndGggIT09IDAsICgpID0+ICdlbXB0eSBzdHJpbmcgZm91bmQgZm9yIHNhbXBsZXIgbmFtZScpO1xuICByZXR1cm4gJ2dldCcgKyBzYW1wbGVyTmFtZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHNhbXBsZXJOYW1lLnNsaWNlKDEpO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyB0aGUgZnVuY3Rpb24gbmFtZSBmcm9tIGFuIGlucHV0IHNhbXBsZXIgbmFtZSBhdCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0gc2FtcGxlck5hbWUgTmFtZSBvZiB0aGUgc2FtcGxlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZUF0T3V0Q29vcmRzKHNhbXBsZXJOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICBhc3NlcnQodHlwZW9mIHNhbXBsZXJOYW1lICE9PSAndW5kZWZpbmVkJyAmJiBzYW1wbGVyTmFtZS5sZW5ndGggIT09IDAsICgpID0+ICdlbXB0eSBzdHJpbmcgZm91bmQgZm9yIHNhbXBsZXIgbmFtZScpO1xuICByZXR1cm4gJ2dldCcgKyBzYW1wbGVyTmFtZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHNhbXBsZXJOYW1lLnNsaWNlKDEpICsgJ0F0T3V0Q29vcmRzJztcbn1cblxuLyoqIFJldHVybnMgYSBuZXcgaW5wdXQgc2hhcGUgKGEgY29weSkgdGhhdCBoYXMgYSBzcXVlZXplZCBsb2dpY2FsIHNoYXBlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNxdWVlemVJbnB1dFNoYXBlKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBzcXVlZXplZFNoYXBlOiBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgLy8gRGVlcCBjb3B5LlxuICBsZXQgbmV3SW5wdXRTaGFwZTogbnVtYmVyW10gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0U2hhcGUpKTtcbiAgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVkU2hhcGU7XG4gIHJldHVybiBuZXdJbnB1dFNoYXBlO1xufVxuXG4vKiogUmV0dXJucyBhIGxpc3Qgb2Ygc3F1ZWV6ZWQgcGFyYW1ldGVycyBmb3Igc2hhZGVyIGZ1bmN0aW9ucyAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNxdWVlemVkUGFyYW1zKHBhcmFtczogc3RyaW5nW10sIGtlcHREaW1zOiBudW1iZXJbXSk6IHN0cmluZyB7XG4gIHJldHVybiBrZXB0RGltcy5tYXAoKGQpID0+IHBhcmFtc1tkXSkuam9pbignLCAnKTtcbn1cblxuLyoqIFJldHVybnMgdGhlIGRhdGEgdHlwZSBmb3IgZGlmZmVyZW50IHJhbmtzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENvb3Jkc0RhdGFUeXBlKHJhbms6IG51bWJlcik6IHN0cmluZyB7XG4gIGlmIChyYW5rIDw9IDEpIHtcbiAgICByZXR1cm4gJ2ludCc7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gMikge1xuICAgIHJldHVybiAnaXZlYzInO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDMpIHtcbiAgICByZXR1cm4gJ2l2ZWMzJztcbiAgfSBlbHNlIGlmIChyYW5rID09PSA0KSB7XG4gICAgcmV0dXJuICdpdmVjNCc7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gNSkge1xuICAgIHJldHVybiAnaXZlYzUnO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDYpIHtcbiAgICByZXR1cm4gJ2l2ZWM2JztcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBFcnJvcihgR1BVIGZvciByYW5rICR7cmFua30gaXMgbm90IHlldCBzdXBwb3J0ZWRgKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0R2xDaGFubmVscyhyYW5rID0gNik6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIFsneCcsICd5JywgJ3onLCAndycsICd1JywgJ3YnXS5zbGljZSgwLCByYW5rKTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZ2V0R2xDaGFubmVscyB9IGZyb20gJy4uL3V0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZlY0NoYW5uZWxzKG5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyKTogc3RyaW5nW10ge1xuICByZXR1cm4gZ2V0R2xDaGFubmVscyhyYW5rKS5tYXAoKGQpID0+IGAke25hbWV9LiR7ZH1gKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoYW5uZWxzKG5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyKTogc3RyaW5nW10ge1xuICBpZiAocmFuayA9PT0gMSkge1xuICAgIHJldHVybiBbbmFtZV07XG4gIH1cbiAgcmV0dXJuIGdldFZlY0NoYW5uZWxzKG5hbWUsIHJhbmspO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdW5wYWNrRnJvbUNoYW5uZWwoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBcbiAgICBmbG9hdCBnZXRDaGFubmVsKHZlYzQgZnJhZywgaW50IGRpbSkge1xuICAgICAgaW50IG1vZENvb3JkID0gaW1vZChkaW0sIDIpO1xuICAgICAgcmV0dXJuIG1vZENvb3JkID09IDAgPyBmcmFnLnIgOiBmcmFnLmc7XG4gICAgfVxuXG4gICAgZmxvYXQgZ2V0Q2hhbm5lbCh2ZWM0IGZyYWcsIHZlYzIgaW5uZXJEaW1zKSB7XG4gICAgICB2ZWMyIG1vZENvb3JkID0gbW9kKGlubmVyRGltcywgMi4pO1xuICAgICAgcmV0dXJuIG1vZENvb3JkLnggPT0gMC4gP1xuICAgICAgICAobW9kQ29vcmQueSA9PSAwLiA/IGZyYWcuciA6IGZyYWcuZykgOlxuICAgICAgICAobW9kQ29vcmQueSA9PSAwLiA/IGZyYWcuYiA6IGZyYWcuYSk7XG4gICAgfVxuICBgO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRDb29yZHNEYXRhVHlwZSB9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHsgZ2V0Q2hhbm5lbHMgfSBmcm9tICcuL3BhY2tpbmctdXRpbHMnO1xuXG5jb25zdCBwYWNrUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAncGFjaycsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRSZXZlcnNlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVQYWNrUHJvZ3JhbUluZm8gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dC5kaW1zO1xuXG4gIGNvbnN0IGlucHV0UmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICAvLyBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVNoYXBlIHdvbid0IGNoYW5nZSBvdXRwdXQgcmFuay4gTmVlZCB0byB2ZXJpZnkgYnkgcnVubmluZyB0ZXN0c1xuICBjb25zdCBvdXRwdXRSYW5rID0gaW5wdXQuZGltcy5sZW5ndGg7XG5cbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShvdXRwdXRSYW5rKTtcbiAgY29uc3QgY2hhbm5lbHMgPSBnZXRDaGFubmVscygncmMnLCBvdXRwdXRSYW5rKTtcbiAgY29uc3Qgc2V0dXAgPSBnZXRTZXR1cChvdXRwdXRSYW5rLCBjaGFubmVscywgaW5wdXRTaGFwZVtpbnB1dFNoYXBlLmxlbmd0aCAtIDJdLCBpbnB1dFNoYXBlW2lucHV0U2hhcGUubGVuZ3RoIC0gMV0pO1xuXG4gIGxldCByZXZlcnNlZElucHV0V0g7XG4gIGlmIChpbnB1dFJhbmsgPT09IDApIHtcbiAgICByZXZlcnNlZElucHV0V0ggPSBbMSwgMV07XG4gIH0gZWxzZSBpZiAoaW5wdXRSYW5rID09PSAxKSB7XG4gICAgcmV2ZXJzZWRJbnB1dFdIID0gW2lucHV0U2hhcGVbMF0sIDFdO1xuICB9IGVsc2Uge1xuICAgIHJldmVyc2VkSW5wdXRXSCA9IFtpbnB1dFNoYXBlW291dHB1dFJhbmsgLSAxXSwgaW5wdXRTaGFwZVtvdXRwdXRSYW5rIC0gMl1dO1xuICB9XG4gIGNvbnN0IG91dE9mQm91bmRzQ29uZGl0aW9uID0gZ2V0T3V0T2ZCb3VuZHNDb25kaXRpb24ob3V0cHV0UmFuaywgcmV2ZXJzZWRJbnB1dFdILCBjaGFubmVscyk7XG4gIGNvbnN0IG91dHB1dCA9IGdldE91dHB1dChpbnB1dFNoYXBlLCBjaGFubmVscyk7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgJHtjb29yZHNEYXRhVHlwZX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcblxuICAgICAgICAgIGlmKCR7b3V0T2ZCb3VuZHNDb25kaXRpb259KSB7XG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQoMCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICR7c2V0dXB9XG5cbiAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCgke291dHB1dH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5wYWNrUHJvZ3JhbU1ldGFkYXRhLFxuICAgIGhhc01haW46IHRydWUsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja1Byb2dyYW1JbmZvTG9hZGVyID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvTG9hZGVyID0+ICh7XG4gIC4uLnBhY2tQcm9ncmFtTWV0YWRhdGEsXG4gIGdldDogKCkgPT4gY3JlYXRlUGFja1Byb2dyYW1JbmZvKGhhbmRsZXIsIGlucHV0KSxcbn0pO1xuXG4vKipcbiAqIGNoZWNrIG91dHB1dCBjb29yZGluYXRlIGxvY2F0aW9uIGFuZCByZXR1cm4gZmFsc2UgaWYgaXQgaXMgb3V0c2lkZSBpbnB1dCdzIHdpZHRoL2hlaWdodCBib3VuZGFyeVxuICovXG5mdW5jdGlvbiBnZXRPdXRPZkJvdW5kc0NvbmRpdGlvbihyYW5rOiBudW1iZXIsIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZGltczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBpZiAocmFuayA9PT0gMCkge1xuICAgIHJldHVybiAnZmFsc2UnO1xuICB9XG4gIGlmIChyYW5rID09PSAxKSB7XG4gICAgcmV0dXJuIGByYyA+ICR7c2hhcGVbMF19YDtcbiAgfVxuXG4gIGxldCBjb25kID0gJyc7XG4gIGZvciAobGV0IGkgPSByYW5rIC0gMjsgaSA8IHJhbms7IGkrKykge1xuICAgIGNvbmQgKz0gYCR7ZGltc1tpXX0gPj0gJHtzaGFwZVtpIC0gcmFuayArIDJdfWA7XG4gICAgaWYgKGkgPCByYW5rIC0gMSkge1xuICAgICAgY29uZCArPSAnfHwnO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb25kO1xufVxuXG4vKipcbiAqIGNvZGUgc25pcHBldCB0byBzYW1wbGUgaW5wdXQgdGV4dHVyZSB3aXRoIG91dHB1dCBjb29yZGluYXRlc1xuICovXG5mdW5jdGlvbiBnZXRPdXRwdXQoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBkaW1zOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgaWYgKHJhbmsgPT09IDApIHtcbiAgICByZXR1cm4gJ2dldEEoKSwgMCwgMCwgMCc7XG4gIH1cblxuICBpZiAocmFuayA9PT0gMSkge1xuICAgIHJldHVybiBgZ2V0QShyYyksXG4gICAgICAgICAgICByYyArIDEgPj0gJHtzaGFwZVswXX0gPyAwLiA6IGdldEEocmMgKyAxKSxcbiAgICAgICAgICAgIDAsIDBgO1xuICB9XG5cbiAgY29uc3QgY29vcmQwMCA9ICdyLCBjJztcbiAgY29uc3QgY29vcmQwMSA9ICdyLCBjcDEnO1xuICBjb25zdCBjb29yZDEwID0gJ3JwMSwgYyc7XG4gIGNvbnN0IGNvb3JkMTEgPSAncnAxLCBjcDEnO1xuICBsZXQgRCA9ICcnO1xuICBpZiAocmFuayA+IDIpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAyOyArK2kpIHtcbiAgICAgIEQgPSBEICsgYCR7ZGltc1tpXX0sYDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGBnZXRBKCR7RH0ke2Nvb3JkMDB9KSxcbiAgICAgICAgICByRWRnZSA/IDAuIDogZ2V0QSgke0R9JHtjb29yZDEwfSksXG4gICAgICAgICAgY0VkZ2UgPyAwLiA6IGdldEEoJHtEfSR7Y29vcmQwMX0pLFxuICAgICAgICAgIHJFZGdlIHx8IGNFZGdlID8gMC4gOiBnZXRBKCR7RH0ke2Nvb3JkMTF9KWA7XG59XG5cbi8qKlxuICogY29kZSBzbmlwcGV0IHRvIHNldHVwIDQgY29vcmRpbmF0ZXMgYW5kIGVkZ2UgY29uZGl0aW9uc1xuICovXG5mdW5jdGlvbiBnZXRTZXR1cChyYW5rOiBudW1iZXIsIGRpbXM6IHN0cmluZ1tdLCByb3dzOiBudW1iZXIsIGNvbHM6IG51bWJlcik6IHN0cmluZyB7XG4gIGlmIChyYW5rID09PSAwIHx8IHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cbiAgLy8gcmFuayA+PSAyIGZvciB3aWR0aCtoZWlnaHQgcGFjay5cbiAgZWxzZSB7XG4gICAgY29uc3Qgc2V0dXAgPSBgXG4gICAgaW50IHIgPSAke2RpbXNbcmFuayAtIDJdfTtcbiAgICBpbnQgYyA9ICR7ZGltc1tyYW5rIC0gMV19O1xuICAgIGludCBycDEgPSAke2RpbXNbcmFuayAtIDJdfSArIDE7XG4gICAgaW50IGNwMSA9ICR7ZGltc1tyYW5rIC0gMV19ICsgMTtcbiAgICBib29sIHJFZGdlID0gcnAxID49ICR7Y29sc307XG4gICAgYm9vbCBjRWRnZSA9IGNwMSA+PSAke3Jvd3N9O1xuICAgIGA7XG4gICAgcmV0dXJuIHNldHVwO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IHVucGFja0Zyb21DaGFubmVsIH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbU1ldGFkYXRhID0gKG91dHB1dFNoYXBlM0Q6IHJlYWRvbmx5IG51bWJlcltdKSA9PiAoe1xuICBuYW1lOiAnUmVzaGFwZSAocGFja2VkKScsXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS5wYWNrZWRdLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgY2FjaGVIaW50OiBgJHtvdXRwdXRTaGFwZTNEfWAsXG59KTtcblxuY29uc3QgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm8gPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQzRDogVGVuc29yLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBvdXRwdXRTaGFwZTNEOiByZWFkb25seSBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZTNEID0gaW5wdXQzRC5kaW1zIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgY29uc3Qgc3F1ZWV6ZWRPdXRwdXRTaGFwZSA9IG91dHB1dFNoYXBlM0QgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuXG4gIGxldCBtYWluTG9vcCA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIGxldCBvdXRwdXRDb29yZHMgPSAnJztcbiAgICBzd2l0Y2ggKGkpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgb3V0cHV0Q29vcmRzID0gJ291dHB1dENvb3JkcyA9IHJjOyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOlxuICAgICAgICBvdXRwdXRDb29yZHMgPSAnb3V0cHV0Q29vcmRzID0gaXZlYzMocmMueCwgcmMueSsxLCByYy56KTsnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgb3V0cHV0Q29vcmRzID0gJ291dHB1dENvb3JkcyA9IGl2ZWMzKHJjLngsIHJjLnksIHJjLnorMSk7JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSBpdmVjMyhyYy54LCByYy55KzEsIHJjLnorMSk7JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9XG5cbiAgICBtYWluTG9vcCArPSBgXG4gICAgICAgICR7b3V0cHV0Q29vcmRzfVxuICAgICAgICAke2kgPiAwID8gJ2lmKG91dHB1dENvb3Jkcy55IDwgcm93cyAmJiBvdXRwdXRDb29yZHMueiA8IGNvbHMpeycgOiAnJ31cbiAgICAgICAgICBpbnQgZmxhdHRlbmVkSW5kZXggPSBnZXRGbGF0dGVuZWRJbmRleChvdXRwdXRDb29yZHMpO1xuXG4gICAgICAgICAgaXZlYzMgaW5wdXRSQyA9IGlucHV0Q29vcmRzRnJvbVJlc2hhcGVkT3V0Q29vcmRzKGZsYXR0ZW5lZEluZGV4KTtcbiAgICAgICAgICB2ZWMyIGlubmVyRGltcyA9IHZlYzIoZmxvYXQoaW5wdXRSQy55KSxmbG9hdChpbnB1dFJDLnopKTtcblxuICAgICAgICAgIHJlc3VsdFske2l9XSA9IGdldENoYW5uZWwoZ2V0QShpbnB1dFJDLngsIGlucHV0UkMueSwgaW5wdXRSQy56KSwgaW5uZXJEaW1zKTtcblxuICAgICAgICAke2kgPiAwID8gJ30nIDogJyd9XG4gICAgICBgO1xuICB9XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke2dldFJlc2hhcGVkSW5wdXRDb29yZHMoaW5wdXRTaGFwZTNEKX1cbiAgICAgICR7Z2V0RmxhdHRlbmVkSW5kZXhGcm9tM0Qoc3F1ZWV6ZWRPdXRwdXRTaGFwZSl9XG4gICAgICAke3VucGFja0Zyb21DaGFubmVsKCl9XG5cbiAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgaXZlYzMgcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcblxuICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4wKTtcblxuICAgICAgICBpdmVjMyBvdXRwdXRDb29yZHM7XG4gICAgICAgIGludCByb3dzID0gJHtzcXVlZXplZE91dHB1dFNoYXBlWzJdfTtcbiAgICAgICAgaW50IGNvbHMgPSAke3NxdWVlemVkT3V0cHV0U2hhcGVbMV19O1xuXG4gICAgICAgICR7bWFpbkxvb3B9XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfVxuICAgIGA7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogc3F1ZWV6ZWRPdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQzRC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQzRDogVGVuc29yLFxuICBvdXRwdXRTaGFwZTNEOiByZWFkb25seSBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtTWV0YWRhdGEob3V0cHV0U2hhcGUzRCk7XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvKGhhbmRsZXIsIGlucHV0M0QsIG1ldGFkYXRhLCBvdXRwdXRTaGFwZTNEKSB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHByb2Nlc3NEaW1zM0Qoc2hhcGU6IEFycmF5TGlrZTxudW1iZXI+KTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHtcbiAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbMSwgMSwgMV07XG4gIH1cbiAgLy8gVE9ETzogc3F1ZWV6ZSBvdGhlciBzaGFwZXMgdG8gMkQgY2FzZVxuICBsZXQgYmF0Y2ggPSAxO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoYXBlLmxlbmd0aCAtIDI7ICsraSkge1xuICAgIGJhdGNoICo9IHNoYXBlW2ldO1xuICB9XG4gIHJldHVybiBbYmF0Y2gsIHNoYXBlLmxlbmd0aCA+IDEgPyBzaGFwZVtzaGFwZS5sZW5ndGggLSAyXSA6IDEsIHNoYXBlW3NoYXBlLmxlbmd0aCAtIDFdXTtcbn1cblxuLy8gRm9yIHBhY2tlZCByZXNoYXBlLCB3ZSBuZWVkIHRvIHJlLWFycmFuZ2UgdGV4ZWwgZGF0YSBmb3Igb3V0cHV0IHNoYXBlLlxuLy8gT3VyIHBhY2sgaXMgZGVzaWduZWQgdG8gcGFjayBhIDJ4MiB0aWxlIGluIGxhc3QgaCBhbmQgdyBkaW1lbnNpb24sIHNvXG4vLyBmb3IgdGhlIHJlc2hhcGVkIG5ldyB0ZW5zb3IsIHdlIGp1c3QgbmVlZCB0byByZS1hcnJhbmdlIHRoZSBsYXN0IGggYW5kXG4vLyB3IGRpbWVuc2lvbi4gRm9yIGFueSBzaGFwZSB0aGF0IGlzIG5vdCBpbiAzRCwgaS5lLiBbYmF0Y2gsIFcsIEhdLCB3ZVxuLy8gZmlyc3QgY29udmVydCBpdCB0byAzRCBieSBjb2xsYXBzaW5nIG90aGVyIGRpbWVuc2lvbiB0byBiYXRjaCBkaW0sIHRoZW5cbi8vIHByb2Nlc3Mgd2l0aCB0aGUgbGFzdCB0d28gZGltZW5zaW9ucy5cbi8vIE5vdGU6IHdlIG9ubHkgbmVlZCB0aGUgc2hhcGUgdGVuc29yIHRvIGNhbGN1bGF0ZSBvdXRwdXQgc2hhcGUsIHNvIHRoZVxuLy8gY29udGVudCBpbiBzaGFwZSB0ZW5zb3IgaXMgbmV2ZXIgdXBsb2FkZWQgdG8gR1BVLiBJdCBpcyBhbHdheXMga2VwdCBpbiBDUFUuXG4vLyBUT0RPOiBvcHRpbWl6ZSB0aGUgYWxnb3JpdGhtIC0tIGluIHNvbWUgY2FzZXMsIGlmIHRoZSBsYXN0IHR3byBkaW1zIGFyZVxuLy8gdGhlIHNhbWUgYmV0d2VlbiBpbnB1dCBzaGFwZSBhbmQgb3V0cHV0IHNoYXBlLCB0aGUgcGFja2VkIHJlc2hhcGUgY2FuIGJlXG4vLyB0cmVhdGVkIGFzIG5vLW9wLlxuZXhwb3J0IGZ1bmN0aW9uIGlzUmVzaGFwZUNoZWFwKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCByZXNoYXBlZERpbXM6IHJlYWRvbmx5IG51bWJlcltdKSB7XG4gIGxldCBpc0NoZWFwUmVzaGFwZSA9IGZhbHNlO1xuICBpZiAoZGltcy5sZW5ndGggPT09IDAgfHwgcmVzaGFwZWREaW1zLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIHNjYWxhclxuICAgIGlzQ2hlYXBSZXNoYXBlID0gdHJ1ZTtcbiAgfSBlbHNlIGlmIChkaW1zLmxlbmd0aCA8IDIgfHwgcmVzaGFwZWREaW1zLmxlbmd0aCA8IDIpIHtcbiAgICAvLyAxRFxuICAgIGlzQ2hlYXBSZXNoYXBlID0gZGltc1tkaW1zLmxlbmd0aCAtIDFdID09PSByZXNoYXBlZERpbXNbcmVzaGFwZWREaW1zLmxlbmd0aCAtIDFdO1xuICB9IGVsc2Uge1xuICAgIC8vIDJEICtcbiAgICBpc0NoZWFwUmVzaGFwZSA9XG4gICAgICBkaW1zW2RpbXMubGVuZ3RoIC0gMV0gPT09IHJlc2hhcGVkRGltc1tyZXNoYXBlZERpbXMubGVuZ3RoIC0gMV0gJiZcbiAgICAgIGRpbXNbZGltcy5sZW5ndGggLSAyXSA9PT0gcmVzaGFwZWREaW1zW3Jlc2hhcGVkRGltcy5sZW5ndGggLSAyXTtcbiAgfVxuXG4gIHJldHVybiBpc0NoZWFwUmVzaGFwZTtcbn1cblxuZnVuY3Rpb24gZ2V0UmVzaGFwZWRJbnB1dENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhzaGFwZSk7XG4gIGNvbnN0IGNvb3JkcyA9IFsnYicsICdyJywgJ2MnXTtcbiAgY29uc3QgaW5kZXggPSAnaW5kZXgnO1xuICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID0gc3RyaWRlc1xuICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzW2ldfSA9ICR7aW5kZXh9IC8gJHtzdHJpZGV9YDtcbiAgICAgIGNvbnN0IGxpbmUyID1cbiAgICAgICAgaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxXG4gICAgICAgICAgPyBgaW50ICR7Y29vcmRzW2kgKyAxXX0gPSAke2luZGV4fSAtICR7Y29vcmRzW2ldfSAqICR7c3RyaWRlfWBcbiAgICAgICAgICA6IGBpbmRleCAtPSAke2Nvb3Jkc1tpXX0gKiAke3N0cmlkZX1gO1xuICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICB9KVxuICAgIC5qb2luKCcnKTtcblxuICByZXR1cm4gYFxuICAgIGl2ZWMzIGlucHV0Q29vcmRzRnJvbVJlc2hhcGVkT3V0Q29vcmRzKGludCBpbmRleCkge1xuICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgcmV0dXJuIGl2ZWMzKGIsIHIsIGMpO1xuICAgIH1cbiAgYDtcbn1cblxuZnVuY3Rpb24gZ2V0RmxhdHRlbmVkSW5kZXhGcm9tM0Qoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSk6IHN0cmluZyB7XG4gIGNvbnN0IHN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoc2hhcGUpO1xuXG4gIHJldHVybiBgXG4gIGludCBnZXRGbGF0dGVuZWRJbmRleChpdmVjMyBjb29yZHMpIHtcbiAgICAvLyByZXZlcnNlIHksIHogb3JkZXJcbiAgICByZXR1cm4gY29vcmRzLnggKiAke3N0cmlkZXNbMF19ICsgY29vcmRzLnogKiAke3N0cmlkZXNbMV19ICsgY29vcmRzLnk7XG4gIH1cbmA7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBUZXh0dXJlRGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBlbmNvZGVBc1VpbnQ4ID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRleHR1cmVEYXRhKTogVGV4dHVyZURhdGEgPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0LnNoYXBlO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIC8qKlxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vdGVuc29yZmxvdy90ZmpzLWNvcmUvYmxvYi9tYXN0ZXIvc3JjL2tlcm5lbHMvd2ViZ2wvZW5jb2RlX2Zsb2F0X2dwdS50c1xuICAgKi9cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgIGNvbnN0IGZsb2F0IEZMT0FUX01BWCA9IDEuNzAxNDExODRlMzg7XG4gICAgY29uc3QgZmxvYXQgRkxPQVRfTUlOID0gMS4xNzU0OTQzNWUtMzg7XG5cbiAgICBib29sIGlzTmFOKGZsb2F0IHZhbCkge1xuICAgICAgcmV0dXJuICh2YWwgPCAxLjAgfHwgMC4wIDwgdmFsIHx8IHZhbCA9PSAwLjApID8gZmFsc2UgOiB0cnVlO1xuICAgIH1cblxuICAgIGhpZ2hwIHZlYzQgZW5jb2RlQXNVaW50OChoaWdocCBmbG9hdCB2KSB7XG4gICAgICBpZiAoaXNOYU4odikpIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoMjU1LCAyNTUsIDI1NSwgMjU1KTtcbiAgICAgIH1cblxuICAgICAgaGlnaHAgZmxvYXQgYXYgPSBhYnModik7XG5cbiAgICAgIGlmKGF2IDwgRkxPQVRfTUlOKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KDAuMCwgMC4wLCAwLjAsIDAuMCk7XG4gICAgICB9IGVsc2UgaWYodiA+IEZMT0FUX01BWCkge1xuICAgICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgMTI4LjAsIDEyNy4wKSAvIDI1NS4wO1xuICAgICAgfSBlbHNlIGlmKHYgPCAtRkxPQVRfTUFYKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KDAuMCwgMC4wLCAgMTI4LjAsIDI1NS4wKSAvIDI1NS4wO1xuICAgICAgfVxuXG4gICAgICBoaWdocCB2ZWM0IGMgPSB2ZWM0KDAsMCwwLDApO1xuXG4gICAgICBoaWdocCBmbG9hdCBlID0gZmxvb3IobG9nMihhdikpO1xuICAgICAgaGlnaHAgZmxvYXQgbSA9IGV4cDIoZnJhY3QobG9nMihhdikpKSAtIDEuMDtcblxuICAgICAgY1syXSA9IGZsb29yKDEyOC4wICogbSk7XG4gICAgICBtIC09IGNbMl0gLyAxMjguMDtcbiAgICAgIGNbMV0gPSBmbG9vcigzMjc2OC4wICogbSk7XG4gICAgICBtIC09IGNbMV0gLyAzMjc2OC4wO1xuICAgICAgY1swXSA9IGZsb29yKDgzODg2MDguMCAqIG0pO1xuXG4gICAgICBoaWdocCBmbG9hdCBlYmlhcyA9IGUgKyAxMjcuMDtcbiAgICAgIGNbM10gPSBmbG9vcihlYmlhcyAvIDIuMCk7XG4gICAgICBlYmlhcyAtPSBjWzNdICogMi4wO1xuICAgICAgY1syXSArPSBmbG9vcihlYmlhcykgKiAxMjguMDtcblxuICAgICAgY1szXSArPSAxMjguMCAqIHN0ZXAoMC4wLCAtdik7XG5cbiAgICAgIHJldHVybiBjIC8gMjU1LjA7XG4gICAgfVxuXG4gICAgdm9pZCBtYWluKCkge1xuICAgICAgZmxvYXQgdmFsdWUgPSAke2dsc2wudGV4dHVyZTJEfShYLFRleENvb3JkcykucjtcbiAgICAgICR7Z2xzbC5vdXRwdXR9ID0gZW5jb2RlQXNVaW50OCh2YWx1ZSk7XG4gICAgfWA7XG4gIGNvbnN0IHByb2dyYW1JbmZvID0ge1xuICAgIG5hbWU6ICdVaW50OEVuY29kZScsXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnRlbnNvci50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUuZG93bmxvYWRVaW50OEFzRmxvYXQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbiAgcmV0dXJuIGluZmVyZW5jZUhhbmRsZXIuZXhlY3V0ZVByb2dyYW0ocHJvZ3JhbUluZm8sIFtpbnB1dC50ZW5zb3JdKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyBnZXRDaGFubmVscywgdW5wYWNrRnJvbUNoYW5uZWwgfSBmcm9tICcuL3BhY2tpbmctdXRpbHMnO1xuXG5jb25zdCB1bnBhY2tQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICd1bnBhY2snLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm8gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCByYW5rID0gaW5wdXQuZGltcy5sZW5ndGg7XG5cbiAgY29uc3QgY2hhbm5lbHMgPSBnZXRDaGFubmVscygncmMnLCByYW5rKTtcbiAgY29uc3QgaW5uZXJEaW1zID0gY2hhbm5lbHMuc2xpY2UoLTIpO1xuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKHJhbmspO1xuICBjb25zdCB1bnBhY2tDaGFubmVsID0gdW5wYWNrRnJvbUNoYW5uZWwoKTtcbiAgY29uc3QgaXNTY2FsYXIgPSBpbnB1dC5kaW1zLmxlbmd0aCA9PT0gMDtcbiAgY29uc3Qgc291cmNlQ29vcmRzID0gaXNTY2FsYXIgPyAnJyA6IGdldFNvdXJjZUNvb3JkcyhyYW5rLCBjaGFubmVscyk7XG4gIGNvbnN0IGNvb3JkcyA9IHJhbmsgPD0gMSA/ICdyYycgOiBgdmVjMigke2lubmVyRGltcy5qb2luKCcsJyl9KWA7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICR7dW5wYWNrQ2hhbm5lbH1cbiAgICB2b2lkIG1haW4oKSB7XG4gICAgICAke2Nvb3Jkc0RhdGFUeXBlfSByYyA9IGdldE91dHB1dENvb3JkcygpO1xuXG4gICAgICAgLy8gU2FtcGxlIHRoZSB0ZXh0dXJlIHdpdGggdGhlIGNvb3JkcyB0byBnZXQgdGhlIHJnYmEgY2hhbm5lbCB2YWx1ZS5cbiAgICAgICB2ZWM0IHBhY2tlZElucHV0ID0gZ2V0QSgke3NvdXJjZUNvb3Jkc30pO1xuXG4gICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KGdldENoYW5uZWwocGFja2VkSW5wdXQsICR7Y29vcmRzfSksIDAsIDAsIDApO1xuICAgICB9XG4gICBgO1xuXG4gIHJldHVybiB7XG4gICAgLi4udW5wYWNrUHJvZ3JhbU1ldGFkYXRhLFxuICAgIGhhc01haW46IHRydWUsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVVbnBhY2tQcm9ncmFtSW5mb0xvYWRlciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiAoe1xuICAuLi51bnBhY2tQcm9ncmFtTWV0YWRhdGEsXG4gIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXQpLFxufSk7XG5cbmZ1bmN0aW9uIGdldFNvdXJjZUNvb3JkcyhyYW5rOiBudW1iZXIsIGRpbXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gJ3JjJztcbiAgfVxuXG4gIGxldCBjb29yZHMgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyBpKyspIHtcbiAgICBjb29yZHMgKz0gZGltc1tpXTtcbiAgICBpZiAoaSA8IHJhbmsgLSAxKSB7XG4gICAgICBjb29yZHMgKz0gJywnO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY29vcmRzO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEVuY29kZXIge1xuICBleHBvcnQgaW50ZXJmYWNlIERhdGFUeXBlTWFwIHtcbiAgICBmbG9hdDogRmxvYXQzMkFycmF5O1xuICAgIGJ5dGU6IFVpbnQ4QXJyYXk7XG4gICAgaW50OiBVaW50MzJBcnJheTtcbiAgfVxuICBleHBvcnQgdHlwZSBEYXRhVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xuICB0eXBlIERhdGFBcnJheVR5cGUgPSBEYXRhVHlwZU1hcFtEYXRhVHlwZV07XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xuZXhwb3J0IGNvbnN0IGVudW0gRW5jb2RlclVzYWdlIHtcbiAgRGVmYXVsdCA9IDAsXG4gIFVwbG9hZE9ubHksXG4gIERvd25sb2FkNEJ5dGVzQXNGbG9hdDMyLFxufVxuLyogZXNsaW50LWVuYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cblxuLyoqXG4gKiBBYnN0cmFjdGlvbiBmb3IgbWFwcGluZyBkYXRhIHR5cGVzIHRvIHRleHR1cmUgdGV4bGV0c1xuICogRW5jb2RpbmcgbWVhbnMgaG93IGEgRmxvYXQzMiBpcyBtYXBwZWQgdG8gMSBvciA0IGNoYW5uZWxzIGZvciBlYWNoIHRleGxldFxuICogRGVjb2RpbmcgbWVhbnMgaG93IGEgdGV4bGV0J3MgY2hhbm5lbHMgYXJlIG1hcHBlZCB0byBhIHJlc3VsdGluZyBGbG9hdDMyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YUVuY29kZXIge1xuICBpbnRlcm5hbEZvcm1hdDogbnVtYmVyO1xuICBmb3JtYXQ6IG51bWJlcjtcbiAgdGV4dHVyZVR5cGU6IG51bWJlcjtcbiAgY2hhbm5lbFNpemU6IG51bWJlcjtcbiAgZW5jb2RlKHNyYzogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCB0ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlO1xuICBhbGxvY2F0ZShzaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGU7XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZTtcbn1cbi8qKlxuICogV2ViR0wyIGRhdGEgZW5jb2RlclxuICogVXNlcyBSMzJGIGFzIHRoZSBmb3JtYXQgZm9yIHRleGxldFxuICovXG5leHBvcnQgY2xhc3MgUmVkRmxvYXQzMkRhdGFFbmNvZGVyIGltcGxlbWVudHMgRGF0YUVuY29kZXIge1xuICBpbnRlcm5hbEZvcm1hdDogbnVtYmVyO1xuICBmb3JtYXQ6IG51bWJlcjtcbiAgdGV4dHVyZVR5cGU6IG51bWJlcjtcbiAgY2hhbm5lbFNpemU6IG51bWJlcjtcbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMMlJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzID0gMSkge1xuICAgIGlmIChjaGFubmVscyA9PT0gMSkge1xuICAgICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLlIzMkY7XG4gICAgICB0aGlzLmZvcm1hdCA9IGdsLlJFRDtcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5GTE9BVDtcbiAgICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB9IGVsc2UgaWYgKGNoYW5uZWxzID09PSA0KSB7XG4gICAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuUkdCQTMyRjtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZ2wuUkdCQTtcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5GTE9BVDtcbiAgICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG51bWJlciBvZiBjaGFubmVsczogJHtjaGFubmVsc31gKTtcbiAgICB9XG4gIH1cbiAgZW5jb2RlKHNyYzogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCB0ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICBsZXQgcmVzdWx0OiBGbG9hdDMyQXJyYXk7XG4gICAgbGV0IHNvdXJjZTogRmxvYXQzMkFycmF5O1xuICAgIGlmIChzcmMuY29uc3RydWN0b3IgIT09IEZsb2F0MzJBcnJheSkge1xuICAgICAgTG9nZ2VyLndhcm5pbmcoJ0VuY29kZXInLCAnZGF0YSB3YXMgbm90IG9mIHR5cGUgRmxvYXQzMjsgY3JlYXRpbmcgbmV3IEZsb2F0MzJBcnJheScpO1xuICAgICAgc291cmNlID0gbmV3IEZsb2F0MzJBcnJheShzcmMpO1xuICAgIH1cbiAgICBpZiAodGV4dHVyZVNpemUgKiB0aGlzLmNoYW5uZWxTaXplID4gc3JjLmxlbmd0aCkge1xuICAgICAgTG9nZ2VyLndhcm5pbmcoJ0VuY29kZXInLCAnU291cmNlIGRhdGEgdG9vIHNtYWxsLiBBbGxvY2F0aW5nIGxhcmdlciBhcnJheScpO1xuICAgICAgc291cmNlID0gc3JjIGFzIEZsb2F0MzJBcnJheTtcbiAgICAgIHJlc3VsdCA9IHRoaXMuYWxsb2NhdGUodGV4dHVyZVNpemUgKiB0aGlzLmNoYW5uZWxTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICBzb3VyY2UuZm9yRWFjaCgodiwgaSkgPT4gKHJlc3VsdFtpXSA9IHYpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc291cmNlID0gc3JjIGFzIEZsb2F0MzJBcnJheTtcbiAgICAgIHJlc3VsdCA9IHNvdXJjZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBhbGxvY2F0ZShzaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KHNpemUgKiA0KTtcbiAgfVxuICBkZWNvZGUoYnVmZmVyOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIGRhdGFTaXplOiBudW1iZXIpOiBGbG9hdDMyQXJyYXkge1xuICAgIGlmICh0aGlzLmNoYW5uZWxTaXplID09PSAxKSB7XG4gICAgICBjb25zdCBmaWx0ZXJlZERhdGEgPSAoYnVmZmVyIGFzIEZsb2F0MzJBcnJheSkuZmlsdGVyKChfdmFsdWUsIGluZGV4KSA9PiBpbmRleCAlIDQgPT09IDApLnN1YmFycmF5KDAsIGRhdGFTaXplKTtcbiAgICAgIHJldHVybiBmaWx0ZXJlZERhdGE7XG4gICAgfVxuICAgIHJldHVybiBidWZmZXIuc3ViYXJyYXkoMCwgZGF0YVNpemUpIGFzIEZsb2F0MzJBcnJheTtcbiAgfVxufVxuLyoqXG4gKiBEYXRhIGVuY29kZXIgZm9yIFdlYkdMIDEgd2l0aCBzdXBwb3J0IGZvciBmbG9hdGluZyBwb2ludCB0ZXh0dXJlXG4gKi9cbmV4cG9ydCBjbGFzcyBSR0JBRmxvYXREYXRhRW5jb2RlciBpbXBsZW1lbnRzIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplOiBudW1iZXI7XG4gIGNvbnN0cnVjdG9yKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzID0gMSwgdGV4dHVyZVR5cGU/OiBudW1iZXIpIHtcbiAgICBpZiAoY2hhbm5lbHMgIT09IDEgJiYgY2hhbm5lbHMgIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgb2YgY2hhbm5lbHM6ICR7Y2hhbm5lbHN9YCk7XG4gICAgfVxuICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SR0JBO1xuICAgIHRoaXMuZm9ybWF0ID0gZ2wuUkdCQTtcbiAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgdGhpcy50ZXh0dXJlVHlwZSA9IHRleHR1cmVUeXBlIHx8IGdsLkZMT0FUO1xuICB9XG4gIGVuY29kZShzcmM6IEZsb2F0MzJBcnJheSwgdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgbGV0IGRlc3QgPSBzcmM7XG4gICAgaWYgKHRoaXMuY2hhbm5lbFNpemUgPT09IDEpIHtcbiAgICAgIExvZ2dlci52ZXJib3NlKCdFbmNvZGVyJywgJ0V4cGxvZGluZyBpbnRvIGEgbGFyZ2VyIGFycmF5Jyk7XG4gICAgICBkZXN0ID0gdGhpcy5hbGxvY2F0ZSh0ZXh0dXJlU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgc3JjLmZvckVhY2goKHYsIGkpID0+IChkZXN0W2kgKiA0XSA9IHYpKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlc3Q7XG4gIH1cbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShzaXplICogNCk7XG4gIH1cbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogRmxvYXQzMkFycmF5IHtcbiAgICBpZiAodGhpcy5jaGFubmVsU2l6ZSA9PT0gMSkge1xuICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gKGJ1ZmZlciBhcyBGbG9hdDMyQXJyYXkpLmZpbHRlcigoX3ZhbHVlLCBpbmRleCkgPT4gaW5kZXggJSA0ID09PSAwKS5zdWJhcnJheSgwLCBkYXRhU2l6ZSk7XG4gICAgICByZXR1cm4gZmlsdGVyZWREYXRhO1xuICAgIH1cbiAgICByZXR1cm4gYnVmZmVyLnN1YmFycmF5KDAsIGRhdGFTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFVpbnQ4RGF0YUVuY29kZXIgaW1wbGVtZW50cyBEYXRhRW5jb2RlciB7XG4gIGludGVybmFsRm9ybWF0OiBudW1iZXI7XG4gIGZvcm1hdDogbnVtYmVyO1xuICB0ZXh0dXJlVHlwZTogbnVtYmVyO1xuICBjaGFubmVsU2l6ZSA9IDQ7XG4gIGNvbnN0cnVjdG9yKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzID0gMSkge1xuICAgIGlmIChjaGFubmVscyA9PT0gMSkge1xuICAgICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLkFMUEhBO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5BTFBIQTsgLy8gbm90IHRlc3RlZFxuICAgICAgdGhpcy50ZXh0dXJlVHlwZSA9IGdsLlVOU0lHTkVEX0JZVEU7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIGlmIChjaGFubmVscyA9PT0gNCkge1xuICAgICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLlJHQkE7XG4gICAgICB0aGlzLmZvcm1hdCA9IGdsLlJHQkE7XG4gICAgICB0aGlzLnRleHR1cmVUeXBlID0gZ2wuVU5TSUdORURfQllURTtcbiAgICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG51bWJlciBvZiBjaGFubmVsczogJHtjaGFubmVsc31gKTtcbiAgICB9XG4gIH1cbiAgZW5jb2RlKHNyYzogVWludDhBcnJheSwgX3RleHR1cmVTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShzcmMuYnVmZmVyLCBzcmMuYnl0ZU9mZnNldCwgc3JjLmJ5dGVMZW5ndGgpO1xuICB9XG4gIGFsbG9jYXRlKHNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHNpemUgKiB0aGlzLmNoYW5uZWxTaXplKTtcbiAgfVxuICBkZWNvZGUoYnVmZmVyOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIGRhdGFTaXplOiBudW1iZXIpOiBVaW50OEFycmF5IHtcbiAgICBpZiAoYnVmZmVyIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgcmV0dXJuIGJ1ZmZlci5zdWJhcnJheSgwLCBkYXRhU2l6ZSk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhcnJheSB0eXBlOiAke2J1ZmZlci5jb25zdHJ1Y3Rvcn1gKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcblxuaW1wb3J0IHsgVGV4dHVyZUxheW91dFN0cmF0ZWd5LCBXaWR0aEhlaWdodFByZWZzIH0gZnJvbSAnLi90ZXh0dXJlLWxheW91dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBUZXh0dXJlTGF5b3V0LCBUZXh0dXJlVHlwZSB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZSA9IChcbiAgdGV4dHVyZUxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLFxuKTogVGV4dHVyZUxheW91dCA9PiB7XG4gIGNvbnN0IGNoYW5uZWwgPSB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUudW5wYWNrZWQgfHwgdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnVucGFja2VkUmV2ZXJzZWQgPyAxIDogNDtcbiAgY29uc3QgaXNQYWNrZWQgPSB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkO1xuICBjb25zdCByZXZlcnNlV0ggPSB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUudW5wYWNrZWRSZXZlcnNlZCB8fCB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkO1xuICBjb25zdCBicmVha0F4aXMgPSB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbiA/IHNoYXBlLmxlbmd0aCAtIDEgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHVucGFja2VkU2hhcGUgPVxuICAgIHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uXG4gICAgICA/IHNoYXBlLm1hcCgoZCwgaSkgPT4gKGkgPT09IHNoYXBlLmxlbmd0aCAtIDEgPyBkICogNCA6IGQpKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIHJldHVybiBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVNoYXBlKHRleHR1cmVMYXlvdXRTdHJhdGVneSwgc2hhcGUsIGNoYW5uZWwsIHVucGFja2VkU2hhcGUsIHtcbiAgICBpc1BhY2tlZCxcbiAgICByZXZlcnNlV0gsXG4gICAgYnJlYWtBeGlzLFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQgPSAoXG4gIHRleHR1cmVMYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZSxcbik6IFtudW1iZXIsIG51bWJlcl0gPT4ge1xuICBjb25zdCBsYXlvdXQgPSBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlKHRleHR1cmVMYXlvdXRTdHJhdGVneSwgc2hhcGUsIHRleHR1cmVUeXBlKTtcbiAgcmV0dXJuIFtsYXlvdXQud2lkdGgsIGxheW91dC5oZWlnaHRdO1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYSBUZXh0dXJlTGF5b3V0IG9iamVjdCBmcm9tIHNoYXBlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSA9IChcbiAgdGV4dHVyZUxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgY2hhbm5lbHM6IDEgfCA0ID0gMSxcbiAgdW5wYWNrZWRTaGFwZT86IHJlYWRvbmx5IG51bWJlcltdLFxuICBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMsXG4pOiBUZXh0dXJlTGF5b3V0ID0+IHtcbiAgY29uc3QgaXNQYWNrZWQgPSAhIShwcmVmcyAmJiBwcmVmcy5pc1BhY2tlZCk7XG4gIGNvbnN0IFt3aWR0aCwgaGVpZ2h0XSA9IHRleHR1cmVMYXlvdXRTdHJhdGVneS5jb21wdXRlVGV4dHVyZVdIKGlzUGFja2VkID8gdW5wYWNrZWRTaGFwZSB8fCBzaGFwZSA6IHNoYXBlLCBwcmVmcyk7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gIGxldCBpbmZlcnJlZERpbXMgPSBzaGFwZS5zbGljZSgwKTtcbiAgaWYgKHJhbmsgPT09IDApIHtcbiAgICBpbmZlcnJlZERpbXMgPSBbMV07XG4gIH1cbiAgaWYgKGNoYW5uZWxzID09PSAxKSB7XG4gICAgLy8gdW5wYWNrZWRTaGFwZSB3aWxsIHRha2UgYHNoYXBlYCBhbmQgbm90IGBpbmZlcnJlZERpbXNgIHNvIGFzIHRvIGNyZWF0ZSBhIHNjYWxhciBUZW5zb3IgaWYgbmVlZCBiZVxuICAgIHVucGFja2VkU2hhcGUgPSBzaGFwZTtcbiAgfSBlbHNlIGlmIChpc1BhY2tlZCkge1xuICAgIGlmIChjaGFubmVscyAhPT0gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhIHBhY2tlZCB0ZXh0dXJlIG11c3QgYmUgNC1jaGFubmVsJyk7XG4gICAgfVxuICAgIHVucGFja2VkU2hhcGUgPSBzaGFwZTtcbiAgICBpZiAocmFuayA+IDApIHtcbiAgICAgIGluZmVycmVkRGltc1tyYW5rIC0gMV0gPSBNYXRoLmNlaWwoaW5mZXJyZWREaW1zW3JhbmsgLSAxXSAvIDIpO1xuICAgIH1cbiAgICBpZiAocmFuayA+IDEpIHtcbiAgICAgIGluZmVycmVkRGltc1tyYW5rIC0gMl0gPSBNYXRoLmNlaWwoaW5mZXJyZWREaW1zW3JhbmsgLSAyXSAvIDIpO1xuICAgIH1cbiAgfSBlbHNlIGlmICghdW5wYWNrZWRTaGFwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5wYWNrZWQgc2hhcGUgaXMgbmVlZGVkIHdoZW4gdXNpbmcgY2hhbm5lbHMgPiAxJyk7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgY2hhbm5lbHMsXG4gICAgaXNQYWNrZWQsXG4gICAgc2hhcGU6IGluZmVycmVkRGltcyxcbiAgICBzdHJpZGVzOiBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoaW5mZXJyZWREaW1zKSxcbiAgICB1bnBhY2tlZFNoYXBlLFxuICAgIHJldmVyc2VkV0g6IHByZWZzICYmIHByZWZzLnJldmVyc2VXSCxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5pbXBvcnQgeyBjcmVhdGVQYWNrUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL29wcy9wYWNrJztcbmltcG9ydCB7IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvTG9hZGVyLCBpc1Jlc2hhcGVDaGVhcCwgcHJvY2Vzc0RpbXMzRCB9IGZyb20gJy4vb3BzL3Jlc2hhcGUtcGFja2VkJztcbmltcG9ydCB7IGVuY29kZUFzVWludDggfSBmcm9tICcuL29wcy91aW50OC1lbmNvZGUnO1xuaW1wb3J0IHsgY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL29wcy91bnBhY2snO1xuaW1wb3J0IHsgV2ViR0xTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4vc2Vzc2lvbi1oYW5kbGVyJztcbmltcG9ydCB7IEVuY29kZXJVc2FnZSB9IGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHtcbiAgY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0LFxuICBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVNoYXBlLFxuICBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlLFxufSBmcm9tICcuL3RleHR1cmUtbGF5b3V0JztcbmltcG9ydCB7IEFydGlmYWN0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVEYXRhLCBUZXh0dXJlTGF5b3V0LCBUZXh0dXJlVHlwZSB9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBnZXRQcm9ncmFtSW5mb1VuaXF1ZUtleSA9IChcbiAgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvIHwgUHJvZ3JhbUluZm9Mb2FkZXIsXG4gIGlucHV0VGV4dHVyZURhdGFzOiBUZXh0dXJlRGF0YVtdLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgaW5wdXRzID0gaW5wdXRUZXh0dXJlRGF0YXNcbiAgICAubWFwKCh0ZXh0dXJlKSA9PiBgJHt0ZXh0dXJlLnVucGFja2VkU2hhcGUuam9pbignLCcpfTske3RleHR1cmUud2lkdGh9eCR7dGV4dHVyZS5oZWlnaHR9YClcbiAgICAuam9pbignXycpO1xuICBsZXQga2V5ID0gcHJvZ3JhbUluZm8ubmFtZTtcbiAgaWYgKHByb2dyYW1JbmZvLmNhY2hlSGludCkge1xuICAgIGtleSArPSAnWycgKyBwcm9ncmFtSW5mby5jYWNoZUhpbnQgKyAnXSc7XG4gIH1cbiAga2V5ICs9ICc6JyArIGlucHV0cztcbiAgcmV0dXJuIGtleTtcbn07XG5cbmV4cG9ydCBjbGFzcyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgaW1wbGVtZW50cyBJbmZlcmVuY2VIYW5kbGVyIHtcbiAgcHJpdmF0ZSBwYWNrZWRUZXh0dXJlRGF0YUNhY2hlOiBNYXA8VGVuc29yLklkLCBUZXh0dXJlRGF0YT47XG4gIHByaXZhdGUgdW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlOiBNYXA8VGVuc29yLklkLCBUZXh0dXJlRGF0YT47XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBzZXNzaW9uOiBXZWJHTFNlc3Npb25IYW5kbGVyKSB7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIFt3aWR0aCwgaGVpZ2h0XVxuICAgKi9cbiAgY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodCh0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksIHNoYXBlLCB0ZXh0dXJlVHlwZSk7XG4gIH1cblxuICBleGVjdXRlUHJvZ3JhbShwcm9ncmFtOiBQcm9ncmFtSW5mbyB8IFByb2dyYW1JbmZvTG9hZGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdKTogVGV4dHVyZURhdGEge1xuICAgIGlmIChpbnB1dHMubGVuZ3RoIDwgcHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnB1dCBzaXplIG11c3RuJ3QgYmUgbGVzcyB0aGFuICR7cHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aH0uYCk7XG4gICAgfVxuICAgIGlmIChwcm9ncmFtLmlucHV0TmFtZXMubGVuZ3RoICE9PSBwcm9ncmFtLmlucHV0VHlwZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IG5hbWVzIHNpemUgZG9lcyBub3QgbWF0Y2ggaW5wdXQgdHlwZXMnKTtcbiAgICB9XG5cbiAgICAvLyBjcmVhdGUgdGV4dHVyZSBpbmZvIGZvciBpbnB1dFxuICAgIGNvbnN0IGlucHV0VGV4dHVyZURhdGFzOiBUZXh0dXJlRGF0YVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm9ncmFtLmlucHV0TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlucHV0VGV4dHVyZURhdGFzW2ldID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0c1tpXSwgcHJvZ3JhbS5pbnB1dFR5cGVzW2ldKTtcbiAgICB9XG5cbiAgICBjb25zdCBrZXkgPSBnZXRQcm9ncmFtSW5mb1VuaXF1ZUtleShwcm9ncmFtLCBpbnB1dFRleHR1cmVEYXRhcyk7XG4gICAgbGV0IGFydGlmYWN0ID0gdGhpcy5zZXNzaW9uLnByb2dyYW1NYW5hZ2VyLmdldEFydGlmYWN0KGtleSk7XG4gICAgY29uc3QgcHJvZ3JhbUluZm8gPSBhcnRpZmFjdFxuICAgICAgPyBhcnRpZmFjdC5wcm9ncmFtSW5mb1xuICAgICAgOiB0eXBlb2YgKHByb2dyYW0gYXMgUHJvZ3JhbUluZm9Mb2FkZXIpLmdldCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IChwcm9ncmFtIGFzIFByb2dyYW1JbmZvTG9hZGVyKS5nZXQoKVxuICAgICAgICA6IChwcm9ncmFtIGFzIFByb2dyYW1JbmZvKTtcblxuICAgIC8vIGNyZWF0ZSB0ZXh0dXJlIGluZm8gZm9yIG91dHB1dFxuICAgIGNvbnN0IG91dHB1dFRleHR1cmVMYXlvdXQgPSBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlKFxuICAgICAgdGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LFxuICAgICAgcHJvZ3JhbUluZm8ub3V0cHV0LmRpbXMsXG4gICAgICBwcm9ncmFtSW5mby5vdXRwdXQudGV4dHVyZVR5cGUsXG4gICAgKTtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGEob3V0cHV0VGV4dHVyZUxheW91dCwgcHJvZ3JhbUluZm8ub3V0cHV0LnR5cGUpO1xuXG4gICAgaWYgKCFhcnRpZmFjdCkge1xuICAgICAgYXJ0aWZhY3QgPSB0aGlzLnNlc3Npb24ucHJvZ3JhbU1hbmFnZXIuYnVpbGQocHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZURhdGFzLCBvdXRwdXRUZXh0dXJlRGF0YSk7XG4gICAgICB0aGlzLnNlc3Npb24ucHJvZ3JhbU1hbmFnZXIuc2V0QXJ0aWZhY3Qoa2V5LCBhcnRpZmFjdCk7XG4gICAgfVxuXG4gICAgdGhpcy5ydW5Qcm9ncmFtKGFydGlmYWN0LCBpbnB1dFRleHR1cmVEYXRhcywgb3V0cHV0VGV4dHVyZURhdGEpO1xuICAgIHJldHVybiBvdXRwdXRUZXh0dXJlRGF0YTtcbiAgfVxuXG4gIHJ1bihwcm9ncmFtOiBQcm9ncmFtSW5mb0xvYWRlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSk6IFRlbnNvciB7XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZURhdGEgPSB0aGlzLmV4ZWN1dGVQcm9ncmFtKHByb2dyYW0sIGlucHV0cyk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhLnRlbnNvcjtcbiAgfVxuXG4gIHByaXZhdGUgcnVuUHJvZ3JhbShhcnRpZmFjdDogQXJ0aWZhY3QsIGlucHV0czogVGV4dHVyZURhdGFbXSwgb3V0cHV0OiBUZXh0dXJlRGF0YSk6IHZvaWQge1xuICAgIC8vIGlucHV0IHNob3VsZCBtYXRjaFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAoISFpbnB1dHNbaV0uaXNQYWNrZWQgIT09IChhcnRpZmFjdC5wcm9ncmFtSW5mby5pbnB1dFR5cGVzW2ldID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRbJHtpfV0gcHJvcGVydHkgcGFja2VkIGluY29uc2lzdGVudGApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIG91dHB1dCBzaG91bGQgbWF0Y2hcbiAgICBpZiAoISFvdXRwdXQuaXNQYWNrZWQgIT09IChhcnRpZmFjdC5wcm9ncmFtSW5mby5vdXRwdXQudGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb3V0cHV0IHByb3BlcnR5IHBhY2tlZCBpbmNvbnNpc3RlbnQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnNlc3Npb24ucHJvZ3JhbU1hbmFnZXIucnVuKGFydGlmYWN0LCBpbnB1dHMsIG91dHB1dCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgVGV4dHVyZURhdGEgb2JqZWN0IGZyb20gYSB0ZW5zb3IuXG4gICAqIFVzYWdlID0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkuXG4gICAqIElmIGEgcmVsYXRlZCB0ZXh0dXJlIGRhdGEgaXMgZm91bmQgaW4gY2FjaGUsIHJldHVybnMgaXQ7XG4gICAqIE90aGVyd2lzZTpcbiAgICogICBDcmVhdGVzIGEgbmV3IHRleHR1cmUgbGF5b3V0IGlmIG5vdCBwcm92aWRlZDtcbiAgICogICBDcmVhdGVzIFdlYkdMVGV4dHVyZSB3aXRoIHRoZSBsYXlvdXQ7XG4gICAqICAgVXBsb2FkIHRlbnNvciBkYXRhIHRvIHRoZSB0ZXh0dXJlO1xuICAgKiAgIENyZWF0ZXMgYSB0ZXh0dXJlIGRhdGEgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gdGVuc29yLlxuICAgKiBAcGFyYW0gdGVuc29yIHRoZSB0ZW5zb3Igd2l0aCBkYXRhIHRvIHVwbG9hZFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRPckNyZWF0ZVRleHR1cmVEYXRhKHRlbnNvcjogVGVuc29yLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUpIHtcbiAgICBsZXQgdGQgPSB0aGlzLmdldFRleHR1cmVEYXRhKHRlbnNvci5kYXRhSWQsIHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpO1xuXG4gICAgaWYgKCF0ZCkge1xuICAgICAgLy8gY2hlY2sgaWYgd2UgaGF2ZSB0ZXh0dXJlIGRhdGEgaW4gZGlmZmVyZW50IHR5cGVcbiAgICAgIHRkID0gdGhpcy5nZXRUZXh0dXJlRGF0YSh0ZW5zb3IuZGF0YUlkLCB0ZXh0dXJlVHlwZSAhPT0gVGV4dHVyZVR5cGUucGFja2VkKTtcbiAgICAgIGlmICh0ZCkge1xuICAgICAgICBpZiAodGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnBhY2sodGQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLnVucGFjayh0ZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRkKSB7XG4gICAgICBjb25zdCBsYXlvdXQgPSBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlKHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSwgdGVuc29yLmRpbXMsIHRleHR1cmVUeXBlKTtcblxuICAgICAgaWYgKHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uKSB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gMTtcbiAgICAgICAgY29uc3QgY2hhbm5lbHMgPSA0O1xuICAgICAgICBjb25zdCBzaGFwZSA9IHRlbnNvci5kaW1zO1xuICAgICAgICBpZiAoc2hhcGUubGVuZ3RoID09PSA0KSB7XG4gICAgICAgICAgLy8gcHJlLXByb2Nlc3NpbmcgZm9yIGtlcm5lbCBkYXRhIG9mIENvbnYuXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBUT0RPOiBjdXJyZW50bHkgdGhpcyBpcyBhIGhhY2tpbmcgdG8gb3ZlcndyaXRlIENvbnYncyB3ZWlnaHQuIFRoZSBjb3JyZWN0IHdheSB0byBkbyB0aGlzIHNob3VsZCBiZTpcbiAgICAgICAgICAvLyAxLiBpbXBsZW1lbnQgdGV4dHVyZSBiYXNlZCBjb25zdC1mb2xkaW5nXG4gICAgICAgICAgLy8gMi4gY3JlYXRlIGEgV2ViR0wgcHJvZ3JhbSBcInByZXByb2Nlc3NDb252V2VpZ2h0XCIgdG8gZG8gdGhlIHNhbWUgd29yayBhcyBiZWxvd1xuICAgICAgICAgIC8vIDMuIHJ1biB0aGUgcHJvZ3JhbSBiZWZvcmUgZG90UHJvZHVjdC5cbiAgICAgICAgICAvL1xuICAgICAgICAgIGNvbnN0IGFkanVzdGVkS2VybmVsU2hhcGUgPSBbc2hhcGVbMF0sIE1hdGguY2VpbCgoc2hhcGVbMV0gKiBzaGFwZVsyXSAqIHNoYXBlWzNdKSAvIGNoYW5uZWxzKV07XG4gICAgICAgICAgY29uc3QgYWRqdXN0ZWRMYXlvdXQgPSBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlKFxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LFxuICAgICAgICAgICAgYWRqdXN0ZWRLZXJuZWxTaGFwZSxcbiAgICAgICAgICAgIHRleHR1cmVUeXBlLFxuICAgICAgICAgICk7XG4gICAgICAgICAgbGV0IGJ1ZmZlciA9IHRlbnNvci5udW1iZXJEYXRhO1xuICAgICAgICAgIGlmICgoc2hhcGVbMV0gKiBzaGFwZVsyXSAqIHNoYXBlWzNdKSAlIGNoYW5uZWxzICE9PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBudW1GZWF0dXJlTWFwcyA9IHNoYXBlWzBdO1xuICAgICAgICAgICAgY29uc3Qgb2xkUm93U2l6ZSA9IHNoYXBlWzFdICogc2hhcGVbMl0gKiBzaGFwZVszXTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1Jvd1NpemUgPSBNYXRoLmNlaWwoKG9sZFJvd1NpemUgKiBncm91cCkgLyBjaGFubmVscykgKiBjaGFubmVscztcbiAgICAgICAgICAgIGNvbnN0IG5ld1NpemUgPSBudW1GZWF0dXJlTWFwcyAqIG5ld1Jvd1NpemU7XG4gICAgICAgICAgICBidWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KG5ld1NpemUpO1xuICAgICAgICAgICAgZm9yIChsZXQgZiA9IDA7IGYgPCBudW1GZWF0dXJlTWFwczsgKytmKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG9sZE9mZnNldCA9IGYgKiBvbGRSb3dTaXplO1xuICAgICAgICAgICAgICBjb25zdCBuZXdPZmZzZXQgPSBmICogbmV3Um93U2l6ZSArIChmICUgZ3JvdXApICogb2xkUm93U2l6ZTtcbiAgICAgICAgICAgICAgYnVmZmVyLnNldCh0ZW5zb3IubnVtYmVyRGF0YS5zdWJhcnJheShvbGRPZmZzZXQsIG9sZE9mZnNldCArIG9sZFJvd1NpemUpLCBuZXdPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShhZGp1c3RlZExheW91dCwgdGVuc29yLnR5cGUsIGJ1ZmZlciwgdGVuc29yLCBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpIHtcbiAgICAgICAgY29uc3QgdW5wYWNrZWRUZXh0dXJlTGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSh0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksIHRlbnNvci5kaW1zLCAxLCBbXSwge1xuICAgICAgICAgIHJldmVyc2VXSDogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHVucGFja2VkVGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKFxuICAgICAgICAgIHVucGFja2VkVGV4dHVyZUxheW91dCxcbiAgICAgICAgICB0ZW5zb3IudHlwZSxcbiAgICAgICAgICB0ZW5zb3IubnVtYmVyRGF0YSxcbiAgICAgICAgICB0ZW5zb3IsXG4gICAgICAgICAgRW5jb2RlclVzYWdlLlVwbG9hZE9ubHksXG4gICAgICAgICk7XG4gICAgICAgIHRkID0gdGhpcy5wYWNrKHVucGFja2VkVGV4dHVyZURhdGEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGQgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKGxheW91dCwgdGVuc29yLnR5cGUsIHRlbnNvci5udW1iZXJEYXRhLCB0ZW5zb3IsIEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRkO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIFRleHR1cmVEYXRhIG9iamVjdCB1c2luZyB0aGUgZ2l2ZW4gZGF0YSBhbmQgYmluZCB0byB0aGUgZ2l2ZW4gdGVuc29yLlxuICAgKiBVc2FnZSA9IEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5LlxuICAgKiBOT1RFOiB0aGlzIGZ1bmN0aW9uIGlzIGEgaGFjayBmb3IgQ29udiBpbXBsZW1lbnRhdGlvbi4gc2hvdWxkIHJlbW92ZSB0aGlzIGZ1bmN0aW9uLCBhZnRlciByZXdyaXRpbmcgQ29udlxuICAgKiBpbXBsZW1lbnRhdGlvbiBieSBHcmFwaC5UcmFuc2Zvcm1lclxuICAgKiBAcGFyYW0gZGF0YVR5cGUgdGhlIHRlbnNvciBkYXRhIHR5cGVcbiAgICogQHBhcmFtIGRhdGEgdGhlIGFjdHVhbCBkYXRhIHRvIHVwbG9hZFxuICAgKiBAcGFyYW0gdGVuc29yIHRoZSB0ZW5zb3IgdG8gYmluZC4gdGVuc29yJ3MgZGF0YSBpcyBpZ25vcmVkLlxuICAgKi9cbiAgY3JlYXRlVGV4dHVyZURhdGFGcm9tTGF5b3V0QmluZFRlbnNvcihcbiAgICBsYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSxcbiAgICBkYXRhOiBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICB0ZW5zb3I6IFRlbnNvcixcbiAgKTogVGV4dHVyZURhdGEge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKGxheW91dCwgZGF0YVR5cGUsIGRhdGEsIHRlbnNvciwgRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVUZXh0dXJlRGF0YShcbiAgICBsYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSxcbiAgICBkYXRhPzogVGVuc29yLk51bWJlclR5cGUsXG4gICAgdGVuc29yPzogVGVuc29yLFxuICAgIHVzYWdlPzogRW5jb2RlclVzYWdlLFxuICApOiBUZXh0dXJlRGF0YSB7XG4gICAgTG9nZ2VyLnZlcmJvc2UoJ0luZmVyZW5jZUhhbmRsZXInLCBgQ3JlYXRpbmcgVGV4dHVyZURhdGE6IGxheW91dDpbJHtKU09OLnN0cmluZ2lmeShsYXlvdXQpfV1gKTtcbiAgICBjb25zdCB0ZXh0dXJlID0gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLmNyZWF0ZVRleHR1cmVGcm9tTGF5b3V0KGRhdGFUeXBlLCBsYXlvdXQsIGRhdGEsIHVzYWdlKTtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YUZyb21UZXh0dXJlKGxheW91dCwgZGF0YVR5cGUsIHRleHR1cmUsIHRlbnNvcik7XG4gIH1cblxuICByZXNoYXBlVW5wYWNrZWQoaW5wdXQ6IFRlbnNvciwgcmVzaGFwZWREaW1zOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvciB7XG4gICAgY29uc3QgaW5wdXRURCA9IHRoaXMuZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YShpbnB1dCwgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICAgIGNvbnN0IG5ld1RleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSB7XG4gICAgICBjaGFubmVsczogaW5wdXRURC5jaGFubmVscyxcbiAgICAgIGhlaWdodDogaW5wdXRURC5oZWlnaHQsXG4gICAgICB3aWR0aDogaW5wdXRURC53aWR0aCxcbiAgICAgIC8vIGhhbmRsZSByZXNoYXBpbmcgaW50byBzY2FsYXIgVGVuc29yc1xuICAgICAgc2hhcGU6IHJlc2hhcGVkRGltcy5sZW5ndGggIT09IDAgPyByZXNoYXBlZERpbXMgOiBbMV0sXG4gICAgICBzdHJpZGVzOiBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMocmVzaGFwZWREaW1zKSxcbiAgICAgIHVucGFja2VkU2hhcGU6IHJlc2hhcGVkRGltcyxcbiAgICB9O1xuICAgIGNvbnN0IG5ld1RleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YUZyb21UZXh0dXJlKG5ld1RleHR1cmVMYXlvdXQsIGlucHV0LnR5cGUsIGlucHV0VEQudGV4dHVyZSk7XG4gICAgcmV0dXJuIG5ld1RleHR1cmVEYXRhLnRlbnNvcjtcbiAgfVxuXG4gIHJlc2hhcGVQYWNrZWQoaW5wdXQ6IFRlbnNvciwgcmVzaGFwZWREaW1zOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvciB7XG4gICAgY29uc3QgaW5wdXRURCA9IHRoaXMuZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YShpbnB1dCwgVGV4dHVyZVR5cGUucGFja2VkKTtcblxuICAgIC8vIGNoZWNrIGlmIHRoZSByZXNoYXBlIGlzICdjaGVhcCdcbiAgICBpZiAoaXNSZXNoYXBlQ2hlYXAoaW5wdXQuZGltcywgcmVzaGFwZWREaW1zKSkge1xuICAgICAgY29uc3QgbmV3VGV4dHVyZUxheW91dDogVGV4dHVyZUxheW91dCA9IHtcbiAgICAgICAgY2hhbm5lbHM6IGlucHV0VEQuY2hhbm5lbHMsXG4gICAgICAgIGhlaWdodDogaW5wdXRURC5oZWlnaHQsXG4gICAgICAgIHdpZHRoOiBpbnB1dFRELndpZHRoLFxuICAgICAgICAvLyBoYW5kbGUgcmVzaGFwaW5nIGludG8gc2NhbGFyIFRlbnNvcnNcbiAgICAgICAgc2hhcGU6IHJlc2hhcGVkRGltcy5sZW5ndGggIT09IDAgPyByZXNoYXBlZERpbXMgOiBbMV0sXG4gICAgICAgIHN0cmlkZXM6IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhyZXNoYXBlZERpbXMpLFxuICAgICAgICB1bnBhY2tlZFNoYXBlOiByZXNoYXBlZERpbXMsXG4gICAgICAgIGlzUGFja2VkOiB0cnVlLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG5ld1RleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YUZyb21UZXh0dXJlKG5ld1RleHR1cmVMYXlvdXQsIGlucHV0LnR5cGUsIGlucHV0VEQudGV4dHVyZSk7XG4gICAgICByZXR1cm4gbmV3VGV4dHVyZURhdGEudGVuc29yO1xuICAgIH1cblxuICAgIGNvbnN0IHNxdWVlemVkSW5wdXRTaGFwZSA9IHByb2Nlc3NEaW1zM0QoaW5wdXQuZGltcyk7XG4gICAgY29uc3Qgc3F1ZWV6ZWRPdXRwdXRTaGFwZSA9IHByb2Nlc3NEaW1zM0QocmVzaGFwZWREaW1zKTtcblxuICAgIGNvbnN0IHNxdWVlemVkSW5wdXRUZW5zb3IgPSB0aGlzLnJlc2hhcGVQYWNrZWQoaW5wdXQsIHNxdWVlemVkSW5wdXRTaGFwZSk7XG4gICAgY29uc3Qgc3F1ZWV6ZWRPdXRwdXRUZW5zb3IgPSB0aGlzLnJ1bihcbiAgICAgIGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvTG9hZGVyKHRoaXMsIHNxdWVlemVkSW5wdXRUZW5zb3IsIHNxdWVlemVkT3V0cHV0U2hhcGUpLFxuICAgICAgW3NxdWVlemVkSW5wdXRUZW5zb3JdLFxuICAgICk7XG4gICAgY29uc3Qgb3V0cHV0VGVuc29yID0gdGhpcy5yZXNoYXBlUGFja2VkKHNxdWVlemVkT3V0cHV0VGVuc29yLCByZXNoYXBlZERpbXMpO1xuICAgIHJldHVybiBvdXRwdXRUZW5zb3I7XG4gIH1cblxuICBjYXN0KGlucHV0OiBUZW5zb3IsIHR5cGU6IFRlbnNvci5EYXRhVHlwZSk6IFRlbnNvciB7XG4gICAgY29uc3QgaW5wdXRURCA9IHRoaXMuZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YShpbnB1dCwgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICAgIGNvbnN0IG5ld1RleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YUZyb21UZXh0dXJlKGlucHV0VEQgYXMgVGV4dHVyZUxheW91dCwgdHlwZSwgaW5wdXRURC50ZXh0dXJlKTtcbiAgICByZXR1cm4gbmV3VGV4dHVyZURhdGEudGVuc29yO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVUZXh0dXJlRGF0YUZyb21UZXh0dXJlKFxuICAgIGxheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLFxuICAgIHRleHR1cmU6IFdlYkdMVGV4dHVyZSxcbiAgICB0ZW5zb3I/OiBUZW5zb3IsXG4gICAgdGVuc29ySWQ/OiBUZW5zb3IuSWQsXG4gICkge1xuICAgIGNvbnN0IHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSA9IHtcbiAgICAgIC4uLmxheW91dCxcbiAgICAgIHRlbnNvcjpcbiAgICAgICAgdGVuc29yIHx8XG4gICAgICAgIG5ldyBUZW5zb3IoXG4gICAgICAgICAgbGF5b3V0LnVucGFja2VkU2hhcGUsXG4gICAgICAgICAgZGF0YVR5cGUsXG4gICAgICAgICAgKF9pZDogVGVuc29yLklkKSA9PiB0aGlzLnJlYWRUZXh0dXJlKHRleHR1cmVEYXRhKSxcbiAgICAgICAgICBhc3luYyAoX2lkOiBUZW5zb3IuSWQpID0+IHRoaXMucmVhZFRleHR1cmVBc3luYyh0ZXh0dXJlRGF0YSksXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHRlbnNvcklkLFxuICAgICAgICApLFxuICAgICAgdGV4dHVyZSxcbiAgICB9O1xuICAgIHRoaXMuc2V0VGV4dHVyZURhdGEodGV4dHVyZURhdGEudGVuc29yLmRhdGFJZCwgdGV4dHVyZURhdGEsIGxheW91dC5pc1BhY2tlZCk7XG4gICAgcmV0dXJuIHRleHR1cmVEYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCBpc1BhY2tlZCA9IGZhbHNlKTogVGV4dHVyZURhdGEgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnNlc3Npb24uaXNJbml0aWFsaXplcih0ZW5zb3JJZClcbiAgICAgID8gdGhpcy5zZXNzaW9uLmdldFRleHR1cmVEYXRhKHRlbnNvcklkLCBpc1BhY2tlZClcbiAgICAgIDogaXNQYWNrZWRcbiAgICAgICAgPyB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKVxuICAgICAgICA6IHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmdldCh0ZW5zb3JJZCk7XG4gIH1cbiAgc2V0VGV4dHVyZURhdGEodGVuc29ySWQ6IFRlbnNvci5JZCwgdGQ6IFRleHR1cmVEYXRhLCBpc1BhY2tlZCA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2Vzc2lvbi5pc0luaXRpYWxpemVyKHRlbnNvcklkKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLnNldFRleHR1cmVEYXRhKHRlbnNvcklkLCB0ZCwgaXNQYWNrZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAoaXNQYWNrZWQgPyB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgOiB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZSkuc2V0KHRlbnNvcklkLCB0ZCk7XG4gICAgfVxuICB9XG4gIGlzVGV4dHVyZUxheW91dENhY2hlZCh0ZW5zb3I6IFRlbnNvciwgaXNQYWNrZWQgPSBmYWxzZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuZ2V0VGV4dHVyZURhdGEodGVuc29yLmRhdGFJZCwgaXNQYWNrZWQpO1xuICB9XG5cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIuY2xlYXJBY3RpdmVUZXh0dXJlcygpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKCh0ZCkgPT4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkKSk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2goKHRkKSA9PiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVsZWFzZVRleHR1cmUodGQpKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIHJlYWRUZXh0dXJlKHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSk6IFRlbnNvci5OdW1iZXJUeXBlIHtcbiAgICBpZiAodGV4dHVyZURhdGEuaXNQYWNrZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlYWRUZXh0dXJlKHRoaXMudW5wYWNrKHRleHR1cmVEYXRhKSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LmlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRVaW50OFRleHR1cmVBc0Zsb2F0KGVuY29kZUFzVWludDgodGhpcywgdGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWFkVGV4dHVyZSh0ZXh0dXJlRGF0YSwgdGV4dHVyZURhdGEudGVuc29yLnR5cGUsIHRleHR1cmVEYXRhLmNoYW5uZWxzKTtcbiAgfVxuXG4gIGFzeW5jIHJlYWRUZXh0dXJlQXN5bmModGV4dHVyZURhdGE6IFRleHR1cmVEYXRhKTogUHJvbWlzZTxUZW5zb3IuTnVtYmVyVHlwZT4ge1xuICAgIGlmICh0ZXh0dXJlRGF0YS5pc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVhZFRleHR1cmVBc3luYyh0aGlzLnVucGFjayh0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC5pc0Zsb2F0MzJEb3dubG9hZFN1cHBvcnRlZCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWFkVWludDhUZXh0dXJlQXNGbG9hdChlbmNvZGVBc1VpbnQ4KHRoaXMsIHRleHR1cmVEYXRhKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFRleHR1cmVBc3luYyh0ZXh0dXJlRGF0YSwgdGV4dHVyZURhdGEudGVuc29yLnR5cGUsIHRleHR1cmVEYXRhLmNoYW5uZWxzKTtcbiAgfVxuXG4gIHBhY2soaW5wdXQ6IFRleHR1cmVEYXRhKTogVGV4dHVyZURhdGEge1xuICAgIGNvbnN0IG91dHB1dFRleHR1cmVEYXRhID0gdGhpcy5leGVjdXRlUHJvZ3JhbShjcmVhdGVQYWNrUHJvZ3JhbUluZm9Mb2FkZXIodGhpcywgaW5wdXQudGVuc29yKSwgW2lucHV0LnRlbnNvcl0pO1xuICAgIHJldHVybiBvdXRwdXRUZXh0dXJlRGF0YTtcbiAgfVxuXG4gIHVucGFjayhpbnB1dDogVGV4dHVyZURhdGEpOiBUZXh0dXJlRGF0YSB7XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZURhdGEgPSB0aGlzLmV4ZWN1dGVQcm9ncmFtKGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvTG9hZGVyKHRoaXMsIGlucHV0LnRlbnNvciksIFtpbnB1dC50ZW5zb3JdKTtcbiAgICByZXR1cm4gb3V0cHV0VGV4dHVyZURhdGE7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuY2xhc3MgQXR0cmlidXRlV2l0aENhY2hlS2V5SW1wbCB7XG4gIGNvbnN0cnVjdG9yKGF0dHJpYnV0ZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pIHtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMsIGF0dHJpYnV0ZSk7XG4gIH1cblxuICBwcml2YXRlIGtleTogc3RyaW5nO1xuICBwdWJsaWMgZ2V0IGNhY2hlS2V5KCk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmtleSkge1xuICAgICAgdGhpcy5rZXkgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0aGlzKVxuICAgICAgICAuc29ydCgpXG4gICAgICAgIC5tYXAoKG5hbWUpID0+IGAkeyh0aGlzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtuYW1lXX1gKVxuICAgICAgICAuam9pbignOycpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5rZXk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBjYWNoZUtleTogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5ID0gPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gIGF0dHJpYnV0ZTogVCxcbik6IFQgJiBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgPT4gbmV3IEF0dHJpYnV0ZVdpdGhDYWNoZUtleUltcGwoYXR0cmlidXRlKSBhcyB1bmtub3duIGFzIFQgJiBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgZXBzaWxvbjogbnVtYmVyO1xuICBtb21lbnR1bTogbnVtYmVyO1xuICBzcGF0aWFsOiBudW1iZXI7XG59XG5cbmNvbnN0IGJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0JhdGNoTm9ybWFsaXphdGlvbicsXG4gIGlucHV0TmFtZXM6IFsnQScsICdTY2FsZScsICdCJywgJ01lYW4nLCAnVmFyaWFuY2UnXSxcbiAgaW5wdXRUeXBlczogW1xuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICBdLFxufTtcblxuZXhwb3J0IGNvbnN0IGJhdGNoTm9ybWFsaXphdGlvbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5iYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZUJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248QmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgZXBzaWxvbiA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnZXBzaWxvbicsIDFlLTUpO1xuICBjb25zdCBtb21lbnR1bSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnbW9tZW50dW0nLCAwLjkpO1xuICBjb25zdCBzcGF0aWFsID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnc3BhdGlhbCcsIDEpO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgZXBzaWxvbiwgbW9tZW50dW0sIHNwYXRpYWwgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVCYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGNvbnN0IFtzY2FsZVdpZHRoLCBzY2FsZUhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBpbnB1dHNbMV0uZGltcyxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgdmVjMiBwb3NpdGlvbiA9IG9mZnNldFRvQ29vcmRzKGluZGljZXNbMV0sICR7c2NhbGVXaWR0aH0sICR7c2NhbGVIZWlnaHR9KTtcbiAgICBmbG9hdCBzY2FsZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShTY2FsZSwgcG9zaXRpb24pKTtcbiAgICBmbG9hdCBtZWFuID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KE1lYW4sIHBvc2l0aW9uKSk7XG4gICAgZmxvYXQgdmFyaWFuY2UgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oVmFyaWFuY2UsIHBvc2l0aW9uKSk7XG4gICAgZmxvYXQgYiA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShCLCBwb3NpdGlvbikpO1xuXG4gICAgcmV0dXJuIHNjYWxlICogKCAoX0EoaW5kaWNlcykgLSBtZWFuKSAvIHNxcnQodmFyaWFuY2UgKyBmbG9hdCgke2F0dHJpYnV0ZXMuZXBzaWxvbn0pKSApICsgYjtcbiAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4uYmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBpbnB1dHNbMF0uZGltcywgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gNSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQmF0Y2hOb3JtYWxpemF0aW9uIHJlcXVpcmVzIDUgaW5wdXRzLicpO1xuICB9XG5cbiAgY29uc3QgWCA9IGlucHV0c1swXTtcbiAgY29uc3Qgc2NhbGUgPSBpbnB1dHNbMV07XG4gIGNvbnN0IEIgPSBpbnB1dHNbMl07XG4gIGNvbnN0IG1lYW4gPSBpbnB1dHNbM107XG4gIGNvbnN0IHZhcl8gPSBpbnB1dHNbNF07XG5cbiAgLy8gaW5wdXQgc2hvdWxkIGF0bGVhc3QgaGF2ZSB0aHJlZSBkaW1lbnNpb25zIC0gTixDLGRpbTEsLi4uLGRpbW5cbiAgLy8gb3RoZXIgaW5wdXRzIGNhbiBoYXZlIG9ubHkgb25lIGRpbWVuc2lvbnNcbiAgaWYgKFxuICAgIFguZGltcy5sZW5ndGggPCAzIHx8XG4gICAgc2NhbGUuZGltcy5sZW5ndGggIT09IDEgfHxcbiAgICBCLmRpbXMubGVuZ3RoICE9PSAxIHx8XG4gICAgbWVhbi5kaW1zLmxlbmd0aCAhPT0gMSB8fFxuICAgIHZhcl8uZGltcy5sZW5ndGggIT09IDFcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChcbiAgICBzY2FsZS5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHxcbiAgICBCLmRpbXNbMF0gIT09IFguZGltc1sxXSB8fFxuICAgIG1lYW4uZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8XG4gICAgdmFyXy5kaW1zWzBdICE9PSBYLmRpbXNbMV1cbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChcbiAgICAoWC50eXBlICE9PSAnZmxvYXQzMicgJiYgWC50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKHNjYWxlLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBzY2FsZS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKEIudHlwZSAhPT0gJ2Zsb2F0MzInICYmIEIudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChtZWFuLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBtZWFuLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAodmFyXy50eXBlICE9PSAnZmxvYXQzMicgJiYgdmFyXy50eXBlICE9PSAnZmxvYXQ2NCcpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCB0ZW5zb3IgdHlwZXMuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlTGF5b3V0IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsLWNvbnRleHQnO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cbmV4cG9ydCBlbnVtIEZ1bmN0aW9uVHlwZSB7XG4gIFZhbHVlQmFzZWQsXG4gIFBvc2l0aW9uYWwsXG59XG5leHBvcnQgaW50ZXJmYWNlIEdsc2xGdW5jdGlvbjxUIGV4dGVuZHMgRnVuY3Rpb25UeXBlPiB7XG4gIGJvZHk6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICB0eXBlOiBUO1xufVxuZXhwb3J0IHR5cGUgR2xzbFZhbHVlRnVuY3Rpb24gPSBHbHNsRnVuY3Rpb248RnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQ+O1xuZXhwb3J0IGludGVyZmFjZSBHbHNsUG9zaXRpb25hbEZ1bmN0aW9uIGV4dGVuZHMgR2xzbEZ1bmN0aW9uPEZ1bmN0aW9uVHlwZS5Qb3NpdGlvbmFsPiB7XG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCBjbGFzcyBHbHNsQ29udGV4dCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBnbENvbnRleHQ6IFdlYkdMQ29udGV4dCxcbiAgICBwdWJsaWMgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvLFxuICAgIHB1YmxpYyBpbnB1dFRleHR1cmVMYXlvdXRzOiBUZXh0dXJlTGF5b3V0W10sXG4gICAgcHVibGljIG91dHB1dFRleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICkge31cbn1cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IocHVibGljIGNvbnRleHQ6IEdsc2xDb250ZXh0KSB7fVxuICBhYnN0cmFjdCBnZXRGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfTtcbiAgYWJzdHJhY3QgZ2V0Q3VzdG9tVHlwZXMoKTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH07XG59XG5cbi8vIGFic3RyYWN0aW9uIHRvIHJlcHJlc2VudCBhIEdMU0wgbGlicmFyeSByb3V0aW5lIGFuZCBpdCdzIGRlcGVuZGVuY2llc1xuZXhwb3J0IGNsYXNzIEdsc2xMaWJSb3V0aW5lIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJvdXRpbmVCb2R5OiBzdHJpbmcsXG4gICAgcHVibGljIGRlcGVuZGVuY2llcz86IHN0cmluZ1tdLFxuICApIHt9XG59XG5cbi8vIGFic3RyYWN0aW9uIHRvIHJlcHJlc2VudCBhIEdMU0wgbGlicmFyeSByb3V0aW5lIGFuZCBpdCdzIGRlcGVuZGVuY2llcyBBUyBHUkFQSCBOb2Rlc1xuLy8gdGhpcyBsZXZlbCBvZiBhYnN0cmFjdGlvbiBpcyB1c2VkIHRvIHRvcG9sb2dpY2FsbHkgc29ydCByb3V0aW5lcyBiZWZvcmUgZnJhZ21lbnQgc2hhZGUgaW5jbHVzaW9uXG5leHBvcnQgY2xhc3MgR2xzbExpYlJvdXRpbmVOb2RlIHtcbiAgZGVwZW5kZW5jaWVzOiBHbHNsTGliUm91dGluZU5vZGVbXTtcbiAgcm91dGluZUJvZHk6IHN0cmluZztcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG5hbWU6IHN0cmluZyxcbiAgICByb3V0aW5lQm9keT86IHN0cmluZyxcbiAgICBkZXBlbmRlbmNpZXM/OiBHbHNsTGliUm91dGluZU5vZGVbXSxcbiAgKSB7XG4gICAgaWYgKGRlcGVuZGVuY2llcykge1xuICAgICAgdGhpcy5kZXBlbmRlbmNpZXMgPSBkZXBlbmRlbmNpZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0gW107XG4gICAgfVxuXG4gICAgaWYgKHJvdXRpbmVCb2R5KSB7XG4gICAgICB0aGlzLnJvdXRpbmVCb2R5ID0gcm91dGluZUJvZHk7XG4gICAgfVxuICB9XG4gIGFkZERlcGVuZGVuY3kobm9kZTogR2xzbExpYlJvdXRpbmVOb2RlKSB7XG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzLnB1c2gobm9kZSk7XG4gICAgfVxuICB9XG59XG5cbi8vIHRvcG9sb2dpY2FsbHkgc29ydCBHTFNMIGxpYnJhcnkgcm91dGluZXMgKGdyYXBoIG5vZGVzIGFic3RyYWN0aW9uKSBiZWZvcmUgc2hhZGVyIHNjcmlwdCBpbmNsdXNpb25cbmV4cG9ydCBjbGFzcyBUb3BvbG9naWNhbFNvcnRHbHNsUm91dGluZXMge1xuICBzdGF0aWMgcmV0dXJuT3JkZXJlZE5vZGVzKG5vZGVzOiBHbHNsTGliUm91dGluZU5vZGVbXSk6IEdsc2xMaWJSb3V0aW5lTm9kZVtdIHtcbiAgICBpZiAoIW5vZGVzIHx8IG5vZGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGlmIChub2Rlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBub2RlcztcbiAgICB9XG5cbiAgICBjb25zdCBjeWNsZUNoZWNrID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgYWxyZWFkeVRyYXZlcnNlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBBcnJheTxHbHNsTGliUm91dGluZU5vZGU+KCk7XG5cbiAgICB0aGlzLmNyZWF0ZU9yZGVyZWROb2Rlcyhub2RlcywgY3ljbGVDaGVjaywgYWxyZWFkeVRyYXZlcnNlZCwgcmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY3JlYXRlT3JkZXJlZE5vZGVzKFxuICAgIGdyYXBoTm9kZXM6IEdsc2xMaWJSb3V0aW5lTm9kZVtdLFxuICAgIGN5Y2xlQ2hlY2s6IFNldDxzdHJpbmc+LFxuICAgIGFscmVhZHlUcmF2ZXJzZWQ6IFNldDxzdHJpbmc+LFxuICAgIHJlc3VsdDogR2xzbExpYlJvdXRpbmVOb2RlW10sXG4gICkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGhOb2Rlcy5sZW5ndGg7ICsraSkge1xuICAgICAgdGhpcy5kZnNUcmF2ZXJzZShncmFwaE5vZGVzW2ldLCBjeWNsZUNoZWNrLCBhbHJlYWR5VHJhdmVyc2VkLCByZXN1bHQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGRmc1RyYXZlcnNlKFxuICAgIHJvb3Q6IEdsc2xMaWJSb3V0aW5lTm9kZSxcbiAgICBjeWNsZUNoZWNrOiBTZXQ8c3RyaW5nPixcbiAgICBhbHJlYWR5VHJhdmVyc2VkOiBTZXQ8c3RyaW5nPixcbiAgICByZXN1bHQ6IEdsc2xMaWJSb3V0aW5lTm9kZVtdLFxuICApIHtcbiAgICAvLyBpZiB0aGlzIHJvb3QgaGFzIGFscmVhZHkgYmVlbiB0cmF2ZXJzZWQgcmV0dXJuXG4gICAgaWYgKCFyb290IHx8IGFscmVhZHlUcmF2ZXJzZWQuaGFzKHJvb3QubmFtZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBjeWNsaWMgZGVwZW5kZW5jeSBoYXMgYmVlbiBkZXRlY3RlZFxuICAgIGlmIChjeWNsZUNoZWNrLmhhcyhyb290Lm5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDeWNsaWMgZGVwZW5kZW5jeSBkZXRlY3RlZC4gQ2FuJ3QgdG9wb2xvZ2ljYWxseSBzb3J0IHJvdXRpbmVzIG5lZWRlZCBmb3Igc2hhZGVyLlwiKTtcbiAgICB9XG5cbiAgICAvLyBob2xkIHRoaXMgbm9kZSB0byBkZXRlY3QgY3ljbGVzIGlmIGFueVxuICAgIGN5Y2xlQ2hlY2suYWRkKHJvb3QubmFtZSk7XG5cbiAgICAvLyB0cmF2ZXJzZSBjaGlsZHJlbiBpbiBhIGRmcyBmYXNoaW9uXG4gICAgY29uc3QgZGVwZW5kZW5jaWVzID0gcm9vdC5kZXBlbmRlbmNpZXM7XG4gICAgaWYgKGRlcGVuZGVuY2llcyAmJiBkZXBlbmRlbmNpZXMubGVuZ3RoID4gMCkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXBlbmRlbmNpZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdGhpcy5kZnNUcmF2ZXJzZShkZXBlbmRlbmNpZXNbaV0sIGN5Y2xlQ2hlY2ssIGFscmVhZHlUcmF2ZXJzZWQsIHJlc3VsdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRkIHRvIHJlc3VsdCBob2xkZXJcbiAgICByZXN1bHQucHVzaChyb290KTtcblxuICAgIC8vIG1hcmsgdGhpcyBub2RlIGFzIHRyYXZlcnNlZCBzbyB0aGF0IHdlIGRvbid0IHRyYXZlcnNlIGZyb20gdGhpcyBhZ2FpblxuICAgIGFscmVhZHlUcmF2ZXJzZWQuYWRkKHJvb3QubmFtZSk7XG5cbiAgICAvLyByZWxlYXNlIHRoZSBob2xkXG4gICAgY3ljbGVDaGVjay5kZWxldGUocm9vdC5uYW1lKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBGdW5jdGlvblR5cGUsIEdsc2xWYWx1ZUZ1bmN0aW9uIH0gZnJvbSAnLi4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBZGQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2FkZF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSArIGI7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdjEgKyB2MjtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xEaXYoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2Rpdl8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSAvIGI7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdjEgLyB2MjtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xNdWwoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ211bF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSAqIGI7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdjEgKiB2MjtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xTdWIoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3N1Yl8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSAtIGI7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdjEgLSB2MjtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xFcXVhbCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnZXF1YWxfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KGEgPT0gYik7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdmVjNChlcXVhbCh2MSwgdjIpKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xHcmVhdGVyKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdncmVhdGVyXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdChhID4gYik7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdmVjNCggdjEuciA+IHYyLnIgLFxuICAgICAgdjEuZyA+IHYyLmcsXG4gICAgICB2MS5iID4gdjIuYixcbiAgICAgIHYxLmEgPiB2Mi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTGVzcygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbGVzc18nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoYSA8IGIpO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoIHYxLnIgPCB2Mi5yICxcbiAgICAgICAgICAgICAgICB2MS5nIDwgdjIuZyxcbiAgICAgICAgICAgICAgICB2MS5iIDwgdjIuYixcbiAgICAgICAgICAgICAgICB2MS5hIDwgdjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEFuZCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnYW5kXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdCggYm9vbChhKSAmJiBib29sKGIpICk7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICBidmVjNCBiMSA9IGJ2ZWM0KHYxKTtcbiAgICBidmVjNCBiMiA9IGJ2ZWM0KHYyKTtcbiAgICByZXR1cm4gdmVjNCggYjEuciAmJiBiMi5yICxcbiAgICAgICAgICAgICAgICBiMS5nICYmIGIyLmcsXG4gICAgICAgICAgICAgICAgYjEuYiAmJiBiMi5iLFxuICAgICAgICAgICAgICAgIGIxLmEgJiYgYjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbE9yKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdvcl8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoIGJvb2woYSkgfHwgYm9vbChiKSApO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgYnZlYzQgYjEgPSBidmVjNCh2MSk7XG4gICAgYnZlYzQgYjIgPSBidmVjNCh2Mik7XG4gICAgcmV0dXJuIHZlYzQoIGIxLnIgfHwgYjIuciAsXG4gICAgICAgICAgICAgICAgYjEuZyB8fCBiMi5nLFxuICAgICAgICAgICAgICAgIGIxLmIgfHwgYjIuYixcbiAgICAgICAgICAgICAgICBiMS5hIHx8IGIyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xYb3IoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3hvcl8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoIGJvb2woYSkgXl4gYm9vbChiKSApO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgYnZlYzQgYjEgPSBidmVjNCh2MSk7XG4gICAgYnZlYzQgYjIgPSBidmVjNCh2Mik7XG4gICAgcmV0dXJuIHZlYzQoIGIxLnIgXl4gYjIuciAsXG4gICAgICAgICAgICAgICAgYjEuZyBeXiBiMi5nLFxuICAgICAgICAgICAgICAgIGIxLmIgXl4gYjIuYixcbiAgICAgICAgICAgICAgICBiMS5hIF5eIGIyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xQb3coKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5CaW5hcnkoJ3BvdycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xQUmVsdSgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAncHJlbHVfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgPCAwLjAgPyBhICogYjogYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KFxuICAgICAgdjEuciA8IDAuMCA/IHYxLnIgKiB2Mi5yOiB2MS5yLFxuICAgICAgdjEuZyA8IDAuMCA/IHYxLmcgKiB2Mi5nOiB2MS5nLFxuICAgICAgdjEuYiA8IDAuMCA/IHYxLmIgKiB2Mi5iOiB2MS5iLFxuICAgICAgdjEuYSA8IDAuMCA/IHYxLmEgKiB2Mi5hOiB2MS5hXG4gICAgICApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5cbmZ1bmN0aW9uIGdsc2xCdWlsdGluQmluYXJ5KGZuYW1lOiBzdHJpbmcpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSBgJHtmbmFtZX1fYDtcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuICR7Zm5hbWV9KGEsIGIpO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuICR7Zm5hbWV9KHYxLCB2Mik7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cblxuY29uc3QgY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgZ2xzbEZ1bmM6IEdsc2xWYWx1ZUZ1bmN0aW9uLFxuICBvdXRwdXRUZW5zb3JUeXBlOiBUZW5zb3IuRGF0YVR5cGUgPSBpbnB1dHNbMF0udHlwZSxcbiAgY2FjaGVLZXk/OiBzdHJpbmcsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBnbHNsRnVuYy5uYW1lLFxuICAgIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gICAgaW5wdXRUeXBlczogW3RleHR1cmVUeXBlLCB0ZXh0dXJlVHlwZV0sXG4gICAgY2FjaGVIaW50OiBjYWNoZUtleSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvKGhhbmRsZXIsIGlucHV0cywgZ2xzbEZ1bmMsIG91dHB1dFRlbnNvclR5cGUpLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm8gPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgZ2xzbEZ1bmM6IEdsc2xWYWx1ZUZ1bmN0aW9uLFxuICBvdXRwdXRUZW5zb3JUeXBlOiBUZW5zb3IuRGF0YVR5cGUgPSBpbnB1dHNbMF0udHlwZSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICBjb25zdCBpc0Jyb2FkY2FzdCA9ICFTaGFwZVV0aWwuYXJlRXF1YWwoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5kaW1zKTtcbiAgbGV0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG5cbiAgY29uc3QgdXNlUGFja2VkVGV4dHVyZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrO1xuXG4gIGlmIChpc0Jyb2FkY2FzdCkge1xuICAgIGNvbnN0IGNhbGN1bGF0ZWRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcywgZmFsc2UpO1xuICAgIGlmICghY2FsY3VsYXRlZFNoYXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBwZXJmb3JtIGJpbmFyeSBvcCBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgICB9XG4gICAgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVkU2hhcGU7XG4gICAgY29uc3Qgb3V0cHV0UmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBhUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gMCA/IGlucHV0c1swXS5kaW1zLmxlbmd0aCA6IDE7XG4gICAgY29uc3QgYlJhbmsgPSBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDAgPyBpbnB1dHNbMV0uZGltcy5sZW5ndGggOiAxO1xuICAgIGNvbnN0IGFCY2FzdCA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gMCA/ICdiY2FzdEluZGljZXNfQShpbmRpY2VzLCBhaW5kaWNlcyk7JyA6ICdhaW5kaWNlc1swXSA9IDA7JztcbiAgICBjb25zdCBiQmNhc3QgPSBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDAgPyAnYmNhc3RJbmRpY2VzX0IoaW5kaWNlcywgYmluZGljZXMpOycgOiAnYmluZGljZXNbMF0gPSAwOyc7XG5cbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgY29uc3Qgc2hhZGVyU291cmNlID0gdXNlUGFja2VkVGV4dHVyZVxuICAgICAgPyBgXG4gICAgICAke2dsc2xGdW5jLmJvZHl9XG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIHZlYzQgYSA9IGdldEFBdE91dENvb3JkcygpO1xuICAgICAgICB2ZWM0IGIgPSBnZXRCQXRPdXRDb29yZHMoKTtcbiAgICAgICAgdmVjNCByZXN1bHQgPSAke2dsc2xGdW5jLm5hbWV9KGEsIGIpO1xuICAgICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICAgIH1gXG4gICAgICA6IGBcbiAgICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtvdXRwdXRSYW5rfV0pIHtcbiAgICAgICAgaW50IGFpbmRpY2VzWyR7YVJhbmt9XTtcbiAgICAgICAgaW50IGJpbmRpY2VzWyR7YlJhbmt9XTtcbiAgICAgICAgJHthQmNhc3R9XG4gICAgICAgICR7YkJjYXN0fVxuICAgICAgICByZXR1cm4gJHtnbHNsRnVuYy5uYW1lfShfQShhaW5kaWNlcyksIF9CKGJpbmRpY2VzKSk7XG4gICAgICB9YDtcblxuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiBnbHNsRnVuYy5uYW1lLFxuICAgICAgaW5wdXROYW1lczogWydBJywgJ0InXSxcbiAgICAgIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZSwgdGV4dHVyZVR5cGVdLFxuICAgICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBvdXRwdXRUZW5zb3JUeXBlLCB0ZXh0dXJlVHlwZSB9LFxuICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgaGFzTWFpbjogdXNlUGFja2VkVGV4dHVyZSxcbiAgICB9O1xuICB9XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICB2b2lkIG1haW4oKSB7XG4gICAgICB2ZWM0IHYxID0gJHtnbHNsLnRleHR1cmUyRH0oQSwgVGV4Q29vcmRzKTtcbiAgICAgIHZlYzQgdjIgPSAke2dsc2wudGV4dHVyZTJEfShCLCBUZXhDb29yZHMpO1xuICAgICAgdmVjNCByZXN1bHQgPSAke2dsc2xGdW5jLm5hbWV9KHYxLCB2Mik7XG4gICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICB9XG4gICAgYDtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6IGdsc2xGdW5jLm5hbWUsXG4gICAgaW5wdXROYW1lczogWydBJywgJ0InXSxcbiAgICBpbnB1dFR5cGVzOiBbdGV4dHVyZVR5cGUsIHRleHR1cmVUeXBlXSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXRzWzBdLmRpbXMsIHR5cGU6IG91dHB1dFRlbnNvclR5cGUsIHRleHR1cmVUeXBlIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgYWRkID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsQWRkKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGFuZCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbEFuZCgpLCAnYm9vbCcpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGRpdiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbERpdigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBlcXVhbCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbEVxdWFsKCksICdib29sJyksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgZ3JlYXRlciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbEdyZWF0ZXIoKSwgJ2Jvb2wnKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBsZXNzID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsTGVzcygpLCAnYm9vbCcpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IG11bCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbE11bCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBvciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbE9yKCksICdib29sJyksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgcG93ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsUG93KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHBSZWx1ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsUFJlbHUoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgc3ViID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsU3ViKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHhvciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbFhvcigpLCAnYm9vbCcpLCBpbnB1dHMpLFxuXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBQcm90b1V0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IGNhc3Q6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248VGVuc29yLkRhdGFUeXBlPiA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICB0bzogVGVuc29yLkRhdGFUeXBlLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICByZXR1cm4gW2hhbmRsZXIuY2FzdChpbnB1dHNbMF0sIHRvKV07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDYXN0QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxUZW5zb3IuRGF0YVR5cGU+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBUZW5zb3IuRGF0YVR5cGUgPT5cbiAgUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3RvJykpO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhc3QgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRDb29yZHNEYXRhVHlwZSwgZ2V0R2xDaGFubmVscyB9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHsgQ29uY2F0QXR0cmlidXRlcyB9IGZyb20gJy4vY29uY2F0JztcbmltcG9ydCB7IGdldENoYW5uZWxzLCB1bnBhY2tGcm9tQ2hhbm5lbCB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YSA9IChpbnB1dENvdW50OiBudW1iZXIsIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnQ29uY2F0IChwYWNrZWQpJyxcbiAgaW5wdXROYW1lczogQXJyYXkuZnJvbSh7IGxlbmd0aDogaW5wdXRDb3VudCB9LCAoX3YsIGkpID0+IGBYJHtpfWApLFxuICBpbnB1dFR5cGVzOiBBcnJheShpbnB1dENvdW50KS5maWxsKFRleHR1cmVUeXBlLnBhY2tlZCksXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtSW5mbyA9IChcbiAgaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGlzOiBudW1iZXIsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBpZiAoYXhpcyA+PSBpbnB1dFNoYXBlLmxlbmd0aCB8fCBheGlzIDwgLTEgKiBpbnB1dFNoYXBlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImF4aXMgc3BlY2lmaWVkIGZvciBjb25jYXQgZG9lc24ndCBtYXRjaCBpbnB1dCBkaW1lbnNpb25hbGl0eVwiKTtcbiAgfVxuICBpZiAoYXhpcyA8IDApIHtcbiAgICBheGlzID0gaW5wdXRTaGFwZS5sZW5ndGggKyBheGlzO1xuICB9XG4gIC8vIGVuc3VyZSBhbGwgb2YgdGhlIG5vbi1jb25jYXRlbmF0ZWQgYXhlcyBtYXRjaCBlYWNoIG90aGVyXG4gIC8vIGNhbGN1bGF0ZSB0aGUgc2hhcGUgb2YgdGhlIG91dHB1dCB0ZW5zb3Igd2hpbGUgd2UgZG8gdGhhdFxuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoMCk7XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgZGF0YU5TaGFwZSA9IGlucHV0c1tpXS5kaW1zLnNsaWNlKCk7XG4gICAgZm9yIChsZXQgYXhpc0luZGV4ID0gMDsgYXhpc0luZGV4IDwgaW5wdXRTaGFwZS5sZW5ndGg7IGF4aXNJbmRleCsrKSB7XG4gICAgICAvLyBhZGQgdG8gdGhlIHBsYWNlaG9sZGVyIGZvciBjb21wdXRpbmcgb3V0cHV0IHNoYXBlXG4gICAgICBpZiAoYXhpc0luZGV4ID09PSBheGlzKSB7XG4gICAgICAgIG91dHB1dFNoYXBlW2F4aXNdICs9IGRhdGFOU2hhcGVbYXhpc0luZGV4XTtcbiAgICAgIH1cbiAgICAgIC8vIGVuc3VyZSBhbGwgbm9uLWNhbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgICAgIGVsc2UgaWYgKGlucHV0U2hhcGVbYXhpc0luZGV4XSAhPT0gZGF0YU5TaGFwZVtheGlzSW5kZXhdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm9uIGNvbmNhdCBkaW1lbnNpb25zIG11c3QgbWF0Y2gnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBjb29yZHMgPSBnZXRDaGFubmVscygnY29vcmRzJywgcmFuayk7XG4gIGNvbnN0IGR0eXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUocmFuayk7XG4gIGNvbnN0IHVucGFja0NoYW5uZWwgPSB1bnBhY2tGcm9tQ2hhbm5lbCgpO1xuXG4gIGNvbnN0IHNoYXBlcyA9IGlucHV0cy5tYXAoKGkpID0+IGkuZGltcyk7XG4gIGNvbnN0IGNoYW5uZWxzID0gZ2V0R2xDaGFubmVscyhyYW5rKTtcbiAgY29uc3Qgb2Zmc2V0czogbnVtYmVyW10gPSBuZXcgQXJyYXkoc2hhcGVzLmxlbmd0aCAtIDEpO1xuXG4gIG9mZnNldHNbMF0gPSBzaGFwZXNbMF1bYXhpc107XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgb2Zmc2V0cy5sZW5ndGg7IGkrKykge1xuICAgIG9mZnNldHNbaV0gPSBvZmZzZXRzW2kgLSAxXSArIHNoYXBlc1tpXVtheGlzXTtcbiAgfVxuXG4gIGNvbnN0IGNoYW5uZWwgPSBjaGFubmVsc1theGlzXTtcbiAgY29uc3QgbGFzdENoYW5uZWxzID0gY2hhbm5lbHMuc2xpY2UoLTIpO1xuICBjb25zdCBhbGxDaGFubmVscyA9IGNoYW5uZWxzLmpvaW4oKTtcblxuICBsZXQgZ2V0VmFsdWVTbmlwcGV0ID0gYGlmICgke2NoYW5uZWx9IDwgJHtvZmZzZXRzWzBdfSkge1xuICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgIGdldFgwKCR7YWxsQ2hhbm5lbHN9KSwgdmVjMigke2xhc3RDaGFubmVscy5qb2luKCl9KSk7XG4gICAgICAgIH1gO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IG9mZnNldHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzaGlmdCA9IG9mZnNldHNbaSAtIDFdO1xuICAgIGdldFZhbHVlU25pcHBldCArPSBgXG4gICAgICAgICAgICBpZiAoJHtjaGFubmVsfSA8ICR7b2Zmc2V0c1tpXX0gICYmICR7Y2hhbm5lbH0gPj0gJHtvZmZzZXRzW2kgLSAxXX0pIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoXG4gICAgICAgICAgICAgICAgZ2V0WCR7aX0oJHtnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0KGNoYW5uZWxzLCBjaGFubmVsLCBzaGlmdCl9KSxcbiAgICAgICAgICAgICAgICB2ZWMyKCR7Z2V0U2hpZnRlZENoYW5uZWxzU25pcHBldChsYXN0Q2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pKTtcbiAgICAgICAgICAgIH1gO1xuICB9XG4gIGNvbnN0IGxhc3RJbmRleCA9IG9mZnNldHMubGVuZ3RoO1xuICBjb25zdCBzaGlmdCA9IG9mZnNldHNbb2Zmc2V0cy5sZW5ndGggLSAxXTtcbiAgZ2V0VmFsdWVTbmlwcGV0ICs9IGBcbiAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsKFxuICAgICAgICAgICAgICBnZXRYJHtsYXN0SW5kZXh9KCR7Z2V0U2hpZnRlZENoYW5uZWxzU25pcHBldChjaGFubmVscywgY2hhbm5lbCwgc2hpZnQpfSksXG4gICAgICAgICAgICAgIHZlYzIoJHtnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0KGxhc3RDaGFubmVscywgY2hhbm5lbCwgc2hpZnQpfSkpO2A7XG5cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgICAke3VucGFja0NoYW5uZWx9XG4gICAgICAgICAgZmxvYXQgZ2V0VmFsdWUoJHtjaGFubmVscy5tYXAoKHgpID0+ICdpbnQgJyArIHgpfSkge1xuICAgICAgICAgICAgJHtnZXRWYWx1ZVNuaXBwZXR9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICAgICAgJHtkdHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICAgICBpbnQgbGFzdERpbSA9IGNvb3Jkcy4ke2NoYW5uZWxzW3JhbmsgLSAxXX07XG4gICAgICAgICAgICBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMV19ID0gY29vcmRzLiR7Y2hhbm5lbHNbcmFuayAtIDJdfTtcbiAgICAgICAgICAgIGNvb3Jkcy4ke2NoYW5uZWxzW3JhbmsgLSAyXX0gPSBsYXN0RGltO1xuXG4gICAgICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoZ2V0VmFsdWUoJHtjb29yZHN9KSwgMC4sIDAuLCAwLik7XG5cbiAgICAgICAgICAgICR7Y29vcmRzW3JhbmsgLSAxXX0gPSAke2Nvb3Jkc1tyYW5rIC0gMV19ICsgMTtcbiAgICAgICAgICAgIGlmICgke2Nvb3Jkc1tyYW5rIC0gMV19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMV19KSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5nID0gZ2V0VmFsdWUoJHtjb29yZHN9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJHtjb29yZHNbcmFuayAtIDJdfSA9ICR7Y29vcmRzW3JhbmsgLSAyXX0gKyAxO1xuICAgICAgICAgICAgaWYgKCR7Y29vcmRzW3JhbmsgLSAyXX0gPCAke291dHB1dFNoYXBlW3JhbmsgLSAyXX0pIHtcbiAgICAgICAgICAgICAgcmVzdWx0LmEgPSBnZXRWYWx1ZSgke2Nvb3Jkc30pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMV19ID0gJHtjb29yZHNbcmFuayAtIDFdfSAtIDE7XG4gICAgICAgICAgICBpZiAoJHtjb29yZHNbcmFuayAtIDJdfSA8ICR7b3V0cHV0U2hhcGVbcmFuayAtIDJdfSAmJlxuICAgICAgICAgICAgICAgICR7Y29vcmRzW3JhbmsgLSAxXX0gPCAke291dHB1dFNoYXBlW3JhbmsgLSAxXX0pIHtcbiAgICAgICAgICAgICAgcmVzdWx0LmIgPSBnZXRWYWx1ZSgke2Nvb3Jkc30pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuXG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbmNhdEF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGgsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzLmF4aXMpIH07XG59O1xuXG5jb25zdCBnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0ID0gKGNoYW5uZWxzOiBzdHJpbmdbXSwgY2hhbm5lbDogc3RyaW5nLCBzaGlmdDogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3QgY2hhbm5lbElkeCA9IGNoYW5uZWxzLmluZGV4T2YoY2hhbm5lbCk7XG4gIGNvbnN0IHJlcyA9IGNoYW5uZWxzLm1hcCgoYywgaWR4KSA9PiB7XG4gICAgaWYgKGlkeCA9PT0gY2hhbm5lbElkeCkge1xuICAgICAgcmV0dXJuIGAke2N9IC0gJHtzaGlmdH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYztcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzLmpvaW4oKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vY29uY2F0LXBhY2tlZCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uY2F0QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4aXM6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbmNhdDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb25jYXRBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb25jYXRBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBpZiAoaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLnBhY2sgJiYgaW5wdXRzWzBdLmRpbXMubGVuZ3RoID4gMSkge1xuICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICAgIGlucHV0cyxcbiAgICApO1xuICAgIHJldHVybiBbb3V0cHV0XTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgIGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICAgIGlucHV0cyxcbiAgICApO1xuICAgIHJldHVybiBbb3V0cHV0XTtcbiAgfVxufTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtTWV0YWRhdGEgPSAoaW5wdXRDb3VudDogbnVtYmVyLCBjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ0NvbmNhdCcsXG4gIGlucHV0TmFtZXM6IEFycmF5LmZyb20oeyBsZW5ndGg6IGlucHV0Q291bnQgfSwgKF92LCBpKSA9PiBgWCR7aX1gKSxcbiAgaW5wdXRUeXBlczogQXJyYXkoaW5wdXRDb3VudCkuZmlsbChUZXh0dXJlVHlwZS51bnBhY2tlZCksXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1JbmZvID0gKFxuICBfaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGlzOiBudW1iZXIsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBpZiAoYXhpcyA+PSBpbnB1dFNoYXBlLmxlbmd0aCB8fCBheGlzIDwgLTEgKiBpbnB1dFNoYXBlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImF4aXMgc3BlY2lmaWVkIGZvciBjb25jYXQgZG9lc24ndCBtYXRjaCBpbnB1dCBkaW1lbnNpb25hbGl0eVwiKTtcbiAgfVxuICBpZiAoYXhpcyA8IDApIHtcbiAgICBheGlzID0gaW5wdXRTaGFwZS5sZW5ndGggKyBheGlzO1xuICB9XG4gIC8vIGVuc3VyZSBhbGwgb2YgdGhlIG5vbi1jb25jYXRlbmF0ZWQgYXhlcyBtYXRjaCBlYWNoIG90aGVyXG4gIC8vIGNhbGN1bGF0ZSB0aGUgc2hhcGUgb2YgdGhlIG91dHB1dCB0ZW5zb3Igd2hpbGUgd2UgZG8gdGhhdFxuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoMCk7XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgZGF0YU5TaGFwZSA9IGlucHV0c1tpXS5kaW1zLnNsaWNlKCk7XG4gICAgZm9yIChsZXQgYXhpc0luZGV4ID0gMDsgYXhpc0luZGV4IDwgaW5wdXRTaGFwZS5sZW5ndGg7IGF4aXNJbmRleCsrKSB7XG4gICAgICAvLyBhZGQgdG8gdGhlIHBsYWNlaG9sZGVyIGZvciBjb21wdXRpbmcgb3V0cHV0IHNoYXBlXG4gICAgICBpZiAoYXhpc0luZGV4ID09PSBheGlzKSB7XG4gICAgICAgIG91dHB1dFNoYXBlW2F4aXNdICs9IGRhdGFOU2hhcGVbYXhpc0luZGV4XTtcbiAgICAgIH1cbiAgICAgIC8vIGVuc3VyZSBhbGwgbm9uLWNhbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgICAgIGVsc2UgaWYgKGlucHV0U2hhcGVbYXhpc0luZGV4XSAhPT0gZGF0YU5TaGFwZVtheGlzSW5kZXhdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm9uIGNvbmNhdCBkaW1lbnNpb25zIG11c3QgbWF0Y2gnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gIGNvbnN0IHNpemVJbkNvbmNhdEF4aXMgPSBuZXcgQXJyYXk8bnVtYmVyPihpbnB1dHMubGVuZ3RoKTtcbiAgbGV0IHByZXZpb3VzU3VtID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplSW5Db25jYXRBeGlzLmxlbmd0aDsgKytpKSB7XG4gICAgcHJldmlvdXNTdW0gKz0gaW5wdXRzW2ldLmRpbXNbYXhpc107XG4gICAgc2l6ZUluQ29uY2F0QXhpc1tpXSA9IHByZXZpb3VzU3VtO1xuICB9XG5cbiAgbGV0IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNNZXRob2QgPSAnJztcbiAgLy8gaW4gbW9zdCBjYXNlcyBsaW5lYXIgc2VhcmNoIGlzIHN1ZmZpY2llbnQsIGFzIGluIG1vc3Qgc2NlbmFyaW9zLCBvbmx5IDIgdGVuc29ycyBhcmUgY29uY2F0ZW5hdGVkXG4gIGlmIChpbnB1dHMubGVuZ3RoIDwgNSkge1xuICAgIGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNNZXRob2QgPSBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTGluZWFyU2VhcmNoKHNpemVJbkNvbmNhdEF4aXMpO1xuICB9IGVsc2Uge1xuICAgIGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNNZXRob2QgPSBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzQmluYXJ5U2VhcmNoKHNpemVJbkNvbmNhdEF4aXMpO1xuICB9XG5cbiAgY29uc3QgZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kID0gZ2V0RmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kKGlucHV0cy5sZW5ndGgsIHJhbmspO1xuICBjb25zdCBnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXhNZXRob2QgPSBnZXRHZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXhNZXRob2Qoc2l6ZUluQ29uY2F0QXhpcyk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgJHtmZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmVNZXRob2R9XG4gICAgICAgICR7Z2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kfVxuICAgICAgICAke2dldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNNZXRob2R9XG4gICAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgdGV4dHVyZUluZGV4ID0gZ2V0VGV4dHVyZVdoZXJlRGF0YVJlc2lkZXMgKGluZGljZXNbJHtheGlzfV0pO1xuXG4gICAgICAgICAgaWYodGV4dHVyZUluZGV4ICE9IDApIHtcbiAgICAgICAgICAgIGluZGljZXNbJHtheGlzfV0gPSBpbmRpY2VzWyR7YXhpc31dIC0gaW50KGdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleCh0ZXh0dXJlSW5kZXgtaW50KDEpKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZSh0ZXh0dXJlSW5kZXgsIGluZGljZXMpO1xuICAgICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbmNhdEF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCwgYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcy5heGlzKSB9O1xufTtcblxuY29uc3QgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0xpbmVhclNlYXJjaCA9IChzaXplSW5Db25jYXRBeGlzOiBudW1iZXJbXSk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHNlYXJjaEF4aXMgPSBzaXplSW5Db25jYXRBeGlzLm1hcChcbiAgICAoc2l6ZSwgaSkgPT4gYGlmKGluZGV4PCR7c2l6ZX0pIHtyZXR1cm4gJHtpfTt9XG5gLFxuICApO1xuICByZXR1cm4gYGludCBnZXRUZXh0dXJlV2hlcmVEYXRhUmVzaWRlcyhpbnQgaW5kZXgpIHtcbiAgICAgICR7c2VhcmNoQXhpcy5qb2luKCcnKX1cbiAgICB9YDtcbn07XG5cbi8vIFRPRE86IEltcGxlbWVudCBCaW5hcnlTZWFyY2ggaW4gR0xTTFxuY29uc3QgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0JpbmFyeVNlYXJjaCA9IChzaXplSW5Db25jYXRBeGlzOiBudW1iZXJbXSk6IHN0cmluZyA9PlxuICBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTGluZWFyU2VhcmNoKHNpemVJbkNvbmNhdEF4aXMpO1xuXG5jb25zdCBnZXRGZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmVNZXRob2QgPSAobnVtYmVyT2ZUZW5zb3JzOiBudW1iZXIsIHRlbnNvclJhbms6IG51bWJlcikgPT4ge1xuICBjb25zdCBjb2RlTGluZXM6IHN0cmluZ1tdID0gW2BmbG9hdCBmZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmUoaW50IHRleHR1cmVJbmRleCwgaW50IGluZGljZXNbJHt0ZW5zb3JSYW5rfV0pIHtgXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZlRlbnNvcnM7ICsraSkge1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBpZiAodGV4dHVyZUluZGV4ID09ICR7aX0pIHsgcmV0dXJuIF9YJHtpfShpbmRpY2VzKTsgfWApO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gbnVtYmVyT2ZUZW5zb3JzIC0gMSkge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgZWxzZSB7IHJldHVybiBfWCR7aX0oaW5kaWNlcyk7IH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgZWxzZSBpZiAodGV4dHVyZUluZGV4ID09ICR7aX0pIHsgcmV0dXJuIF9YJHtpfShpbmRpY2VzKTsgfWApO1xuICAgIH1cbiAgfVxuICBjb2RlTGluZXMucHVzaCgnXFx0JyArICd9Jyk7XG4gIHJldHVybiBjb2RlTGluZXMuam9pbignXFxuJyk7XG59O1xuXG5jb25zdCBnZXRHZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXhNZXRob2QgPSAoc2l6ZUluQ29uY2F0QXhpczogbnVtYmVyW10pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjb2RlTGluZXM6IHN0cmluZ1tdID0gWydpbnQgZ2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4KGludCBpbmRleCkgeyddO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemVJbkNvbmNhdEF4aXMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgaWYgKGluZGV4ID09ICR7aX0pIHsgcmV0dXJuICR7c2l6ZUluQ29uY2F0QXhpc1tpXX07IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IHNpemVJbkNvbmNhdEF4aXMubGVuZ3RoIC0gMSkge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgZWxzZSB7IHJldHVybiAke3NpemVJbkNvbmNhdEF4aXNbaV19OyB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgYGVsc2UgaWYgKGluZGV4ID09ICR7aX0pIHsgcmV0dXJuICR7c2l6ZUluQ29uY2F0QXhpc1tpXX07IH1gKTtcbiAgICB9XG4gIH1cbiAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyAnfScpO1xuXG4gIHJldHVybiBjb2RlTGluZXMuam9pbignXFxuJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDb25jYXRBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPENvbmNhdEF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBDb25jYXRBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXM6IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnKSB9KTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcigndG9vIGZldyBpbnB1dHMnKTtcbiAgfVxuXG4gIGNvbnN0IGlucHV0VHlwZSA9IGlucHV0c1swXS50eXBlO1xuICBjb25zdCBpbnB1dERpbWVuc2lvbmFsaXR5ID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuXG4gIC8vIFRPRE86IFN1cHBvcnQgc3RyaW5nIGNvbmNhdFxuICBpZiAoaW5wdXRUeXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignc3RyaW5nIHRlbnNvciBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICB9XG5cbiAgZm9yIChjb25zdCBpbnB1dCBvZiBpbnB1dHMpIHtcbiAgICAvLyBtYWtlIHN1cmUgdHlwZXMgb2YgYWxsIGlucHV0cyBtYXRjaFxuICAgIGlmIChpbnB1dC50eXBlICE9PSBpbnB1dFR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgdGVuc29ycyBzaG91bGQgYmUgb25lIHR5cGUnKTtcbiAgICB9XG5cbiAgICAvLyBtYWtlIHN1cmUgdGhlIGRpbWVuc2lvbmFsaXR5IG9mIGFsbCBpbnB1dHMgYXJlIHRoZSBzYW1lXG4gICAgaWYgKGlucHV0LmRpbXMubGVuZ3RoICE9PSBpbnB1dERpbWVuc2lvbmFsaXR5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHRlbnNvcnMgc2hvdWxkIGhhdmUgdGhlIHNhbWUgc2hhcGUnKTtcbiAgICB9XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IE1BWF9DTElQLCBNSU5fQ0xJUCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgRnVuY3Rpb25UeXBlLCBHbHNsVmFsdWVGdW5jdGlvbiB9IGZyb20gJy4uL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBYnMoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnYWJzJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEFjb3MoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnYWNvcycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBc2luKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2FzaW4nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQXRhbigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdhdGFuJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbENlaWwoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnY2VpbCcpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xDb3MoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnY29zJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEVsdShhbHBoYTogbnVtYmVyKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2VsdSc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGNvbnN0IGZsb2F0IGFscGhhID0gZmxvYXQoJHthbHBoYX0pO1xuXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gYSA+PSAwLjAgPyBhOiAoZXhwKGEpIC0gMS4wKSAqIGFscGhhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHZlYzQoJHtuYW1lfV8odi54KSwgJHtuYW1lfV8odi55KSwgJHtuYW1lfV8odi56KSwgJHtuYW1lfV8odi53KSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRXhwKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2V4cCcpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xGbG9vcigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdmbG9vcicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xDbGlwKG1pbjogbnVtYmVyLCBtYXg6IG51bWJlcik6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdjbGlwJztcbiAgY29uc3QgYm9keSA9IGBcbiAgY29uc3QgZmxvYXQgbWluID0gZmxvYXQoJHttaW59KTtcbiAgY29uc3QgZmxvYXQgbWF4ID0gZmxvYXQoJHttYXh9KTtcblxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGNsYW1wKGEsIG1pbiwgbWF4KTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiBjbGFtcCh2LCBtaW4sIG1heCk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsSWRlbnRpdHkoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2luZGVudGl0eSc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2O1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbExlYWt5UmVsdShhbHBoYTogbnVtYmVyKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2xlYWt5UmVsdSc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGNvbnN0IGZsb2F0IGFscGhhID0gZmxvYXQoJHthbHBoYX0pO1xuXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gYSA8IDAuMCA/IGEgKiBhbHBoYSA6IGE7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gdmVjNCgke25hbWV9Xyh2LngpLCAke25hbWV9Xyh2LnkpLCAke25hbWV9Xyh2LnopLCAke25hbWV9Xyh2LncpKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xMb2coKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnbG9nJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbE5lZygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbmVnJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiAtYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiAtdjtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xOb3QoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ25vdCc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gZmxvYXQoICEgYm9vbChhKSApO1xuICB9XG4gIGJvb2wgJHtuYW1lfV8oYm9vbCBhKSB7XG4gICAgcmV0dXJuICFhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHZlYzQoIWJvb2wodi54KSwgIWJvb2wodi55KSwgIWJvb2wodi56KSwgIWJvb2wodi53KSk7XG4gIH1cbiAgYnZlYzQgJHtuYW1lfV8oYnZlYzQgdikge1xuICAgIHJldHVybiBidmVjNCghdi54LCAhdi55LCAhdi56LCAhdi53KTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xTaW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnc2luJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFJlbHUoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3JlbHUnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIG1heCggYSwgMC4wICk7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gbWF4KCB2LCAwLjAgKTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xTaWdtb2lkKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdzaWdtb2lkJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiAxLjAgLyAoMS4wICsgZXhwKC1hKSk7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gMS4wIC8gKDEuMCArIGV4cCgtdikpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7IGJvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFNxcnQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnc3FydCcpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xUYW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgndGFuJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFRhbmgoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3RhbmgnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgYSA9IGNsYW1wKGEsIC0xMC4sIDEwLik7XG4gICAgYSA9IGV4cCgyLiphKTtcbiAgICByZXR1cm4gKGEgLSAxLikgLyAoYSArIDEuKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHYgPSBjbGFtcCh2LCAtMTAuLCAxMC4pO1xuICAgIHYgPSBleHAoMi4qdik7XG4gICAgcmV0dXJuICh2IC0gMS4pIC8gKHYgKyAxLik7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHsgYm9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWQgfTtcbn1cbmZ1bmN0aW9uIGdsc2xCdWlsdGluVW5hcnkobmFtZTogc3RyaW5nKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuICR7bmFtZX0oYSk7XG4gIH1cbiAgdmVjNCAke25hbWV9Xyh2ZWM0IHYpIHtcbiAgICByZXR1cm4gJHtuYW1lfSh2KTtcbiAgfVxuICBgO1xuICByZXR1cm4geyBib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZCB9O1xufVxuXG4vLy8vL1xuLy8vLy9cbi8vLy8vXG5cbmNvbnN0IGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8gPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXQ6IFRlbnNvcixcbiAgZ2xzbEZ1bmM6IEdsc2xWYWx1ZUZ1bmN0aW9uLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB0ZXh0dXJlVHlwZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrID8gVGV4dHVyZVR5cGUucGFja2VkIDogVGV4dHVyZVR5cGUudW5wYWNrZWQ7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGUgfSxcbiAgICBzaGFkZXJTb3VyY2U6IGBcbiAgICAgJHtnbHNsRnVuYy5ib2R5fVxuICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgdmVjNCB2ID0gJHtnbHNsLnRleHR1cmUyRH0oQSwgVGV4Q29vcmRzKTtcbiAgICAgICB2ID0gJHtnbHNsRnVuYy5uYW1lfV8odik7XG4gICAgICAgJHtnbHNsLm91dHB1dH0gPSB2O1xuICAgICB9XG4gICAgIGAsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgZ2xzbEZ1bmM6IEdsc2xWYWx1ZUZ1bmN0aW9uLFxuICBjYWNoZUtleT86IHN0cmluZyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICBjb25zdCBtZXRhZGF0YSA9IHsgbmFtZTogZ2xzbEZ1bmMubmFtZSwgaW5wdXRUeXBlczogW3RleHR1cmVUeXBlXSwgaW5wdXROYW1lczogWydBJ10sIGNhY2hlSGludDogY2FjaGVLZXkgfTtcbiAgcmV0dXJuIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXQsIGdsc2xGdW5jKSB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFicyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQWJzKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGFjb3MgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEFjb3MoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgYXNpbiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQXNpbigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBhdGFuID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBdGFuKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBDbGlwQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IG1pbjogbnVtYmVyO1xuICByZWFkb25seSBtYXg6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGNsaXAgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDbGlwQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihcbiAgICAgIGhhbmRsZXIsXG4gICAgICBpbnB1dHNbMF0sXG4gICAgICBnbHNsQ2xpcChhdHRyaWJ1dGVzLm1pbiwgYXR0cmlidXRlcy5tYXgpLFxuICAgICAgYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICApLFxuICAgIGlucHV0cyxcbiAgKSxcbl07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNsaXBBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBDbGlwQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIG1pbjogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtaW4nLCBNSU5fQ0xJUCksXG4gICAgbWF4OiBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21heCcsIE1BWF9DTElQKSxcbiAgfSk7XG5cbmV4cG9ydCBjb25zdCBjbGlwVjExID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgYXR0cmlidXRlcyA9IGdlbmVyYXRlQ2xpcEF0dHJpYnV0ZXNGcm9tSW5wdXRzKGhhbmRsZXIsIGlucHV0cyk7XG4gIHJldHVybiBjbGlwKGhhbmRsZXIsIFtpbnB1dHNbMF1dLCBhdHRyaWJ1dGVzKTtcbn07XG5cbmNvbnN0IGdlbmVyYXRlQ2xpcEF0dHJpYnV0ZXNGcm9tSW5wdXRzID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IENsaXBBdHRyaWJ1dGVzID0+IHtcbiAgaWYgKFxuICAgIGlucHV0cy5sZW5ndGggPj0gMyAmJlxuICAgICghaGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzFdLmRhdGFJZCkgfHwgIWhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1syXS5kYXRhSWQpKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2R5bmFtaWMgY2xpcCBhdHRyaWJ1dGVzIGFyZSBub3QgYWxsb3dlZCcpO1xuICB9XG5cbiAgY29uc3QgbWluID0gaW5wdXRzLmxlbmd0aCA+PSAzID8gaW5wdXRzWzFdLm51bWJlckRhdGFbMF0gOiBNSU5fQ0xJUDtcbiAgY29uc3QgbWF4ID0gaW5wdXRzLmxlbmd0aCA+PSAzID8gaW5wdXRzWzJdLm51bWJlckRhdGFbMF0gOiBNQVhfQ0xJUDtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IG1pbiwgbWF4IH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGNlaWwgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbENlaWwoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgY29zID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xDb3MoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgaW50ZXJmYWNlIEVsdUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhbHBoYTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgZWx1ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogRWx1QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xFbHUoYXR0cmlidXRlcy5hbHBoYSksIGF0dHJpYnV0ZXMuY2FjaGVLZXkpLFxuICAgIGlucHV0cyxcbiAgKSxcbl07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUVsdUF0dHJpYnV0ZXMgPSAobm9kZTogR3JhcGguTm9kZSk6IEVsdUF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYWxwaGE6IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAxLjApIH0pO1xuXG5leHBvcnQgY29uc3QgZXhwID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xFeHAoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3QgZmxvb3IgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbEZsb29yKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IGlkZW50aXR5ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xJZGVudGl0eSgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGVha3lSZWx1QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGFscGhhOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBsZWFreVJlbHUgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogTGVha3lSZWx1QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xMZWFreVJlbHUoYXR0cmlidXRlcy5hbHBoYSksIGF0dHJpYnV0ZXMuY2FjaGVLZXkpLFxuICAgIGlucHV0cyxcbiAgKSxcbl07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUxlYWt5UmVsdUF0dHJpYnV0ZXMgPSAobm9kZTogR3JhcGguTm9kZSk6IExlYWt5UmVsdUF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYWxwaGE6IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAwLjAxKSB9KTtcblxuZXhwb3J0IGNvbnN0IGxvZyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsTG9nKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IG5lZyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsTmVnKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IG5vdCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsTm90KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHJlbHUgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFJlbHUoKSksIGlucHV0cyksXG5dO1xuXG5leHBvcnQgY29uc3Qgc2lnbW9pZCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsU2lnbW9pZCgpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBzaW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFNpbigpKSwgaW5wdXRzKSxcbl07XG5cbmV4cG9ydCBjb25zdCBzcXJ0ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IFtcbiAgaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xTcXJ0KCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHRhbiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiBbXG4gIGhhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsVGFuKCkpLCBpbnB1dHMpLFxuXTtcblxuZXhwb3J0IGNvbnN0IHRhbmggPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4gW1xuICBoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFRhbmgoKSksIGlucHV0cyksXG5dO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGUgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUnO1xuaW1wb3J0IHsgTUFYX0NMSVAsIE1JTl9DTElQIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBHbHNsVmFsdWVGdW5jdGlvbiB9IGZyb20gJy4uL2dsc2wtZGVmaW5pdGlvbnMnO1xuXG5pbXBvcnQgeyBnbHNsQ2xpcCwgZ2xzbFJlbHUsIGdsc2xTaWdtb2lkIH0gZnJvbSAnLi91bmFyeS1vcCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IGFjdGl2YXRpb246IHN0cmluZztcbiAgcmVhZG9ubHkgY2xpcE1pbj86IG51bWJlcjtcbiAgcmVhZG9ubHkgY2xpcE1heD86IG51bWJlcjtcbiAgcmVhZG9ubHkgYWN0aXZhdGlvbkNhY2hlS2V5OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBY3RpdmF0aW9uU25pcHBldChhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKSB7XG4gIGxldCBmdW5jOiBHbHNsVmFsdWVGdW5jdGlvbjtcbiAgc3dpdGNoIChhdHRyaWJ1dGVzLmFjdGl2YXRpb24pIHtcbiAgICBjYXNlICdSZWx1JzpcbiAgICAgIGZ1bmMgPSBnbHNsUmVsdSgpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnU2lnbW9pZCc6XG4gICAgICBmdW5jID0gZ2xzbFNpZ21vaWQoKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0NsaXAnOlxuICAgICAgZnVuYyA9IGdsc2xDbGlwKGF0dHJpYnV0ZXMuY2xpcE1pbiEsIGF0dHJpYnV0ZXMuY2xpcE1heCEpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gVE9ETzogYWRkaW5nIG90aGVyIGFjdGl2YXRpb25zIHRoYXQgY2FuIGJlIGZ1c2VkLlxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4geyBhY3RpdmF0aW9uRnVuY3Rpb246ICcnLCBhcHBseUFjdGl2YXRpb246ICcnIH07XG4gIH1cblxuICBjb25zdCBhY3RpdmF0aW9uTmFtZSA9IGZ1bmMubmFtZTtcbiAgY29uc3QgYWN0aXZhdGlvbkZ1bmN0aW9uID0gZnVuYy5ib2R5O1xuICBjb25zdCBhcHBseUFjdGl2YXRpb24gPSBgdmFsdWUgPSAke2FjdGl2YXRpb25OYW1lfV8odmFsdWUpO2A7XG4gIHJldHVybiB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH07XG59XG5cbmV4cG9ydCBjb25zdCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogQXR0cmlidXRlKTogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGFjdGl2YXRpb24gPSBhdHRyaWJ1dGVzLmdldFN0cmluZygnYWN0aXZhdGlvbicsICcnKTtcblxuICBpZiAoYWN0aXZhdGlvbiA9PT0gJ0NsaXAnKSB7XG4gICAgY29uc3QgW2NsaXBNaW4sIGNsaXBNYXhdID0gYXR0cmlidXRlcy5nZXRGbG9hdHMoJ2FjdGl2YXRpb25fcGFyYW1zJywgW01JTl9DTElQLCBNQVhfQ0xJUF0pO1xuICAgIHJldHVybiB7IGFjdGl2YXRpb24sIGNsaXBNYXgsIGNsaXBNaW4sIGFjdGl2YXRpb25DYWNoZUtleTogYCR7YWN0aXZhdGlvbn06JHtjbGlwTWlufSwke2NsaXBNYXh9YCB9O1xuICB9XG4gIHJldHVybiB7IGFjdGl2YXRpb24sIGFjdGl2YXRpb25DYWNoZUtleTogYWN0aXZhdGlvbiB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY2FsY3VsYXRlT3V0cHV0U2hhcGUsIENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb252JztcbmltcG9ydCB7IGdldEFjdGl2YXRpb25TbmlwcGV0IH0gZnJvbSAnLi9mdXNlLXV0aWxzJztcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBjYWNoZUhpbnQ6IHN0cmluZyk6IFByb2dyYW1NZXRhZGF0YSA9PiAoe1xuICBuYW1lOiAnR3JvdXBlZENvbnYnLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydYJywgJ1cnLCAnQmlhcyddIDogWydYJywgJ1cnXSxcbiAgaW5wdXRUeXBlczogaGFzQmlhc1xuICAgID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdXG4gICAgOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICBjb25zdCBwcm9jZXNzQmlhcyA9IGhhc0JpYXMgPyAndmFsdWUgKz0gZ2V0QmlhcyhvdXRwdXRfY2hhbm5lbCk7JyA6ICcnO1xuICBjb25zdCB4U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCB3U2hhcGUgPSBpbnB1dHNbMV0uZGltcy5zbGljZSgpO1xuICBjb25zdCBvdXRwdXRDaGFubmVsc1Blckdyb3VwID0gd1NoYXBlWzBdIC8gYXR0cmlidXRlcy5ncm91cDtcbiAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgJ0dyb3VwZWRDb252JyxcbiAgICBgYXV0cFBhZDoke2F0dHJpYnV0ZXMuYXV0b1BhZH0sIGRpbGF0aW9uczoke2F0dHJpYnV0ZXMuZGlsYXRpb25zfSwgZ3JvdXA6JHthdHRyaWJ1dGVzLmdyb3VwfSwga2VybmVsU2hhcGU6JHtcbiAgICAgIGF0dHJpYnV0ZXMua2VybmVsU2hhcGVcbiAgICB9LCBwYWRzOiR7YXR0cmlidXRlcy5wYWRzfSwgc3RyaWRlczoke2F0dHJpYnV0ZXMuc3RyaWRlc31gLFxuICApO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhTaGFwZSwgd1NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMpO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgY29uc3QgaXZlYzIgc3RyaWRlcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfSwgJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19KTtcbiAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5wYWRzWzBdfSwgJHthdHRyaWJ1dGVzLnBhZHNbMV19KTtcbiAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gIHZvaWQgbWFpbigpIHtcbiAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDtcbiAgICBpbnQgb3V0cHV0X2NoYW5uZWwgPSBjb29yZHMueTtcbiAgICBpdmVjMiB4UkNDb3JuZXIgPSBjb29yZHMuencgKiBzdHJpZGVzIC0gcGFkcztcbiAgICBpbnQgZ3JvdXBfaWQgPSBvdXRwdXRfY2hhbm5lbCAvICR7b3V0cHV0Q2hhbm5lbHNQZXJHcm91cH07XG5cbiAgICBmbG9hdCB2YWx1ZSA9IDAuMDtcbiAgICBmb3IgKGludCB3SW5DaGFubmVsID0gMDsgd0luQ2hhbm5lbCA8ICR7d1NoYXBlWzFdfTsgd0luQ2hhbm5lbCsrKSB7XG4gICAgICBpbnQgaW5wdXRfY2hhbm5lbCA9IGdyb3VwX2lkICogJHt3U2hhcGVbMV19ICsgd0luQ2hhbm5lbDtcbiAgICAgIGZvciAoaW50IHdIZWlnaHQgPSAwOyB3SGVpZ2h0IDwgJHt3U2hhcGVbMl19OyB3SGVpZ2h0KyspIHtcbiAgICAgICAgaW50IHhIZWlnaHQgPSB4UkNDb3JuZXIueCArIHdIZWlnaHQgKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzBdfTtcblxuICAgICAgICBpZiAoeEhlaWdodCA8IDAgfHwgeEhlaWdodCA+PSAke3hTaGFwZVsyXX0pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaW50IHdXaWR0aCA9IDA7IHdXaWR0aCA8ICR7d1NoYXBlWzNdfTsgd1dpZHRoKyspIHtcbiAgICAgICAgICBpbnQgeFdpZHRoID0geFJDQ29ybmVyLnkgKyB3V2lkdGggKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzFdfTtcbiAgICAgICAgICBpZiAoeFdpZHRoIDwgMCB8fCB4V2lkdGggPj0gJHt4U2hhcGVbM119KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmbG9hdCB4VmFsID0gZ2V0WChiYXRjaCwgaW5wdXRfY2hhbm5lbCwgeFdpZHRoLCB4SGVpZ2h0KTtcbiAgICAgICAgICBmbG9hdCB3VmFsID0gZ2V0VyhvdXRwdXRfY2hhbm5lbCwgd0luQ2hhbm5lbCwgd1dpZHRoLCB3SGVpZ2h0KTtcbiAgICAgICAgICB2YWx1ZSArPSB4VmFsKndWYWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgJHtwcm9jZXNzQmlhc31cbiAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQodmFsdWUsIC4wLCAuMCwgLjApO1xuICB9XG5gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIG1ldGFkYXRhLCBhdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBDb252QXR0cmlidXRlcyB9IGZyb20gJy4vY29udic7XG5pbXBvcnQgeyB1bnBhY2tGcm9tQ2hhbm5lbCB9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1NZXRhZGF0YSA9IChjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ0ltMkNvbCAocGFja2VkKScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIHg6IFRlbnNvcixcbiAgdzogVGVuc29yLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB4c2hhcGUgPSB4LmRpbXM7XG4gIGNvbnN0IHdzaGFwZSA9IHcuZGltcztcbiAgY29uc3Qgcm93RGltID0gMjtcbiAgY29uc3QgY29sRGltID0gMztcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgaW0yY29sU2hhcGUgPSBbd3NoYXBlWzFdICogd3NoYXBlWzJdICogd3NoYXBlWzNdLCBvdXRwdXRTaGFwZVsyXSAqIG91dHB1dFNoYXBlWzNdXTtcbiAgY29uc3Qga2VybmVsU2l6ZSA9IHdzaGFwZVsyXSAqIHdzaGFwZVszXTtcbiAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgbGV0IHVucm9sbGVkID0gJyc7XG5cbiAgZm9yIChsZXQgcm93ID0gMDsgcm93IDw9IDE7IHJvdysrKSB7XG4gICAgZm9yIChsZXQgY29sID0gMDsgY29sIDw9IDE7IGNvbCsrKSB7XG4gICAgICB1bnJvbGxlZCArPSBgXG4gICAgICAgICAgICBibG9ja0luZGV4ID0gcmMueCArICR7Y29sfTtcbiAgICAgICAgICAgIHBvcyA9IHJjLnkgKyAke3Jvd307XG5cbiAgICAgICAgICAgIGlmKGJsb2NrSW5kZXggPCAke2ltMmNvbFNoYXBlWzFdfSAmJiBwb3MgPCAke2ltMmNvbFNoYXBlWzBdfSkge1xuICAgICAgICAgICAgICBvZmZzZXRZID0gaW50KGJsb2NrSW5kZXggLyAoJHtvdXRwdXRTaGFwZVtyYW5rIC0gMV19KSkgKiAke2F0dHJpYnV0ZXMuc3RyaWRlc1swXX0gLVxuICAgICAgICAgICAgICAgICR7YXR0cmlidXRlcy5wYWRzWzBdfTtcbiAgICAgICAgICAgICAgZDAgPSBvZmZzZXRZICsgJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXX0gKiAoaW1vZChwb3MsICR7a2VybmVsU2l6ZX0pIC8gJHt3c2hhcGVbMl19KTtcblxuICAgICAgICAgICAgICBpZihkMCA8ICR7eHNoYXBlW3Jvd0RpbV19ICYmIGQwID49IDApIHtcbiAgICAgICAgICAgICAgICBvZmZzZXRYID0gaW1vZChibG9ja0luZGV4LCAke291dHB1dFNoYXBlW3JhbmsgLSAxXX0pICogJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19IC1cbiAgICAgICAgICAgICAgICAgICR7YXR0cmlidXRlcy5wYWRzWzFdfTtcbiAgICAgICAgICAgICAgICBkMSA9IG9mZnNldFggKyAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzFdfSAqIGltb2QoaW1vZChwb3MsICR7a2VybmVsU2l6ZX0pLCAke3dzaGFwZVsyXX0pO1xuXG4gICAgICAgICAgICAgICAgaWYoZDEgPCAke3hzaGFwZVtjb2xEaW1dfSAmJiBkMSA+PSAwKSB7XG5cbiAgICAgICAgICAgICAgICAgIGNoID0gaW50KGZsb2F0KHBvcykvICR7a2VybmVsU2l6ZX0uKTtcbiAgICAgICAgICAgICAgICAgICAgaW5uZXJEaW1zID0gdmVjMihkMCwgZDEpO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRbJHtyb3cgKiAyICsgY29sfV0gPSBnZXRDaGFubmVsKFxuICAgICAgICAgICAgICAgICAgICAgIGdldEEoMCwgY2gsIGludChpbm5lckRpbXMueCksXG4gICAgICAgICAgICAgICAgICAgICAgaW50KGlubmVyRGltcy55KSksIGlubmVyRGltcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBgO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7dW5wYWNrQ2hhbm5lbH1cblxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICBpdmVjMiByYyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLjApO1xuICAgICAgICAgIGludCBibG9ja0luZGV4LCBwb3MsIG9mZnNldFksIGQwLCBvZmZzZXRYLCBkMSwgY2g7XG4gICAgICAgICAgdmVjMiBpbm5lckRpbXM7XG4gICAgICAgICAgJHt1bnJvbGxlZH1cbiAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICAgIH1cbiAgICAgICAgICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IGltMmNvbFNoYXBlLCB0eXBlOiB4LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICB4OiBUZW5zb3IsXG4gIHc6IFRlbnNvcixcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtTWV0YWRhdGEoYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgeCwgdywgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzIH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyBnZXRBY3RpdmF0aW9uU25pcHBldCwgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcywgcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9mdXNlLXV0aWxzJztcbmltcG9ydCB7IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9tYXRtdWwtcGFjayc7XG5cbmV4cG9ydCBjb25zdCBtYXRNdWw6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248SW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBpZiAoaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLnBhY2spIHtcbiAgICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyldO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKV07XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZU1hdE11bEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248SW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzID0+IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyhub2RlLmF0dHJpYnV0ZXMpO1xuXG5jb25zdCBjcmVhdGVNYXRtdWxQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdNYXRNdWwnLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydBJywgJ0InLCAnQmlhcyddIDogWydBJywgJ0InXSxcbiAgaW5wdXRUeXBlczogaGFzQmlhc1xuICAgID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdXG4gICAgOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmZ1bmN0aW9uIGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvKFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhY3RpdmF0aW9uQXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvIHtcbiAgY29uc3QgYVNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGJTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGFTaGFwZSwgYlNoYXBlLCB0cnVlKTtcbiAgaWYgKCFvdXRwdXRTaGFwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHVzZSBtYXRtdWwgb24gdGhlIGdpdmVuIHRlbnNvcnNcIik7XG4gIH1cbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBhbGxHbENoYW5uZWxzID0gZ2V0R2xDaGFubmVscygpO1xuICBjb25zdCB7IGFjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9uIH0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhY3RpdmF0aW9uQXR0cmlidXRlcyk7XG5cbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICBjb25zdCBwcm9jZXNzQmlhcyA9IGhhc0JpYXMgPyAndmFsdWUgKz0gZ2V0Qmlhc0Zvck1hdG11bCgpOycgOiAnJztcbiAgY29uc3QgZ2V0Qmlhc0Zvck1hdG11bFNuaXBwZXQgPSBoYXNCaWFzXG4gICAgPyBgJHtnZXRCaWFzRm9yTWF0bXVsKGNvb3Jkc0RhdGFUeXBlLCBhbGxHbENoYW5uZWxzLCBpbnB1dHNbMl0uZGltcywgb3V0cHV0U2hhcGUsIGZhbHNlKX1gXG4gICAgOiAnJztcblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBhcmFuayA9IGFTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGJyYW5rID0gYlNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgc2hhcmVkRGltID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICR7YWN0aXZhdGlvbkZ1bmN0aW9ufVxuICAgICR7Z2V0Qmlhc0Zvck1hdG11bFNuaXBwZXR9XG4gICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgYVske2FyYW5rfV07XG4gICAgICAgIGludCBiWyR7YnJhbmt9XTtcbiAgICAgICAgYmNhc3RNYXRtdWxJbmRpY2VzX0EoaW5kaWNlcywgYSk7XG4gICAgICAgIGJjYXN0TWF0bXVsSW5kaWNlc19CKGluZGljZXMsIGIpO1xuXG4gICAgICAgIGZsb2F0IHZhbHVlO1xuICAgICAgICBmb3IgKGludCBrPTA7IGs8JHtzaGFyZWREaW19OyArK2spIHtcbiAgICAgICAgICAgIGFbJHthcmFuayAtIDF9XSA9IGs7XG4gICAgICAgICAgICBiWyR7YnJhbmsgLSAyfV0gPSBrO1xuICAgICAgICAgICAgdmFsdWUgKz0gX0EoYSkgKiBfQihiKTtcbiAgICAgICAgfVxuICAgICAgICAke3Byb2Nlc3NCaWFzfVxuICAgICAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyKFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhY3RpdmF0aW9uQXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyIHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVNYXRtdWxQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGFjdGl2YXRpb25BdHRyaWJ1dGVzLmFjdGl2YXRpb25DYWNoZUtleSk7XG4gIHJldHVybiB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvKG1ldGFkYXRhLCBpbnB1dHMsIGFjdGl2YXRpb25BdHRyaWJ1dGVzKSB9O1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01hdE11bCByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltc1tpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAxXSAhPT0gaW5wdXRzWzFdLmRpbXNbaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMl0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NoYXJlZCBkaW1lbnNpb24gZG9lcyBub3QgbWF0Y2guJyk7XG4gIH1cblxuICBpZiAoXG4gICAgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0NjQnKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0cyBzaG91bGQgYmUgZmxvYXQgdHlwZScpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSBpbnB1dHNbMV0udHlwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXRzIHR5cGVzIHNob3VsZCBtYXRjaCcpO1xuICB9XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Qmlhc0Zvck1hdG11bChcbiAgY29vcmRzRGF0YVR5cGU6IHN0cmluZyxcbiAgYWxsR2xDaGFubmVsczogcmVhZG9ubHkgc3RyaW5nW10sXG4gIGluU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGlzUGFja2VkOiBib29sZWFuLFxuKTogc3RyaW5nIHtcbiAgbGV0IHVucGFja2VkQ29vcmRzU25pcHBldCA9ICcnO1xuICBjb25zdCBpblJhbmsgPSBpblNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgb3V0UmFuayA9IG91dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgcmFua0RpZmYgPSBvdXRSYW5rIC0gaW5SYW5rO1xuICBpZiAob3V0UmFuayA8IDIgJiYgaW5SYW5rID4gMCkge1xuICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9ICdjb29yZHMnO1xuICB9IGVsc2Uge1xuICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9IGluU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbaSArIHJhbmtEaWZmXX1gKS5qb2luKCcsICcpO1xuICB9XG4gIGNvbnN0IGJyb2FkY2FzdERpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5TaGFwZSwgb3V0U2hhcGUpO1xuICBjb25zdCBjb29yZHNTbmlwcGV0ID0gYnJvYWRjYXN0RGltcy5tYXAoKGQpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2QgKyByYW5rRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgY29uc3QgaW5TaXplID0gU2hhcGVVdGlsLnNpemUoaW5TaGFwZSk7XG4gIGNvbnN0IGlzSW5wdXRTY2FsYXIgPSBpblNpemUgPT09IDE7XG4gIGxldCBvdXRwdXQgPSAndmVjNChvdXRwdXRWYWx1ZS54eCwgb3V0cHV0VmFsdWUueXkpJztcbiAgaWYgKGlzSW5wdXRTY2FsYXIpIHtcbiAgICBvdXRwdXQgPSAndmVjNChvdXRwdXRWYWx1ZS54KSc7XG4gIH1cbiAgY29uc3QgZ2V0Qmlhc0Zvck1hdG11bFNvdXJjZSA9IGlzUGFja2VkXG4gICAgPyBgXG52ZWM0IGdldEJpYXNGb3JNYXRtdWwoKSB7XG4gICR7Y29vcmRzRGF0YVR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAke2Nvb3Jkc1NuaXBwZXR9XG4gIHZlYzQgb3V0cHV0VmFsdWUgPSBnZXRCaWFzKCR7dW5wYWNrZWRDb29yZHNTbmlwcGV0fSk7XG4gIHJldHVybiAke291dHB1dH07XG59YFxuICAgIDogYFxuZmxvYXQgZ2V0Qmlhc0Zvck1hdG11bCgpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7Y29vcmRzU25pcHBldH1cbiAgcmV0dXJuIGdldEJpYXMoY29vcmRzLngpO1xufWA7XG5cbiAgcmV0dXJuIGdldEJpYXNGb3JNYXRtdWxTb3VyY2U7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRDb29yZHNEYXRhVHlwZSwgZ2V0R2xDaGFubmVscyB9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHsgZ2V0QWN0aXZhdGlvblNuaXBwZXQsIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgZ2V0Qmlhc0Zvck1hdG11bCB9IGZyb20gJy4vbWF0bXVsJztcblxuY29uc3QgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnTWF0TXVsIChwYWNrZWQpJyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnQScsICdCJywgJ0JpYXMnXSA6IFsnQScsICdCJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXNcbiAgICA/IFtUZXh0dXJlVHlwZS5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkXVxuICAgIDogW1RleHR1cmVUeXBlLnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkXSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IHByb2Nlc3NCaWFzID0gaGFzQmlhcyA/ICd2YWx1ZSArPSBnZXRCaWFzRm9yTWF0bXVsKCk7JyA6ICcnO1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoYVNoYXBlLCBiU2hhcGUsIHRydWUpO1xuICBjb25zdCBpc0Jyb2FkY2FzdCA9ICFTaGFwZVV0aWwuYXJlRXF1YWwoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5kaW1zKTtcblxuICBpZiAoIW91dHB1dFNoYXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgdXNlIG1hdG11bCBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgfVxuICBjb25zdCBzaGFyZWREaW0gPSBhU2hhcGVbYVNoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBzaGFyZWREaW1JbmRleCA9IE1hdGguY2VpbChzaGFyZWREaW0gLyAyKTtcbiAgY29uc3QgYVJhbmsgPSBhU2hhcGUubGVuZ3RoO1xuICBjb25zdCBiUmFuayA9IGJTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IG91dFJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGFsbEdsQ2hhbm5lbHMgPSBnZXRHbENoYW5uZWxzKCk7XG4gIGNvbnN0IHsgYWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb24gfSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGFjdGl2YXRpb25BdHRyaWJ1dGVzKTtcblxuICBjb25zdCBnZXRCaWFzRm9yTWF0bXVsU25pcHBldCA9IGhhc0JpYXNcbiAgICA/IGAke2dldEJpYXNGb3JNYXRtdWwoY29vcmRzRGF0YVR5cGUsIGFsbEdsQ2hhbm5lbHMsIGlucHV0c1syXS5kaW1zLCBvdXRwdXRTaGFwZSwgdHJ1ZSl9YFxuICAgIDogJyc7XG5cbiAgY29uc3QgZ2V0QmNhc3RlZFNhbXBsZXJGb3JNYXRtdWxTbmlwcGV0ID0gaXNCcm9hZGNhc3RcbiAgICA/IGAke2dldEJjYXN0U2FtcGxlckZvck1hdG11bChjb29yZHNEYXRhVHlwZSwgYWxsR2xDaGFubmVscywgaW5wdXRzLCBvdXRwdXRTaGFwZSl9YFxuICAgIDogJyc7XG5cbiAgY29uc3QgZ2V0U2FtcGxlckFJbkxvb3BTbmlwcGV0ID0gaXNCcm9hZGNhc3QgPyAnZ2V0QUF0T3V0Q29vcmRzTWF0bXVsKGkpJyA6IGBnZXRBKCR7Z2V0QShhbGxHbENoYW5uZWxzLCBhUmFuayl9KWA7XG4gIGNvbnN0IGdldFNhbXBsZXJCSW5Mb29wU25pcHBldCA9IGlzQnJvYWRjYXN0ID8gJ2dldEJBdE91dENvb3Jkc01hdG11bChpKScgOiBgZ2V0Qigke2dldEIoYWxsR2xDaGFubmVscywgYlJhbmspfSlgO1xuICBjb25zdCBnZXRPdXRwdXRDb29yZHNTbmlwcGV0ID0gaXNCcm9hZGNhc3RcbiAgICA/ICcnXG4gICAgOiBgJHtjb29yZHNEYXRhVHlwZX0gcmMgPVxuICAgICAgICAgIGdldE91dHB1dENvb3JkcygpOyBpbnQgbGFzdERpbSA9IHJjLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMV19OyByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDFdfSA9XG4gICAgICAgICAgcmMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAyXX07IHJjLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMl19ID0gbGFzdERpbTtcbiAgICAgIGA7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgICAgICR7Z2V0QmNhc3RlZFNhbXBsZXJGb3JNYXRtdWxTbmlwcGV0fVxuICAgICAgICAgICAgJHtnZXRCaWFzRm9yTWF0bXVsU25pcHBldH1cbiAgICAgICAgICAgICR7YWN0aXZhdGlvbkZ1bmN0aW9ufVxuICAgICAgICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICAgICAgICAke2dldE91dHB1dENvb3Jkc1NuaXBwZXR9XG5cbiAgICAgICAgICAgICAgdmVjNCB2YWx1ZSA9IHZlYzQoMCk7XG4gICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtzaGFyZWREaW1JbmRleH07IGkrKykge1xuICAgICAgICAgICAgICAgIHZlYzQgYSA9ICR7Z2V0U2FtcGxlckFJbkxvb3BTbmlwcGV0fTtcbiAgICAgICAgICAgICAgICB2ZWM0IGIgPSAke2dldFNhbXBsZXJCSW5Mb29wU25pcHBldH07XG5cbiAgICAgICAgICAgICAgICB2YWx1ZSArPSAoYS5ycmJiICogYi5yZ3JnKTtcbiAgICAgICAgICAgICAgICB2YWx1ZSArPSAoYS5nZ2FhICogYi5iYWJhKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAke3Byb2Nlc3NCaWFzfVxuICAgICAgICAgICAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhY3RpdmF0aW9uQXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGFjdGl2YXRpb25BdHRyaWJ1dGVzLmFjdGl2YXRpb25DYWNoZUtleSk7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhY3RpdmF0aW9uQXR0cmlidXRlcyksXG4gIH07XG59O1xuXG5mdW5jdGlvbiBnZXRCY2FzdFNhbXBsZXJGb3JNYXRtdWwoXG4gIGNvb3Jkc0RhdGFUeXBlOiBzdHJpbmcsXG4gIGFsbEdsQ2hhbm5lbHM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBvdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBzdHJpbmcge1xuICBsZXQgdW5wYWNrZWRBQ29vcmRzU25pcHBldCA9IFtdO1xuICBsZXQgdW5wYWNrZWRCQ29vcmRzU25pcHBldCA9IFtdO1xuXG4gIGNvbnN0IGluQVNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGluQlNoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG5cbiAgY29uc3QgaW5BUmFuayA9IGluQVNoYXBlLmxlbmd0aDtcbiAgY29uc3QgaW5CUmFuayA9IGluQlNoYXBlLmxlbmd0aDtcblxuICBjb25zdCBvdXRSYW5rID0gb3V0U2hhcGUubGVuZ3RoO1xuICBjb25zdCByYW5rQURpZmYgPSBvdXRSYW5rIC0gaW5BUmFuaztcbiAgY29uc3QgcmFua0JEaWZmID0gb3V0UmFuayAtIGluQlJhbms7XG5cbiAgdW5wYWNrZWRBQ29vcmRzU25pcHBldCA9IGluQVNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2kgKyByYW5rQURpZmZdfWApO1xuICB1bnBhY2tlZEFDb29yZHNTbmlwcGV0W2luQVJhbmsgLSAxXSA9ICdpKjInO1xuICB1bnBhY2tlZEFDb29yZHNTbmlwcGV0LmpvaW4oJywgJyk7XG4gIHVucGFja2VkQkNvb3Jkc1NuaXBwZXQgPSBpbkJTaGFwZS5tYXAoKF9zLCBpKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tpICsgcmFua0JEaWZmXX1gKTtcbiAgdW5wYWNrZWRCQ29vcmRzU25pcHBldFtpbkJSYW5rIC0gMl0gPSAnaSoyJztcbiAgdW5wYWNrZWRCQ29vcmRzU25pcHBldC5qb2luKCcsICcpO1xuXG4gIGNvbnN0IGJyb2FkY2FzdEFEaW1zID0gQnJvYWRjYXN0VXRpbC5nZXRCcm9hZGNhc3REaW1zKGluQVNoYXBlLCBvdXRTaGFwZSk7XG4gIGNvbnN0IGJyb2FkY2FzdEJEaW1zID0gQnJvYWRjYXN0VXRpbC5nZXRCcm9hZGNhc3REaW1zKGluQlNoYXBlLCBvdXRTaGFwZSk7XG5cbiAgY29uc3QgY29vcmRzQVNuaXBwZXQgPSBicm9hZGNhc3RBRGltcy5tYXAoKGQpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2QgKyByYW5rQURpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gIGNvbnN0IGNvb3Jkc0JTbmlwcGV0ID0gYnJvYWRjYXN0QkRpbXMubWFwKChkKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tkICsgcmFua0JEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICBjb25zdCBzd2FwRGltU25pcHBldCA9IGBpbnQgbGFzdERpbSA9IGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDFdfTtcbiAgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMV19ID0gY29vcmRzLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMl19O1xuICBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAyXX0gPSBsYXN0RGltO2A7XG5cbiAgY29uc3QgZ2V0QmNhc3RTYW1wbGVyTWF0bXVsU291cmNlID0gYFxudmVjNCBnZXRBQXRPdXRDb29yZHNNYXRtdWwoaW50IGkpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7c3dhcERpbVNuaXBwZXR9XG4gICR7Y29vcmRzQVNuaXBwZXR9XG4gIHZlYzQgb3V0cHV0VmFsdWUgPSBnZXRBKCR7dW5wYWNrZWRBQ29vcmRzU25pcHBldH0pO1xuICByZXR1cm4gb3V0cHV0VmFsdWU7XG59XG5cbnZlYzQgZ2V0QkF0T3V0Q29vcmRzTWF0bXVsKGludCBpKSB7XG4gICR7Y29vcmRzRGF0YVR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAke3N3YXBEaW1TbmlwcGV0fVxuICAke2Nvb3Jkc0JTbmlwcGV0fVxuICB2ZWM0IG91dHB1dFZhbHVlID0gZ2V0Qigke3VucGFja2VkQkNvb3Jkc1NuaXBwZXR9KTtcbiAgcmV0dXJuIG91dHB1dFZhbHVlO1xufWA7XG5cbiAgcmV0dXJuIGdldEJjYXN0U2FtcGxlck1hdG11bFNvdXJjZTtcbn1cblxuZnVuY3Rpb24gZ2V0QShhbGxHbENoYW5uZWxzOiBzdHJpbmdbXSwgcmFuazogbnVtYmVyKTogc3RyaW5nIHtcbiAgbGV0IHJlcyA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAyOyBpKyspIHtcbiAgICByZXMgKz0gYHJjLiR7YWxsR2xDaGFubmVsc1tpXX0sIGA7XG4gIH1cbiAgcmVzICs9IGByYy4ke2FsbEdsQ2hhbm5lbHNbcmFuayAtIDJdfSwgYCArICdpKjInO1xuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiBnZXRCKGFsbEdsQ2hhbm5lbHM6IHN0cmluZ1tdLCByYW5rOiBudW1iZXIpOiBzdHJpbmcge1xuICBsZXQgcmVzID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7IGkrKykge1xuICAgIHJlcyArPSBgcmMuJHthbGxHbENoYW5uZWxzW2ldfSwgYDtcbiAgfVxuICByZXMgKz0gJ2kqMiwgJyArIGByYy4ke2FsbEdsQ2hhbm5lbHNbcmFuayAtIDFdfWA7XG4gIHJldHVybiByZXM7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmltcG9ydCB7IGNhbGN1bGF0ZU91dHB1dFNoYXBlLCBDb252QXR0cmlidXRlcyB9IGZyb20gJy4vY29udic7XG5pbXBvcnQgeyBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vaW0yY29sLXBhY2snO1xuaW1wb3J0IHsgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL21hdG11bC1wYWNrJztcblxuZXhwb3J0IGNvbnN0IGNvbnYyRFBhY2tlZFBvaW50d2lzZSA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBrc2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4c2hhcGUsIGtzaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcbiAgY29uc3QgcmVzaGFwZWRYID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1swXSwgW3hzaGFwZVsxXSwgeHNoYXBlWzJdICogeHNoYXBlWzNdXSk7XG4gIGNvbnN0IHJlc2hhcGVkSyA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChpbnB1dHNbMV0sIFtrc2hhcGVbMF0sIGtzaGFwZVsxXV0pO1xuXG4gIGNvbnN0IG1hdG11bElucHV0cyA9IGlucHV0cy5sZW5ndGggPiAyID8gW3Jlc2hhcGVkSywgcmVzaGFwZWRYLCBpbnB1dHNbMl1dIDogW3Jlc2hhcGVkSywgcmVzaGFwZWRYXTtcbiAgY29uc3QgbWF0bXVsT3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgbWF0bXVsSW5wdXRzLCBhdHRyaWJ1dGVzKSxcbiAgICBtYXRtdWxJbnB1dHMsXG4gICk7XG4gIHJldHVybiBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQobWF0bXVsT3V0cHV0LCBvdXRwdXRTaGFwZSk7XG59O1xuXG5leHBvcnQgY29uc3QgY29udjJEUGFja2VkID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yID0+IHtcbiAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhzaGFwZSwga3NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuXG4gIC8vIHJ1biBpbTJjb2xcbiAgY29uc3QgaW0yY29sT3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBpbnB1dHNbMV0sIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSxcbiAgICBbaW5wdXRzWzBdXSxcbiAgKTtcblxuICAvLyByZXNoYXBlIGtlcm5lbFxuICBjb25zdCBrZXJuZWxSZXNoYXBlZCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChpbnB1dHNbMV0sIFtrc2hhcGVbMF0sIGtzaGFwZVsxXSAqIGtzaGFwZVsyXSAqIGtzaGFwZVszXV0pO1xuXG4gIC8vIHJ1biBtYXRtdWxcbiAgY29uc3QgbWF0bXVsSW5wdXRzID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/IFtrZXJuZWxSZXNoYXBlZCwgaW0yY29sT3V0cHV0LCBpbnB1dHNbMl1dIDogW2tlcm5lbFJlc2hhcGVkLCBpbTJjb2xPdXRwdXRdO1xuICBjb25zdCBtYXRtdWxPdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBtYXRtdWxJbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgIG1hdG11bElucHV0cyxcbiAgKTtcblxuICAvLyByZXNoYXBlIG91dHB1dFxuICBjb25zdCBvdXRwdXRSZXNoYXBlZCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChtYXRtdWxPdXRwdXQsIG91dHB1dFNoYXBlKTtcbiAgcmV0dXJuIG91dHB1dFJlc2hhcGVkO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuXG5jb25zdCBjcmVhdGVJbTJDb2xQcm9ncmFtTWV0YWRhdGEgPSAoY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdJbTJDb2wnLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZUltMkNvbFByb2dyYW1JbmZvID0gKFxuICBfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICB4OiBUZW5zb3IsXG4gIHc6IFRlbnNvcixcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeHNoYXBlID0geC5kaW1zO1xuICBjb25zdCB3c2hhcGUgPSB3LmRpbXM7XG5cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgaW0yY29sRGltcyA9IGNhbGN1bGF0ZUltMkNvbERpbXMoeHNoYXBlLCB3c2hhcGUsIG91dHB1dFNoYXBlLCA0KTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgIGNvbnN0IGludCBYQyA9ICR7eHNoYXBlWzFdfTtcbiAgICAgICAgY29uc3QgaW50IFhIID0gJHt4c2hhcGVbMl19O1xuICAgICAgICBjb25zdCBpbnQgWFcgPSAke3hzaGFwZVszXX07XG4gICAgICAgIGNvbnN0IGludCBLSCA9ICR7YXR0cmlidXRlcy5rZXJuZWxTaGFwZVswXX07XG4gICAgICAgIGNvbnN0IGludCBLVyA9ICR7YXR0cmlidXRlcy5rZXJuZWxTaGFwZVsxXX07XG4gICAgICAgIGNvbnN0IGludCBkaWxhdGlvbkggPSAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzBdfTtcbiAgICAgICAgY29uc3QgaW50IGRpbGF0aW9uVyA9ICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMV19O1xuICAgICAgICBjb25zdCBpbnQgc3RyaWRlSCA9ICR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfTtcbiAgICAgICAgY29uc3QgaW50IHN0cmlkZVcgPSAke2F0dHJpYnV0ZXMuc3RyaWRlc1sxXX07XG4gICAgICAgIGNvbnN0IGludCBwYWRIID0gJHthdHRyaWJ1dGVzLnBhZHNbMF19O1xuICAgICAgICBjb25zdCBpbnQgcGFkVyA9ICR7YXR0cmlidXRlcy5wYWRzWzFdfTtcbiAgICAgICAgY29uc3QgaW50IEtIS1cgPSBLSCpLVztcbiAgICAgICAgY29uc3QgaW50IFhDS0hLVyA9IFhDICogS0hLVztcbiAgICAgICAgY29uc3QgaW50IG91dHB1dENoYW5uZWxzID0gNDtcbiAgICAgICAgdmVjNCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IGIgID0gaW5kaWNlc1swXTsgLy8gYmF0Y2ggc2l6ZVxuICAgICAgICAgIGludCBvaCA9IGluZGljZXNbMV0gKiBzdHJpZGVIIC0gcGFkSDsgLy9vdXRwdXQgaGVpZ2h0XG4gICAgICAgICAgaW50IG93ID0gaW5kaWNlc1syXSAqIHN0cmlkZVcgLSBwYWRXOyAvL291dHB1dCB3aWR0aFxuICAgICAgICAgIGludCBwID0gaW5kaWNlc1szXSAqIG91dHB1dENoYW5uZWxzOyAvL3BhdGNoXG4gICAgICAgICAgdmVjNCB2YWx1ZSA9IHZlYzQoMC4wKTtcbiAgICAgICAgICBmb3IoaW50IGk9MDsgaSA8IG91dHB1dENoYW5uZWxzOyArK2kpIHtcbiAgICAgICAgICAgIGlmKHAgPCBYQ0tIS1cpIHtcbiAgICAgICAgICAgICAgaW50IHBhdGNoQyA9IHAgLyBLSEtXO1xuICAgICAgICAgICAgICBpbnQgcGF0Y2hIID0gKHAgLSBwYXRjaEMqS0hLVykgLyBLVztcbiAgICAgICAgICAgICAgaW50IHBhdGNoVyA9IChwIC0gcGF0Y2hDKktIS1cpIC0gcGF0Y2hIICogS1c7XG4gICAgICAgICAgICAgIGludCB4aDIgPSBvaCArIHBhdGNoSCAqIGRpbGF0aW9uSDtcbiAgICAgICAgICAgICAgaW50IHh3MiA9IG93ICsgcGF0Y2hXICogZGlsYXRpb25XO1xuICAgICAgICAgICAgICBpbnQgeFske3hzaGFwZS5sZW5ndGh9XTtcbiAgICAgICAgICAgICAgeFswXSA9IGI7XG4gICAgICAgICAgICAgIHhbMV0gPSBwYXRjaEM7XG4gICAgICAgICAgICAgIHhbMl0gPSB4aDI7XG4gICAgICAgICAgICAgIHhbM10gPSB4dzI7XG4gICAgICAgICAgICAgIGlmKHhoMiA+PSAwICYmXG4gICAgICAgICAgICAgICAgICB4aDIgPCBYSCAmJlxuICAgICAgICAgICAgICAgICAgeHcyID49IDAgJiZcbiAgICAgICAgICAgICAgICAgIHh3MiA8IFhXKSB7XG4gICAgICAgICAgICAgICAgdmFsdWVbaV0gPSBfWCh4KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgKytwO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW0yY29sRGltcywgdHlwZTogeC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbiB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICB4OiBUZW5zb3IsXG4gIHc6IFRlbnNvcixcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVJbTJDb2xQcm9ncmFtTWV0YWRhdGEoYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgZ2V0OiAoKSA9PiBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgeCwgdywgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZUltMkNvbERpbXMgPSAoXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgY2hhbm5lbHMgPSA0LFxuKTogbnVtYmVyW10gPT4gW1xuICBvdXRwdXRTaGFwZVswXSxcbiAgb3V0cHV0U2hhcGVbMl0sXG4gIG91dHB1dFNoYXBlWzNdLFxuICBNYXRoLmNlaWwoKGlucHV0U2hhcGVbMV0gKiBrZXJuZWxTaGFwZVsyXSAqIGtlcm5lbFNoYXBlWzNdKSAvIGNoYW5uZWxzKSxcbl07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGdldEFjdGl2YXRpb25TbmlwcGV0LCBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9mdXNlLXV0aWxzJztcbmltcG9ydCB7IGNhbGN1bGF0ZUltMkNvbERpbXMgfSBmcm9tICcuL2ltMmNvbCc7XG5cbmNvbnN0IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcykgPT4gKHtcbiAgbmFtZTogJ0NvbnZEb3RQcm9kdWN0JyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnSW0yQ29sJywgJ0snLCAnQiddIDogWydJbTJDb2wnLCAnSyddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzXG4gICAgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sIFRleHR1cmVUeXBlLnVucGFja2VkXVxuICAgIDogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uXSxcbiAgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuYWN0aXZhdGlvbkNhY2hlS2V5LFxufSk7XG5cbmNvbnN0IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBvdXRwdXRTaGFwZTogbnVtYmVyW10sXG4gIGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBrc2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3QgYWRqdXN0ZWRLZXJuZWxTaGFwZSA9IFtrc2hhcGVbMF0sIE1hdGguY2VpbCgoeHNoYXBlWzFdICoga3NoYXBlWzJdICoga3NoYXBlWzNdKSAvIDQpXTtcbiAgY29uc3QgaW0yY29sU2hhcGUgPSBjYWxjdWxhdGVJbTJDb2xEaW1zKHhzaGFwZSwga3NoYXBlLCBvdXRwdXRTaGFwZSk7XG4gIGNvbnN0IFtrV2lkdGgsIGtIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgYWRqdXN0ZWRLZXJuZWxTaGFwZSxcbiAgICBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uLFxuICApO1xuXG4gIGNvbnN0IGltMmNvbFN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoaW0yY29sU2hhcGUpO1xuICBjb25zdCBbaW0yY29sV2lkdGgsIGltMmNvbEhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBpbTJjb2xTaGFwZSxcbiAgICBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uLFxuICApO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gIGNvbnN0IGluaXRWYWx1ZSA9IGlucHV0cy5sZW5ndGggPCAzID8gJzAuMCcgOiAnX0IoYiknO1xuICBjb25zdCBzaGFyZWREaW0gPSBNYXRoLmNlaWwoKHhzaGFwZVsxXSAqIGtzaGFwZVsyXSAqIGtzaGFwZVszXSkgLyA0KTtcbiAgY29uc3QgeyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcyk7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuJHthY3RpdmF0aW9uRnVuY3Rpb259XG5mbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gIGludCBiWzFdO1xuICBiWzBdID0gaW5kaWNlc1sxXTtcbiAgaW50IGltMmNvbFs0XTtcbiAgaW0yY29sWzBdID0gaW5kaWNlc1swXTtcbiAgaW0yY29sWzFdID0gaW5kaWNlc1syXTtcbiAgaW0yY29sWzJdID0gaW5kaWNlc1szXTtcbiAgaW50IGltMmNvbE9mZnNldCA9IGltMmNvbFswXSAqICR7aW0yY29sU3RyaWRlc1swXX0gKyBpbTJjb2xbMV0gKiAke2ltMmNvbFN0cmlkZXNbMV19ICsgaW0yY29sWzJdICogJHtcbiAgICBpbTJjb2xTdHJpZGVzWzJdXG4gIH07XG4gIGludCBrZXJuZWxPZmZzZXQgPSBpbmRpY2VzWzFdICogJHthZGp1c3RlZEtlcm5lbFNoYXBlWzFdfTtcbiAgZmxvYXQgdmFsdWUgPSAke2luaXRWYWx1ZX07XG4gIGZvciAoaW50IGkgPSAwOyBpIDwgJHtzaGFyZWREaW19OyArK2kpIHtcbiAgICB2ZWMyIGltMmNvbENvb3JkcyA9IG9mZnNldFRvQ29vcmRzKGltMmNvbE9mZnNldCwgJHtpbTJjb2xXaWR0aH0sICR7aW0yY29sSGVpZ2h0fSk7XG4gICAgdmVjMiBrZXJuZWxDb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhrZXJuZWxPZmZzZXQsICR7a1dpZHRofSwgJHtrSGVpZ2h0fSk7XG4gICAgdmFsdWUgKz0gZG90KCR7Z2xzbC50ZXh0dXJlMkR9KEltMkNvbCwgaW0yY29sQ29vcmRzKSwgJHtnbHNsLnRleHR1cmUyRH0oSywga2VybmVsQ29vcmRzKSk7XG4gICAgKytpbTJjb2xPZmZzZXQ7XG4gICAgKytrZXJuZWxPZmZzZXQ7XG4gIH1cbiAgJHthcHBseUFjdGl2YXRpb259XG4gIHJldHVybiB2YWx1ZTtcbn1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGF0dHJpYnV0ZXMpO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIGdldDogKCkgPT4gY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi8uLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgUG9vbENvbnZVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmltcG9ydCB7IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vY29udi1ncm91cGVkJztcbmltcG9ydCB7IGNvbnYyRFBhY2tlZCB9IGZyb20gJy4vY29udi1wYWNrJztcbmltcG9ydCB7IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mb0xvYWRlciB9IGZyb20gJy4vZG90LXByb2R1Y3QnO1xuaW1wb3J0IHsgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcywgcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9mdXNlLXV0aWxzJztcbmltcG9ydCB7IGNyZWF0ZUltMkNvbFByb2dyYW1JbmZvTG9hZGVyIH0gZnJvbSAnLi9pbTJjb2wnO1xuaW1wb3J0IHsgY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIgfSBmcm9tICcuL21hdG11bCc7XG5cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVPdXRwdXRTaGFwZSA9IChcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgYWRqdXN0UGFkczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCBiYXRjaFNpemUgPSBpbnB1dFNoYXBlWzBdO1xuICBjb25zdCBpbnB1dFNwYXRpYWxTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoMik7XG4gIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRTcGF0aWFsU2hhcGUubGVuZ3RoO1xuICBjb25zdCBvdXRDaGFubmVscyA9IGtlcm5lbFNoYXBlWzBdO1xuICBjb25zdCBrZXJuZWxTcGF0aWFsU2hhcGUgPSBrZXJuZWxTaGFwZS5zbGljZSgyKTtcbiAgY29uc3QgZGlsYXRlZEtlcm5lbFNoYXBlID0ga2VybmVsU3BhdGlhbFNoYXBlLm1hcCgodiwgaSkgPT4gdiArICh2IC0gMSkgKiAoZGlsYXRpb25zW2ldIC0gMSkpO1xuICBjb25zdCBpbnB1dFNwYXRpYWxTaGFwZVdpdGhQYWQgPSBpbnB1dFNwYXRpYWxTaGFwZS5tYXAoKHYsIGkpID0+IHYgKyBhZGp1c3RQYWRzW2ldICsgYWRqdXN0UGFkc1tpICsgc3BhdGlhbFJhbmtdKTtcbiAgY29uc3Qgb3V0cHV0U3BhdGlhbFNoYXBlID0gaW5wdXRTcGF0aWFsU2hhcGVXaXRoUGFkLm1hcCgodiwgaSkgPT5cbiAgICBNYXRoLmZsb29yKCh2IC0gZGlsYXRlZEtlcm5lbFNoYXBlW2ldICsgc3RyaWRlc1tpXSkgLyBzdHJpZGVzW2ldKSxcbiAgKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbYmF0Y2hTaXplLCBvdXRDaGFubmVsc10uY29uY2F0KC4uLm91dHB1dFNwYXRpYWxTaGFwZSk7XG4gIHJldHVybiBvdXRwdXRTaGFwZTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udkF0dHJpYnV0ZXMgZXh0ZW5kcyBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhdXRvUGFkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IGdyb3VwOiBudW1iZXI7XG4gIHJlYWRvbmx5IGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgcGFkczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgY29udjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb252QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpOyAvLyBjdXJyZW50bHkgd2lsbCBmYWlsIGlmIG5vdCBjb252MkRcbiAgcmV0dXJuIGNvbnYyZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpO1xufTtcblxuY29uc3QgY29udjJkOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbnZBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgYWRqdXN0ZWRBdHRyaWJ1dGVzID0gZ2V0QWRqdXN0ZWRDb252QXR0cmlidXRlcyhhdHRyaWJ1dGVzLCBpbnB1dHMpO1xuICBjb25zdCBwYWNrTW9kZSA9IGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5wYWNrO1xuICBjb25zdCBpc1BvaW50d2lzZSA9IGFkanVzdGVkQXR0cmlidXRlcy5rZXJuZWxTaGFwZVswXSA9PT0gMSAmJiBhZGp1c3RlZEF0dHJpYnV0ZXMua2VybmVsU2hhcGVbMV0gPT09IDE7XG4gIGlmIChhZGp1c3RlZEF0dHJpYnV0ZXMuZ3JvdXAgPiAxKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpLFxuICAgICAgaW5wdXRzLFxuICAgICk7XG4gICAgcmV0dXJuIFtyZXN1bHRdO1xuICB9IGVsc2UgaWYgKGlzUG9pbnR3aXNlICYmIHBhY2tNb2RlKSB7XG4gICAgcmV0dXJuIFtjb252MkRVbnBhY2tlZFBvaW50d2lzZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyldO1xuICB9IGVsc2UgaWYgKHBhY2tNb2RlICYmIGlucHV0c1swXS5kaW1zLmxlbmd0aCA9PT0gNCAmJiBpbnB1dHNbMF0uZGltc1swXSA9PT0gMSAmJiAhaXNQb2ludHdpc2UpIHtcbiAgICByZXR1cm4gW2NvbnYyRFBhY2tlZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyldO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbY29udjJEVW5wYWNrZWQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpXTtcbiAgfVxufTtcblxuY29uc3QgY29udjJEVW5wYWNrZWRQb2ludHdpc2UgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gIGNvbnN0IHJlc2hhcGVkWCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgW3hzaGFwZVsxXSwgeHNoYXBlWzJdICogeHNoYXBlWzNdXSk7XG4gIGNvbnN0IHJlc2hhcGVkSyA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1sxXSwgW2tzaGFwZVswXSwga3NoYXBlWzFdXSk7XG5cbiAgY29uc3QgbWF0bXVsSW5wdXRzID0gaW5wdXRzLmxlbmd0aCA+IDIgPyBbcmVzaGFwZWRLLCByZXNoYXBlZFgsIGlucHV0c1syXV0gOiBbcmVzaGFwZWRLLCByZXNoYXBlZFhdO1xuICBjb25zdCBtYXRtdWxPdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihtYXRtdWxJbnB1dHMsIGF0dHJpYnV0ZXMpLCBtYXRtdWxJbnB1dHMpO1xuICByZXR1cm4gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQobWF0bXVsT3V0cHV0LCBvdXRwdXRTaGFwZSk7XG59O1xuXG5jb25zdCBjb252MkRVbnBhY2tlZCA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbik6IFRlbnNvciA9PiB7XG4gIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBrc2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4c2hhcGUsIGtzaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcbiAgY29uc3QgeEltMkNvbCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZUltMkNvbFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgaW5wdXRzWzFdLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gICAgW2lucHV0c1swXV0sXG4gICk7XG5cbiAgY29uc3QgZG90UHJvZHVjdElucHV0cyA9IGlucHV0cy5sZW5ndGggPT09IDMgPyBbeEltMkNvbCwgaW5wdXRzWzFdLCBpbnB1dHNbMl1dIDogW3hJbTJDb2wsIGlucHV0c1sxXV07XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSxcbiAgICBkb3RQcm9kdWN0SW5wdXRzLFxuICApO1xuICByZXR1cm4gb3V0cHV0O1xufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRDb252QXR0cmlidXRlcyA9IDxUIGV4dGVuZHMgQ29udkF0dHJpYnV0ZXM+KGF0dHJpYnV0ZXM6IFQsIGlucHV0czogVGVuc29yW10pOiBUID0+IHtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBvcCwgaW5mZXIgaXQgZnJvbSB0aGUgd2VpZ2h0IHRlbnNvciBkaW1zXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAobGV0IGkgPSAyOyBpIDwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGtlcm5lbFNoYXBlLnB1c2goaW5wdXRzWzFdLmRpbXNbaV0pO1xuICAgIH1cbiAgfVxuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzLnNsaWNlKCk7XG4gIFBvb2xDb252VXRpbC5hZGp1c3RQYWRzQmFzZWRPbkF1dG9QYWQoXG4gICAgaW5wdXRzWzBdLmRpbXMsXG4gICAgYXR0cmlidXRlcy5zdHJpZGVzLFxuICAgIGF0dHJpYnV0ZXMuZGlsYXRpb25zLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIHBhZHMsXG4gICAgYXR0cmlidXRlcy5hdXRvUGFkLFxuICApO1xuXG4gIC8vIGFsd2F5cyByZXR1cm4gYSBuZXcgb2JqZWN0IHNvIGRvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYXR0cmlidXRlc1xuICBjb25zdCBuZXdBdHRyaWJ1dGVzOiBUID0gT2JqZWN0LmFzc2lnbih7fSwgYXR0cmlidXRlcyk7XG4gIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywgeyBrZXJuZWxTaGFwZSwgcGFkcywgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfSk7XG4gIHJldHVybiBuZXdBdHRyaWJ1dGVzO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ29udkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248Q29udkF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBDb252QXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBub2RlLmF0dHJpYnV0ZXM7XG4gIGNvbnN0IGFjdGl2YXRpb25BdHRyaWJ1dGVzID0gcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpO1xuICAvLyBUT0RPIDogTWFrZSB0aGlzIGdlbmVyaWMgZW5vdWdoIHRvIGNvbXB1dGUgZGVmYXVsdCBhdHRyaWJ1dGVzIGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGNvbnN0IGF1dG9QYWQgPSBhdHRyaWJ1dGVzLmdldFN0cmluZygnYXV0b19wYWQnLCAnTk9UU0VUJyk7XG4gIGNvbnN0IGRpbGF0aW9ucyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnZGlsYXRpb25zJywgWzEsIDFdKTtcbiAgY29uc3QgZ3JvdXAgPSBhdHRyaWJ1dGVzLmdldEludCgnZ3JvdXAnLCAxKTtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScsIFtdKTtcbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygncGFkcycsIFswLCAwLCAwLCAwXSk7XG4gIGNvbnN0IHN0cmlkZXMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3N0cmlkZXMnLCBbMSwgMV0pO1xuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIGF1dG9QYWQsXG4gICAgZGlsYXRpb25zLFxuICAgIGdyb3VwLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIHBhZHMsXG4gICAgc3RyaWRlcyxcbiAgICAuLi5hY3RpdmF0aW9uQXR0cmlidXRlcyxcbiAgfSk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICAvLyBSZWZlciB0byB0aGUgYmVsb3cgbGluayBmb3IgYWxsIGlucHV0IGNoZWNrc1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL09wZXJhdG9ycy5tZCNDb252XG4gIGlmICghaW5wdXRzIHx8IChpbnB1dHMubGVuZ3RoICE9PSAyICYmIGlucHV0cy5sZW5ndGggIT09IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IHJlcXVpcmVzIDIgb3IgMyBpbnB1dHMnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQgfHwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgb25seSBzdXBwb3J0IDItZGltZW5zaW9uYWwgY29udicpO1xuICB9XG5cbiAgLy8gRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTFxuICBjb25zdCBkYXRhQ2hhbm5lbCA9IGlucHV0c1swXS5kaW1zWzFdO1xuICBjb25zdCBmaWx0ZXJJbkNoYW5uZWwgPSBpbnB1dHNbMV0uZGltc1sxXSAqIGF0dHJpYnV0ZXMuZ3JvdXA7XG4gIGlmIChkYXRhQ2hhbm5lbCAhPT0gZmlsdGVySW5DaGFubmVsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMJyk7XG4gIH1cblxuICAvLyBpZiBiaWFzIGlzIHByb3ZpZGVkIGl0IHNob3VsZCBiZSAxRCBhbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBzaG91bGQgYmUgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBmZWF0dXJlIG1hcHNcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgKGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMSB8fCBpbnB1dHNbMV0uZGltc1swXSAhPT0gaW5wdXRzWzJdLmRpbXNbMF0pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJpYXMnKTtcbiAgfVxuXG4gIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMjtcbiAgLy8gd3JvbmcgZGlsYXRpb25zIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5kaWxhdGlvbnMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgZGlsYXRpb25zIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHN0cmlkZXMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgc3RyaWRlcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBwYWRzIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmsgKiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBwYWRzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rICogMn1EYCk7XG4gIH1cblxuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBzcGVjaWZpZWQsIGl0J3MgZGF0YSBsZW5ndGggbXVzdCBiZSAyIGxlc3MgdGhhbiBkaW1zIGxlbmd0aCBvZiB0aGUgd2VpZ2h0cyB0ZW5zb3JcbiAgLy8gKHRoZSBmaXJzdCAyIGRpbXMgYXJlIGJhdGNoX3NpemUgYW5kIGNoYW5uZWxzKVxuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggIT09IDAgJiYgYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggIT09IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAtIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQga2VybmVsIHNoYXBlJyk7XG4gIH1cblxuICAvLyBUT0RPIDogTmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgZmxvYXQ2NFxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyB8fCBpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IGlucHV0KFgsVykgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG5cbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgaW5wdXRzWzJdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiBpbnB1dChiaWFzKSBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vLi4vLi4vYmFja2VuZCc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9jb252JztcbmltcG9ydCB7IGdldEFjdGl2YXRpb25TbmlwcGV0LCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuXG5jb25zdCBjb21wdXRlVG90YWxQYWQgPSAoXG4gIGluRGltOiBudW1iZXIsXG4gIHN0cmlkZTogbnVtYmVyLFxuICBhZGo6IG51bWJlcixcbiAga2VybmVsOiBudW1iZXIsXG4gIGRpbGF0aW9uOiBudW1iZXIsXG4gIG91dFNpemU6IG51bWJlcixcbikgPT4gKGluRGltIC0gMSkgKiBzdHJpZGUgKyBhZGogKyAoa2VybmVsIC0gMSkgKiBkaWxhdGlvbiArIDEgLSBvdXRTaXplO1xuXG5jb25zdCBkaXN0cmlidXRlUGFkZGluZyA9ICh0b3RhbFBhZDogbnVtYmVyLCBhdXRvUGFkOiBzdHJpbmcsIHBhZHM6IG51bWJlcltdLCBoZWFkOiBudW1iZXIsIHRhaWw6IG51bWJlcikgPT4ge1xuICBjb25zdCBzbWFsbFBhZCA9IE1hdGguZmxvb3IodG90YWxQYWQgLyAyKTtcbiAgaWYgKGF1dG9QYWQgPT09ICdTQU1FX1VQUEVSJykge1xuICAgIHBhZHNbaGVhZF0gPSBzbWFsbFBhZDtcbiAgICBwYWRzW3RhaWxdID0gdG90YWxQYWQgLSBzbWFsbFBhZDtcbiAgfSBlbHNlIGlmIChhdXRvUGFkID09PSAnU0FNRV9MT1dFUicpIHtcbiAgICBwYWRzW2hlYWRdID0gdG90YWxQYWQgLSBzbWFsbFBhZDtcbiAgICBwYWRzW3RhaWxdID0gc21hbGxQYWQ7XG4gIH1cbn07XG5cbmNvbnN0IGNhbGN1bGF0ZU91dHB1dFNoYXBlQW5kUGFkcyA9IChcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXV0b1BhZDogc3RyaW5nLFxuICBwYWRzOiBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG91dHB1dFBhZGRpbmc6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogbnVtYmVyW10sXG4pID0+IHtcbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aCAtIDI7XG4gIGNvbnN0IHVwZGF0ZVNoYXBlID0gb3V0cHV0U2hhcGUubGVuZ3RoID09PSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNwYXRpYWxSYW5rOyArK2kpIHtcbiAgICBjb25zdCBvdXRTaXplID0gdXBkYXRlU2hhcGUgPyBpbnB1dFNoYXBlW2kgKyAyXSAqIHN0cmlkZXNbaV0gOiBvdXRwdXRTaGFwZVtpXTtcbiAgICBjb25zdCB0b3RhbFBhZCA9IGNvbXB1dGVUb3RhbFBhZChpbnB1dFNoYXBlW2kgKyAyXSwgc3RyaWRlc1tpXSwgcGFkc1tpXSwga2VybmVsU2hhcGVbaV0sIGRpbGF0aW9uc1tpXSwgb3V0U2l6ZSk7XG4gICAgZGlzdHJpYnV0ZVBhZGRpbmcodG90YWxQYWQsIGF1dG9QYWQsIHBhZHMsIGksIGkgKyBzcGF0aWFsUmFuayk7XG4gICAgaWYgKHVwZGF0ZVNoYXBlKSB7XG4gICAgICBvdXRwdXRTaGFwZS5wdXNoKFxuICAgICAgICBzdHJpZGVzW2ldICogKGlucHV0U2hhcGVbaSArIDJdIC0gMSkgK1xuICAgICAgICAgIG91dHB1dFBhZGRpbmdbaV0gK1xuICAgICAgICAgIChrZXJuZWxTaGFwZVtpXSAtIDEpICogZGlsYXRpb25zW2ldICtcbiAgICAgICAgICAxIC1cbiAgICAgICAgICBwYWRzW2ldIC1cbiAgICAgICAgICBwYWRzW2kgKyBzcGF0aWFsUmFua10sXG4gICAgICApO1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGludGVyZmFjZSBDb252VHJhbnNwb3NlQXR0cmlidXRlcyBleHRlbmRzIENvbnZBdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgb3V0cHV0UGFkZGluZzogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbnZUcmFuc3Bvc2U6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udlRyYW5zcG9zZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTsgLy8gY3VycmVudGx5IHdpbGwgZmFpbCBpZiBub3QgY29udlRyYW5zcG9zZTJEXG4gIHJldHVybiBjb252VHJhbnNwb3NlMmQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbn07XG5cbmNvbnN0IGNvbnZUcmFuc3Bvc2UyZDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb252VHJhbnNwb3NlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IGFkanVzdGVkQXR0cmlidXRlcyA9IGdldEFkanVzdGVkQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMoYXR0cmlidXRlcywgaW5wdXRzKTtcbiAgcmV0dXJuIFtjb252VHJhbnNwb3NlMkRVbnBhY2tlZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyldO1xufTtcblxuY29uc3QgY3JlYXRlQ29udlRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ0NvbnZUcmFuc3Bvc2UnLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydYJywgJ1cnLCAnQiddIDogWydYJywgJ1cnXSxcbiAgaW5wdXRUeXBlczogaGFzQmlhc1xuICAgID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdXG4gICAgOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IHZhbHVlSW5pdCA9IGhhc0JpYXMgPyAnZ2V0QihvdXRwdXRfY2hhbm5lbCknIDogJzAuMCc7XG4gIGNvbnN0IHhTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCB3U2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVsxXTtcbiAgY29uc3QgaW5wdXRDaGFubmVsc1Blckdyb3VwID0gd1NoYXBlWzBdIC8gYXR0cmlidXRlcy5ncm91cDtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbaW5wdXRzWzBdLmRpbXNbMF0sIGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cCwgLi4uYXR0cmlidXRlcy5vdXRwdXRTaGFwZV07XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgeyBhY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbiB9ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcyk7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICBjb25zdCBpdmVjMiBzdHJpZGVzID0gaXZlYzIoJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19LCAke2F0dHJpYnV0ZXMuc3RyaWRlc1sxXX0pO1xuICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHthdHRyaWJ1dGVzLnBhZHNbMF19LCAke2F0dHJpYnV0ZXMucGFkc1sxXX0pO1xuICAke2FjdGl2YXRpb25GdW5jdGlvbn1cbiAgdm9pZCBtYWluKCkge1xuICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgIGludCBiYXRjaCA9IGNvb3Jkcy54O1xuICAgIGludCBvdXRwdXRfY2hhbm5lbCA9IGNvb3Jkcy55O1xuXG4gICAgaXZlYzIgbG9jID0gY29vcmRzLnp3ICsgcGFkcztcblxuICAgIGludCBncm91cF9pZCA9IG91dHB1dF9jaGFubmVsIC8gJHtvdXRwdXRDaGFubmVsc1Blckdyb3VwfTtcbiAgICBpbnQgd091dENoYW5uZWwgPSBvdXRwdXRfY2hhbm5lbCAtIGdyb3VwX2lkICogJHtvdXRwdXRDaGFubmVsc1Blckdyb3VwfTtcblxuICAgIGZsb2F0IHZhbHVlID0gJHt2YWx1ZUluaXR9O1xuICAgIGZvciAoaW50IGluQ2hhbm5lbE9mZnNldCA9IDA7IGluQ2hhbm5lbE9mZnNldCA8ICR7aW5wdXRDaGFubmVsc1Blckdyb3VwfTsgaW5DaGFubmVsT2Zmc2V0KyspIHtcbiAgICAgIGludCBpbnB1dF9jaGFubmVsID0gZ3JvdXBfaWQgKiAke2lucHV0Q2hhbm5lbHNQZXJHcm91cH0gKyBpbkNoYW5uZWxPZmZzZXQ7XG4gICAgICBmb3IgKGludCB3V09mZiA9IDA7IHdXT2ZmIDwgJHt3U2hhcGVbMl19OyB3V09mZisrKSB7XG4gICAgICAgIGZvciAoaW50IHdIT2ZmID0gMDsgd0hPZmYgPCAke3dTaGFwZVszXX07IHdIT2ZmKyspIHtcbiAgICAgICAgICBpdmVjMiB3T2ZmID0gaXZlYzIod1dPZmYgKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzBdfSwgd0hPZmYgKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzFdfSk7XG4gICAgICAgICAgaXZlYzIgd0xvYyA9IGxvYyAtIHdPZmY7XG4gICAgICAgICAgaXZlYzIgd0xvY0luID0gd0xvYyAvIHN0cmlkZXM7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgd0xvY0luICogc3RyaWRlcyA9PSB3TG9jICYmXG4gICAgICAgICAgICB3TG9jSW4ueCA+PSAwICYmIHdMb2NJbi54IDwgJHt4U2hhcGVbMl19ICYmXG4gICAgICAgICAgICB3TG9jSW4ueSA+PSAwICYmIHdMb2NJbi55IDwgJHt4U2hhcGVbM119XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBmbG9hdCB4VmFsID0gZ2V0WChiYXRjaCwgaW5wdXRfY2hhbm5lbCwgd0xvY0luLnksIHdMb2NJbi54KTtcbiAgICAgICAgICAgIGZsb2F0IHdWYWwgPSBnZXRXKGlucHV0X2NoYW5uZWwsIHdPdXRDaGFubmVsLCB3SE9mZiwgd1dPZmYpO1xuICAgICAgICAgICAgdmFsdWUgKz0geFZhbCAqIHdWYWw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCh2YWx1ZSwgLjAsIC4wLCAuMCk7XG4gIH1cbmA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWUsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbnZUcmFuc3Bvc2VQcm9ncmFtSW5mb0xvYWRlciA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVDb252VHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgbWV0YWRhdGEsIGF0dHJpYnV0ZXMpLFxuICB9O1xufTtcblxuY29uc3QgY29udlRyYW5zcG9zZTJEVW5wYWNrZWQgPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCByZXN1bHQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICBjcmVhdGVVbnBhY2tlZENvbnZUcmFuc3Bvc2VQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmNvbnN0IGdldEFkanVzdGVkQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgPSA8VCBleHRlbmRzIENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPihhdHRyaWJ1dGVzOiBULCBpbnB1dHM6IFRlbnNvcltdKTogVCA9PiB7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgb3AsIGluZmVyIGl0IGZyb20gdGhlIHdlaWdodCB0ZW5zb3IgZGltc1xuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGxldCBpID0gMjsgaSA8IGlucHV0c1sxXS5kaW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0c1sxXS5kaW1zW2ldKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzLnNsaWNlKCk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gYXR0cmlidXRlcy5vdXRwdXRTaGFwZS5zbGljZSgpO1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIC8vIElmIG91dHB1dFNoYXBlIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBvcCwgaW5mZXIgaXQgZnJvbSB0aGUgcGFyYW1ldGVyc1xuICAvLyBTaW1pbGFybHksIGF1dG9tYXRpY2FsbHkgaW5mZXIgcGFkcyBpZiBub3Qgc3BlY2lmaWVkXG4gIGNhbGN1bGF0ZU91dHB1dFNoYXBlQW5kUGFkcyhcbiAgICBpbnB1dFNoYXBlLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIGF0dHJpYnV0ZXMuZGlsYXRpb25zLFxuICAgIGF0dHJpYnV0ZXMuYXV0b1BhZCxcbiAgICBwYWRzLFxuICAgIGF0dHJpYnV0ZXMuc3RyaWRlcyxcbiAgICBhdHRyaWJ1dGVzLm91dHB1dFBhZGRpbmcsXG4gICAgb3V0cHV0U2hhcGUsXG4gICk7XG5cbiAgLy8gYWx3YXlzIHJldHVybiBhIG5ldyBvYmplY3Qgc28gZG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBhdHRyaWJ1dGVzXG4gIGNvbnN0IG5ld0F0dHJpYnV0ZXM6IFQgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKTtcbiAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBwYWRzLCBvdXRwdXRTaGFwZSwgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfSk7XG4gIHJldHVybiBuZXdBdHRyaWJ1dGVzO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248Q29udlRyYW5zcG9zZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhdHRyaWJ1dGVzID0gbm9kZS5hdHRyaWJ1dGVzO1xuICBjb25zdCBhY3RpdmF0aW9uQXR0cmlidXRlcyA9IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTtcbiAgLy8gVE9ETyA6IE1ha2UgdGhpcyBnZW5lcmljIGVub3VnaCB0byBjb21wdXRlIGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBjb25zdCBhdXRvUGFkID0gYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICBjb25zdCBkaWxhdGlvbnMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2RpbGF0aW9ucycsIFsxLCAxXSk7XG4gIGNvbnN0IGdyb3VwID0gYXR0cmlidXRlcy5nZXRJbnQoJ2dyb3VwJywgMSk7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5nZXRJbnRzKCdrZXJuZWxfc2hhcGUnLCBbXSk7XG4gIGNvbnN0IG91dHB1dFBhZGRpbmcgPSBhdHRyaWJ1dGVzLmdldEludHMoJ291dHB1dF9wYWRkaW5nJywgWzAsIDBdKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBhdHRyaWJ1dGVzLmdldEludHMoJ291dHB1dF9zaGFwZScsIFtdKTtcbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygncGFkcycsIFswLCAwLCAwLCAwXSk7XG4gIGNvbnN0IHN0cmlkZXMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3N0cmlkZXMnLCBbMSwgMV0pO1xuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIGF1dG9QYWQsXG4gICAgZGlsYXRpb25zLFxuICAgIGdyb3VwLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIG91dHB1dFBhZGRpbmcsXG4gICAgb3V0cHV0U2hhcGUsXG4gICAgcGFkcyxcbiAgICBzdHJpZGVzLFxuICAgIC4uLmFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuICB9KTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIC8vIFJlZmVyIHRvIHRoZSBiZWxvdyBsaW5rIGZvciBhbGwgaW5wdXQgY2hlY2tzXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvT3BlcmF0b3JzLm1kI0NvbnZcbiAgaWYgKCFpbnB1dHMgfHwgKGlucHV0cy5sZW5ndGggIT09IDIgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgcmVxdWlyZXMgMiBvciAzIGlucHV0cycpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCB8fCBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBvbmx5IHN1cHBvcnQgMi1kaW1lbnNpb25hbCBjb252Jyk7XG4gIH1cblxuICAvLyBGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMXG4gIGNvbnN0IGRhdGFDaGFubmVsID0gaW5wdXRzWzBdLmRpbXNbMV07XG4gIGNvbnN0IGZpbHRlckluQ2hhbm5lbCA9IGlucHV0c1sxXS5kaW1zWzBdO1xuICBpZiAoZGF0YUNoYW5uZWwgIT09IGZpbHRlckluQ2hhbm5lbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTCcpO1xuICB9XG5cbiAgY29uc3QgZmVhdHVyZU1hcHMgPSBpbnB1dHNbMV0uZGltc1sxXSAqIGF0dHJpYnV0ZXMuZ3JvdXA7XG5cbiAgLy8gaWYgYmlhcyBpcyBwcm92aWRlZCBpdCBzaG91bGQgYmUgMUQgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgZmVhdHVyZSBtYXBzXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIChpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgfHwgaW5wdXRzWzJdLmRpbXNbMF0gIT09IGZlYXR1cmVNYXBzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBiaWFzJyk7XG4gIH1cblxuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDI7XG4gIC8vIHdyb25nIGRpbGF0aW9ucyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuZGlsYXRpb25zLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRpbGF0aW9ucyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBzdHJpZGVzIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHN0cmlkZXMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3JvbmcgcGFkcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMucGFkcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rICogMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgcGFkcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFuayAqIDJ9RGApO1xuICB9XG5cbiAgLy8gV3Jvbmcgb3V0cHV0IHBhZGRpbmcgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLm91dHB1dFBhZGRpbmcubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgb3V0cHV0X3BhZGRpbmcgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gaWYga2VybmVsU2hhcGUgaXMgc3BlY2lmaWVkLCBpdCdzIGRhdGEgbGVuZ3RoIG11c3QgYmUgMiBsZXNzIHRoYW4gZGltcyBsZW5ndGggb2YgdGhlIHdlaWdodHMgdGVuc29yXG4gIC8vICh0aGUgZmlyc3QgMiBkaW1zIGFyZSBiYXRjaF9zaXplIGFuZCBjaGFubmVscylcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSAwICYmIGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGtlcm5lbCBzaGFwZScpO1xuICB9XG5cbiAgLy8gYXMgd2l0aCBrZXJuZWxTaGFwZSwgbXVzdCBoYXZlIHNhbWUgbnVtYmVyIG9mIHNwYXRpYWwgZGltcyBhcyBpbnB1dFxuICBpZiAoYXR0cmlidXRlcy5vdXRwdXRTaGFwZS5sZW5ndGggIT09IDAgJiYgYXR0cmlidXRlcy5vdXRwdXRTaGFwZS5sZW5ndGggIT09IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgb3V0cHV0IHNoYXBlJyk7XG4gIH1cblxuICAvLyBUT0RPIDogTmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgZmxvYXQ2NFxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyB8fCBpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252VHJhbnNwb3NlIGlucHV0KFgsVykgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG5cbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgaW5wdXRzWzJdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udlRyYW5zcG9zZSBpbnB1dChiaWFzKSBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNwb3NlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IHBlcm06IG51bWJlcltdO1xufVxuXG5jb25zdCB0cmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdUcmFuc3Bvc2UnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCB0cmFuc3Bvc2U6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248VHJhbnNwb3NlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogVHJhbnNwb3NlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4udHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGF0dHJpYnV0ZXMucGVybSksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VHJhbnNwb3NlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzID0+IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHBlcm06IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwZXJtJywgW10pIH0pO1xuXG5jb25zdCBjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyA9IChcbiAgX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgcGVybTogbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dC5kaW1zO1xuICBwZXJtID0gZ2V0QWRqdXN0ZWRQZXJtKGlucHV0U2hhcGUsIHBlcm0pO1xuICBjb25zdCB1bnBhY2tlZE91dHB1dFNoYXBlID0gZ2V0T3V0cHV0U2hhcGUoaW5wdXRTaGFwZSwgcGVybSk7XG4gIGNvbnN0IHJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgLy8gQSBkaW1zPVske2lucHV0c1swXS5kaW1zLnRvU3RyaW5nKCl9XVxuICAvLyBvdXQgRGltcz1bJHt1bnBhY2tlZE91dHB1dFNoYXBlLnRvU3RyaW5nKCl9XVxuICAvLyBiYXNlZCBvbiBwZXJtPVske3Blcm0udG9TdHJpbmcoKX1dXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7Z2V0UGVybUZ1bmN0aW9uQm9keSgncGVybScsIHBlcm0sIHJhbmspfVxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgYVske3Jhbmt9XTtcbiAgICAgICAgcGVybShhLCBpbmRpY2VzKTtcbiAgICAgICAgcmV0dXJuIF9BKGEpO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4udHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiB1bnBhY2tlZE91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBnZXRBZGp1c3RlZFBlcm0gPSAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHBlcm06IG51bWJlcltdKTogbnVtYmVyW10gPT4ge1xuICBpZiAocGVybSAmJiBwZXJtLmxlbmd0aCAhPT0gaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICBwZXJtID0gWy4uLmlucHV0U2hhcGUua2V5cygpXS5yZXZlcnNlKCk7XG4gIH1cbiAgcmV0dXJuIHBlcm07XG59O1xuXG5jb25zdCBnZXRPdXRwdXRTaGFwZSA9IChpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcGVybTogbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSA9PiB7XG4gIHBlcm0gPSBnZXRBZGp1c3RlZFBlcm0oaW5wdXRTaGFwZSwgcGVybSk7XG4gIHJldHVybiBTaGFwZVV0aWwuc29ydEJhc2VkT25QZXJtKGlucHV0U2hhcGUsIHBlcm0pO1xufTtcblxuY29uc3QgZ2V0UGVybUZ1bmN0aW9uQm9keSA9IChuYW1lOiBzdHJpbmcsIHBlcm06IG51bWJlcltdLCByYW5rOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCByZXZlcnNlRnVuYyA9IFtdO1xuICByZXZlcnNlRnVuYy5wdXNoKGB2b2lkICR7bmFtZX0ob3V0IGludCBhWyR7cmFua31dLCBpbnQgc3JjWyR7cmFua31dKSB7YCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgcmV2ZXJzZUZ1bmMucHVzaChgXFx0YVske3Blcm1baV19XT1zcmNbJHtpfV07YCk7XG4gIH1cbiAgcmV2ZXJzZUZ1bmMucHVzaCgnXFx0fScpO1xuICByZXR1cm4gcmV2ZXJzZUZ1bmMuam9pbignXFxuJyk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9zZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuaW1wb3J0IHsgdHJhbnNwb3NlLCBUcmFuc3Bvc2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi90cmFuc3Bvc2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIERlcHRoVG9TcGFjZUF0dHJpYnV0ZXMge1xuICBtb2RlOiAnRENSJyB8ICdDUkQnO1xuICBibG9ja3NpemU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGRlcHRoVG9TcGFjZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBibG9ja3NpemUgPSBhdHRyaWJ1dGVzLmJsb2Nrc2l6ZTtcbiAgY29uc3QgYmxvY2tzaXplU3FyID0gYmxvY2tzaXplICogYmxvY2tzaXplO1xuICBjb25zdCB0cmFuc3Bvc2VQZXJtID0gYXR0cmlidXRlcy5tb2RlID09PSAnRENSJyA/IFswLCAzLCA0LCAxLCA1LCAyXSA6IFswLCAxLCA0LCAyLCA1LCAzXTtcbiAgY29uc3QgZmlyc3RSZXNoYXBlU2hhcGUgPVxuICAgIGF0dHJpYnV0ZXMubW9kZSA9PT0gJ0RDUidcbiAgICAgID8gW1xuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzBdLFxuICAgICAgICAgIGJsb2Nrc2l6ZSxcbiAgICAgICAgICBibG9ja3NpemUsXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMV0gLyBibG9ja3NpemVTcXIsXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMl0sXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbM10sXG4gICAgICAgIF1cbiAgICAgIDogW1xuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzBdLFxuICAgICAgICAgIGlucHV0c1swXS5kaW1zWzFdIC8gYmxvY2tzaXplU3FyLFxuICAgICAgICAgIGJsb2Nrc2l6ZSxcbiAgICAgICAgICBibG9ja3NpemUsXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMl0sXG4gICAgICAgICAgaW5wdXRzWzBdLmRpbXNbM10sXG4gICAgICAgIF07XG5cbiAgLy8gY29uc3QgdHJhbnNwb3NlID0gbmV3IFdlYkdMVHJhbnNwb3NlKCk7XG4gIC8vIGNvbnN0IGF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlKHVuZGVmaW5lZCk7XG4gIC8vIGF0dHJpYnV0ZXMuc2V0KCdwZXJtJywgJ2ludHMnLCB0cmFuc3Bvc2VQZXJtKTtcbiAgLy8gdHJhbnNwb3NlLmluaXRpYWxpemUoYXR0cmlidXRlcyk7XG5cbiAgLy8gRmlyc3QgcmVzaGFwZVxuICBjb25zdCBmaXJzdFJlc2hhcGVkVGVuc29yID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBmaXJzdFJlc2hhcGVTaGFwZSk7XG5cbiAgLy8gdHJhbnNwb3NlXG4gIGNvbnN0IHRyYW5zcG9zZUF0dHJpYnV0ZXM6IFRyYW5zcG9zZUF0dHJpYnV0ZXMgPSB7IHBlcm06IHRyYW5zcG9zZVBlcm0sIGNhY2hlS2V5OiBgJHt0cmFuc3Bvc2VQZXJtfWAgfTtcbiAgY29uc3QgW3RyYW5zcG9zZU91dHB1dF0gPSB0cmFuc3Bvc2UoaW5mZXJlbmNlSGFuZGxlciwgW2ZpcnN0UmVzaGFwZWRUZW5zb3JdLCB0cmFuc3Bvc2VBdHRyaWJ1dGVzKTtcblxuICAvLyBTZWNvbmQgcmVzaGFwZVxuICBjb25zdCBzZWNvbmRSZXNoYXBlU2hhcGUgPSBbXG4gICAgaW5wdXRzWzBdLmRpbXNbMF0sXG4gICAgaW5wdXRzWzBdLmRpbXNbMV0gLyBibG9ja3NpemVTcXIsXG4gICAgaW5wdXRzWzBdLmRpbXNbMl0gKiBibG9ja3NpemUsXG4gICAgaW5wdXRzWzBdLmRpbXNbM10gKiBibG9ja3NpemUsXG4gIF07XG4gIGNvbnN0IHJlc3VsdCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKHRyYW5zcG9zZU91dHB1dCwgc2Vjb25kUmVzaGFwZVNoYXBlKTtcbiAgcmV0dXJuIFtyZXN1bHRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IERlcHRoVG9TcGFjZUF0dHJpYnV0ZXMgPT4ge1xuICAvLyBwcm9jZXNzaW5nIG5vZGUgYXR0cmlidXRlc1xuICBjb25zdCBibG9ja3NpemUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdibG9ja3NpemUnKTtcbiAgaWYgKGJsb2Nrc2l6ZSA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGJsb2Nrc2l6ZSBtdXN0IGJlID49IDEsIGJ1dCBnb3QgOiAke2Jsb2Nrc2l6ZX0gZm9yIERlcHRoVG9TcGFjZWApO1xuICB9XG4gIGNvbnN0IG1vZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdtb2RlJywgJ0RDUicpO1xuICBpZiAobW9kZSAhPT0gJ0RDUicgJiYgbW9kZSAhPT0gJ0NSRCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBtb2RlOiAke21vZGV9IGZvciBEZXB0aFRvU3BhY2VgKTtcbiAgfVxuICByZXR1cm4geyBtb2RlLCBibG9ja3NpemUgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYERlcHRoVG9TcGFjZSBleHBlY3QgMSBpbnB1dHMsIGJ1dCBnb3QgJHtpbnB1dHMubGVuZ3RofWApO1xuICB9XG5cbiAgLy8gSW5wdXQgaGFzIHRvIGJlIGEgNC1EIHRlbnNvclxuICAvLyBUT0RPOiBTdXBwb3J0IHN0cmluZyBkZXB0aC10by1zcGFjZS5cbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJyB8fCBpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdEZXB0aFRvU3BhY2UgaW5wdXQgc2hvdWxkIGJlIGEgNC1EIG51bWVyaWMgdGVuc29yJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBmbGF0dGVuOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcj4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXhpczogbnVtYmVyLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF4aXMpO1xuXG4gIGNvbnN0IG91dHB1dERpbXMgPSBTaGFwZVV0aWwuZmxhdHRlblNoYXBlKGlucHV0c1swXS5kaW1zLCBheGlzKTtcbiAgcmV0dXJuIFtpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIG91dHB1dERpbXMpXTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUZsYXR0ZW5BdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPG51bWJlcj4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlciA9PlxuICBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJywgMSk7IC8vIGRlZmF1bHQgYXhpcyBpcyAxXG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF4aXM6IG51bWJlcik6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0dGVuIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBjb25zdCByID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICBpZiAociA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2NhbGFyIHRlbnNvciBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICB9XG5cbiAgaWYgKGF4aXMgPCAtciB8fCBheGlzID4gcikge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBheGlzJyk7XG4gIH1cblxuICAvLyBUT0RPOiBTdXBwb3J0IHN0cmluZyB0eXBlXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmluZyB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZC4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4vYmFja2VuZCc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgdHlwZSBPcGVyYXRvckltcGxlbWVudGF0aW9uPFQ+ID0gKGluZmVyZW5jZUhhbmRsZXI6IEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGNvbnRleHQ6IFQpID0+IFRlbnNvcltdO1xuZXhwb3J0IHR5cGUgT3BlcmF0b3JJbml0aWFsaXphdGlvbjxUPiA9IChub2RlOiBHcmFwaC5Ob2RlLCBncmFwaDogR3JhcGgpID0+IFQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlcmF0b3Ige1xuICByZWFkb25seSBpbXBsOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPHVua25vd24+O1xuICByZWFkb25seSBjb250ZXh0OiBHcmFwaC5Ob2RlIHwgdW5rbm93bjtcbn1cblxuZXhwb3J0IGNvbnN0IE5VTUJFUl9UWVBFUzogcmVhZG9ubHkgVGVuc29yLkRhdGFUeXBlW10gPSBbXG4gICdmbG9hdDMyJyxcbiAgJ2Zsb2F0NjQnLFxuICAnaW50MzInLFxuICAnaW50MTYnLFxuICAnaW50OCcsXG4gICd1aW50MTYnLFxuICAndWludDMyJyxcbiAgJ3VpbnQ4Jyxcbl07XG5leHBvcnQgY29uc3QgSU5UX1RZUEVTOiByZWFkb25seSBUZW5zb3IuRGF0YVR5cGVbXSA9IFsnaW50MzInLCAnaW50MTYnLCAnaW50OCcsICd1aW50MTYnLCAndWludDMyJywgJ3VpbnQ4J107XG5leHBvcnQgY29uc3QgRkxPQVRfVFlQRVM6IHJlYWRvbmx5IFRlbnNvci5EYXRhVHlwZVtdID0gWydmbG9hdDMyJywgJ2Zsb2F0NjQnXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBOVU1CRVJfVFlQRVMsIE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbnRlcmZhY2UgR2F0aGVyQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4aXM6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGdhdGhlcjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxHYXRoZXJBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBHYXRoZXJBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMuYXhpcyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZUdhdGhlclByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdhdGhlckF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248R2F0aGVyQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IEdhdGhlckF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDApIH0pO1xuXG5jb25zdCBnYXRoZXJQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdHYXRoZXInLFxuICBpbnB1dE5hbWVzOiBbJ0EnLCAnQiddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmNvbnN0IGNyZWF0ZUdhdGhlclByb2dyYW1JbmZvID0gKFxuICBfaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGlzOiBudW1iZXIsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBpbmRleERhdGFTaGFwZSA9IGlucHV0c1sxXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gbmV3IEFycmF5KGlucHV0U2hhcGUubGVuZ3RoICsgaW5kZXhEYXRhU2hhcGUubGVuZ3RoIC0gMSk7XG5cbiAgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF4aXMsIGlucHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgaW5kZXhDb3B5T3BzOiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dFNoYXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgLy8gb3V0cHV0U2hhcGUgaXMgZGl2aWRlZCBpbnRvIHRocmVlIHBhcnRzOiBBLCBCLCBDXG4gICAgLy8gfDAgICAgICAgIGF4aXN8ICBheGlzICsgaW5kZXhEYXRhU2hhcGUubGVuZ3RoIHwgICAgICAgICAgZW5kfFxuICAgIC8vIHwgICAgIEEgICAgICAgfCAgICAgICAgICAgICBCICAgICAgICAgICAgICAgICB8ICAgICAgQyAgICAgIHxcbiAgICAvL1xuICAgIC8vIGlucHV0SWR4OiBbQSwgaW5wdXRzWzFdW0JdLCBDXVxuICAgIGlmIChpIDwgYXhpcykge1xuICAgICAgLy8gQVxuICAgICAgb3V0cHV0U2hhcGVbaV0gPSBpbnB1dFNoYXBlW2ldO1xuICAgICAgaW5kZXhDb3B5T3BzLnB1c2goYGlucHV0SWR4WyR7aX1dID0gb3V0cHV0SWR4WyR7aX1dO2ApO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaSA8IGF4aXMgKyBpbmRleERhdGFTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgLy8gQlxuICAgICAgICBvdXRwdXRTaGFwZVtpXSA9IGluZGV4RGF0YVNoYXBlW2kgLSBheGlzXTtcbiAgICAgICAgaW5kZXhDb3B5T3BzLnB1c2goYGluZGV4RGF0YUlkeFske2kgLSBheGlzfV0gPSBvdXRwdXRJZHhbJHtpfV07YCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDXG4gICAgICAgIG91dHB1dFNoYXBlW2ldID0gaW5wdXRTaGFwZVtpIC0gaW5kZXhEYXRhU2hhcGUubGVuZ3RoICsgMV07IC8vIHNraXAgMSBmb3IgYXhpc1xuICAgICAgICBpbmRleENvcHlPcHMucHVzaChgaW5wdXRJZHhbJHtpIC0gaW5kZXhEYXRhU2hhcGUubGVuZ3RoICsgMX1dID0gb3V0cHV0SWR4WyR7aX1dO2ApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG9yYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoIHx8IDE7XG4gIGNvbnN0IGlyYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGlEcmFuayA9IGluZGV4RGF0YVNoYXBlLmxlbmd0aCB8fCAxO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtvcmFua31dKSB7XG4gICAgICAgIGludCBpbnB1dElkeFske2lyYW5rfV07XG4gICAgICAgIGludCBpbmRleERhdGFJZHhbJHtpRHJhbmt9XTtcbiAgICAgICAgaW5kZXhEYXRhSWR4WzBdID0gMDtcbiAgICAgICAgJHtpbmRleENvcHlPcHMuam9pbignXFxuICAgICAgICAnKX1cbiAgICAgICAgaW50IGlkeCA9IGludChfQihpbmRleERhdGFJZHgpKTtcbiAgICAgICAgaW5wdXRJZHhbJHtheGlzfV0gPSBpZHggPCAwID8gaWR4ICsgJHtpbnB1dFNoYXBlW2F4aXNdfSA6IGlkeDtcbiAgICAgICAgcmV0dXJuIF9BKGlucHV0SWR4KTtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUdhdGhlclByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEdhdGhlckF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0geyAuLi5nYXRoZXJQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSB9O1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVHYXRoZXJQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzLmF4aXMpIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBheGlzOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignR2F0aGVyIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG4gIGNvbnN0IHRlbnNvclJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGlmICh0ZW5zb3JSYW5rIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoYXhpcyA8IC10ZW5zb3JSYW5rIHx8IGF4aXMgPiB0ZW5zb3JSYW5rIC0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBheGlzLicpO1xuICB9XG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicgJiYgaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQxNicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IEdlbW1VdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2VtbUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICB0cmFuc0E6IGJvb2xlYW47XG4gIHRyYW5zQjogYm9vbGVhbjtcbiAgYWxwaGE6IG51bWJlcjtcbiAgYmV0YTogbnVtYmVyO1xuICBpc09wdGlvbmFsQzogYm9vbGVhbjsgLy8gaW4gb3BzZXQgMTEsIEMgYmVjb21lcyBvcHRpb25hbFxufVxuXG5leHBvcnQgY29uc3QgZ2VtbTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxHZW1tQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZUdlbW1Qcm9ncmFtSW5mb0xvYWRlcihpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5jb25zdCBwYXJzZUdlbW1BdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUsIGlzT3B0aW9uYWxDOiBib29sZWFuKTogR2VtbUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCB0cmFuc0EgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCd0cmFuc0EnLCAwKSAhPT0gMDtcbiAgY29uc3QgdHJhbnNCID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgndHJhbnNCJywgMCkgIT09IDA7XG4gIGNvbnN0IGFscGhhID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdhbHBoYScsIDEuMCk7XG4gIGNvbnN0IGJldGEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2JldGEnLCAxLjApO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgdHJhbnNBLCB0cmFuc0IsIGFscGhhLCBiZXRhLCBpc09wdGlvbmFsQyB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjc6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248R2VtbUF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBHZW1tQXR0cmlidXRlcyA9PlxuICBwYXJzZUdlbW1BdHRyaWJ1dGVzKG5vZGUsIGZhbHNlKTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2VtbUF0dHJpYnV0ZXNWMTE6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248R2VtbUF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBHZW1tQXR0cmlidXRlcyA9PlxuICBwYXJzZUdlbW1BdHRyaWJ1dGVzKG5vZGUsIHRydWUpO1xuXG5jb25zdCBjcmVhdGVHZW1tUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdHZW1tJyxcbiAgICBpbnB1dE5hbWVzOiBpbnB1dHMubGVuZ3RoID09PSAzID8gWydBJywgJ0InLCAnQyddIDogWydBJywgJ0InXSxcbiAgICBpbnB1dFR5cGVzOlxuICAgICAgaW5wdXRzLmxlbmd0aCA9PT0gM1xuICAgICAgICA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXVxuICAgICAgICA6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgIGtleTogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgfTtcblxuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVHZW1tUHJvZ3JhbUluZm8obWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcykgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUdlbW1Qcm9ncmFtSW5mbyA9IChcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGFTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGJTaGFwZSA9IGlucHV0c1sxXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IFtNLCBOXSA9IEdlbW1VdGlsLmdldFNoYXBlT2ZHZW1tUmVzdWx0KFxuICAgIGFTaGFwZSxcbiAgICBhdHRyaWJ1dGVzLnRyYW5zQSxcbiAgICBiU2hhcGUsXG4gICAgYXR0cmlidXRlcy50cmFuc0IsXG4gICAgaW5wdXRzLmxlbmd0aCA9PT0gMyA/IGlucHV0c1syXS5kaW1zIDogdW5kZWZpbmVkLFxuICApO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFtNLCBOXTtcbiAgaWYgKCFvdXRwdXRTaGFwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHVzZSBnZW1tIG9uIHRoZSBnaXZlbiB0ZW5zb3JzXCIpO1xuICB9XG4gIGxldCBzaGFyZWREaW0gPSBhU2hhcGVbYVNoYXBlLmxlbmd0aCAtIDFdO1xuICBsZXQgbGluZSA9ICcnO1xuICBpZiAoYXR0cmlidXRlcy50cmFuc0EpIHtcbiAgICBzaGFyZWREaW0gPSBhU2hhcGVbMF07XG4gIH1cbiAgaWYgKGF0dHJpYnV0ZXMudHJhbnNBICYmIGF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgbGluZSA9ICd2YWx1ZSArPSBfQV9UKGEpICogX0JfVChiKTsnO1xuICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMudHJhbnNBICYmICFhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgIGxpbmUgPSAndmFsdWUgKz0gX0FfVChhKSAqIF9CKGIpOyc7XG4gIH0gZWxzZSBpZiAoIWF0dHJpYnV0ZXMudHJhbnNBICYmIGF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgbGluZSA9ICd2YWx1ZSArPSBfQShhKSAqIF9CX1QoYik7JztcbiAgfSBlbHNlIGlmICghYXR0cmlidXRlcy50cmFuc0EgJiYgIWF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgbGluZSA9ICd2YWx1ZSArPSBfQShhKSAqIF9CKGIpOyc7XG4gIH1cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgZGVjbGFyZUMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gYGludCBjWyR7aW5wdXRzWzJdLmRpbXMubGVuZ3RofV07YCA6ICcnO1xuICBjb25zdCBicm9hZGNhc3RDID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/ICdiY2FzdEluZGljZXNfQyhpbmRpY2VzLCBjKTsnIDogJyc7XG4gIGNvbnN0IGNhbGN1bGF0ZUMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gJ3ZhbHVlICs9IGJldGEgKiBfQyhjKTsnIDogJyc7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgYVske3Jhbmt9XTtcbiAgICAgICAgICBpbnQgYlske3Jhbmt9XTtcbiAgICAgICAgICAke2RlY2xhcmVDfVxuXG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCBhKTtcbiAgICAgICAgICBjb3B5VmVjKGluZGljZXMsIGIpO1xuICAgICAgICAgICR7YnJvYWRjYXN0Q31cblxuICAgICAgICAgIGZsb2F0IHZhbHVlID0gMC4wO1xuICAgICAgICAgIGZvciAoaW50IGs9MDsgazwke3NoYXJlZERpbX07ICsraykge1xuICAgICAgICAgICAgICBhWyR7cmFuayAtIDF9XSA9IGs7XG4gICAgICAgICAgICAgIGJbJHtyYW5rIC0gMn1dID0gaztcbiAgICAgICAgICAgICAgJHtsaW5lfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhbHVlID0gdmFsdWUgKiBhbHBoYTtcbiAgICAgICAgICAke2NhbGN1bGF0ZUN9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgdmFyaWFibGVzOiBbXG4gICAgICB7IG5hbWU6ICdhbHBoYScsIHR5cGU6ICdmbG9hdCcsIGRhdGE6IGF0dHJpYnV0ZXMuYWxwaGEgfSxcbiAgICAgIHsgbmFtZTogJ2JldGEnLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBhdHRyaWJ1dGVzLmJldGEgfSxcbiAgICBdLFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEdlbW1BdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBpcyBtaXNzaW5nJyk7XG4gIH1cbiAgaWYgKGF0dHJpYnV0ZXMuaXNPcHRpb25hbEMgJiYgKGlucHV0cy5sZW5ndGggPCAyIHx8IGlucHV0cy5sZW5ndGggPiAzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmICghYXR0cmlidXRlcy5pc09wdGlvbmFsQyAmJiBpbnB1dHMubGVuZ3RoICE9PSAzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHZW1tIHJlcXVpcmVzIDMgaW5wdXRzJyk7XG4gIH1cblxuICAvLyAnQycgY2FuIGJlIG9mIGRpbWVuc2lvbmFsaXR5IDEgb3IgMiBvbmx5XG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMSAmJiBpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUgb2YgQycpO1xuICB9XG5cbiAgaWYgKFxuICAgIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgKGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQ2NCcpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSBpbnB1dHNbMV0udHlwZSB8fCAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzWzJdLnR5cGUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCB0eXBlcyBhcmUgbWlzbWF0Y2hlZCcpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBJbWFnZVNjYWxlckF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBzY2FsZTogbnVtYmVyO1xuICBiaWFzOiBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGltYWdlU2NhbGVyOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEltYWdlU2NhbGVyQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUltYWdlU2NhbGVyQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxJbWFnZVNjYWxlckF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3Qgc2NhbGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ3NjYWxlJyk7XG4gIGNvbnN0IGJpYXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXRzKCdiaWFzJyk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBzY2FsZSwgYmlhcyB9KTtcbn07XG5cbmNvbnN0IGltYWdlU2NhbGVyUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnSW1hZ2VTY2FsZXInLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmNvbnN0IGNyZWF0ZUltYWdlU2NhbGVyUHJvZ3JhbUluZm8gPSAoXG4gIF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEltYWdlU2NhbGVyQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBnZXRCaWFzTWV0aG9kID0gY3JlYXRlR2V0Qmlhc01ldGhvZChhdHRyaWJ1dGVzLmJpYXMubGVuZ3RoKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtnZXRCaWFzTWV0aG9kfVxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICByZXR1cm4gX1goaW5kaWNlcykgKiBzY2FsZSArIGdldEJpYXMoYmlhcywgaW5kaWNlc1sxXSk7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICB2YXJpYWJsZXM6IFtcbiAgICAgIHsgbmFtZTogJ2JpYXMnLCB0eXBlOiAnZmxvYXQnLCBhcnJheUxlbmd0aDogYXR0cmlidXRlcy5iaWFzLmxlbmd0aCwgZGF0YTogYXR0cmlidXRlcy5iaWFzIH0sXG4gICAgICB7IG5hbWU6ICdzY2FsZScsIHR5cGU6ICdmbG9hdCcsIGRhdGE6IGF0dHJpYnV0ZXMuc2NhbGUgfSxcbiAgICBdLFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZUltYWdlU2NhbGVyUHJvZ3JhbUluZm9Mb2FkZXIgPSAoXG4gIGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IHsgLi4uaW1hZ2VTY2FsZXJQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSB9O1xuICByZXR1cm4geyAuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMpIH07XG59O1xuXG5jb25zdCBjcmVhdGVHZXRCaWFzTWV0aG9kID0gKG51bUNoYW5uZWxzOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjb2RlTGluZXM6IHN0cmluZ1tdID0gW2BmbG9hdCBnZXRCaWFzKGZsb2F0IGJpYXNbJHtudW1DaGFubmVsc31dLCBpbnQgY2hhbm5lbCkge2BdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUNoYW5uZWxzOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgaWYgKGNoYW5uZWwgPT0gJHtpfSkgeyByZXR1cm4gYmlhc1ske2l9XTsgfWApO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gbnVtQ2hhbm5lbHMgLSAxKSB7XG4gICAgICBjb2RlTGluZXMucHVzaCgnXFx0JyArIGBlbHNlIHsgcmV0dXJuIGJpYXNbJHtpfV07IH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZUxpbmVzLnB1c2goJ1xcdCcgKyBgZWxzZSBpZiAoY2hhbm5lbCA9PSAke2l9KSB7IHJldHVybiBiaWFzWyR7aX1dOyB9YCk7XG4gICAgfVxuICB9XG4gIGNvZGVMaW5lcy5wdXNoKCdcXHQnICsgJ30nKTtcbiAgcmV0dXJuIGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW1hZ2VTY2FsZXIgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgaW5zdGFuY2VOb3JtYWxpemF0aW9uOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcj4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgZXBzaWxvbjogbnVtYmVyLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IG1lYW5BbmRWYXJpYW5jZSA9IGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZU1lYW5BbmRWYXJpYW5jZVByb2dyYW1JbmZvTG9hZGVyKGlucHV0c1swXSksIGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIGNyZWF0ZUNvbXB1dGVPdXRwdXRQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGVwc2lsb24sIG1lYW5BbmRWYXJpYW5jZS5kaW1zKSxcbiAgICBbaW5wdXRzWzBdLCBtZWFuQW5kVmFyaWFuY2UsIGlucHV0c1sxXSwgaW5wdXRzWzJdXSxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlSW5zdGFuY2VOb3JtYWxpemF0aW9uQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXI+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBudW1iZXIgPT5cbiAgbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdlcHNpbG9uJywgMWUtNSk7XG5cbmNvbnN0IG1lYW5BbmRWYXJpYW5jZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0luc3RhbmNlTm9ybWFsaXphdGlvbl9NZWFuQW5kVmFyaWFuY2UnLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmNvbnN0IGNyZWF0ZU1lYW5BbmRWYXJpYW5jZVByb2dyYW1JbmZvID0gKG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHhEaW1zID0gaW5wdXQuZGltcy5zbGljZSgpO1xuICBjb25zdCBjaGFubmVsID0geERpbXNbMV07XG4gIGNvbnN0IGNoYW5uZWxTaXplID0geERpbXNbMl0gKiB4RGltc1szXTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbeERpbXNbMF0sIGNoYW5uZWxdO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIHZlYzQgcHJvY2VzcyhpbnRbMl0gaW5kaWNlcykge1xuICAgICAgICB2ZWM0IHYgPSB2ZWM0KDAuMCk7XG4gICAgICAgIGludCBhWzRdO1xuICAgICAgICBhWzBdID0gaW5kaWNlc1swXTtcbiAgICAgICAgYVsxXSA9IGluZGljZXNbMV07XG4gICAgICAgIGZsb2F0IHRlbXAgPSAwLjA7XG4gICAgICAgIGZvcihpbnQgYTI9MDsgYTI8JHt4RGltc1syXX07IGEyKyspIHtcbiAgICAgICAgICBhWzJdID0gYTI7XG4gICAgICAgICAgZm9yKGludCBhMz0wOyBhMzwke3hEaW1zWzNdfTsgYTMrKykge1xuICAgICAgICAgICAgYVszXSA9IGEzO1xuICAgICAgICAgICAgZmxvYXQgeCA9IF9YKGEpO1xuICAgICAgICAgICAgdGVtcCArPSB4O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmbG9hdCBtZWFuID0gdGVtcCAvIGZsb2F0KCR7Y2hhbm5lbFNpemV9KTtcbiAgICAgICAgdGVtcCA9IDAuMDtcbiAgICAgICAgZm9yKGludCBhMj0wOyBhMjwke3hEaW1zWzJdfTsgYTIrKykge1xuICAgICAgICAgIGFbMl0gPSBhMjtcbiAgICAgICAgICBmb3IoaW50IGEzPTA7IGEzPCR7eERpbXNbM119OyBhMysrKSB7XG4gICAgICAgICAgICBhWzNdID0gYTM7XG4gICAgICAgICAgICBmbG9hdCB4ID0gX1goYSk7XG4gICAgICAgICAgICB0ZW1wICs9ICh4IC0gbWVhbikgKiAoeCAtIG1lYW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2LnIgPSBtZWFuO1xuICAgICAgICB2LmcgPSB0ZW1wIC8gZmxvYXQoJHtjaGFubmVsU2l6ZX0pO1xuXG4gICAgICAgIHJldHVybiB2O1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbiB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZU1lYW5BbmRWYXJpYW5jZVByb2dyYW1JbmZvTG9hZGVyID0gKGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiAoe1xuICAuLi5tZWFuQW5kVmFyaWFuY2VQcm9ncmFtTWV0YWRhdGEsXG4gIGdldDogKCkgPT4gY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm8obWVhbkFuZFZhcmlhbmNlUHJvZ3JhbU1ldGFkYXRhLCBpbnB1dCksXG59KTtcblxuY29uc3QgY29tcHV0ZU91dHB1dFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0luc3RhbmNlTm9ybWFsaXphdGlvbl9Db21wdXRlT3V0cHV0JyxcbiAgaW5wdXROYW1lczogWydYJywgJ01lYW5BbmRWYXJpYW5jZScsICdTY2FsZScsICdCJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbiwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmNvbnN0IGNyZWF0ZUNvbXB1dGVPdXRwdXRQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICBpbnB1dDogVGVuc29yLFxuICBlcHNpbG9uOiBudW1iZXIsXG4gIG1lYW5BbmRWYXJpYW5jZVNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KFxuICAgIG1lYW5BbmRWYXJpYW5jZVNoYXBlLFxuICAgIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sXG4gICk7XG4gIGNvbnN0IFttZWFuQW5kVmFyaWFuY2VXaWR0aCwgbWVhbkFuZFZhcmlhbmNlSGVpZ2h0XSA9IFt0ZXh0dXJlV2lkdGggLyA0LCB0ZXh0dXJlSGVpZ2h0XTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgdmVjNCBnZXRfTWVhbkFuZFZhcmlhbmNlKGludFsyXSBtdikge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gaW5kaWNlc1RvT2Zmc2V0X01lYW5BbmRWYXJpYW5jZShtdik7XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke21lYW5BbmRWYXJpYW5jZVdpZHRofSwgJHttZWFuQW5kVmFyaWFuY2VIZWlnaHR9KTtcbiAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KE1lYW5BbmRWYXJpYW5jZSwgY29vcmRzKTtcbiAgICAgIH1cblxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbNF0gaW5kaWNlcykge1xuICAgICAgICBpbnQgbXZbMl07XG4gICAgICAgIG12WzBdID0gaW5kaWNlc1swXTtcbiAgICAgICAgbXZbMV0gPSBpbmRpY2VzWzFdO1xuICAgICAgICB2ZWM0IG1lYW5fYW5kX3ZhcmlhbmNlID0gZ2V0X01lYW5BbmRWYXJpYW5jZShtdik7XG4gICAgICAgIGZsb2F0IG1lYW4gPSBtZWFuX2FuZF92YXJpYW5jZS5yO1xuICAgICAgICBmbG9hdCB2YXJpYW5jZSA9IG1lYW5fYW5kX3ZhcmlhbmNlLmc7XG5cbiAgICAgICAgaW50IHNiWzFdO1xuICAgICAgICBzYlswXSA9IGluZGljZXNbMV07XG4gICAgICAgIGZsb2F0IHNjYWxlID0gX1NjYWxlKHNiKTtcbiAgICAgICAgZmxvYXQgYiA9IF9CKHNiKTtcblxuICAgICAgICByZXR1cm4gc2NhbGUgKiAoX1goaW5kaWNlcykgLSBtZWFuKSAvIHNxcnQodmFyaWFuY2UgKyBlcHNpbG9uKSArIGI7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgdmFyaWFibGVzOiBbeyBuYW1lOiAnZXBzaWxvbicsIHR5cGU6ICdmbG9hdCcsIGRhdGE6IGVwc2lsb24gfV0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlQ29tcHV0ZU91dHB1dFByb2dyYW1JbmZvTG9hZGVyID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGVwc2lsb246IG51bWJlcixcbiAgbWVhbkFuZFZhcmlhbmNlU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICBjb25zdCBtZXRhZGF0YSA9IHsgLi4uY29tcHV0ZU91dHB1dFByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBgJHtlcHNpbG9ufWAgfTtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBnZXQ6ICgpID0+IGNyZWF0ZUNvbXB1dGVPdXRwdXRQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXQsIGVwc2lsb24sIG1lYW5BbmRWYXJpYW5jZVNoYXBlKSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5zdGFuY2VOb3JtYWxpemF0aW9uIHJlcXVpcmVzIDMgaW5wdXRzLicpO1xuICB9XG5cbiAgY29uc3QgWCA9IGlucHV0c1swXTtcbiAgY29uc3Qgc2NhbGUgPSBpbnB1dHNbMV07XG4gIGNvbnN0IEIgPSBpbnB1dHNbMl07XG5cbiAgLy8gaW5wdXQgc2hvdWxkIGF0IGxlYXN0IGhhdmUgdGhyZWUgZGltZW5zaW9ucyAtIE4sQyxkaW0xLC4uLixkaW1uXG4gIC8vIG90aGVyIGlucHV0cyBjYW4gaGF2ZSBvbmx5IG9uZSBkaW1lbnNpb25zXG4gIGlmIChYLmRpbXMubGVuZ3RoIDwgMyB8fCBzY2FsZS5kaW1zLmxlbmd0aCAhPT0gMSB8fCBCLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChzY2FsZS5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHwgQi5kaW1zWzBdICE9PSBYLmRpbXNbMV0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHNoYXBlcyBhcmUgbWlzbWF0Y2hlZC4nKTtcbiAgfVxuICBpZiAoXG4gICAgKFgudHlwZSAhPT0gJ2Zsb2F0MzInICYmIFgudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChzY2FsZS50eXBlICE9PSAnZmxvYXQzMicgJiYgc2NhbGUudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgIChCLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBCLnR5cGUgIT09ICdmbG9hdDY0JylcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignT25seSBzdXBwb3J0IDQtRCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIExybkF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBhbHBoYTogbnVtYmVyO1xuICBiZXRhOiBudW1iZXI7XG4gIGJpYXM6IG51bWJlcjtcbiAgc2l6ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgbHJuOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPExybkF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IExybkF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgLy8gaWYgKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5wYWNrKSB7XG4gIC8vICAgcmV0dXJuIFtpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVQYWNrZWRMcm5Qcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAvLyAgIGlucHV0cyldO1xuICAvLyB9IGVsc2Uge1xuICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZUxyblByb2dyYW1JbmZvTG9hZGVyKGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyldO1xuICAvL31cbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUxybkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248THJuQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IExybkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhbHBoYSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAwLjAwMDEpO1xuICBjb25zdCBiZXRhID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdiZXRhJywgMC43NSk7XG4gIGNvbnN0IGJpYXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2JpYXMnLCAxLjApO1xuICBjb25zdCBzaXplID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnc2l6ZScpO1xuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBhbHBoYSwgYmV0YSwgYmlhcywgc2l6ZSB9KTtcbn07XG5cbmNvbnN0IGxyblByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0xSTicsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZnVuY3Rpb24gY3JlYXRlTHJuUHJvZ3JhbUluZm8oaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogTHJuQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvIHtcbiAgY29uc3QgQyA9IGlucHV0c1swXS5kaW1zWzFdO1xuICBjb25zdCByYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICBjb25zdCBmcm9tID0gLU1hdGguZmxvb3IoKGF0dHJpYnV0ZXMuc2l6ZSAtIDEpIC8gMik7XG4gIGNvbnN0IHRvID0gTWF0aC5jZWlsKChhdHRyaWJ1dGVzLnNpemUgLSAxKSAvIDIpO1xuICBjb25zdCBhbHBoYSA9IGBmbG9hdCgke2F0dHJpYnV0ZXMuYWxwaGF9KSAvIGZsb2F0KCR7YXR0cmlidXRlcy5zaXplfSlgO1xuICBjb25zdCBiaWFzID0gYGZsb2F0KCR7YXR0cmlidXRlcy5iaWFzfSlgO1xuICBjb25zdCBiZXRhID0gYGZsb2F0KCR7YXR0cmlidXRlcy5iZXRhfSlgO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGludCBjID0gaW5kaWNlc1sxXTtcbiAgICAgICAgZmxvYXQgeCA9IF9YKGluZGljZXMpO1xuICAgICAgICBmbG9hdCBzcXVhcmVfc3VtID0gMC4wO1xuXG4gICAgICAgIGZvciAoaW50IGkgPSAke2Zyb219OyBpIDw9ICR7dG99OyBpKyspIHtcbiAgICAgICAgICBpbnQgaWR4ID0gYyArIGk7XG4gICAgICAgICAgaWYgKGMgPj0gMCAmJiBjIDwgJHtDfSkge1xuICAgICAgICAgICAgaW5kaWNlc1sxXSA9IGlkeDtcbiAgICAgICAgICAgIGZsb2F0IGogPSBfWChpbmRpY2VzKTtcbiAgICAgICAgICAgIHNxdWFyZV9zdW0gKz0gaiAqIGo7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB4IC8gcG93KCR7Ymlhc30gKyAke2FscGhhfSAqIHNxdWFyZV9zdW0sICR7YmV0YX0pO1xuICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLmxyblByb2dyYW1NZXRhZGF0YSxcbiAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgb3V0cHV0OiB7IGRpbXM6IGlucHV0c1swXS5kaW1zLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTHJuUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogTHJuQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyIHtcbiAgcmV0dXJuIHsgLi4ubHJuUHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGdldDogKCkgPT4gY3JlYXRlTHJuUHJvZ3JhbUluZm8oaW5wdXRzLCBhdHRyaWJ1dGVzKSB9O1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xSTiByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBvbmx5IHN1cHBvcnQgTFJOIGZvciBpbnB1dCB3aXRoIFwiTkNIV1wiIGZvcm1hdCcpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBzaG91bGQgYmUgZmxvYXQgdHlwZScpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgZ2V0R2xzbCwgR2xzbCB9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBQYWRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgbW9kZTogc3RyaW5nO1xuICByZWFkb25seSBwYWRzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgdmFsdWU6IG51bWJlcjtcbn1cblxuY29uc3QgcGFkUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnUGFkJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgcGFkVjI6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UGFkQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMihpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5wYWRQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhZFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcyksXG4gICAgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVBhZEF0dHJpYnV0ZXNWMjogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxQYWRBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogUGFkQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IG1vZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdtb2RlJywgJ2NvbnN0YW50Jyk7XG4gIGNvbnN0IHZhbHVlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCd2YWx1ZScsIDAuMCk7XG4gIGNvbnN0IHBhZHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygncGFkcycpO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgbW9kZSwgdmFsdWUsIHBhZHMgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFkVjExOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPHN0cmluZz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgbW9kZTogc3RyaW5nLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0c1YxMShpbnB1dHMpO1xuICBjb25zdCBhdHRydWJ1dGVzID0gZ2VuZXJhdGVQYWRBdHRyaWJ1dGVzRnJvbUlucHV0cyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIG1vZGUpO1xuICByZXR1cm4gcGFkVjIoaW5mZXJlbmNlSGFuZGxlciwgW2lucHV0c1swXV0sIGF0dHJ1YnV0ZXMpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUGFkQXR0cmlidXRlc1YxMTogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxzdHJpbmc+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBzdHJpbmcgPT5cbiAgbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICdjb25zdGFudCcpO1xuXG5jb25zdCBnZW5lcmF0ZVBhZEF0dHJpYnV0ZXNGcm9tSW5wdXRzID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIG1vZGU6IHN0cmluZyxcbik6IFBhZEF0dHJpYnV0ZXMgPT4ge1xuICBpZiAoXG4gICAgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1sxXS5kYXRhSWQpIHx8XG4gICAgKGlucHV0cy5sZW5ndGggPj0gMyAmJiAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzJdLmRhdGFJZCkpXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignZHluYW1pYyBwYWQgYXR0cmlidXRlcyBhcmUgbm90IGFsbG93ZWQnKTtcbiAgfVxuXG4gIGNvbnN0IHBhZHMgPSBBcnJheS5mcm9tKGlucHV0c1sxXS5pbnRlZ2VyRGF0YSk7XG4gIGNvbnN0IHZhbHVlID0gaW5wdXRzLmxlbmd0aCA+PSAzID8gaW5wdXRzWzJdLmZsb2F0RGF0YVswXSA6IDAuMDtcblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgbW9kZSwgcGFkcywgdmFsdWUgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVQYWRQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dDogVGVuc29yLFxuICBhdHRyaWJ1dGVzOiBQYWRBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFNoYXBlVXRpbC5wYWRTaGFwZShpbnB1dC5kaW1zLnNsaWNlKCksIGF0dHJpYnV0ZXMucGFkcyk7XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHBhZEZ1bmN0aW9uID0gZ2V0UGFkRnVuY3Rpb24oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXQsIGF0dHJpYnV0ZXMpO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke3BhZEZ1bmN0aW9ufVxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgICAgICAgIHJldHVybiBwYWRBKGluZGljZXMpO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ1BhZCcsXG4gICAgaW5wdXROYW1lczogWydBJ10sXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjIgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQYWQgcmVxdWlyZXMgMSBpbnB1dCcpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTEgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCAoaW5wdXRzLmxlbmd0aCAhPT0gMiAmJiBpbnB1dHMubGVuZ3RoICE9PSAzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGFkIHJlcXVpcmVzIDIgb3IgMyBpbnB1dHMnKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSAzICYmIGlucHV0c1syXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5jb25zdCBnZXRQYWRGdW5jdGlvbiA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGF0dHJpYnV0ZXM6IFBhZEF0dHJpYnV0ZXMpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IFt3aWR0aCwgaGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KGlucHV0LmRpbXMsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgY29uc3Qgc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhpbnB1dC5kaW1zKTtcblxuICBzd2l0Y2ggKGF0dHJpYnV0ZXMubW9kZSkge1xuICAgIGNhc2UgJ2NvbnN0YW50JzpcbiAgICAgIHJldHVybiBnZXRQYWRDb25zdGFudChnbHNsLCBpbnB1dC5kaW1zLCBzdHJpZGVzLCB3aWR0aCwgaGVpZ2h0LCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMudmFsdWUpO1xuICAgIGNhc2UgJ3JlZmxlY3QnOlxuICAgICAgcmV0dXJuIGdldFBhZFJlZmxlY3QoZ2xzbCwgaW5wdXQuZGltcywgc3RyaWRlcywgd2lkdGgsIGhlaWdodCwgYXR0cmlidXRlcy5wYWRzKTtcbiAgICBjYXNlICdlZGdlJzpcbiAgICAgIHJldHVybiBnZXRQYWRFZGdlKGdsc2wsIGlucHV0LmRpbXMsIHN0cmlkZXMsIHdpZHRoLCBoZWlnaHQsIGF0dHJpYnV0ZXMucGFkcyk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBtb2RlJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdldFBhZENvbnN0YW50ID0gKFxuICBnbHNsOiBHbHNsLFxuICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICB3aWR0aDogbnVtYmVyLFxuICBoZWlnaHQ6IG51bWJlcixcbiAgcGFkczogbnVtYmVyW10sXG4gIHZhbHVlOiBudW1iZXIsXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICBsZXQgYmxvY2sgPSAnJztcbiAgZm9yIChsZXQgaSA9IHJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgIGJsb2NrICs9IGBcbiAgICAgICAgayA9IG1bJHtpfV0gLSAke3BhZHNbaV19O1xuICAgICAgICBpZiAoayA8IDApICByZXR1cm4gY29uc3RhbnQ7XG4gICAgICAgIGlmIChrID49ICR7c2hhcGVbaV19KSByZXR1cm4gY29uc3RhbnQ7XG4gICAgICAgIG9mZnNldCArPSBrICogJHtzdHJpZGVzW2ldfTtcbiAgICAgICAgYDtcbiAgfVxuICByZXR1cm4gYFxuICAgICAgZmxvYXQgcGFkQShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICBjb25zdCBmbG9hdCBjb25zdGFudCA9IGZsb2F0KCR7dmFsdWV9KTtcbiAgICAgICAgaW50IG9mZnNldCA9IDA7XG4gICAgICAgIGludCBrID0gMDtcbiAgICAgICAgJHtibG9ja31cbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7d2lkdGh9LCAke2hlaWdodH0pO1xuICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBjb29yZHMpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgYDtcbn07XG5cbmNvbnN0IGdldFBhZFJlZmxlY3QgPSAoXG4gIGdsc2w6IEdsc2wsXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHdpZHRoOiBudW1iZXIsXG4gIGhlaWdodDogbnVtYmVyLFxuICBwYWRzOiBudW1iZXJbXSxcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBibG9jayArPSBgXG4gICAgICAgIGsgPSBtWyR7aX1dIC0gJHtwYWRzW2ldfTtcbiAgICAgICAgaWYgKGsgPCAwKSB7IGsgPSAtazsgfVxuICAgICAgICB7XG4gICAgICAgICAgY29uc3QgaW50IF8ybl8xID0gJHsyICogKHNoYXBlW2ldIC0gMSl9O1xuICAgICAgICAgIGsgPSBpbnQoIG1vZCggZmxvYXQoayksIGZsb2F0KF8ybl8xKSApICkgO1xuICAgICAgICAgIGlmKGsgPj0gJHtzaGFwZVtpXX0pIHsgayA9IF8ybl8xIC0gazsgfVxuICAgICAgICB9XG4gICAgICAgIG9mZnNldCArPSBrICogJHtzdHJpZGVzW2ldfTtcbiAgICAgICAgYDtcbiAgfVxuICByZXR1cm4gYFxuICAgICAgZmxvYXQgcGFkQShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gMDtcbiAgICAgICAgaW50IGsgPSAwO1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIGNvb3JkcykpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBgO1xufTtcblxuY29uc3QgZ2V0UGFkRWRnZSA9IChcbiAgZ2xzbDogR2xzbCxcbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgd2lkdGg6IG51bWJlcixcbiAgaGVpZ2h0OiBudW1iZXIsXG4gIHBhZHM6IG51bWJlcltdLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICBsZXQgYmxvY2sgPSAnJztcbiAgZm9yIChsZXQgaSA9IHJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgIGJsb2NrICs9IGBcbiAgICAgICAgayA9IG1bJHtpfV0gLSAke3BhZHNbaV19O1xuICAgICAgICBpZiAoayA8IDApICBrID0gMDtcbiAgICAgICAgaWYgKGsgPj0gJHtzaGFwZVtpXX0pIGsgPSAke3NoYXBlW2ldIC0gMX07XG4gICAgICAgIG9mZnNldCArPSBrICogJHtzdHJpZGVzW2ldfTtcbiAgICAgIGA7XG4gIH1cbiAgcmV0dXJuIGBcbiAgICAgIGZsb2F0IHBhZEEoaW50IG1bJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IDA7XG4gICAgICAgIGludCBrID0gMDtcbiAgICAgICAgJHtibG9ja31cbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7d2lkdGh9LCAke2hlaWdodH0pO1xuICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBjb29yZHMpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgYDtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgUG9vbENvbnZVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF2ZXJhZ2VQb29sQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF1dG9QYWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgY2VpbE1vZGU6IG51bWJlcjtcbiAgcmVhZG9ubHkgY291bnRJbmNsdWRlUGFkOiBib29sZWFuO1xuICByZWFkb25seSBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBwYWRzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGF2ZXJhZ2VQb29sOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEF2ZXJhZ2VQb29sQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBtZXRhZGF0YSA9IHtcbiAgICBuYW1lOiAnQXZlcmFnZVBvb2wnLFxuICAgIGlucHV0TmFtZXM6IFsnWCddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICB9O1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7IC4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBtZXRhZGF0YSwgZmFsc2UsIGF0dHJpYnV0ZXMpIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248QXZlcmFnZVBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF1dG9QYWQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhdXRvX3BhZCcsICdOT1RTRVQnKTtcbiAgY29uc3QgY2VpbE1vZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdjZWlsX21vZGUnLCAwKTtcbiAgY29uc3QgY291bnRJbmNsdWRlUGFkID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnY291bnRfaW5jbHVkZV9wYWQnLCAwKSA9PT0gMCA/IGZhbHNlIDogdHJ1ZTtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygna2VybmVsX3NoYXBlJyk7XG4gIGNvbnN0IHN0cmlkZXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3RyaWRlcycsIFtdKTtcbiAgY29uc3QgcGFkcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgW10pO1xuXG4gIC8vIFRPRE86IHN1cHBvcnQgYXR0cmlidXRlICdjZWlsX21vZGUnXG4gIGlmIChjZWlsTW9kZSAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndXNpbmcgY2VpbCgpIGluIHNoYXBlIGNvbXB1dGF0aW9uIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciBBdmVyYWdlUG9vbCcpO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF1dG9QYWQsIGNlaWxNb2RlLCBjb3VudEluY2x1ZGVQYWQsIGtlcm5lbFNoYXBlLCBzdHJpZGVzLCBwYWRzIH0pO1xufTtcblxuY29uc3QgY3JlYXRlQXZlcmFnZVBvb2xQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvdXRwdXRTaGFwZV0gPSBnZXRBZGp1c3RlZFBvb2xBdHRyaWJ1dGVzQW5kT3V0cHV0U2hhcGUoXG4gICAgaW5wdXRzLFxuICAgIGF0dHJpYnV0ZXMsXG4gICAgaXNHbG9iYWxPcGVyYXRvcixcbiAgKTtcbiAgY29uc3Qga2VybmVsU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGFkanVzdGVkQXR0cmlidXRlcy5rZXJuZWxTaGFwZSk7XG4gIGNvbnN0IG9wMSA9ICd2YWx1ZSArPSBfWCh4KTsnO1xuICBsZXQgb3AyID0gJyc7XG4gIGlmIChhZGp1c3RlZEF0dHJpYnV0ZXMuY291bnRJbmNsdWRlUGFkKSB7XG4gICAgb3AyICs9IGB2YWx1ZSAvPSBmbG9hdCgke2tlcm5lbFNpemV9KTtgO1xuICB9IGVsc2Uge1xuICAgIG9wMiArPSBgdmFsdWUgLz0gZmxvYXQoJHtrZXJuZWxTaXplfSAtIHBhZCk7YDtcbiAgfVxuICBjb25zdCBwb29saW5nQ29kZSA9IGdlbmVyYXRlUG9vbGluZ0NvZGUoaW5wdXRzWzBdLmRpbXMsIGFkanVzdGVkQXR0cmlidXRlcywgb3AxLCBvcDIsICcwLjAnKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAke3Bvb2xpbmdDb2RlfVxuICAgICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgZ2xvYmFsQXZlcmFnZVBvb2w6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248QXZlcmFnZVBvb2xBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdHbG9iYWxBdmVyYWdlUG9vbCcsXG4gICAgaW5wdXROYW1lczogWydYJ10sXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICBjYWNoZUhpbnQ6IGAke2F0dHJpYnV0ZXMuY291bnRJbmNsdWRlUGFkfWAsXG4gIH07XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlQXZlcmFnZVBvb2xQcm9ncmFtSW5mbyhpbnB1dHMsIG1ldGFkYXRhLCB0cnVlLCBhdHRyaWJ1dGVzKSB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2xvYmFsQXZlcmFnZVBvb2xBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEF2ZXJhZ2VQb29sQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBjb3VudEluY2x1ZGVQYWQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdjb3VudF9pbmNsdWRlX3BhZCcsIDApID09PSAwID8gZmFsc2UgOiB0cnVlO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBhdXRvUGFkOiAnJyxcbiAgICBjZWlsTW9kZTogMCxcbiAgICBjb3VudEluY2x1ZGVQYWQsXG4gICAga2VybmVsU2hhcGU6IFtdLFxuICAgIHN0cmlkZXM6IFtdLFxuICAgIHBhZHM6IFtdLFxuICB9KTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWF4UG9vbEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMge1xuICByZWFkb25seSBzdG9yYWdlT3JkZXI6IG51bWJlcjtcbiAgcmVhZG9ubHkgZGlsYXRpb25zOiBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IG1heFBvb2w6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248TWF4UG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IE1heFBvb2xBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBtZXRhZGF0YSA9IHtcbiAgICBuYW1lOiAnTWF4UG9vbCcsXG4gICAgaW5wdXROYW1lczogWydYJ10sXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gIH07XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvKGlucHV0cywgbWV0YWRhdGEsIGZhbHNlLCBhdHRyaWJ1dGVzKSB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTWF4UG9vbEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248TWF4UG9vbEF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogTWF4UG9vbEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhdXRvUGFkID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnYXV0b19wYWQnLCAnTk9UU0VUJyk7XG4gIGNvbnN0IGNlaWxNb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnY2VpbF9tb2RlJywgMCk7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScpO1xuICBjb25zdCBzdHJpZGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3N0cmlkZXMnLCBbXSk7XG4gIGNvbnN0IHBhZHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygncGFkcycsIFtdKTtcbiAgY29uc3Qgc3RvcmFnZU9yZGVyID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnc3RvcmFnZV9vcmRlcicsIDApO1xuICBjb25zdCBkaWxhdGlvbnMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnZGlsYXRpb25zJywgW10pO1xuXG4gIC8vIFRPRE86IHN1cHBvcnQgYXR0cmlidXRlICdjZWlsX21vZGUnIGFuZCAnc3RvcmFnZV9vcmRlcidcbiAgaWYgKHN0b3JhZ2VPcmRlciAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY29sdW1uIG1ham9yIHN0b3JhZ2Ugb3JkZXIgaXMgbm90IHlldCBzdXBwb3J0ZWQgZm9yIE1heFBvb2wnKTtcbiAgfVxuICBpZiAoY2VpbE1vZGUgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzaW5nIGNlaWwoKSBpbiBzaGFwZSBjb21wdXRhdGlvbiBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgTWF4UG9vbCcpO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYXV0b1BhZCxcbiAgICBjZWlsTW9kZSxcbiAgICBjb3VudEluY2x1ZGVQYWQ6IGZhbHNlLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIHN0cmlkZXMsXG4gICAgcGFkcyxcbiAgICBzdG9yYWdlT3JkZXIsXG4gICAgZGlsYXRpb25zLFxuICB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZU1heFBvb2xQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgYXR0cmlidXRlczogTWF4UG9vbEF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFthZGp1c3RlZEF0dHJpYnV0ZXMsIG91dHB1dFNoYXBlXSA9IGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZShcbiAgICBpbnB1dHMsXG4gICAgYXR0cmlidXRlcyxcbiAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICApO1xuICBjb25zdCBvcDEgPSBgXG4gICAgICB2YWx1ZSA9IG1heChfWCh4KSwgdmFsdWUpO1xuICAgIGA7XG4gIGNvbnN0IG9wMiA9ICcnO1xuICBjb25zdCBwb29saW5nQ29kZSA9IGdlbmVyYXRlUG9vbGluZ0NvZGUoaW5wdXRzWzBdLmRpbXMsIGFkanVzdGVkQXR0cmlidXRlcywgb3AxLCBvcDIsICctMWU1Jyk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7cG9vbGluZ0NvZGV9XG4gICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBnZXRBZGp1c3RlZFBvb2xBdHRyaWJ1dGVzQW5kT3V0cHV0U2hhcGUgPSAoXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyB8IE1heFBvb2xBdHRyaWJ1dGVzLFxuICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuKTogW0F2ZXJhZ2VQb29sQXR0cmlidXRlcyB8IE1heFBvb2xBdHRyaWJ1dGVzLCBudW1iZXJbXV0gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgaGFzRGlsYXRpb25zID0gT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cmlidXRlcywgJ2RpbGF0aW9ucycpO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGUuc2xpY2UoKTtcbiAgY29uc3Qgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuc3RyaWRlcy5zbGljZSgpO1xuICBjb25zdCBkaWxhdGlvbnM6IG51bWJlcltdID0gaGFzRGlsYXRpb25zID8gKGF0dHJpYnV0ZXMgYXMgTWF4UG9vbEF0dHJpYnV0ZXMpLmRpbGF0aW9ucy5zbGljZSgpIDogW107XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMuc2xpY2UoKTtcbiAgUG9vbENvbnZVdGlsLmFkanVzdFBvb2xBdHRyaWJ1dGVzKGlzR2xvYmFsT3BlcmF0b3IsIGlucHV0U2hhcGUsIGtlcm5lbFNoYXBlLCBzdHJpZGVzLCBkaWxhdGlvbnMsIHBhZHMpO1xuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gUG9vbENvbnZVdGlsLmNvbXB1dGVQb29sT3V0cHV0U2hhcGUoXG4gICAgaXNHbG9iYWxPcGVyYXRvcixcbiAgICBpbnB1dFNoYXBlLFxuICAgIHN0cmlkZXMsXG4gICAgZGlsYXRpb25zLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIHBhZHMsXG4gICAgYXR0cmlidXRlcy5hdXRvUGFkLFxuICApO1xuXG4gIGNvbnN0IG5ld0F0dHJpYnV0ZXMgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKTtcbiAgaWYgKGhhc0RpbGF0aW9ucykge1xuICAgIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywgeyBrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkcywgZGlsYXRpb25zLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleSB9KTtcbiAgfSBlbHNlIHtcbiAgICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHsga2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHMsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH0pO1xuICB9XG4gIHJldHVybiBbbmV3QXR0cmlidXRlcywgb3V0cHV0U2hhcGVdO1xufTtcblxuY29uc3QgZ2xvYmFsTWF4UG9vbEF0dHJpYnV0ZXMgPSB7XG4gIGF1dG9QYWQ6ICcnLFxuICBjZWlsTW9kZTogMCxcbiAgY291bnRJbmNsdWRlUGFkOiBmYWxzZSxcbiAga2VybmVsU2hhcGU6IFtdLFxuICBzdHJpZGVzOiBbXSxcbiAgcGFkczogW10sXG4gIHN0b3JhZ2VPcmRlcjogMCxcbiAgZGlsYXRpb25zOiBbXSxcbiAgY2FjaGVLZXk6ICcnLFxufTtcblxuY29uc3QgZ2xvYmFsTWF4UG9vbE1ldGFkYXRhID0ge1xuICBuYW1lOiAnR2xvYmFsTWF4UG9vbCcsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IGdsb2JhbE1heFBvb2wgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5nbG9iYWxNYXhQb29sTWV0YWRhdGEsXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZU1heFBvb2xQcm9ncmFtSW5mbyhpbnB1dHMsIGdsb2JhbE1heFBvb2xNZXRhZGF0YSwgdHJ1ZSwgZ2xvYmFsTWF4UG9vbEF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bvb2wgb3BzIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5jb25zdCBnZW5lcmF0ZVBvb2xpbmdDb2RlID0gKFxuICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsXG4gIG9wMTogc3RyaW5nLFxuICBvcDI6IHN0cmluZyxcbiAgc3RhcnQ6IHN0cmluZyxcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJhbmsgPSBpbnB1dERpbXMubGVuZ3RoO1xuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPD0gMikge1xuICAgIGNvbnN0IGt3ID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZVthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IHN3ID0gYXR0cmlidXRlcy5zdHJpZGVzW2F0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBwd1N0YXJ0ID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLyAyIC0gMV07XG4gICAgY29uc3QgcHdFbmQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IGRpbVcgPSBpbnB1dERpbXNbcmFuayAtIDFdO1xuICAgIGxldCBjb2RlVyA9ICcnO1xuICAgIGxldCBjb2RlSCA9ICcnO1xuICAgIGxldCBjb2RlSEVuZCA9ICcnO1xuICAgIGlmIChwd1N0YXJ0ICsgcHdFbmQgIT09IDApIHtcbiAgICAgIGNvZGVXID0gYFxuICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtrd307IGkrKykge1xuICAgICAgICAgICAgeFske3Jhbmt9IC0gMV0gPSBpbmRpY2VzWyR7cmFua30gLSAxXSAqICR7c3d9IC0gJHtwd1N0YXJ0fSArIGk7XG4gICAgICAgICAgICBpZiAoeFske3Jhbmt9IC0gMV0gPCAwIHx8IHhbJHtyYW5rfSAtIDFdID49ICR7ZGltV30pIHtcbiAgICAgICAgICAgICAgcGFkKys7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgJHtvcDF9XG4gICAgICAgICAgfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVXID0gYFxuICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtrd307IGkrKykge1xuICAgICAgICAgICAgeFske3Jhbmt9IC0gMV0gPSBpbmRpY2VzWyR7cmFua30gLSAxXSAqICR7c3d9IC0gJHtwd1N0YXJ0fSArIGk7XG4gICAgICAgICAgICAke29wMX1cbiAgICAgICAgICB9YDtcbiAgICB9XG5cbiAgICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPT09IDIpIHtcbiAgICAgIGNvbnN0IGtoID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZVthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAtIDJdO1xuICAgICAgY29uc3Qgc2ggPSBhdHRyaWJ1dGVzLnN0cmlkZXNbYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAtIDJdO1xuICAgICAgY29uc3QgcGhTdGFydCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC8gMiAtIDJdO1xuICAgICAgY29uc3QgcGhFbmQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAtIDJdO1xuICAgICAgY29uc3QgZGltSCA9IGlucHV0RGltc1tyYW5rIC0gMl07XG4gICAgICBpZiAocGhTdGFydCArIHBoRW5kICE9PSAwKSB7XG4gICAgICAgIGNvZGVIID0gYFxuICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCAke2tofTsgaisrKSB7XG4gICAgICAgICAgICAgIHhbJHtyYW5rfSAtIDJdID0gaW5kaWNlc1ske3Jhbmt9IC0gMl0gKiAke3NofSAtICR7cGhTdGFydH0gKyBqO1xuICAgICAgICAgICAgICBpZiAoeFske3Jhbmt9IC0gMl0gPCAwIHx8IHhbJHtyYW5rfSAtIDJdID49ICR7ZGltSH0pIHtcbiAgICAgICAgICAgICAgICBwYWQrPSAke2t3fTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgIGA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb2RlSCA9IGBcbiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgJHtraH07IGorKykge1xuICAgICAgICAgICAgICB4WyR7cmFua30gLSAyXSA9IGluZGljZXNbJHtyYW5rfSAtIDJdICogJHtzaH0gLSAke3BoU3RhcnR9ICsgajtcbiAgICAgICAgICAgIGA7XG4gICAgICB9XG4gICAgICBjb2RlSEVuZCA9IGBcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgfVxuXG4gICAgY29uc3QgcG9vbGluZ0NvZGUgPSBgXG4gICAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgeFske3Jhbmt9XTtcbiAgICAgICAgICBjb3B5VmVjKGluZGljZXMsIHgpO1xuXG4gICAgICAgICAgZmxvYXQgdmFsdWUgPSAke3N0YXJ0fTtcbiAgICAgICAgICBpbnQgcGFkID0gMDtcbiAgICAgICAgICAke2NvZGVIfVxuICAgICAgICAgICR7Y29kZVd9XG4gICAgICAgICAgJHtjb2RlSEVuZH1cbiAgICAgICAgICAke29wMn1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIHBvb2xpbmdDb2RlO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGtlcm5lbFNpemUgPSBTaGFwZVV0aWwuc2l6ZShhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgICBjb25zdCBrZXJuZWxTdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUpO1xuICAgIGNvbnN0IHN0cmlkZXNSYW5rID0ga2VybmVsU3RyaWRlcy5sZW5ndGg7XG4gICAgY29uc3QgcGFkc1JhbmsgPSBhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoO1xuICAgIGNvbnN0IG9mZnNldFRvSW5kaWNlc0Z1bmN0aW9uID0gb2Zmc2V0VG9JbmRpY2VzKHN0cmlkZXNSYW5rKTtcbiAgICBjb25zdCBjb3B5SW5wdXREaW1zID0gY29weUFycmF5KGlucHV0RGltcywgJ2lucHV0RGltcycpO1xuICAgIGNvbnN0IGNvcHlQYWRzID0gY29weUFycmF5KGF0dHJpYnV0ZXMucGFkcywgJ3BhZHMnKTtcbiAgICBjb25zdCBjb3B5S2VybmVsU3RyaWRlcyA9IGNvcHlBcnJheShrZXJuZWxTdHJpZGVzLCAna2VybmVsU3RyaWRlcycpO1xuICAgIGNvbnN0IGNvcHlTdHJpZGVzID0gY29weUFycmF5KGF0dHJpYnV0ZXMuc3RyaWRlcywgJ3N0cmlkZXMnKTtcbiAgICBjb25zdCBoYXNQYWRzID0gYXR0cmlidXRlcy5wYWRzLnJlZHVjZSgoc3VtLCBjdXIpID0+IHN1bSArIGN1cik7XG4gICAgbGV0IHBhZENvZGUgPSAnJztcbiAgICBpZiAoaGFzUGFkcykge1xuICAgICAgcGFkQ29kZSA9IGBcbiAgICAgICAgICAgIGlmICh4W2pdID49IGlucHV0RGltc1tqXSB8fCB4W2pdIDwgMCkge1xuICAgICAgICAgICAgICBwYWQrKztcbiAgICAgICAgICAgICAgaXNQYWQgPSB0cnVlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFpc1BhZCkge1xuICAgICAgICAgICAgJHtvcDF9XG4gICAgICAgICAgfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhZENvZGUgPSBgXG4gICAgICAgICAgfVxuICAgICAgICAgICR7b3AxfVxuICAgICAgICBgO1xuICAgIH1cbiAgICBjb25zdCBwb29saW5nQ29kZSA9IGBcbiAgICAgICAgJHtvZmZzZXRUb0luZGljZXNGdW5jdGlvbn1cbiAgICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCB4WyR7cmFua31dO1xuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgeCk7XG4gICAgICAgICAgaW50IG9mZnNldFske3N0cmlkZXNSYW5rfV07XG4gICAgICAgICAgaW50IHBhZHNbJHtwYWRzUmFua31dO1xuICAgICAgICAgIGludCBpbnB1dERpbXNbJHtyYW5rfV07XG4gICAgICAgICAgaW50IGtlcm5lbFN0cmlkZXNbJHtzdHJpZGVzUmFua31dO1xuICAgICAgICAgIGludCBzdHJpZGVzWyR7c3RyaWRlc1Jhbmt9XTtcbiAgICAgICAgICAke2NvcHlQYWRzfVxuICAgICAgICAgICR7Y29weUlucHV0RGltc31cbiAgICAgICAgICAke2NvcHlTdHJpZGVzfVxuICAgICAgICAgICR7Y29weUtlcm5lbFN0cmlkZXN9XG5cbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9ICR7c3RhcnR9O1xuICAgICAgICAgIGludCBwYWQgPSAwO1xuICAgICAgICAgIGJvb2wgaXNQYWQgPSBmYWxzZTtcbiAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7a2VybmVsU2l6ZX07IGkrKykge1xuICAgICAgICAgICAgb2Zmc2V0VG9JbmRpY2VzKGksIGtlcm5lbFN0cmlkZXMsIG9mZnNldCk7XG4gICAgICAgICAgICBpc1BhZCA9IGZhbHNlO1xuICAgICAgICAgICAgZm9yIChpbnQgaiA9ICR7cmFua30gLSAke3N0cmlkZXNSYW5rfTsgaiA8ICR7cmFua307IGorKykge1xuICAgICAgICAgICAgICB4W2pdID0gaW5kaWNlc1tqXSAqIHN0cmlkZXNbaiAtICR7cmFua30gKyAke3N0cmlkZXNSYW5rfV1cbiAgICAgICAgICAgICAgICArIG9mZnNldFtqIC0gJHtyYW5rfSArICR7c3RyaWRlc1Jhbmt9XSAtIHBhZHNbaiAtIDJdO1xuICAgICAgICAgICAgICAke3BhZENvZGV9XG4gICAgICAgICAgfVxuICAgICAgICAgICR7b3AyfVxuXG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBwb29saW5nQ29kZTtcbiAgfVxufTtcblxuY29uc3QgY29weUFycmF5ID0gKGFycmF5OiByZWFkb25seSBudW1iZXJbXSwgYXJyYXlOYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBsZXQgYmxvY2sgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgIGJsb2NrICs9IGBcbiAgICAgICR7YXJyYXlOYW1lfVske2l9XSA9ICR7YXJyYXlbaV19O1xuICAgIGA7XG4gIH1cbiAgcmV0dXJuIGJsb2NrO1xufTtcblxuY29uc3Qgb2Zmc2V0VG9JbmRpY2VzID0gKHJhbms6IG51bWJlcik6IHN0cmluZyA9PiBgXG4gIHZvaWQgb2Zmc2V0VG9JbmRpY2VzKGludCBvZmZzZXQsIGludFske3Jhbmt9XSBzdHJpZGVzLCBvdXQgaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICBpZiAoJHtyYW5rfSA9PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtyYW5rfSAtIDE7ICsraSkge1xuICAgICAgaW5kaWNlc1tpXSA9IG9mZnNldCAvIHN0cmlkZXNbaV07XG4gICAgICBvZmZzZXQgLT0gaW5kaWNlc1tpXSAqIHN0cmlkZXNbaV07XG4gICAgfVxuICAgIGluZGljZXNbJHtyYW5rfSAtIDFdID0gb2Zmc2V0O1xuICB9YDtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBOVU1CRVJfVFlQRVMsIE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVkdWNlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4ZXM6IG51bWJlcltdO1xuICByZWFkb25seSBrZWVwRGltczogYm9vbGVhbjtcbn1cblxuLy8gcmV0dXJuIFtpbml0IG9wcywgcmVkdWNlIG9wcywgZmluYWwgb3BzXVxudHlwZSBSZWR1Y2VPcCA9IChpbnB1dHM6IFRlbnNvcltdLCBheGVzOiBudW1iZXJbXSkgPT4gc3RyaW5nW107XG5cbmNvbnN0IHJlZHVjZSA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuICBuYW1lOiBzdHJpbmcsXG4gIHJlZHVjZU9wOiBSZWR1Y2VPcCxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCByZWR1Y2VQcm9ncmFtTWV0YWRhdGEgPSB7XG4gICAgbmFtZSxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICB9O1xuXG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHtcbiAgICAgIC4uLnJlZHVjZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCBuYW1lLCByZWR1Y2VPcCwgcmVkdWNlUHJvZ3JhbU1ldGFkYXRhKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVkdWNlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogUmVkdWNlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF4ZXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnYXhlcycsIFtdKTtcbiAgY29uc3Qga2VlcERpbXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdrZWVwZGltcycsIDEpID09PSAxO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhlcywga2VlcERpbXMgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVSZWR1Y2VQcm9ncmFtSW5mbyA9IChcbiAgX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbiAgX25hbWU6IHN0cmluZyxcbiAgcmVkdWNlT3A6IFJlZHVjZU9wLFxuICByZWR1Y2VQcm9ncmFtTWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGU6IG51bWJlcltdID0gW107XG4gIGNvbnN0IGlSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIHx8IDE7XG5cbiAgY29uc3QgaWR4Q29weSA9IFtdOyAvLyBjb3B5IG91dHB1dCBpbmRleGVzIHRvIGlucHV0IGluZGV4ZXNcblxuICBjb25zdCBheGVzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4ZXMoYXR0cmlidXRlcy5heGVzLCBpbnB1dHNbMF0uZGltcy5sZW5ndGgpO1xuICBjb25zdCBvcHMgPSByZWR1Y2VPcChpbnB1dHMsIGF4ZXMpO1xuICBsZXQgcmVkdWNlT3BzID0gb3BzWzFdO1xuXG4gIGZvciAobGV0IGsgPSAwOyBrIDwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoOyBrKyspIHtcbiAgICAvLyBpZiB0aGlzIGF4aXMgaXMgcmVkdWNlZFxuICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKGF0dHJpYnV0ZXMua2VlcERpbXMpIHtcbiAgICAgICAgb3V0cHV0U2hhcGUucHVzaCgxKTtcbiAgICAgIH0gLy8gZWxzZSB7IHJlbW92ZSB0aGUgYXhpcyBmcm9tIG91dHB1dFNoYXBlOyB9XG5cbiAgICAgIC8vIGxvb3Agb3ZlciB0aGUgZC10aCBheGlzXG4gICAgICByZWR1Y2VPcHMgPSBgXG4gICAgICAgICAgZm9yKGludCBqJHtrfSA9IDA7IGoke2t9IDwgJHtpbnB1dHNbMF0uZGltc1trXX07IGoke2t9KyspIHtcbiAgICAgICAgICAgIGlucHV0SWR4WyR7a31dID0gaiR7a307XG4gICAgICAgICAgICAke3JlZHVjZU9wc31cbiAgICAgICAgICB9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWR4Q29weS5wdXNoKGBpbnB1dElkeFske2t9XSA9IG91dHB1dElkeFske291dHB1dFNoYXBlLmxlbmd0aH1dO2ApO1xuXG4gICAgICBvdXRwdXRTaGFwZS5wdXNoKGlucHV0c1swXS5kaW1zW2tdKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBvUmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aCB8fCAxO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske29SYW5rfV0pIHtcbiAgICAgICAgZmxvYXQgdmFsdWU7ICAgICAgICAgICAgICAgICAvLyBmaW5hbCByZXN1bHRcbiAgICAgICAgaW50IGlucHV0SWR4WyR7aVJhbmt9XTsgICAgICAvLyBhZGRyZXNzaW5nIGlucHV0IGRhdGFcbiAgICAgICAgJHtpZHhDb3B5LmpvaW4oJ1xcbicpfVxuICAgICAgICAke29wc1swXX0gICAgICAgLy8gaW5pdCBvcHMgZm9yIHJlZHVjZSBtYXgvbWluXG4gICAgICAgICR7cmVkdWNlT3BzfVxuICAgICAgICAke29wc1syXX0gICAgICAgLy8gZmluYWwgY29tcHV0YXRpb24gZm9yIHJlZHVjZSBtZWFuXG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1gO1xuXG4gIHJldHVybiB7XG4gICAgLi4ucmVkdWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZCB9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgLy8gVE9ETzogc3VwcG9ydCBSZWR1Y2UqIG9wZXJhdG9ycyB3aXRoIDIgaW5wdXRzLlxuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWR1Y2Ugb3AgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VTdW06IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKCk6IHN0cmluZ1tdID0+IFsndmFsdWUgPSAwLjA7JywgJ3ZhbHVlICs9IF9BKGlucHV0SWR4KTsnLCAnJ107XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlU3VtJywgcmVkdWNlT3ApO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZU1lYW46IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKTogc3RyaW5nW10gPT4ge1xuICAgIGxldCBzaXplID0gMS4wO1xuICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBzaXplICo9IGlucHV0c1swXS5kaW1zW2tdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbJ3ZhbHVlID0gMC4wOycsICd2YWx1ZSArPSBfQShpbnB1dElkeCk7JywgYHZhbHVlIC89ICR7c2l6ZX0uO2BdOyAvLyBlbnN1cmUgcmVhbCBudW1iZXIgd2l0aCBgLmBcbiAgfTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VNZWFuJywgcmVkdWNlT3ApO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZU1heDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBzdHJpbmdbXSA9PiB7XG4gICAgY29uc3QgaWR4WmVybyA9IFtdO1xuICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0SWR4WyR7a31dID0gMDtgKTsgLy8gZmlyc3QgZWxlbWVudFxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbYCR7aWR4WmVyby5qb2luKCdcXG4nKX1cXG52YWx1ZSA9IF9BKGlucHV0SWR4KTtgLCAndmFsdWUgPSBtYXgodmFsdWUsIF9BKGlucHV0SWR4KSk7JywgJyddO1xuICB9O1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZU1heCcsIHJlZHVjZU9wKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNaW46IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKTogc3RyaW5nW10gPT4ge1xuICAgIGNvbnN0IGlkeFplcm8gPSBbXTtcbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgICBpZiAoYXhlcy5pbmRleE9mKGspID49IDAgfHwgYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWR4WmVyby5wdXNoKGBpbnB1dElkeFske2t9XSA9IDA7YCk7IC8vIGZpcnN0IGVsZW1lbnRcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gW2Ake2lkeFplcm8uam9pbignXFxuJyl9XFxudmFsdWUgPSBfQShpbnB1dElkeCk7YCwgJ3ZhbHVlID0gbWluKHZhbHVlLCBfQShpbnB1dElkeCkpOycsICcnXTtcbiAgfTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VNaW4nLCByZWR1Y2VPcCk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlUHJvZDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoKTogc3RyaW5nW10gPT4gWyd2YWx1ZSA9IDEuMDsnLCAndmFsdWUgKj0gX0EoaW5wdXRJZHgpOycsICcnXTtcbiAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VQcm9kJywgcmVkdWNlT3ApO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZUxvZ1N1bTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoKTogc3RyaW5nW10gPT4gWyd2YWx1ZSA9IDAuMDsnLCAndmFsdWUgKz0gX0EoaW5wdXRJZHgpOycsICd2YWx1ZSA9IGxvZyh2YWx1ZSk7J107XG4gIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTG9nU3VtJywgcmVkdWNlT3ApO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZUxvZ1N1bVNxdWFyZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoKTogc3RyaW5nW10gPT4gWydmbG9hdCB0OyB2YWx1ZSA9IDAuMDsnLCAndCA9IF9BKGlucHV0SWR4KTsgdmFsdWUgKz0gdCAqIHQ7JywgJyddO1xuICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZUxvZ1N1bVNxdWFyZScsIHJlZHVjZU9wKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IHJlc2hhcGUgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICBjb25zdCByZXNoYXBlZERpbXMgPSBTaGFwZVV0aWwuY2FsY3VsYXRlUmVzaGFwZWREaW1zKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uaW50ZWdlckRhdGEpO1xuICBpZiAoaGFuZGxlci5zZXNzaW9uLnBhY2spIHtcbiAgICByZXR1cm4gW2hhbmRsZXIucmVzaGFwZVBhY2tlZChpbnB1dHNbMF0sIHJlc2hhcGVkRGltcyldO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbaGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCByZXNoYXBlZERpbXMpXTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVwc2FtcGxlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IG9wc2V0OiBudW1iZXI7XG4gIHJlYWRvbmx5IGlzUmVzaXplOiBib29sZWFuO1xuICByZWFkb25seSBtb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNjYWxlczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGV4dHJhcG9sYXRpb25WYWx1ZTogbnVtYmVyO1xuICByZWFkb25seSBjb29yZGluYXRlVHJhbnNmb3JtTW9kZTogc3RyaW5nO1xuICByZWFkb25seSB1c2VFeHRyYXBvbGF0aW9uOiBib29sZWFuO1xuICByZWFkb25seSBuZWVkUm9pSW5wdXQ6IGJvb2xlYW47XG4gIHJlYWRvbmx5IG5lYXJlc3RNb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGN1YmljQ29lZmZpY2llbnRBOiBudW1iZXI7XG4gIHJlYWRvbmx5IGV4Y2x1ZGVPdXRzaWRlOiBib29sZWFuO1xuICByZWFkb25seSB1c2VOZWFyZXN0MnhPcHRpbWl6YXRpb246IGJvb2xlYW47XG4gIHJlYWRvbmx5IHJvaUlucHV0SWR4OiBudW1iZXI7XG4gIHJlYWRvbmx5IHNjYWxlc0lucHV0SWR4OiBudW1iZXI7XG4gIHJlYWRvbmx5IHNpemVzSW5wdXRJZHg6IG51bWJlcjtcbn1cblxuY29uc3QgdXBzYW1wbGVQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdVcHNhbXBsZScsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHVwc2FtcGxlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi51cHNhbXBsZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlVXBzYW1wbGVQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWNzogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDcpO1xuXG5leHBvcnQgY29uc3QgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWOTogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID0gKFxuICBub2RlOiBHcmFwaC5Ob2RlLFxuKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDkpO1xuXG5leHBvcnQgY29uc3QgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMgPSAobm9kZTogR3JhcGguTm9kZSwgb3BzZXQ6IG51bWJlcik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGlzUmVzaXplID0gb3BzZXQgPj0gMTA7XG5cbiAgLy8gcHJvY2Vzc2luZyBub2RlIGF0dHJpYnV0ZXNcbiAgY29uc3QgbW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnbmVhcmVzdCcpO1xuICBpZiAobW9kZSAhPT0gJ25lYXJlc3QnICYmIG1vZGUgIT09ICdsaW5lYXInICYmIChvcHNldCA8IDExIHx8IG1vZGUgIT09ICdjdWJpYycpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgbW9kZTogJHttb2RlfWApO1xuICB9XG5cbiAgbGV0IHNjYWxlczogbnVtYmVyW10gPSBbXTtcbiAgaWYgKG9wc2V0IDwgOSkge1xuICAgIHNjYWxlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdHMoJ3NjYWxlcycpO1xuICAgIHNjYWxlc1ZhbGlkYXRpb24oc2NhbGVzLCBtb2RlLCBpc1Jlc2l6ZSk7XG4gIH1cblxuICBjb25zdCBleHRyYXBvbGF0aW9uVmFsdWUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2V4dHJhcG9sYXRpb25fdmFsdWUnLCAwLjApO1xuXG4gIGNvbnN0IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID1cbiAgICBvcHNldCA+IDEwID8gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnY29vcmRpbmF0ZV90cmFuc2Zvcm1hdGlvbl9tb2RlJywgJ2hhbGZfcGl4ZWwnKSA6ICdhc3ltbWV0cmljJztcbiAgaWYgKFxuICAgIFtcbiAgICAgICdhc3ltbWV0cmljJyxcbiAgICAgICdweXRvcmNoX2hhbGZfcGl4ZWwnLFxuICAgICAgJ3RmX2hhbGZfcGl4ZWxfZm9yX25uJyxcbiAgICAgICdhbGlnbl9jb3JuZXJzJyxcbiAgICAgICd0Zl9jcm9wX2FuZF9yZXNpemUnLFxuICAgICAgJ2hhbGZfcGl4ZWwnLFxuICAgIF0uaW5kZXhPZihjb29yZGluYXRlVHJhbnNmb3JtTW9kZSkgPT09IC0xXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcihgY29vcmRpbmF0ZV90cmFuc2Zvcm1fbW9kZSAnJHtjb29yZGluYXRlVHJhbnNmb3JtTW9kZX0nIGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgfVxuICBjb25zdCBuZWVkUm9pSW5wdXQgPSBjb29yZGluYXRlVHJhbnNmb3JtTW9kZSA9PT0gJ3RmX2Nyb3BfYW5kX3Jlc2l6ZSc7XG4gIGNvbnN0IHVzZUV4dHJhcG9sYXRpb24gPSBuZWVkUm9pSW5wdXQ7XG5cbiAgY29uc3QgbmVhcmVzdE1vZGUgPVxuICAgIG1vZGUgPT09ICduZWFyZXN0JyAmJiBvcHNldCA+PSAxMSA/IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ25lYXJlc3RfbW9kZScsICdyb3VuZF9wcmVmZXJfZmxvb3InKSA6ICcnO1xuICBpZiAoWydyb3VuZF9wcmVmZXJfZmxvb3InLCAncm91bmRfcHJlZmVyX2NlaWwnLCAnZmxvb3InLCAnY2VpbCcsICcnXS5pbmRleE9mKG5lYXJlc3RNb2RlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG5lYXJlc3RfbW9kZSAnJHtuZWFyZXN0TW9kZX0nIGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgfVxuXG4gIGNvbnN0IGN1YmljQ29lZmZpY2llbnRBID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdjdWJpY19jb2VmZl9hJywgLTAuNzUpO1xuICBjb25zdCBleGNsdWRlT3V0c2lkZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2V4Y2x1ZGVfb3V0c2lkZScsIDApICE9PSAwO1xuICBpZiAoZXhjbHVkZU91dHNpZGUgJiYgbW9kZSAhPT0gJ2N1YmljJykge1xuICAgIHRocm93IG5ldyBFcnJvcignZXhjbHVkZV9vdXRzaWRlIGNhbiBiZSBzZXQgdG8gMSBvbmx5IHdoZW4gbW9kZSBpcyBDVUJJQy4nKTtcbiAgfVxuXG4gIGNvbnN0IHVzZU5lYXJlc3QyeE9wdGltaXphdGlvbiA9XG4gICAgb3BzZXQgPCAxMSA/IHRydWUgOiBtb2RlID09PSAnbmVhcmVzdCcgJiYgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPT09ICdhc3ltbWV0cmljJyAmJiBuZWFyZXN0TW9kZSA9PT0gJ2Zsb29yJztcblxuICBsZXQgcm9pSW5wdXRJZHggPSAwO1xuICBsZXQgc2NhbGVzSW5wdXRJZHggPSAwO1xuICBsZXQgc2l6ZXNJbnB1dElkeCA9IDA7XG5cbiAgaWYgKG9wc2V0ID4gMTApIHtcbiAgICAvLyBoYW5kbGUgd2hlbiByb2lJbnB1dCBpcyBub3QgZ2l2ZW5cbiAgICBpZiAobm9kZS5pbnB1dHMubGVuZ3RoID4gMikge1xuICAgICAgcm9pSW5wdXRJZHggPSAxO1xuICAgICAgc2NhbGVzSW5wdXRJZHggPSAyO1xuICAgICAgc2l6ZXNJbnB1dElkeCA9IDM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlc0lucHV0SWR4ID0gMTtcbiAgICAgIHNpemVzSW5wdXRJZHggPSAyO1xuICAgIH1cbiAgfSBlbHNlIGlmIChvcHNldCA9PT0gOSkge1xuICAgIHNjYWxlc0lucHV0SWR4ID0gMTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIG9wc2V0LFxuICAgIGlzUmVzaXplLFxuICAgIG1vZGUsXG4gICAgc2NhbGVzLFxuICAgIGV4dHJhcG9sYXRpb25WYWx1ZSxcbiAgICBjb29yZGluYXRlVHJhbnNmb3JtTW9kZSxcbiAgICB1c2VFeHRyYXBvbGF0aW9uLFxuICAgIG5lZWRSb2lJbnB1dCxcbiAgICBuZWFyZXN0TW9kZSxcbiAgICBjdWJpY0NvZWZmaWNpZW50QSxcbiAgICBleGNsdWRlT3V0c2lkZSxcbiAgICB1c2VOZWFyZXN0MnhPcHRpbWl6YXRpb24sXG4gICAgcm9pSW5wdXRJZHgsXG4gICAgc2NhbGVzSW5wdXRJZHgsXG4gICAgc2l6ZXNJbnB1dElkeCxcbiAgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVVcHNhbXBsZVByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBbaW5wdXRXaWR0aCwgaW5wdXRIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgaW5wdXRzWzBdLmRpbXMsXG4gICAgVGV4dHVyZVR5cGUudW5wYWNrZWQsXG4gICk7XG5cbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5tYXAoKGRpbSwgaSkgPT4gTWF0aC5mbG9vcihkaW0gKiBhdHRyaWJ1dGVzLnNjYWxlc1tpXSkpO1xuICBjb25zdCBbb3V0cHV0V2lkdGgsIG91dHB1dEhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBvdXRwdXRTaGFwZSxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgKTtcbiAgY29uc3QgZGltID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gIGNvbnN0IG91dHB1dFBpdGNoZXMgPSBuZXcgQXJyYXk8bnVtYmVyPihkaW0pO1xuICBjb25zdCBpbnB1dFBpdGNoZXMgPSBuZXcgQXJyYXk8bnVtYmVyPihkaW0pO1xuICBsZXQgcHJlY2FsY3VsYXRlZFBpdGNoZXMgPSBgXG4gICAgICBpbnQgb3V0cHV0X3BpdGNoZXNbJHtkaW19XTtcbiAgICAgIGludCBpbnB1dF9waXRjaGVzWyR7ZGltfV07XG4gICAgICBgO1xuICBmb3IgKGxldCBkID0gZGltIC0gMTsgZCA+PSAwOyBkLS0pIHtcbiAgICBvdXRwdXRQaXRjaGVzW2RdID0gZCA9PT0gZGltIC0gMSA/IDEgOiBvdXRwdXRQaXRjaGVzW2QgKyAxXSAqIG91dHB1dFNoYXBlW2QgKyAxXTtcbiAgICBpbnB1dFBpdGNoZXNbZF0gPSBkID09PSBkaW0gLSAxID8gMSA6IGlucHV0UGl0Y2hlc1tkICsgMV0gKiBpbnB1dHNbMF0uZGltc1tkICsgMV07XG5cbiAgICBwcmVjYWxjdWxhdGVkUGl0Y2hlcyArPSBgXG4gICAgICAgIG91dHB1dF9waXRjaGVzWyR7ZH1dID0gJHtvdXRwdXRQaXRjaGVzW2RdfTtcbiAgICAgICAgaW5wdXRfcGl0Y2hlc1ske2R9XSA9ICR7aW5wdXRQaXRjaGVzW2RdfTtcbiAgICAgICAgYDtcbiAgfVxuICBjb25zdCBnZXRJbnB1dEZsb2F0RnVuY3Rpb24gPSBgXG4gICAgICBmbG9hdCBnZXRJbnB1dEZsb2F0KGludCBpbmRleCkge1xuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKGluZGV4LCAke2lucHV0V2lkdGh9LCAke2lucHV0SGVpZ2h0fSk7XG4gICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KFgsIGNvb3JkcykpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBgO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9XG4gICAgYXR0cmlidXRlcy5tb2RlID09PSAnbmVhcmVzdCdcbiAgICAgID8gLy8gbmVhcmVzdFxuICAgICAgICBgXG4gICAgJHtnZXRJbnB1dEZsb2F0RnVuY3Rpb259XG4gICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske2RpbX1dKSB7XG4gICAgICBpbnQgaW5wdXRfaW5kZXggPSAwO1xuICAgICAgaW50IG91dHB1dF9pbmRleCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHtvdXRwdXRXaWR0aH0sICR7b3V0cHV0SGVpZ2h0fSk7XG5cbiAgICAgICR7cHJlY2FsY3VsYXRlZFBpdGNoZXN9XG5cbiAgICAgIGludCBkLCBtO1xuICAgICAgZm9yIChpbnQgZGltID0gMDsgZGltIDwgJHtkaW19OyArK2RpbSkge1xuICAgICAgICBkID0gb3V0cHV0X2luZGV4IC8gb3V0cHV0X3BpdGNoZXNbZGltXTtcbiAgICAgICAgbSA9IG91dHB1dF9pbmRleCAtIGQgKiBvdXRwdXRfcGl0Y2hlc1tkaW1dO1xuICAgICAgICBvdXRwdXRfaW5kZXggPSBtO1xuXG4gICAgICAgIGlmIChzY2FsZXNbZGltXSAhPSAxICYmIGQgPiAwKSB7XG4gICAgICAgICAgaW50IGQyID0gZCAvIHNjYWxlc1tkaW1dO1xuICAgICAgICAgIG0gPSBkIC0gZDIgKiBzY2FsZXNbZGltXTtcbiAgICAgICAgICBkID0gZDI7XG4gICAgICAgIH1cbiAgICAgICAgaW5wdXRfaW5kZXggKz0gaW5wdXRfcGl0Y2hlc1tkaW1dICogZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXgpO1xuICAgIH1gXG4gICAgICA6IGRpbSA9PT0gNFxuICAgICAgICA/IC8vIGJpbGluZWFyIDREXG4gICAgICAgICAgYFxuICAgICR7Z2V0SW5wdXRGbG9hdEZ1bmN0aW9ufVxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbNF0pIHtcbiAgICAgIGludCBpbnB1dF9pbmRleCA9IDA7XG4gICAgICBpbnQgb3V0cHV0X2luZGV4ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke291dHB1dFdpZHRofSwgJHtvdXRwdXRIZWlnaHR9KTtcblxuICAgICAgJHtwcmVjYWxjdWxhdGVkUGl0Y2hlc31cblxuICAgICAgaW50IG07XG4gICAgICBpbnQgaW5kZXhfb2ZfZGltMCwgaW5kZXhfb2ZfZGltMSwgaW5kZXhfb2ZfZGltMiwgaW5kZXhfb2ZfZGltMztcbiAgICAgIGluZGV4X29mX2RpbTAgPSBvdXRwdXRfaW5kZXggLyBvdXRwdXRfcGl0Y2hlc1swXTtcbiAgICAgIG0gPSBvdXRwdXRfaW5kZXggLSBpbmRleF9vZl9kaW0wICogb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBpbmRleF9vZl9kaW0xID0gbSAvIG91dHB1dF9waXRjaGVzWzFdO1xuICAgICAgbSA9IG0gLSBpbmRleF9vZl9kaW0xICogb3V0cHV0X3BpdGNoZXNbMV07XG4gICAgICBpbmRleF9vZl9kaW0yID0gbSAvIG91dHB1dF9waXRjaGVzWzJdO1xuICAgICAgbSA9IG0gLSBpbmRleF9vZl9kaW0yICogb3V0cHV0X3BpdGNoZXNbMl07XG4gICAgICBpbmRleF9vZl9kaW0zID0gbTtcblxuICAgICAgaW50IGluZGV4X29mX2lucHV0X2RpbTIsIGluZGV4X29mX2lucHV0X2RpbTMsIHhfb2Zmc2V0LCB5X29mZnNldDtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTIgPSBpbmRleF9vZl9kaW0yIC8gc2NhbGVzWzJdO1xuICAgICAgeV9vZmZzZXQgPSBpbmRleF9vZl9kaW0yIC0gaW5kZXhfb2ZfaW5wdXRfZGltMiAqIHNjYWxlc1syXTtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTMgPSBpbmRleF9vZl9kaW0zIC8gc2NhbGVzWzNdO1xuICAgICAgeF9vZmZzZXQgPSBpbmRleF9vZl9kaW0zIC0gaW5kZXhfb2ZfaW5wdXRfZGltMyAqIHNjYWxlc1szXTtcblxuICAgICAgaW5wdXRfaW5kZXggPSBpbmRleF9vZl9kaW0wICogaW5wdXRfcGl0Y2hlc1swXSArXG4gICAgICAgICAgICBpbmRleF9vZl9kaW0xICogaW5wdXRfcGl0Y2hlc1sxXSArXG4gICAgICAgICAgICBpbmRleF9vZl9pbnB1dF9kaW0yICogaW5wdXRfcGl0Y2hlc1syXSArXG4gICAgICAgICAgICBpbmRleF9vZl9pbnB1dF9kaW0zO1xuXG4gICAgICBmbG9hdCB4MDAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4KTtcbiAgICAgIGZsb2F0IHgxMCwgeDAxLCB4MTE7XG5cbiAgICAgIGJvb2wgZW5kX29mX2RpbTIgPSBmYWxzZTtcbiAgICAgIGlmIChpbmRleF9vZl9pbnB1dF9kaW0yID09ICgke2lucHV0c1swXS5kaW1zWzJdfSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gMlxuICAgICAgICB4MDEgPSB4MDA7XG4gICAgICAgIGVuZF9vZl9kaW0yID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHgwMSA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzJdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTMgPT0gKGlucHV0X3BpdGNoZXNbMl0gLSAxKSkge1xuICAgICAgICAvLyBJdCdzIHRoZSBlbmQgaW4gZGltZW5zaW9uIDNcbiAgICAgICAgeDEwID0geDAwO1xuICAgICAgICB4MTEgPSB4MDE7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgeDEwID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIDEpO1xuICAgICAgICB4MTEgPSBlbmRfb2ZfZGltMiA/IHgxMCA6IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzJdICsgMSk7XG4gICAgICB9XG5cbiAgICAgIGZsb2F0IHkwID0geDAwICsgZmxvYXQoeV9vZmZzZXQpICogKHgwMSAtIHgwMCkgLyBmbG9hdChzY2FsZXNbMl0pO1xuICAgICAgZmxvYXQgeTEgPSB4MTAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDExIC0geDEwKSAvIGZsb2F0KHNjYWxlc1syXSk7XG4gICAgICByZXR1cm4geTAgKyBmbG9hdCh4X29mZnNldCkgKiAoeTEgLSB5MCkgLyBmbG9hdChzY2FsZXNbM10pO1xuICAgIH1gXG4gICAgICAgIDogLy8gYmlsaW5lYXIgMkRcbiAgICAgICAgICBgXG4gICAgJHtnZXRJbnB1dEZsb2F0RnVuY3Rpb259XG4gICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1syXSkge1xuICAgICAgaW50IGlucHV0X2luZGV4ID0gMDtcbiAgICAgIGludCBvdXRwdXRfaW5kZXggPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7b3V0cHV0V2lkdGh9LCAke291dHB1dEhlaWdodH0pO1xuXG4gICAgICAke3ByZWNhbGN1bGF0ZWRQaXRjaGVzfVxuXG4gICAgICBpbnQgbTtcbiAgICAgIGludCBpbmRleF9vZl9kaW0wLCBpbmRleF9vZl9kaW0xO1xuICAgICAgaW5kZXhfb2ZfZGltMCA9IG91dHB1dF9pbmRleCAvIG91dHB1dF9waXRjaGVzWzBdO1xuICAgICAgbSA9IG91dHB1dF9pbmRleCAtIGluZGV4X29mX2RpbTAgKiBvdXRwdXRfcGl0Y2hlc1swXTtcbiAgICAgIGluZGV4X29mX2RpbTEgPSBtO1xuXG4gICAgICBpbnQgaW5kZXhfb2ZfaW5wdXRfZGltMCwgaW5kZXhfb2ZfaW5wdXRfZGltMSwgeF9vZmZzZXQsIHlfb2Zmc2V0O1xuICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMCA9IGluZGV4X29mX2RpbTAgLyBzY2FsZXNbMF07XG4gICAgICB5X29mZnNldCA9IGluZGV4X29mX2RpbTAgLSBpbmRleF9vZl9pbnB1dF9kaW0wICogc2NhbGVzWzBdO1xuICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMSA9IGluZGV4X29mX2RpbTEgLyBzY2FsZXNbMV07XG4gICAgICB4X29mZnNldCA9IGluZGV4X29mX2RpbTEgLSBpbmRleF9vZl9pbnB1dF9kaW0xICogc2NhbGVzWzFdO1xuXG4gICAgICBpbnB1dF9pbmRleCA9IGluZGV4X29mX2lucHV0X2RpbTAgKiBpbnB1dF9waXRjaGVzWzBdICsgaW5kZXhfb2ZfaW5wdXRfZGltMTtcblxuICAgICAgZmxvYXQgeDAwID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCk7XG4gICAgICBmbG9hdCB4MTAsIHgwMSwgeDExO1xuXG4gICAgICBib29sIGVuZF9vZl9kaW0wID0gZmFsc2U7XG4gICAgICBpZiAoaW5kZXhfb2ZfaW5wdXRfZGltMCA9PSAoJHtpbnB1dHNbMF0uZGltc1swXX0gLSAxKSkge1xuICAgICAgICAvLyBJdCdzIHRoZSBlbmQgaW4gZGltZW5zaW9uIDBcbiAgICAgICAgeDAxID0geDAwO1xuICAgICAgICBlbmRfb2ZfZGltMCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4MDEgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgaW5wdXRfcGl0Y2hlc1swXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbmRleF9vZl9pbnB1dF9kaW0xID09IChpbnB1dF9waXRjaGVzWzBdIC0gMSkpIHtcbiAgICAgICAgLy8gSXQncyB0aGUgZW5kIGluIGRpbWVuc2lvbiAxXG4gICAgICAgIHgxMCA9IHgwMDtcbiAgICAgICAgeDExID0geDAxO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHgxMCA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyAxKTtcbiAgICAgICAgeDExID0gZW5kX29mX2RpbTAgPyB4MTAgOiBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgaW5wdXRfcGl0Y2hlc1swXSArIDEpO1xuICAgICAgfVxuXG4gICAgICBmbG9hdCB5MCA9IHgwMCArIGZsb2F0KHlfb2Zmc2V0KSAqICh4MDEgLSB4MDApIC8gZmxvYXQoc2NhbGVzWzBdKTtcbiAgICAgIGZsb2F0IHkxID0geDEwICsgZmxvYXQoeV9vZmZzZXQpICogKHgxMSAtIHgxMCkgLyBmbG9hdChzY2FsZXNbMF0pO1xuICAgICAgcmV0dXJuIHkwICsgZmxvYXQoeF9vZmZzZXQpICogKHkxIC0geTApIC8gZmxvYXQoc2NhbGVzWzFdKTtcbiAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi51cHNhbXBsZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gICAgdmFyaWFibGVzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdzY2FsZXMnLFxuICAgICAgICB0eXBlOiAnaW50JyxcbiAgICAgICAgYXJyYXlMZW5ndGg6IGF0dHJpYnV0ZXMuc2NhbGVzLmxlbmd0aCxcbiAgICAgICAgZGF0YTogYXR0cmlidXRlcy5zY2FsZXMubWFwKCh4KSA9PiBNYXRoLmNlaWwoeCkpLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZTogVXBzYW1wbGVBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmIChcbiAgICAhaW5wdXRzIHx8XG4gICAgKGF0dHJpYnV0ZS5vcHNldCA8IDkgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMSkgfHxcbiAgICAoYXR0cmlidXRlLm9wc2V0ID49IDkgJiYgYXR0cmlidXRlLm9wc2V0IDwgMTEgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMikgfHxcbiAgICAoYXR0cmlidXRlLm9wc2V0ID49IDExICYmIGlucHV0cy5sZW5ndGggPCAyKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKGF0dHJpYnV0ZS5zY2FsZXMubGVuZ3RoID4gMCAmJiBpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IGF0dHJpYnV0ZS5zY2FsZXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0ZW5zb3IgdHlwZXMuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzY2FsZXNWYWxpZGF0aW9uID0gKHNjYWxlczogbnVtYmVyW10sIG1vZGU6IHN0cmluZywgaXNSZXNpemU6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgaWYgKCFpc1Jlc2l6ZSkge1xuICAgIGZvciAoY29uc3Qgc2NhbGUgb2Ygc2NhbGVzKSB7XG4gICAgICBpZiAoc2NhbGUgPCAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU2NhbGUgdmFsdWUgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxLicpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGNvbnN0IHNjYWxlIG9mIHNjYWxlcykge1xuICAgICAgaWYgKHNjYWxlIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTY2FsZSB2YWx1ZSBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAuJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChtb2RlID09PSAnbGluZWFyJyB8fCBtb2RlID09PSAnY3ViaWMnKSB7XG4gICAgaWYgKHNjYWxlcy5sZW5ndGggIT09IDIgJiYgKHNjYWxlcy5sZW5ndGggIT09IDQgfHwgc2NhbGVzWzBdICE9PSAxIHx8IHNjYWxlc1sxXSAhPT0gMSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJ0xpbmVhcicgbW9kZSBhbmQgJ0N1YmljJyBtb2RlIG9ubHkgc3VwcG9ydCAyLUQgaW5wdXRzICgnQmlsaW5lYXInLCAnQmljdWJpYycpIFxcXG4gICAgICAgIG9yIDQtRCBpbnB1dHMgd2l0aCB0aGUgY29ycmVzcG9uZGluZyBvdXRlcm1vc3QgMiBzY2FsZSB2YWx1ZXMgYmVpbmcgMSBcXFxuICAgICAgICBpbiB0aGUgJHtpc1Jlc2l6ZSA/ICdSZXNpemUnIDogJ1Vwc2FtcGxlJ30gb3BlYXJ0b3IuYCk7XG4gICAgfVxuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7IE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb24gfSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRDb29yZHNEYXRhVHlwZSB9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHsgdW5wYWNrRnJvbUNoYW5uZWwgfSBmcm9tICcuL3BhY2tpbmctdXRpbHMnO1xuaW1wb3J0IHsgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMsIHNjYWxlc1ZhbGlkYXRpb24sIFVwc2FtcGxlQXR0cmlidXRlcywgdmFsaWRhdGVJbnB1dHMgfSBmcm9tICcuL3Vwc2FtcGxlJztcblxuY29uc3QgcmVzaXplUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnUmVzaXplJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHJlc2l6ZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4ucmVzaXplUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVQYWNrZWRSZXNpemVQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjEwOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4gcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMobm9kZSwgMTApO1xuXG5leHBvcnQgY29uc3QgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjExOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4gcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMobm9kZSwgMTEpO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRSZXNpemVQcm9ncmFtSW5mbyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgW3NjYWxlcywgb3V0cHV0U2hhcGVdID0gcHJlcGFyZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpO1xuXG4gIGNvbnN0IGlzU2FtZSA9IHNjYWxlcy5ldmVyeSgoczogbnVtYmVyKSA9PiBzID09PSAxKSAmJiBhdHRyaWJ1dGVzLmNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlICE9PSAndGZfY3JvcF9hbmRfcmVzaXplJztcbiAgaWYgKGlzU2FtZSkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5yZXNpemVQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkIH0sXG4gICAgICBoYXNNYWluOiB0cnVlLFxuICAgICAgc2hhZGVyU291cmNlOiBgdm9pZCBtYWluKCkge1xuICAgICAgICAgICAgICAgICAgICB2ZWM0IHYgPSAke2dsc2wudGV4dHVyZTJEfShYLCBUZXhDb29yZHMpO1xuICAgICAgICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHY7XG4gICAgICAgICAgICAgICAgfWAsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IGRpbSA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgaWYgKGRpbSA8IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dCBkaW1lbnNpb24gc2hvdWxkIGJlIGF0IGxlYXN0IDIsIGJ1dCBnb3QgJHtkaW19YCk7XG4gIH1cblxuICBjb25zdCBvdXRwdXRIZWlnaHQgPSBvdXRwdXRTaGFwZVtkaW0gLSAyXTtcbiAgY29uc3Qgb3V0cHV0V2lkdGggPSBvdXRwdXRTaGFwZVtkaW0gLSAxXTtcblxuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGlmIChkaW0gIT09IGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXQgZGltZW5zaW9uIHNob3VsZCBtYXRjaCBpbnB1dCAke2lucHV0U2hhcGUubGVuZ3RofSwgYnV0IGdvdCAke2RpbX1gKTtcbiAgfVxuICBjb25zdCBpbnB1dEhlaWdodCA9IGlucHV0U2hhcGVbZGltIC0gMl07XG4gIGNvbnN0IGlucHV0V2lkdGggPSBpbnB1dFNoYXBlW2RpbSAtIDFdO1xuXG4gIGNvbnN0IHNjYWxlc0hlaWdodCA9IHNjYWxlc1tkaW0gLSAyXTtcbiAgY29uc3Qgc2NhbGVzV2lkdGggPSBzY2FsZXNbZGltIC0gMV07XG5cbiAgbGV0IGdldFNvdXJjZUZyYWNJbmRleCA9ICcnO1xuXG4gIGlmIChhdHRyaWJ1dGVzLm1vZGUgIT09ICdsaW5lYXInKSB7XG4gICAgLy8gVE9ETzogc3VwcG9ydCBvdGhlciBtb2Rlc1xuICAgIHRocm93IG5ldyBFcnJvcihgcmVzaXplIChwYWNrZWQpIGRvZXMgbm90IHN1cHBvcnQgbW9kZTogJyR7YXR0cmlidXRlcy5tb2RlfSdgKTtcbiAgfVxuICBzd2l0Y2ggKGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUpIHtcbiAgICBjYXNlICdhc3ltbWV0cmljJzpcbiAgICAgIGdldFNvdXJjZUZyYWNJbmRleCA9IGBcbiAgICAgICAgICAgICAgICAgICAgdmVjNCBnZXRTb3VyY2VGcmFjSW5kZXgoaXZlYzQgY29vcmRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmVjNChjb29yZHMpIC8gc2NhbGVXSFdIO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2hhbGZfcGl4ZWwnOlxuICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAodmVjNChjb29yZHMpICsgMC41KSAvIHNjYWxlV0hXSCAtIDAuNTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGA7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdweXRvcmNoX2hhbGZfcGl4ZWwnOlxuICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQgZmNvb3JkcyA9IHZlYzQoY29vcmRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0V2lkdGh9LjAgPiAxLjAgPyAoZmNvb3Jkcy54ICsgMC41KSAvIHNjYWxlV0hXSC54IC0gMC41IDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0SGVpZ2h0fS4wID4gMS4wID8gKGZjb29yZHMueSArIDAuNSkgLyBzY2FsZVdIV0gueSAtIDAuNSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke291dHB1dFdpZHRofS4wID4gMS4wID8gKGZjb29yZHMueiArIDAuNSkgLyBzY2FsZVdIV0gueiAtIDAuNSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke291dHB1dEhlaWdodH0uMCA+IDEuMCA/IChmY29vcmRzLncgKyAwLjUpIC8gc2NhbGVXSFdILncgLSAwLjUgOiAwLjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGA7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdhbGlnbl9jb3JuZXJzJzpcbiAgICAgIGdldFNvdXJjZUZyYWNJbmRleCA9IGBcbiAgICAgICAgICAgICAgICAgICAgdmVjNCBnZXRTb3VyY2VGcmFjSW5kZXgoaXZlYzQgY29vcmRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWM0IHJlc2l6ZWQgPSB2ZWM0KCR7b3V0cHV0V2lkdGh9LjAgLSAxLjAsICR7b3V0cHV0SGVpZ2h0fS4wIC0gMS4wLCAke291dHB1dFdpZHRofS4wIC0gMS4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0SGVpZ2h0fS4wIC0gMS4wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQgb3JpZ2luYWwgPSB2ZWM0KCR7aW5wdXRXaWR0aH0uMCAtIDEuMCwgJHtpbnB1dEhlaWdodH0uMCAtIDEuMCwgJHtpbnB1dFdpZHRofS4wIC0gMS4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7aW5wdXRIZWlnaHR9LjAgLSAxLjApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCBuZXdfc2NhbGUgPSBvcmlnaW5hbCAvIHJlc2l6ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmVjNChjb29yZHMpICogbmV3X3NjYWxlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBUT0RPOnN1cHBvcnRpbmcgb3RoZXIgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGVzXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlc2l6ZSAocGFja2VkKSBkb2VzIG5vdCBzdXBwb3J0IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlOiBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnJHthdHRyaWJ1dGVzLmNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlfSdgKTtcbiAgfVxuXG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUoZGltKTtcbiAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgICAgIGNvbnN0IHZlYzIgaW5wdXRXSCA9IHZlYzIoJHtpbnB1dEhlaWdodH0uMCwgJHtpbnB1dFdpZHRofS4wKTtcbiAgICAgICAgICAgIGNvbnN0IHZlYzQgc2NhbGVXSFdIID0gdmVjNChmbG9hdCgke3NjYWxlc0hlaWdodH0pLCBmbG9hdCgke3NjYWxlc1dpZHRofSksIGZsb2F0KCR7c2NhbGVzSGVpZ2h0fSksIGZsb2F0KCR7XG4gICAgICAgICAgICAgIHNjYWxlc1dpZHRoXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAke3VucGFja0NoYW5uZWx9XG4gICAgICAgICAgICAke2dldFNvdXJjZUZyYWNJbmRleH1cbiAgICAgICAgICAgIGZsb2F0IGdldEFWYWx1ZShpbnQgeDEwLCBpbnQgciwgaW50IGMsIGludCBkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoZ2V0QSh4MTAsIHIsIGMsIGQpLCB2ZWMyKGMsIGQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAgICAgICAke2Nvb3Jkc0RhdGFUeXBlfSByYyA9IGdldE91dHB1dENvb3JkcygpO1xuXG4gICAgICAgICAgICAgICAgaW50IGJhdGNoID0gcmNbMF07XG4gICAgICAgICAgICAgICAgaW50IGRlcHRoID0gcmNbMV07XG5cbiAgICAgICAgICAgICAgICAvLyByZXRyaWV2ZSB0aGUgNCBjb29yZGluYXRlcyB0aGF0IGlzIHVzZWQgaW4gdGhlIDQgcGFja2VkIG91dHB1dCB2YWx1ZXMuXG4gICAgICAgICAgICAgICAgaXZlYzQgY29vcmRzID0gaXZlYzQocmMud3osIHJjLncgKyAxLCByYy56ICsgMSk7XG5cbiAgICAgICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIHNvdXJjZSBpbmRleCBpbiBmcmFjdGlvblxuICAgICAgICAgICAgICAgIHZlYzQgc291cmNlRnJhYyA9IGdldFNvdXJjZUZyYWNJbmRleChjb29yZHMpO1xuXG4gICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBsb3dlciBhbmQgdXBwZXIgYm91bmQgb2YgdGhlIDQgdmFsdWVzIHRoYXQgd2lsbCBiZSBwYWNrZWQgaW50byBvbmUgdGV4ZWwuXG4gICAgICAgICAgICAgICAgaXZlYzQgeDAwID0gaXZlYzQobWF4KHNvdXJjZUZyYWMueHksIHZlYzIoMC4wKSksIG1pbihpbnB1dFdIIC0gMS4wLCBjZWlsKHNvdXJjZUZyYWMueHkpKSk7XG4gICAgICAgICAgICAgICAgaXZlYzQgeDAxID0gaXZlYzQobWF4KHNvdXJjZUZyYWMueHcsIHZlYzIoMC4wKSksIG1pbihpbnB1dFdIIC0gMS4wLCBjZWlsKHNvdXJjZUZyYWMueHcpKSk7XG4gICAgICAgICAgICAgICAgaXZlYzQgeDEwID0gaXZlYzQobWF4KHNvdXJjZUZyYWMuenksIHZlYzIoMC4wKSksIG1pbihpbnB1dFdIIC0gMS4wLCBjZWlsKHNvdXJjZUZyYWMuenkpKSk7XG4gICAgICAgICAgICAgICAgaXZlYzQgeDExID0gaXZlYzQobWF4KHNvdXJjZUZyYWMuencsIHZlYzIoMC4wKSksIG1pbihpbnB1dFdIIC0gMS4wLCBjZWlsKHNvdXJjZUZyYWMuencpKSk7XG5cbiAgICAgICAgICAgICAgICBib29sIGhhc05leHRSb3cgPSByYy53IDwgJHtvdXRwdXRIZWlnaHQgLSAxfTtcbiAgICAgICAgICAgICAgICBib29sIGhhc05leHRDb2wgPSByYy56IDwgJHtvdXRwdXRXaWR0aCAtIDF9O1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyB0b3AtbGVmdCBjb3JuZXIgaW50byBvbmUgdmVjNCBzdHJ1Y3R1cmVcbiAgICAgICAgICAgICAgICB2ZWM0IHRvcExlZnQgPSB2ZWM0KFxuICAgICAgICAgICAgICAgICAgICBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDAueCwgeDAwLnkpLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Q29sID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAxLngsIHgwMS55KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMC54LCB4MTAueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIChoYXNOZXh0Um93ICYmIGhhc05leHRDb2wpID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDExLngsIHgxMS55KSA6IDAuMCk7XG5cbiAgICAgICAgICAgICAgICAvLyBwYWNrIHgwMCwgeDAxLCB4MTAsIHgxMSdzIHRvcC1yaWdodCBjb3JuZXIgaW50byBvbmUgdmVjNCBzdHJ1Y3R1cmVcbiAgICAgICAgICAgICAgICB2ZWM0IHRvcFJpZ2h0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLngsIHgwMC53KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS54LCB4MDEudykgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueCwgeDEwLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS54LCB4MTEudykgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyBib3R0b20tbGVmdCBjb3JuZXIgaW50byBvbmUgdmVjNCBzdHJ1Y3R1cmVcbiAgICAgICAgICAgICAgICB2ZWM0IGJvdHRvbUxlZnQgPSB2ZWM0KFxuICAgICAgICAgICAgICAgICAgICBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDAueiwgeDAwLnkpLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Q29sID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAxLnosIHgwMS55KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dFJvdyA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMC56LCB4MTAueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIChoYXNOZXh0Um93ICYmIGhhc05leHRDb2wpID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDExLnosIHgxMS55KSA6IDAuMCk7XG5cbiAgICAgICAgICAgICAgICAvLyBwYWNrIHgwMCwgeDAxLCB4MTAsIHgxMSdzIGJvdHRvbS1yaWdodCBjb3JuZXIgaW50byBvbmUgdmVjNCBzdHJ1Y3R1cmVcbiAgICAgICAgICAgICAgICB2ZWM0IGJvdHRvbVJpZ2h0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLnosIHgwMC53KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS56LCB4MDEudykgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueiwgeDEwLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS56LCB4MTEudykgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBpbnRlcnBvbGF0aW9uIGZyYWN0aW9uIG9uIHUgYW5kIHYgZGlyZWN0aW9uXG4gICAgICAgICAgICAgICAgdmVjNCBmcmFjID0gdmVjNChzb3VyY2VGcmFjKSAtIGZsb29yKHNvdXJjZUZyYWMpO1xuICAgICAgICAgICAgICAgIHZlYzQgY2xhbXBGcmFjID0gY2xhbXAoZnJhYywgdmVjNCgwLjApLCB2ZWM0KDEuMCkpO1xuXG4gICAgICAgICAgICAgICAgdmVjNCB0b3AgPSBtaXgodG9wTGVmdCwgdG9wUmlnaHQsIGNsYW1wRnJhYy55d3l3KTtcbiAgICAgICAgICAgICAgICB2ZWM0IGJvdHRvbSA9IG1peChib3R0b21MZWZ0LCBib3R0b21SaWdodCwgY2xhbXBGcmFjLnl3eXcpO1xuICAgICAgICAgICAgICAgIHZlYzQgbmV3VmFsdWUgPSBtaXgodG9wLCBib3R0b20sIGNsYW1wRnJhYy54eHp6KTtcblxuICAgICAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNChuZXdWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ucmVzaXplUHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWQgfSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHByZXBhcmVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzKTogW3JlYWRvbmx5IG51bWJlcltdLCByZWFkb25seSBudW1iZXJbXV0gPT4ge1xuICBjb25zdCB4ID0gaW5wdXRzWzBdO1xuICBjb25zdCB4RGltcyA9IHguZGltcztcblxuICBsZXQgc2NhbGVzID0gYXR0cmlidXRlcy5zY2FsZXM7XG4gIGxldCBvdXRwdXRTaXplczogbnVtYmVyW10gfCB1bmRlZmluZWQ7XG4gIGlmIChzY2FsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgY29uc3Qgc2NhbGVzVGVuc29yID0gaW5wdXRzW2F0dHJpYnV0ZXMuc2NhbGVzSW5wdXRJZHhdO1xuICAgIGlmIChzY2FsZXNUZW5zb3IgJiYgc2NhbGVzVGVuc29yLnNpemUgIT09IDApIHtcbiAgICAgIGlmIChpbnB1dHNbYXR0cmlidXRlcy5zaXplc0lucHV0SWR4XSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ09ubHkgb25lIG9mIHNjYWxlcyBvciBzaXplcyBtdXN0IGJlIHByb3ZpZGVkIGFzIGlucHV0LicpO1xuICAgICAgfVxuICAgICAgc2NhbGVzID0gcGFyc2VTY2FsZXNEYXRhKHNjYWxlc1RlbnNvciwgYXR0cmlidXRlcy5tb2RlLCBhdHRyaWJ1dGVzLmlzUmVzaXplKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc2l6ZXNUZW5zb3IgPSBpbnB1dHNbYXR0cmlidXRlcy5zaXplc0lucHV0SWR4XTtcbiAgICAgIGlmICghc2l6ZXNUZW5zb3IgfHwgc2l6ZXNUZW5zb3Iuc2l6ZSA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciBzY2FsZXMgb3Igc2l6ZXMgTVVTVCBiZSBwcm92aWRlZCBhcyBpbnB1dC4nKTtcbiAgICAgIH1cblxuICAgICAgb3V0cHV0U2l6ZXMgPSBBcnJheS5mcm9tKHNpemVzVGVuc29yLmludGVnZXJEYXRhKTtcbiAgICAgIHNjYWxlcyA9IHBhcnNlU2NhbGVzRGF0YUZyb21PdXRwdXRTaXplKG91dHB1dFNpemVzLCB4RGltcywgYXR0cmlidXRlcy5tb2RlLCBhdHRyaWJ1dGVzLmlzUmVzaXplKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGlucHV0c1thdHRyaWJ1dGVzLnNpemVzSW5wdXRJZHhdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09ubHkgb25lIG9mIHNjYWxlcyBvciBzaXplcyBtdXN0IGJlIHByb3ZpZGVkIGFzIGlucHV0LicpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHlEaW1zID0gb3V0cHV0U2l6ZXMgfHwgeERpbXMubWFwKChkaW0sIGkpID0+IE1hdGguZmxvb3IoZGltICogc2NhbGVzW2ldKSk7XG5cbiAgcmV0dXJuIFtzY2FsZXMsIHlEaW1zXTtcbn07XG5cbmNvbnN0IHBhcnNlU2NhbGVzRGF0YSA9IChzY2FsZTogVGVuc29yLCBtb2RlOiBzdHJpbmcsIGlzUmVzaXplOiBib29sZWFuKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCBzY2FsZXMgPSBBcnJheS5mcm9tKHNjYWxlLmZsb2F0RGF0YSk7XG4gIHNjYWxlc1ZhbGlkYXRpb24oc2NhbGVzLCBtb2RlLCBpc1Jlc2l6ZSk7XG4gIHJldHVybiBzY2FsZXM7XG59O1xuXG5jb25zdCBwYXJzZVNjYWxlc0RhdGFGcm9tT3V0cHV0U2l6ZSA9IChcbiAgeURpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICB4RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG1vZGU6IHN0cmluZyxcbiAgaXNSZXNpemU6IGJvb2xlYW4sXG4pOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IGxlbmd0aCA9IHhEaW1zLmxlbmd0aDtcbiAgY29uc3Qgc2NhbGVzID0gbmV3IEFycmF5PG51bWJlcj4obGVuZ3RoKTtcblxuICBmb3IgKGxldCBpID0gMCwgZW5kID0gbGVuZ3RoOyBpIDwgZW5kOyBpKyspIHtcbiAgICBpZiAoeERpbXNbaV0gPT09IDApIHtcbiAgICAgIGlmICh5RGltc1tpXSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGRpbSBpcyB6ZXJvIGJ1dCByZXF1aXJlZCBvdXRwdXQgZGltIGlzIG5vbi16ZXJvLicpO1xuICAgICAgfVxuICAgICAgc2NhbGVzW2ldID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NhbGVzW2ldID0geURpbXNbaV0gLyB4RGltc1tpXTtcbiAgICB9XG4gIH1cbiAgc2NhbGVzVmFsaWRhdGlvbihzY2FsZXMsIG1vZGUsIGlzUmVzaXplKTtcbiAgcmV0dXJuIHNjYWxlcztcbn07XG5cbi8vIHJvaSBkYXRhIGlzIG5vdCB1c2VkIHlldC4gYnV0IGxlYXZlIGhlcmUgZm9yIGZ1dHVyZSB1c2FnZS5cbi8vIGNvbnN0IGdldFJvaSA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMpIDogbnVtYmVyW10gPT4ge1xuLy8gICAgIGxldCByb2k6IG51bWJlcltdID0gW107XG4vLyAgICAgaWYgKGF0dHJpYnV0ZXMubmVlZFJvaUlucHV0KSB7XG4vLyAgICAgICAgIGlmIChhdHRyaWJ1dGVzLnJvaUlucHV0SWR4IDw9IDApIHtcbi8vICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCByb2kgaW5wdXQgaW5kZXguJyk7XG4vLyAgICAgICAgIH1cbi8vICAgICAgICAgY29uc3Qgcm9pVGVuc29yID0gaW5wdXRzW2F0dHJpYnV0ZXMucm9pSW5wdXRJZHhdO1xuLy8gICAgICAgICByb2kgPSByb2lUZW5zb3Iuc2l6ZSA+IDAgPyBBcnJheS5mcm9tKHJvaVRlbnNvci5mbG9hdERhdGEpIDogW107XG4vLyAgICAgfSBlbHNlIHtcbi8vICAgICAgICAgcm9pID0gbmV3IEFycmF5KGlucHV0c1swXS5kaW1zLmxlbmd0aCAqIDIpLmZpbGwoMCk7XG4vLyAgICAgfVxuLy8gICAgIHJldHVybiByb2k7XG4vLyB9O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3Qgc2hhcGUgPSAoX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgcmV0dXJuIFtuZXcgVGVuc29yKFtpbnB1dHNbMF0uZGltcy5sZW5ndGhdLCAnaW50MzInLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgbmV3IEludDMyQXJyYXkoaW5wdXRzWzBdLmRpbXMpKV07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgTlVNQkVSX1RZUEVTLCBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBTbGljZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGVzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZW5kczogbnVtYmVyW107XG4gIHJlYWRvbmx5IHN0YXJ0czogbnVtYmVyW107XG59XG5cbmNvbnN0IHNsaWNlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU2xpY2UnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBzbGljZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxTbGljZUF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFNsaWNlQXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAge1xuICAgICAgLi4uc2xpY2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICBnZXQ6ICgpID0+IGNyZWF0ZVNsaWNlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzKSxcbiAgICB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU2xpY2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFNsaWNlQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IFNsaWNlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IHN0YXJ0cyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzdGFydHMnKTtcbiAgY29uc3QgZW5kcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdlbmRzJyk7XG4gIGNvbnN0IGF4ZXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnYXhlcycsIFtdKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHN0YXJ0cywgZW5kcywgYXhlcyB9KTtcbn07XG5cbmNvbnN0IGNyZWF0ZVNsaWNlUHJvZ3JhbUluZm8gPSAoXG4gIF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGF0dHJpYnV0ZXM6IFNsaWNlQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgYXhlcyA9IGF0dHJpYnV0ZXMuYXhlcy5sZW5ndGggPT09IDAgPyBpbnB1dC5kaW1zLnNsaWNlKDApLm1hcCgoX3ZhbCwgaSkgPT4gaSkgOiBhdHRyaWJ1dGVzLmF4ZXM7XG4gIGNvbnN0IG5vcm1hbGl6ZWRBeGVzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4ZXMoYXhlcywgaW5wdXQuZGltcy5sZW5ndGgpO1xuICBjb25zdCBzdGFydHMgPSBhdHRyaWJ1dGVzLnN0YXJ0cy5tYXAoKHN0YXJ0LCBpKSA9PiB7XG4gICAgaWYgKHN0YXJ0ID4gaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV0gLSAxKSB7XG4gICAgICByZXR1cm4gaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV07XG4gICAgfVxuICAgIHJldHVybiBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhzdGFydCwgaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV0pO1xuICB9KTtcbiAgY29uc3QgZW5kcyA9IGF0dHJpYnV0ZXMuZW5kcy5tYXAoKGVuZCwgaSkgPT4ge1xuICAgIGlmIChlbmQgPiBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSAtIDEpIHtcbiAgICAgIHJldHVybiBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXTtcbiAgICB9XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGVuZCwgaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV0pO1xuICB9KTtcblxuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0LmRpbXMuc2xpY2UoKTtcblxuICBjb25zdCBzbGljZU9wczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBub3JtYWxpemVkQXhlcy5sZW5ndGg7IGkrKykge1xuICAgIG91dHB1dFNoYXBlW25vcm1hbGl6ZWRBeGVzW2ldXSA9IGVuZHNbaV0gLSBzdGFydHNbaV07XG4gICAgaWYgKHN0YXJ0c1tpXSA+IDApIHtcbiAgICAgIHNsaWNlT3BzLnB1c2goYG91dHB1dElkeFske25vcm1hbGl6ZWRBeGVzW2ldfV0gKz0gJHtzdGFydHNbaV19O2ApO1xuICAgIH0gLy8gZWxzZSB7IHNsaWNlT3BzLnB1c2goYG91dHB1dElkeFske25vcm1hbGl6ZWRBeGVzW2ldfV0gKz0gMDtgKTsgfVxuICB9XG5cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgb3V0cHV0SWR4WyR7cmFua31dKSB7XG4gICAgICAgICR7c2xpY2VPcHMuam9pbignXFxuICAgICAgJyl9XG4gICAgICAgIHJldHVybiBfQShvdXRwdXRJZHgpO1xuICAgICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4uc2xpY2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NsaWNlIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKE5VTUJFUl9UWVBFUy5pbmRleE9mKGlucHV0c1swXS50eXBlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHNsaWNlVjEwID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMTAoaW5wdXRzKTtcbiAgY29uc3QgYXR0cmlidXRlcyA9IGdlbmVyYXRlU2xpY2VBdHRyaWJ1dGVzRnJvbUlucHV0cyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICB7XG4gICAgICAuLi5zbGljZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGdldDogKCkgPT4gY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGF0dHJpYnV0ZXMpLFxuICAgIH0sXG4gICAgW2lucHV0c1swXV0sXG4gICk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IGdlbmVyYXRlU2xpY2VBdHRyaWJ1dGVzRnJvbUlucHV0cyA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuKTogU2xpY2VBdHRyaWJ1dGVzID0+IHtcbiAgaWYgKFxuICAgICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMV0uZGF0YUlkKSB8fFxuICAgICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMl0uZGF0YUlkKSB8fFxuICAgIChpbnB1dHMubGVuZ3RoID49IDQgJiYgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1szXS5kYXRhSWQpKSB8fFxuICAgIChpbnB1dHMubGVuZ3RoID49IDUgJiYgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1s0XS5kYXRhSWQpKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2R5bmFtaWMgc2xpY2UgYXR0cmlidXRlcyBhcmUgbm90IGFsbG93ZWQnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHMubGVuZ3RoID49IDUgJiYgaW5wdXRzWzRdLmludGVnZXJEYXRhLnNvbWUoKGk6IG51bWJlcikgPT4gaSAhPT0gMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBub24tMSBzdGVwcyBpcyBub3Qgc3VwcG9ydGVkIGZvciBTbGljZScpO1xuICB9XG5cbiAgY29uc3Qgc3RhcnRzID0gQXJyYXkuZnJvbShpbnB1dHNbMV0uaW50ZWdlckRhdGEpO1xuICBjb25zdCBlbmRzID0gQXJyYXkuZnJvbShpbnB1dHNbMl0uaW50ZWdlckRhdGEpO1xuICBjb25zdCBheGVzID0gaW5wdXRzLmxlbmd0aCA+PSA0ID8gQXJyYXkuZnJvbShpbnB1dHNbM10uaW50ZWdlckRhdGEpIDogW107XG4gIGNvbnN0IGNhY2hlS2V5ID0gYCR7YXhlc307JHtzdGFydHN9OyR7ZW5kc31gO1xuICByZXR1cm4geyBzdGFydHMsIGVuZHMsIGF4ZXMsIGNhY2hlS2V5IH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YxMCA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAzIHx8IGlucHV0cy5sZW5ndGggPiA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IG51bWJlci4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1syXS50eXBlICE9PSAnaW50MzInIHx8IGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID49IDQgJiYgKGlucHV0c1szXS50eXBlICE9PSAnaW50MzInIHx8IGlucHV0c1szXS5kaW1zLmxlbmd0aCAhPT0gMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSA1ICYmIChpbnB1dHNbNF0udHlwZSAhPT0gJ2ludDMyJyB8fCBpbnB1dHNbNF0uZGltcy5sZW5ndGggIT09IDEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyB0cmFuc3Bvc2UsIFRyYW5zcG9zZUF0dHJpYnV0ZXMgfSBmcm9tICcuL3RyYW5zcG9zZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU29mdG1heEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG59XG5cbmNvbnN0IHNvZnRtYXhDb21wdXRlTWF4UHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU29mdG1heENvbXB1dGVNYXgnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmNvbnN0IHNvZnRtYXhDb21wdXRlU2NhbGVQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTb2Z0bWF4Q29tcHV0ZVNjYWxlJyxcbiAgaW5wdXROYW1lczogWydBJywgJ01heCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmNvbnN0IHNvZnRtYXhQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTb2Z0TWF4JyxcbiAgaW5wdXROYW1lczogWydBJywgJ01heCcsICdOb3JtJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBzb2Z0bWF4OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNvZnRtYXhBdHRyaWJ1dGVzPiA9IChcbiAgaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBhdHRyaWJ1dGVzOiBTb2Z0bWF4QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBsb2dpY2FsUm93Q291bnQgPSBTaGFwZVV0aWwuc2l6ZVRvRGltZW5zaW9uKGlucHV0U2hhcGUsIGF4aXMpO1xuICBjb25zdCBmZWF0dXJlQ291bnQgPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXRTaGFwZSwgYXhpcyk7XG5cbiAgY29uc3Qgb3V0cHV0ID0gY29tcHV0ZVNvZnRtYXgoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCBsb2dpY2FsUm93Q291bnQsIGZlYXR1cmVDb3VudCk7XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTb2Z0bWF4QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxTb2Z0bWF4QXR0cmlidXRlcz4gPSAoXG4gIG5vZGU6IEdyYXBoLk5vZGUsXG4pOiBTb2Z0bWF4QXR0cmlidXRlcyA9PiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJywgMSkgfSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzVjEzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFNvZnRtYXhBdHRyaWJ1dGVzPiA9IChcbiAgbm9kZTogR3JhcGguTm9kZSxcbik6IFNvZnRtYXhBdHRyaWJ1dGVzID0+IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXM6IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAtMSkgfSk7XG5cbi8vIFRoZSBcInNlbWFudGljXCIgbWVhbmluZyBvZiBheGlzIGhhcyBjaGFuZ2VkIGluIG9wc2V0LTEzLlxuLy8gUGxlYXNlIGNvbXBhcmU6IGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvT3BlcmF0b3JzLm1kI1NvZnRtYXhcbi8vIHdpdGggaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9DaGFuZ2Vsb2cubWQjU29mdG1heC0xMSBmb3IgZGV0YWlsZWQgZXhwbGFuYXRpb25zXG4vLyBUbyBhY2NvdW50IGZvciB0aGUgb3BzZXQtMTMgYmVoYXZpb3IsIG91ciBwbGFuIHdpbGwgYmUgdG8gdHJhbnNwb3NlIHRoZSBcImF4aXNcIiBkaW0gdG8gdGhlIGlubmVybW9zdCBkaW1cbi8vIGFuZCBwZXJmb3JtIHNvZnRtYXggYW5kIHRoZW4gcmV2ZXJzZSB0aGUgdHJhbnNwb3NlLiBXZSBjYW4gc2tpcCB0aGUgdHJhbnNwb3NpbmcgYXNwZWN0IGlmIHRoZSBheGlzIGlzIGFscmVhZHlcbi8vIHRoZSBpbm5lcm1vc3QgZGltXG5leHBvcnQgY29uc3Qgc29mdG1heFYxMzogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxTb2Z0bWF4QXR0cmlidXRlcz4gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogU29mdG1heEF0dHJpYnV0ZXMsXG4pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgcmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuXG4gIGNvbnN0IGlzVHJhbnNwb3NlUmVxdWlyZWQgPSBheGlzICE9PSByYW5rIC0gMSA/IHRydWUgOiBmYWxzZTtcbiAgY29uc3QgdHJhbnNwb3NlZElucHV0U2hhcGU6IG51bWJlcltdID0gW107XG4gIGxldCBwZXJtOiBudW1iZXJbXSA9IFtdO1xuICBsZXQgdHJhbnNwb3NlZElucHV0czogVGVuc29yW10gPSBbXTtcbiAgbGV0IHRyYW5zcG9zZUF0dHJpYnV0ZTogVHJhbnNwb3NlQXR0cmlidXRlcztcblxuICBpZiAoaXNUcmFuc3Bvc2VSZXF1aXJlZCkge1xuICAgIHBlcm0gPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiByYW5rIH0pLm1hcCgoXywgaSkgPT4gaSk7XG5cbiAgICAvLyBzd2FwIHRoZSBpbm5lcm1vc3QgZGltIHdpdGggdGhlIGRpbSBjb3JyZXNwb25kaW5nIHRvIGF4aXNcbiAgICBwZXJtW2F4aXNdID0gcmFuayAtIDE7XG4gICAgcGVybVtyYW5rIC0gMV0gPSBheGlzO1xuXG4gICAgcGVybS5tYXAoKHApID0+IHRyYW5zcG9zZWRJbnB1dFNoYXBlLnB1c2goaW5wdXRTaGFwZVtwXSkpO1xuXG4gICAgdHJhbnNwb3NlQXR0cmlidXRlID0gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgcGVybSB9KTtcbiAgICB0cmFuc3Bvc2VkSW5wdXRzID0gdHJhbnNwb3NlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgdHJhbnNwb3NlQXR0cmlidXRlKTtcbiAgfVxuXG4gIGNvbnN0IGxvZ2ljYWxSb3dDb3VudCA9IGlzVHJhbnNwb3NlUmVxdWlyZWRcbiAgICA/IFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24odHJhbnNwb3NlZElucHV0U2hhcGUsIHJhbmsgLSAxKVxuICAgIDogU2hhcGVVdGlsLnNpemVUb0RpbWVuc2lvbihpbnB1dFNoYXBlLCByYW5rIC0gMSk7XG4gIGNvbnN0IGZlYXR1cmVDb3VudCA9IGlzVHJhbnNwb3NlUmVxdWlyZWRcbiAgICA/IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbih0cmFuc3Bvc2VkSW5wdXRTaGFwZSwgcmFuayAtIDEpXG4gICAgOiBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXRTaGFwZSwgcmFuayAtIDEpO1xuXG4gIGNvbnN0IG91dHB1dCA9IGNvbXB1dGVTb2Z0bWF4KFxuICAgIGluZmVyZW5jZUhhbmRsZXIsXG4gICAgaXNUcmFuc3Bvc2VSZXF1aXJlZCA/IHRyYW5zcG9zZWRJbnB1dHMgOiBpbnB1dHMsXG4gICAgYXR0cmlidXRlcyxcbiAgICBsb2dpY2FsUm93Q291bnQsXG4gICAgZmVhdHVyZUNvdW50LFxuICApO1xuXG4gIGlmIChpc1RyYW5zcG9zZVJlcXVpcmVkKSB7XG4gICAgY29uc3QgcmV2ZXJzZWRPdXRwdXQgPSB0cmFuc3Bvc2UoaW5mZXJlbmNlSGFuZGxlciwgb3V0cHV0LCB0cmFuc3Bvc2VBdHRyaWJ1dGUhKTtcbiAgICByZXR1cm4gcmV2ZXJzZWRPdXRwdXQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxufTtcblxuY29uc3QgY29tcHV0ZVNvZnRtYXggPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgYXR0cmlidXRlczogU29mdG1heEF0dHJpYnV0ZXMsXG4gIGxvZ2ljYWxSb3dDb3VudDogbnVtYmVyLFxuICBmZWF0dXJlQ291bnQ6IG51bWJlcixcbik6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgY29tcHV0ZU1heFByb2dyYW1JbmZvID0gY3JlYXRlQ29tcHV0ZU1heFByb2dyYW1JbmZvKFxuICAgIGluZmVyZW5jZUhhbmRsZXIsXG4gICAgaW5wdXRzWzBdLFxuICAgIGxvZ2ljYWxSb3dDb3VudCxcbiAgICBmZWF0dXJlQ291bnQsXG4gICAgW2xvZ2ljYWxSb3dDb3VudF0sXG4gICk7XG4gIGNvbnN0IG1heCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4uc29mdG1heENvbXB1dGVNYXhQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBjb21wdXRlTWF4UHJvZ3JhbUluZm8gfSxcbiAgICBpbnB1dHMsXG4gICk7XG5cbiAgY29uc3QgY29tcHV0ZVNjYWxlUHJvZ3JhbUluZm8gPSBjcmVhdGVDb21wdXRTY2FsZVByb2dyYW1JbmZvKFxuICAgIGluZmVyZW5jZUhhbmRsZXIsXG4gICAgaW5wdXRzWzBdLFxuICAgIGxvZ2ljYWxSb3dDb3VudCxcbiAgICBmZWF0dXJlQ291bnQsXG4gICAgY29tcHV0ZU1heFByb2dyYW1JbmZvLm91dHB1dC5kaW1zLFxuICAgIFtsb2dpY2FsUm93Q291bnRdLFxuICApO1xuICBjb25zdCBzY2FsZSA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4uc29mdG1heENvbXB1dGVTY2FsZVByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBnZXQ6ICgpID0+IGNvbXB1dGVTY2FsZVByb2dyYW1JbmZvIH0sXG4gICAgW2lucHV0c1swXSwgbWF4XSxcbiAgKTtcblxuICBjb25zdCBzb2Z0TWF4UHJvZ3JhbUluZm8gPSBjcmVhdGVTb2Z0TWF4UHJvZ3JhbUluZm8oXG4gICAgaW5mZXJlbmNlSGFuZGxlcixcbiAgICBpbnB1dHNbMF0sXG4gICAgbG9naWNhbFJvd0NvdW50LFxuICAgIGZlYXR1cmVDb3VudCxcbiAgICBjb21wdXRlTWF4UHJvZ3JhbUluZm8ub3V0cHV0LmRpbXMsXG4gICAgY29tcHV0ZVNjYWxlUHJvZ3JhbUluZm8ub3V0cHV0LmRpbXMsXG4gICk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4uc29mdG1heFByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBnZXQ6ICgpID0+IHNvZnRNYXhQcm9ncmFtSW5mbyB9LFxuICAgIFtpbnB1dHNbMF0sIG1heCwgc2NhbGVdLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIHRleHR1cmUgdGhhdCBjb250YWlucyB0aGUgbWF4aW11bSB2YWx1ZSBvZiBlYWNoIG9mIHRoZSAnTicgcm93c1xuICovXG5jb25zdCBjcmVhdGVDb21wdXRlTWF4UHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgbG9naWNhbFJvd0NvdW50OiBudW1iZXIsXG4gIGZlYXR1cmVDb3VudDogbnVtYmVyLFxuICBvdXRwdXRTaGFwZTogbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFt0ZXh0dXJlV2lkdGgsIHRleHR1cmVIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgaW5wdXQuZGltcyxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgKTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICBpZiAobG9naWNhbFJvd0NvdW50IDwgMSB8fCBmZWF0dXJlQ291bnQgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdMb2dpY2FsIHJvdyBjb3VudCBOIGFuZCBmZWF0dXJlIGNvdW50IEQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICB9XG5cbiAgaWYgKG91dHB1dFNoYXBlLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uYWxpdHkgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgMScpO1xuICB9XG5cbiAgaWYgKG91dHB1dFNoYXBlWzBdICE9PSBsb2dpY2FsUm93Q291bnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIG9mIHRoZSBvdXRwdXQgc2hvdWxkIGJlIGVxdWFsIHRvIGxvZ2ljYWwgcm93IGNvdW50Jyk7XG4gIH1cblxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICAgICAgaW50IGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCA9IGluZGljZXNbMF0gKiAke2ZlYXR1cmVDb3VudH07XG5cbiAgICAgICAgZmxvYXQgbWF4ID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIG9mZnNldFRvQ29vcmRzKGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCwgJHt0ZXh0dXJlV2lkdGh9LFxuICAgICAgICAke3RleHR1cmVIZWlnaHR9ICkpKTtcbiAgICAgICAgZm9yKGludCBpPTE7IGk8JHtmZWF0dXJlQ291bnR9OyArK2kpXG4gICAgICAgIHtcbiAgICAgICAgICBmbG9hdCBjdXJyZW50ID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIG9mZnNldFRvQ29vcmRzKGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCArIGksXG4gICAgICAgICAgICAke3RleHR1cmVXaWR0aH0sICR7dGV4dHVyZUhlaWdodH0pKSk7XG4gICAgICAgICAgaWYoY3VycmVudCA+IG1heClcbiAgICAgICAgICBtYXggPSBjdXJyZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnNvZnRtYXhDb21wdXRlTWF4UHJvZ3JhbU1ldGFkYXRhLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYSB0ZXh0dXJlIHRoYXQgY29udGFpbnMgdGhlIG5vcm1hbGl6YXRpb24gZmFjdG9yIGZvciBlYWNoIG9mIHRoZSAnTicgcm93c1xuICovXG5jb25zdCBjcmVhdGVDb21wdXRTY2FsZVByb2dyYW1JbmZvID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGxvZ2ljYWxSb3dDb3VudDogbnVtYmVyLFxuICBmZWF0dXJlQ291bnQ6IG51bWJlcixcbiAgbWF4RWxlbWVudFBlckxvZ2ljYWxSb3c6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IFt0ZXh0dXJlV2lkdGgsIHRleHR1cmVIZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoXG4gICAgaW5wdXQuZGltcyxcbiAgICBUZXh0dXJlVHlwZS51bnBhY2tlZCxcbiAgKTtcbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICBpZiAobG9naWNhbFJvd0NvdW50IDwgMSB8fCBmZWF0dXJlQ291bnQgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdMb2dpY2FsIHJvdyBjb3VudCBOIGFuZCBmZWF0dXJlIGNvdW50IEQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICB9XG5cbiAgaWYgKG91dHB1dFNoYXBlLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uYWxpdHkgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgMScpO1xuICB9XG5cbiAgaWYgKG91dHB1dFNoYXBlWzBdICE9PSBsb2dpY2FsUm93Q291bnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIG9mIHRoZSBvdXRwdXQgc2hvdWxkIGJlIGVxdWFsIHRvIGxvZ2ljYWwgcm93IGNvdW50Jyk7XG4gIH1cblxuICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3cubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgaW50ZXJtZWRpYXRlIHJlc3VsdHMgc2hvdWxkIGJlIDEnKTtcbiAgfVxuXG4gIGlmIChtYXhFbGVtZW50UGVyTG9naWNhbFJvd1swXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSBvZiB0aGUgaW50ZXJtZWRpYXRlIHJlc3VsdHMgc2hvdWxkIGJlIGVxdWFsIHRvIGxvZ2ljYWwgcm93IGNvdW50Jyk7XG4gIH1cblxuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICAgICAgaW50IGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCA9IGluZGljZXNbMF0gKiAke2ZlYXR1cmVDb3VudH07XG5cbiAgICAgICAgZmxvYXQgbm9ybV9mYWN0b3IgPSAwLjA7XG4gICAgICAgIGZsb2F0IG1heCA9IF9NYXgoaW5kaWNlcyk7XG4gICAgICAgIGZvcihpbnQgaT0wOyBpPCR7ZmVhdHVyZUNvdW50fTsgKytpKVxuICAgICAgICB7XG4gICAgICAgICAgbm9ybV9mYWN0b3IgKz0gZXhwKGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBvZmZzZXRUb0Nvb3Jkcyhsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQgKyBpLFxuICAgICAgICAgICAgJHt0ZXh0dXJlV2lkdGh9LCAke3RleHR1cmVIZWlnaHR9KSkpIC0gbWF4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBub3JtX2ZhY3RvcjtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLnNvZnRtYXhDb21wdXRlU2NhbGVQcm9ncmFtTWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7IGRpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVTb2Z0TWF4UHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXQ6IFRlbnNvcixcbiAgbG9naWNhbFJvd0NvdW50OiBudW1iZXIsXG4gIGZlYXR1cmVDb3VudDogbnVtYmVyLFxuICBtYXhFbGVtZW50UGVyTG9naWNhbFJvdzogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG5vcm1hbGl6YXRpb25QZXJMb2dpY2FsUm93OiByZWFkb25seSBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPSBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChcbiAgICBpbnB1dC5kaW1zLFxuICAgIFRleHR1cmVUeXBlLnVucGFja2VkLFxuICApO1xuICBjb25zdCByYW5rID0gaW5wdXQuZGltcy5sZW5ndGg7XG5cbiAgaWYgKGxvZ2ljYWxSb3dDb3VudCA8IDEgfHwgZmVhdHVyZUNvdW50IDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTG9naWNhbCByb3cgY291bnQgTiBhbmQgZmVhdHVyZSBjb3VudCBEIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgfVxuXG4gIGlmIChtYXhFbGVtZW50UGVyTG9naWNhbFJvdy5sZW5ndGggIT09IDEgfHwgbm9ybWFsaXphdGlvblBlckxvZ2ljYWxSb3cubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgaW50ZXJtZWRpYXRlIHJlc3VsdHMgc2hvdWxkIGJlIDEnKTtcbiAgfVxuXG4gIGlmIChtYXhFbGVtZW50UGVyTG9naWNhbFJvd1swXSAhPT0gbG9naWNhbFJvd0NvdW50IHx8IG5vcm1hbGl6YXRpb25QZXJMb2dpY2FsUm93WzBdICE9PSBsb2dpY2FsUm93Q291bnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgfVxuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcblxuICAgICAgLy8gZ2V0IG9mZnNldCBvZiBjdXJyZW50IGxvZ2ljYWwgdGVuc29yIGluZGV4IGZyb20gdGhlIDItRCB0ZXh0dXJlIGNvb3JkaW5hdGVzIChUZXhDb29yZHMpXG4gICAgICBpbnQgb2Zmc2V0ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke3RleHR1cmVXaWR0aH0sICR7dGV4dHVyZUhlaWdodH0pO1xuXG4gICAgICAvL2RldGVybWluZSB0aGUgbG9naWNhbCByb3cgZm9yIHRoaXMgaW5kZXhcbiAgICAgIGludCBsb2dpY2FsX3Jvd19pbmRleFsxXTtcbiAgICAgIGxvZ2ljYWxfcm93X2luZGV4WzBdID0gb2Zmc2V0IC8gJHtmZWF0dXJlQ291bnR9O1xuXG4gICAgICBmbG9hdCBub3JtX2ZhY3RvciA9IF9Ob3JtKGxvZ2ljYWxfcm93X2luZGV4KTtcblxuICAgICAgLy8gYXZvaWQgcG9zc2libGUgZGl2aXNpb24gYnkgMFxuICAgICAgLy8gaWYgbm9ybV9mYWNvciBpcyAwLCBhbGwgZWxlbWVudHMgYXJlIHplcm9cbiAgICAgIC8vIGlmIHNvLCByZXR1cm4gMFxuICAgICAgaWYobm9ybV9mYWN0b3IgPT0gMC4wKVxuICAgICAgICByZXR1cm4gMC4wO1xuXG4gICAgICByZXR1cm4gZXhwKF9BKGluZGljZXMpIC0gX01heChsb2dpY2FsX3Jvd19pbmRleCkpIC8gbm9ybV9mYWN0b3I7XG4gICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4uc29mdG1heFByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTb2Z0bWF4IHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUnKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwsIFNwbGl0VXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNwbGl0QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4aXM6IG51bWJlcjtcbiAgcmVhZG9ubHkgc3BsaXQ6IG51bWJlcltdO1xuICByZWFkb25seSBudW1PdXRwdXRzOiBudW1iZXI7XG59XG5cbmNvbnN0IHNwbGl0UHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU3BsaXQnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBzcGxpdDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxTcGxpdEF0dHJpYnV0ZXM+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF0dHJpYnV0ZXM6IFNwbGl0QXR0cmlidXRlcyxcbik6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXR0cmlidXRlcy5heGlzLCBpbnB1dHNbMF0uZGltcy5sZW5ndGgpO1xuICBjb25zdCBjb3VudCA9IGdldFByb2dyYW1Db3VudChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF4aXMsIGF0dHJpYnV0ZXMpO1xuICBjb25zdCBvdXRwdXQ6IFRlbnNvcltdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7ICsraSkge1xuICAgIG91dHB1dC5wdXNoKFxuICAgICAgaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgIHtcbiAgICAgICAgICAuLi5zcGxpdFByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICBjYWNoZUhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9OyR7aX1gLFxuICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlU3BsaXRQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGF0dHJpYnV0ZXMsIGF4aXMsIGkpLFxuICAgICAgICB9LFxuICAgICAgICBpbnB1dHMsXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU3BsaXRBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFNwbGl0QXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IFNwbGl0QXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF4aXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJywgMCk7XG4gIGNvbnN0IHNwbGl0ID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3NwbGl0JywgW10pO1xuICBjb25zdCBudW1PdXRwdXRzID0gbm9kZS5vdXRwdXRzLmxlbmd0aDtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXMsIHNwbGl0LCBudW1PdXRwdXRzIH0pO1xufTtcblxuY29uc3QgZ2V0UHJvZ3JhbUNvdW50ID0gKFxuICBfaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLFxuICBpbnB1dHM6IFRlbnNvcltdLFxuICBheGlzOiBudW1iZXIsXG4gIGF0dHJpYnV0ZXM6IFNwbGl0QXR0cmlidXRlcyxcbik6IG51bWJlciA9PiB7XG4gIGNvbnN0IFssIG9mZnNldHNdID0gU3BsaXRVdGlsLnNwbGl0U2hhcGUoaW5wdXRzWzBdLmRpbXMsIGF4aXMsIGF0dHJpYnV0ZXMuc3BsaXQsIGF0dHJpYnV0ZXMubnVtT3V0cHV0cyk7XG4gIHJldHVybiBvZmZzZXRzLmxlbmd0aDtcbn07XG5cbmNvbnN0IGNyZWF0ZVNwbGl0UHJvZ3JhbUluZm8gPSAoXG4gIF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0OiBUZW5zb3IsXG4gIGF0dHJpYnV0ZXM6IFNwbGl0QXR0cmlidXRlcyxcbiAgYXhpczogbnVtYmVyLFxuICBpbmRleDogbnVtYmVyLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbc2hhcGVzLCBvZmZzZXRzXSA9IFNwbGl0VXRpbC5zcGxpdFNoYXBlKGlucHV0LmRpbXMsIGF4aXMsIGF0dHJpYnV0ZXMuc3BsaXQsIGF0dHJpYnV0ZXMubnVtT3V0cHV0cyk7XG4gIGNvbnN0IG9mZnNldCA9IG9mZnNldHNbaW5kZXhdO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IHNoYXBlc1tpbmRleF07XG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW5kaWNlc1ske2F4aXN9XSArPSAke29mZnNldH07XG4gICAgICAgIHJldHVybiBfQShpbmRpY2VzKTtcbiAgICAgIH1cbiAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLnNwbGl0UHJvZ3JhbU1ldGFkYXRhLFxuICAgIGNhY2hlSGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX06JHtpbmRleH1gLFxuICAgIG91dHB1dDogeyBkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkIH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTcGxpdCByZXF1aXJlcyBvbmUgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICdpbnQ4JyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAndWludDgnICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICdpbnQxNicgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ3VpbnQxNicgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2ludDMyJyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAndWludDMyJyAmJlxuICAgIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiZcbiAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnICYmXG4gICAgaW5wdXRzWzBdLnR5cGUgIT09ICdib29sJ1xuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9uIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IHNxdWVlemU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248bnVtYmVyW10+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4ZXM6IG51bWJlcltdLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFNoYXBlVXRpbC5zcXVlZXplU2hhcGUoaW5wdXRzWzBdLmRpbXMsIGF4ZXMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIG91dHB1dFNoYXBlKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuZXhwb3J0IGNvbnN0IHNxdWVlemVWMTMgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0c1YxMyhpbnB1dHMpO1xuICByZXR1cm4gc3F1ZWV6ZShpbmZlcmVuY2VIYW5kbGVyLCBbaW5wdXRzWzBdXSwgQXJyYXkuZnJvbShpbnB1dHNbMV0uaW50ZWdlckRhdGEpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNxdWVlemVBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPG51bWJlcltdPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyW10gPT5cbiAgbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnKTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTcXVlZXplIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTcXVlZXplIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBnZXRHbHNsIH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgV2ViR0xJbmZlcmVuY2VIYW5kbGVyIH0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGUgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBzdW0gPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IHN1bVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgICBuYW1lOiAnU3VtJyxcbiAgICBpbnB1dE5hbWVzOiBpbnB1dHMubWFwKChfdiwgaSkgPT4gYFgke2l9YCksXG4gICAgaW5wdXRUeXBlczogbmV3IEFycmF5KGlucHV0cy5sZW5ndGgpLmZpbGwoVGV4dHVyZVR5cGUudW5wYWNrZWQpLFxuICB9O1xuXG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgIHsgLi4uc3VtUHJvZ3JhbU1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVN1bVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgc3VtUHJvZ3JhbU1ldGFkYXRhKSB9LFxuICAgIGlucHV0cyxcbiAgKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgY3JlYXRlU3VtUHJvZ3JhbUluZm8gPSAoXG4gIGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlcixcbiAgaW5wdXRzOiBUZW5zb3JbXSxcbiAgc3VtUHJvZ3JhbU1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBzdW1MaW5lID0gaW5wdXRzLm1hcCgoX3YsIGkpID0+IGAke2dsc2wudGV4dHVyZTJEfShYJHtpfSxUZXhDb29yZHMpYCkuam9pbignICsgJyk7XG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgdmVjNCByZXN1bHQgPSAke3N1bUxpbmV9O1xuICAgICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICAgIH1cbiAgICBgO1xuICByZXR1cm4ge1xuICAgIC4uLnN1bVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3VtIHJlcXVpcmVzIGlucHV0cy4nKTtcbiAgfVxuXG4gIGNvbnN0IGxlbmd0aCA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAobGVuZ3RoICE9PSBpbnB1dHNbaV0uZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgc2hhcGVzIGFyZSBtaXNtYXRjaGVkLicpO1xuICAgIH1cblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuZ3RoOyBqKyspIHtcbiAgICAgIGlmIChpbnB1dHNbMF0uZGltc1tqXSAhPT0gaW5wdXRzW2ldLmRpbXNbal0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBzaGFwZXMgYXJlIG5vdCBtYXRjaGVkLicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzW2ldLnR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgdHlwZXMgYXJlIG5vdCBtYXRjaGVkLicpO1xuICAgIH1cbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgTlVNQkVSX1RZUEVTIH0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IHRpbGUgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gIGNvbnN0IHRpbGVQcm9ncmFtTWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ1RpbGUnLFxuICAgIGlucHV0TmFtZXM6IFsnQSddLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIH07XG5cbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgeyAuLi50aWxlUHJvZ3JhbU1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVRpbGVQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIHRpbGVQcm9ncmFtTWV0YWRhdGEpIH0sXG4gICAgaW5wdXRzLFxuICApO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5jb25zdCBjcmVhdGVUaWxlUHJvZ3JhbUluZm8gPSAoXG4gIF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIHRpbGVQcm9ncmFtTWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gbmV3IEFycmF5KGlucHV0U2hhcGUubGVuZ3RoKTtcblxuICBjb25zdCB0aWxlT3BzOiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0U2hhcGUubGVuZ3RoOyBpKyspIHtcbiAgICBvdXRwdXRTaGFwZVtpXSA9IGlucHV0U2hhcGVbaV0gKiBpbnB1dHNbMV0ubnVtYmVyRGF0YVtpXTtcbiAgICB0aWxlT3BzLnB1c2goYGlucHV0SWR4WyR7aX1dID0gaW50KG1vZChmbG9hdChvdXRwdXRJZHhbJHtpfV0pLCAke2lucHV0U2hhcGVbaV19LikpO2ApO1xuICB9XG5cbiAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgb3V0cHV0SWR4WyR7cmFua31dKSB7XG4gICAgICAgIGludCBpbnB1dElkeFske3Jhbmt9XTtcbiAgICAgICAgJHt0aWxlT3BzLmpvaW4oJ1xcbicpfVxuICAgICAgICByZXR1cm4gX0EoaW5wdXRJZHgpO1xuICAgICAgfVxuICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4udGlsZVByb2dyYW1NZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHsgZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWQgfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RpbGUgcmVxdWlyZXMgMiBpbnB1dC4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgc2Vjb25kIGlucHV0IHNoYXBlIG11c3QgMSBkaW1lbnNpb24uJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS5kaW1zWzBdICE9PSBpbnB1dHNbMF0uZGltcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKE5VTUJFUl9UWVBFUy5pbmRleE9mKGlucHV0c1swXS50eXBlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicgJiYgaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQxNicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcmVwZWF0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbiB9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCB1bnNxdWVlemU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248bnVtYmVyW10+ID0gKFxuICBpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsXG4gIGlucHV0czogVGVuc29yW10sXG4gIGF4ZXM6IG51bWJlcltdLFxuKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFNoYXBlVXRpbC51bnNxdWVlemVTaGFwZShpbnB1dHNbMF0uZGltcywgYXhlcyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgb3V0cHV0U2hhcGUpO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5leHBvcnQgY29uc3QgdW5zcXVlZXplVjEzID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMTMoaW5wdXRzKTtcbiAgcmV0dXJuIHVuc3F1ZWV6ZShpbmZlcmVuY2VIYW5kbGVyLCBbaW5wdXRzWzBdXSwgQXJyYXkuZnJvbShpbnB1dHNbMV0uaW50ZWdlckRhdGEpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVuc3F1ZWV6ZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyW10+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBudW1iZXJbXSA9PlxuICBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnYXhlcycpO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3F1ZWV6ZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCB0ZW5zb3IgdHlwZXMuJyk7XG4gIH1cbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjEzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5zcXVlZXplIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IE9wU2V0IH0gZnJvbSAnLi4vLi4vb3BzZXQnO1xuXG5pbXBvcnQgeyBiYXRjaE5vcm1hbGl6YXRpb24sIHBhcnNlQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2JhdGNoLW5vcm1hbGl6YXRpb24nO1xuaW1wb3J0ICogYXMgYmluYXJ5T3BzIGZyb20gJy4vb3BzL2JpbmFyeS1vcCc7XG5pbXBvcnQgeyBjYXN0LCBwYXJzZUNhc3RBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvY2FzdCc7XG5pbXBvcnQgeyBjb25jYXQsIHBhcnNlQ29uY2F0QXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2NvbmNhdCc7XG5pbXBvcnQgeyBjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvY29udic7XG5pbXBvcnQgeyBjb252VHJhbnNwb3NlLCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvY29udi10cmFuc3Bvc2UnO1xuaW1wb3J0IHsgZGVwdGhUb1NwYWNlLCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9kZXB0aC10by1zcGFjZSc7XG5pbXBvcnQgeyBmbGF0dGVuLCBwYXJzZUZsYXR0ZW5BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZmxhdHRlbic7XG5pbXBvcnQgeyBnYXRoZXIsIHBhcnNlR2F0aGVyQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2dhdGhlcic7XG5pbXBvcnQgeyBnZW1tLCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjExLCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjcgfSBmcm9tICcuL29wcy9nZW1tJztcbmltcG9ydCB7IGltYWdlU2NhbGVyLCBwYXJzZUltYWdlU2NhbGVyQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2ltYWdlLXNjYWxlcic7XG5pbXBvcnQgeyBpbnN0YW5jZU5vcm1hbGl6YXRpb24sIHBhcnNlSW5zdGFuY2VOb3JtYWxpemF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2luc3RhbmNlLW5vcm1hbGl6YXRpb24nO1xuaW1wb3J0IHsgbHJuLCBwYXJzZUxybkF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9scm4nO1xuaW1wb3J0IHsgbWF0TXVsLCBwYXJzZU1hdE11bEF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9tYXRtdWwnO1xuaW1wb3J0IHsgcGFkVjExLCBwYWRWMiwgcGFyc2VQYWRBdHRyaWJ1dGVzVjExLCBwYXJzZVBhZEF0dHJpYnV0ZXNWMiB9IGZyb20gJy4vb3BzL3BhZCc7XG5pbXBvcnQge1xuICBhdmVyYWdlUG9vbCxcbiAgZ2xvYmFsQXZlcmFnZVBvb2wsXG4gIGdsb2JhbE1heFBvb2wsXG4gIG1heFBvb2wsXG4gIHBhcnNlQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLFxuICBwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbiAgcGFyc2VNYXhQb29sQXR0cmlidXRlcyxcbn0gZnJvbSAnLi9vcHMvcG9vbCc7XG5pbXBvcnQge1xuICBwYXJzZVJlZHVjZUF0dHJpYnV0ZXMsXG4gIHJlZHVjZUxvZ1N1bSxcbiAgcmVkdWNlTG9nU3VtU3F1YXJlLFxuICByZWR1Y2VNYXgsXG4gIHJlZHVjZU1lYW4sXG4gIHJlZHVjZU1pbixcbiAgcmVkdWNlUHJvZCxcbiAgcmVkdWNlU3VtLFxufSBmcm9tICcuL29wcy9yZWR1Y2UnO1xuaW1wb3J0IHsgcmVzaGFwZSB9IGZyb20gJy4vb3BzL3Jlc2hhcGUnO1xuaW1wb3J0IHsgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjEwLCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTEsIHJlc2l6ZSB9IGZyb20gJy4vb3BzL3Jlc2l6ZS1wYWNrZWQnO1xuaW1wb3J0IHsgc2hhcGUgfSBmcm9tICcuL29wcy9zaGFwZSc7XG5pbXBvcnQgeyBwYXJzZVNsaWNlQXR0cmlidXRlcywgc2xpY2UsIHNsaWNlVjEwIH0gZnJvbSAnLi9vcHMvc2xpY2UnO1xuaW1wb3J0IHsgcGFyc2VTb2Z0bWF4QXR0cmlidXRlcywgcGFyc2VTb2Z0bWF4QXR0cmlidXRlc1YxMywgc29mdG1heCwgc29mdG1heFYxMyB9IGZyb20gJy4vb3BzL3NvZnRtYXgnO1xuaW1wb3J0IHsgcGFyc2VTcGxpdEF0dHJpYnV0ZXMsIHNwbGl0IH0gZnJvbSAnLi9vcHMvc3BsaXQnO1xuaW1wb3J0IHsgcGFyc2VTcXVlZXplQXR0cmlidXRlcywgc3F1ZWV6ZSwgc3F1ZWV6ZVYxMyB9IGZyb20gJy4vb3BzL3NxdWVlemUnO1xuaW1wb3J0IHsgc3VtIH0gZnJvbSAnLi9vcHMvc3VtJztcbmltcG9ydCB7IHRpbGUgfSBmcm9tICcuL29wcy90aWxlJztcbmltcG9ydCB7IHBhcnNlVHJhbnNwb3NlQXR0cmlidXRlcywgdHJhbnNwb3NlIH0gZnJvbSAnLi9vcHMvdHJhbnNwb3NlJztcbmltcG9ydCAqIGFzIHVuYXJ5T3BzIGZyb20gJy4vb3BzL3VuYXJ5LW9wJztcbmltcG9ydCB7IHBhcnNlVW5zcXVlZXplQXR0cmlidXRlcywgdW5zcXVlZXplLCB1bnNxdWVlemVWMTMgfSBmcm9tICcuL29wcy91bnNxdWVlemUnO1xuaW1wb3J0IHsgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWNywgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWOSwgdXBzYW1wbGUgfSBmcm9tICcuL29wcy91cHNhbXBsZSc7XG5cbmV4cG9ydCBjb25zdCBXRUJHTF9PUF9SRVNPTFZFX1JVTEVTOiByZWFkb25seSBPcFNldC5SZXNvbHZlUnVsZVtdID0gW1xuICBbJ0FicycsICcnLCAnNisnLCB1bmFyeU9wcy5hYnNdLFxuICBbJ0Fjb3MnLCAnJywgJzcrJywgdW5hcnlPcHMuYWNvc10sXG4gIFsnQWRkJywgJycsICc3KycsIGJpbmFyeU9wcy5hZGRdLFxuICBbJ0FuZCcsICcnLCAnNysnLCBiaW5hcnlPcHMuYW5kXSxcbiAgWydBc2luJywgJycsICc3KycsIHVuYXJ5T3BzLmFzaW5dLFxuICBbJ0F0YW4nLCAnJywgJzcrJywgdW5hcnlPcHMuYXRhbl0sXG4gIC8vIFRPRE86IHN1cHBvcnQgbmV3IGF0dHJpYnV0ZXMgZm9yIEF2ZXJhZ2VQb29sLTEwXG4gIFsnQXZlcmFnZVBvb2wnLCAnJywgJzcrJywgYXZlcmFnZVBvb2wsIHBhcnNlQXZlcmFnZVBvb2xBdHRyaWJ1dGVzXSxcbiAgWydCYXRjaE5vcm1hbGl6YXRpb24nLCAnJywgJzcrJywgYmF0Y2hOb3JtYWxpemF0aW9uLCBwYXJzZUJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXNdLFxuICBbJ0Nhc3QnLCAnJywgJzYrJywgY2FzdCwgcGFyc2VDYXN0QXR0cmlidXRlc10sXG4gIFsnQ2VpbCcsICcnLCAnNisnLCB1bmFyeU9wcy5jZWlsXSxcbiAgWydDbGlwJywgJycsICc2LTEwJywgdW5hcnlPcHMuY2xpcCwgdW5hcnlPcHMucGFyc2VDbGlwQXR0cmlidXRlc10sXG4gIFsnQ2xpcCcsICcnLCAnMTErJywgdW5hcnlPcHMuY2xpcFYxMV0sXG4gIFsnQ29uY2F0JywgJycsICc0KycsIGNvbmNhdCwgcGFyc2VDb25jYXRBdHRyaWJ1dGVzXSxcbiAgWydDb252JywgJycsICcxKycsIGNvbnYsIHBhcnNlQ29udkF0dHJpYnV0ZXNdLFxuICBbJ0NvbnZUcmFuc3Bvc2UnLCAnJywgJzErJywgY29udlRyYW5zcG9zZSwgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlc10sXG4gIFsnQ29zJywgJycsICc3KycsIHVuYXJ5T3BzLmNvc10sXG4gIFsnRGl2JywgJycsICc3KycsIGJpbmFyeU9wcy5kaXZdLFxuICBbJ0Ryb3BvdXQnLCAnJywgJzcrJywgdW5hcnlPcHMuaWRlbnRpdHldLFxuICBbJ0RlcHRoVG9TcGFjZScsICcnLCAnMSsnLCBkZXB0aFRvU3BhY2UsIHBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlc10sXG4gIFsnRXF1YWwnLCAnJywgJzcrJywgYmluYXJ5T3BzLmVxdWFsXSxcbiAgWydFbHUnLCAnJywgJzYrJywgdW5hcnlPcHMuZWx1LCB1bmFyeU9wcy5wYXJzZUVsdUF0dHJpYnV0ZXNdLFxuICBbJ0V4cCcsICcnLCAnNisnLCB1bmFyeU9wcy5leHBdLFxuICBbJ0ZsYXR0ZW4nLCAnJywgJzErJywgZmxhdHRlbiwgcGFyc2VGbGF0dGVuQXR0cmlidXRlc10sXG4gIFsnRmxvb3InLCAnJywgJzYrJywgdW5hcnlPcHMuZmxvb3JdLFxuICBbJ0Z1c2VkQ29udicsICdjb20ubWljcm9zb2Z0JywgJzErJywgY29udiwgcGFyc2VDb252QXR0cmlidXRlc10sXG4gIFsnR2F0aGVyJywgJycsICcxKycsIGdhdGhlciwgcGFyc2VHYXRoZXJBdHRyaWJ1dGVzXSxcbiAgWydHZW1tJywgJycsICc3LTEwJywgZ2VtbSwgcGFyc2VHZW1tQXR0cmlidXRlc1Y3XSxcbiAgWydHZW1tJywgJycsICcxMSsnLCBnZW1tLCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjExXSxcbiAgWydHbG9iYWxBdmVyYWdlUG9vbCcsICcnLCAnMSsnLCBnbG9iYWxBdmVyYWdlUG9vbCwgcGFyc2VHbG9iYWxBdmVyYWdlUG9vbEF0dHJpYnV0ZXNdLFxuICBbJ0dsb2JhbE1heFBvb2wnLCAnJywgJzErJywgZ2xvYmFsTWF4UG9vbF0sXG4gIFsnR3JlYXRlcicsICcnLCAnNysnLCBiaW5hcnlPcHMuZ3JlYXRlcl0sXG4gIFsnSWRlbnRpdHknLCAnJywgJzErJywgdW5hcnlPcHMuaWRlbnRpdHldLFxuICBbJ0ltYWdlU2NhbGVyJywgJycsICcxKycsIGltYWdlU2NhbGVyLCBwYXJzZUltYWdlU2NhbGVyQXR0cmlidXRlc10sXG4gIFsnSW5zdGFuY2VOb3JtYWxpemF0aW9uJywgJycsICc2KycsIGluc3RhbmNlTm9ybWFsaXphdGlvbiwgcGFyc2VJbnN0YW5jZU5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzXSxcbiAgWydMZWFreVJlbHUnLCAnJywgJzYrJywgdW5hcnlPcHMubGVha3lSZWx1LCB1bmFyeU9wcy5wYXJzZUxlYWt5UmVsdUF0dHJpYnV0ZXNdLFxuICBbJ0xlc3MnLCAnJywgJzcrJywgYmluYXJ5T3BzLmxlc3NdLFxuICBbJ0xSTicsICcnLCAnMSsnLCBscm4sIHBhcnNlTHJuQXR0cmlidXRlc10sXG4gIFsnTG9nJywgJycsICc2KycsIHVuYXJ5T3BzLmxvZ10sXG4gIFsnTWF0TXVsJywgJycsICcxKycsIG1hdE11bCwgcGFyc2VNYXRNdWxBdHRyaWJ1dGVzXSxcbiAgLy8gVE9ETzogc3VwcG9ydCBuZXcgYXR0cmlidXRlcyBmb3IgTWF4UG9vbC04IGFuZCBNYXhQb29sLTEwXG4gIFsnTWF4UG9vbCcsICcnLCAnMSsnLCBtYXhQb29sLCBwYXJzZU1heFBvb2xBdHRyaWJ1dGVzXSxcbiAgWydNdWwnLCAnJywgJzcrJywgYmluYXJ5T3BzLm11bF0sXG4gIFsnTmVnJywgJycsICc2KycsIHVuYXJ5T3BzLm5lZ10sXG4gIFsnTm90JywgJycsICcxKycsIHVuYXJ5T3BzLm5vdF0sXG4gIFsnT3InLCAnJywgJzcrJywgYmluYXJ5T3BzLm9yXSxcbiAgWydQYWQnLCAnJywgJzItMTAnLCBwYWRWMiwgcGFyc2VQYWRBdHRyaWJ1dGVzVjJdLFxuICBbJ1BhZCcsICcnLCAnMTErJywgcGFkVjExLCBwYXJzZVBhZEF0dHJpYnV0ZXNWMTFdLFxuICBbJ1BvdycsICcnLCAnNysnLCBiaW5hcnlPcHMucG93XSxcbiAgWydQUmVsdScsICcnLCAnNysnLCBiaW5hcnlPcHMucFJlbHVdLFxuICBbJ1JlZHVjZUxvZ1N1bScsICcnLCAnMSsnLCByZWR1Y2VMb2dTdW0sIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlTWF4JywgJycsICcxKycsIHJlZHVjZU1heCwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VNZWFuJywgJycsICcxKycsIHJlZHVjZU1lYW4sIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlTWluJywgJycsICcxKycsIHJlZHVjZU1pbiwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VQcm9kJywgJycsICcxKycsIHJlZHVjZVByb2QsIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlU3VtJywgJycsICcxLTEyJywgcmVkdWNlU3VtLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZVN1bVNxdWFyZScsICcnLCAnMSsnLCByZWR1Y2VMb2dTdW1TcXVhcmUsIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVsdScsICcnLCAnNisnLCB1bmFyeU9wcy5yZWx1XSxcbiAgWydSZXNoYXBlJywgJycsICc1KycsIHJlc2hhcGVdLFxuICBbJ1Jlc2l6ZScsICcnLCAnMTAnLCByZXNpemUsIHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMF0sXG4gIFsnUmVzaXplJywgJycsICcxMSsnLCByZXNpemUsIHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMV0sXG4gIFsnU2hhcGUnLCAnJywgJzErJywgc2hhcGVdLFxuICBbJ1NpZ21vaWQnLCAnJywgJzYrJywgdW5hcnlPcHMuc2lnbW9pZF0sXG4gIFsnU2luJywgJycsICc3KycsIHVuYXJ5T3BzLnNpbl0sXG4gIFsnU2xpY2UnLCAnJywgJzEwKycsIHNsaWNlVjEwXSwgLy8gVE9ETzogc3VwcG9ydCAnc3RlcHMnIGZvciBTbGljZS0xMFxuICBbJ1NsaWNlJywgJycsICcxLTknLCBzbGljZSwgcGFyc2VTbGljZUF0dHJpYnV0ZXNdLFxuICAvLyBUaGUgXCJzZW1hbnRpY1wiIG1lYW5pbmcgb2YgYXhpcyBoYXMgY2hhbmdlZCBpbiBvcHNldC0xMy5cbiAgWydTb2Z0bWF4JywgJycsICcxLTEyJywgc29mdG1heCwgcGFyc2VTb2Z0bWF4QXR0cmlidXRlc10sXG4gIFsnU29mdG1heCcsICcnLCAnMTMrJywgc29mdG1heFYxMywgcGFyc2VTb2Z0bWF4QXR0cmlidXRlc1YxM10sXG4gIC8vICdTcGxpdCcgb3BlcmF0b3IgaGFzIGFuIG9wdGlvbmFsIGF0dHJpYnV0ZSAnc3BsaXQnXG4gIC8vIHRoaXMgYXR0cmlidXRlIGRldGVybWluZXMgaG93IHRoZSBzcGVjaWZpZWQgYXhpcyBvZiBpbnB1dCBkYXRhIGlzIHNwbGl0LlxuICAvLyBXaGVuIHRoZSBhdHRyaWJ1dGUgaXMgbWlzc2luZywgd2UgbmVlZCB0aGUgY291bnQgb2YgbnVtYmVyIG9mIG91dHB1dHNcbiAgLy8gc28gdGhhdCB3ZSBjYW4gZGV0ZXJtaW5lIHRoZSAnc3BsaXQnIGF0dHJpYnV0ZSBmcm9tIHRoZSBydW50aW1lIGlucHV0IHRvIHRoZSBPcGVyYXRvclxuICBbJ1NwbGl0JywgJycsICcyLTEyJywgc3BsaXQsIHBhcnNlU3BsaXRBdHRyaWJ1dGVzXSxcbiAgWydTcXJ0JywgJycsICc2KycsIHVuYXJ5T3BzLnNxcnRdLFxuICBbJ1NxdWVlemUnLCAnJywgJzEtMTInLCBzcXVlZXplLCBwYXJzZVNxdWVlemVBdHRyaWJ1dGVzXSxcbiAgWydTcXVlZXplJywgJycsICcxMysnLCBzcXVlZXplVjEzXSxcbiAgWydTdWInLCAnJywgJzcrJywgYmluYXJ5T3BzLnN1Yl0sXG4gIFsnU3VtJywgJycsICc2KycsIHN1bV0sXG4gIFsnVGFuJywgJycsICc3KycsIHVuYXJ5T3BzLnRhbl0sXG4gIFsnVGFuaCcsICcnLCAnNisnLCB1bmFyeU9wcy50YW5oXSxcbiAgWydUaWxlJywgJycsICc2KycsIHRpbGVdLFxuICBbJ1RyYW5zcG9zZScsICcnLCAnMSsnLCB0cmFuc3Bvc2UsIHBhcnNlVHJhbnNwb3NlQXR0cmlidXRlc10sXG4gIFsnVXBzYW1wbGUnLCAnJywgJzctOCcsIHVwc2FtcGxlLCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y3XSxcbiAgWydVcHNhbXBsZScsICcnLCAnOScsIHVwc2FtcGxlLCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y5XSxcbiAgWydVbnNxdWVlemUnLCAnJywgJzEtMTInLCB1bnNxdWVlemUsIHBhcnNlVW5zcXVlZXplQXR0cmlidXRlc10sXG4gIFsnVW5zcXVlZXplJywgJycsICcxMysnLCB1bnNxdWVlemVWMTNdLFxuICBbJ1hvcicsICcnLCAnNysnLCBiaW5hcnlPcHMueG9yXSxcbl07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmNvbnN0IElOTElORV9GVU5DX0RFRl9SRUdFWCA9IC9AaW5saW5lW1xcc1xcblxccl0rKFxcdyspW1xcc1xcblxccl0rKFswLTlhLXpBLVpfXSspXFxzKlxcKChbXildKilcXClcXHMqeygoW159XXxbXFxuXFxyXSkqKX0vZ207XG5jb25zdCBGVU5DX0NBTExfUkVHRVggPSAnKFxcXFx3Kyk/XFxcXHMrKFtfMC05YS16QS1aXSspXFxcXHMrPVxcXFxzK19fRlVOQ19fXFxcXCgoLiopXFxcXClcXFxccyo7Jztcbi8qKlxuICogR0xTTCBwcmVwcm9jZXNzb3IgcmVzcG9uc2libGUgZm9yIHJlc29sdmluZyBAaW5saW5lIGRpcmVjdGl2ZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VJbmxpbmVzKHNjcmlwdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgaW5saW5lRGVmczogeyBbbmFtZTogc3RyaW5nXTogeyBwYXJhbXM6IEFycmF5PHsgdHlwZTogc3RyaW5nOyBuYW1lOiBzdHJpbmcgfSB8IG51bGw+OyBib2R5OiBzdHJpbmcgfSB9ID0ge307XG4gIGxldCBtYXRjaDtcbiAgd2hpbGUgKChtYXRjaCA9IElOTElORV9GVU5DX0RFRl9SRUdFWC5leGVjKHNjcmlwdCkpICE9PSBudWxsKSB7XG4gICAgY29uc3QgcGFyYW1zID0gbWF0Y2hbM11cbiAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAubWFwKChzKSA9PiB7XG4gICAgICAgIGNvbnN0IHRva2VucyA9IHMudHJpbSgpLnNwbGl0KCcgJyk7XG4gICAgICAgIGlmICh0b2tlbnMgJiYgdG9rZW5zLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgIHJldHVybiB7IHR5cGU6IHRva2Vuc1swXSwgbmFtZTogdG9rZW5zWzFdIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigodikgPT4gdiAhPT0gbnVsbCk7XG4gICAgaW5saW5lRGVmc1ttYXRjaFsyXV0gPSB7IHBhcmFtcywgYm9keTogbWF0Y2hbNF0gfTtcbiAgfVxuICBmb3IgKGNvbnN0IG5hbWUgaW4gaW5saW5lRGVmcykge1xuICAgIGNvbnN0IHJlZ2V4U3RyaW5nID0gRlVOQ19DQUxMX1JFR0VYLnJlcGxhY2UoJ19fRlVOQ19fJywgbmFtZSk7XG4gICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKHJlZ2V4U3RyaW5nLCAnZ20nKTtcbiAgICB3aGlsZSAoKG1hdGNoID0gcmVnZXguZXhlYyhzY3JpcHQpKSAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgdHlwZSA9IG1hdGNoWzFdO1xuICAgICAgY29uc3QgdmFyaWFibGUgPSBtYXRjaFsyXTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IG1hdGNoWzNdLnNwbGl0KCcsJyk7XG4gICAgICBjb25zdCBkZWNsTGluZSA9IHR5cGUgPyBgJHt0eXBlfSAke3ZhcmlhYmxlfTtgIDogJyc7XG4gICAgICBsZXQgbmV3Qm9keTogc3RyaW5nID0gaW5saW5lRGVmc1tuYW1lXS5ib2R5O1xuICAgICAgbGV0IHBhcmFtUmVkZWNMaW5lID0gJyc7XG4gICAgICBpbmxpbmVEZWZzW25hbWVdLnBhcmFtcy5mb3JFYWNoKCh2LCBpKSA9PiB7XG4gICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgcGFyYW1SZWRlY0xpbmUgKz0gYCR7di50eXBlfSAke3YubmFtZX0gPSAke3BhcmFtc1tpXX07XFxuYDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBuZXdCb2R5ID0gYCR7cGFyYW1SZWRlY0xpbmV9XFxuICR7bmV3Qm9keX1gO1xuICAgICAgbmV3Qm9keSA9IG5ld0JvZHkucmVwbGFjZSgncmV0dXJuJywgYCR7dmFyaWFibGV9ID0gYCk7XG4gICAgICBjb25zdCByZXBsYWNlbWVudCA9IGBcbiAgICAgICR7ZGVjbExpbmV9XG4gICAgICB7XG4gICAgICAgICR7bmV3Qm9keX1cbiAgICAgIH1cbiAgICAgIGA7XG4gICAgICBzY3JpcHQgPSBzY3JpcHQucmVwbGFjZShtYXRjaFswXSwgcmVwbGFjZW1lbnQpO1xuICAgIH1cbiAgfVxuICBzY3JpcHQgPSBzY3JpcHQucmVwbGFjZShJTkxJTkVfRlVOQ19ERUZfUkVHRVgsICcnKTtcbiAgcmV0dXJuIHNjcmlwdDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi8uLi91dGlsJztcblxuLyoqIExheW91dCBwcmVmZXJlbmNlcyAqL1xuZXhwb3J0IGludGVyZmFjZSBXaWR0aEhlaWdodFByZWZzIHtcbiAgYnJlYWtBeGlzPzogbnVtYmVyO1xuICBpc1BhY2tlZD86IGJvb2xlYW47XG4gIHJldmVyc2VXSD86IGJvb2xlYW47XG59XG4vKipcbiAqIFRleHR1cmVMYXlvdXRTdHJhdGVneSBpcyBhbiBhYnN0cmFjdGlvbiBmb3IgZGlmZmVyZW50IHBsYW5zXG4gKiBmb3IgbWFwcGluZyBuLWRpbWVuc2lvbmFsIGFycmF5cyB0byAyRCB0ZXh0dXJlcyAoYW5kIGJhY2spXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZUxheW91dFN0cmF0ZWd5IHtcbiAgY29tcHV0ZVRleHR1cmVXSChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyk6IFtudW1iZXIsIG51bWJlcl07XG59XG5cbi8qKlxuICogVGhpcyBzdHJhdGVneSB0cnkgdG8gZmluZCB0aGUgbWluaW1hbCBtYXgoVyxIKSB0aGF0IGZ1bGZpbGxzIChXICogSCA9PSB0b3RhbFNpemUpXG4gKi9cbmV4cG9ydCBjbGFzcyBBbHdheXNLZWVwT3JpZ2luYWxTaXplU3RyYXRlZ3kgaW1wbGVtZW50cyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgbWF4VGV4dHVyZVNpemU6IG51bWJlcikge31cbiAgY29tcHV0ZVRleHR1cmVXSChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIC8vIHNjYWxhciB0ZW5zb3JcbiAgICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gWzEsIDFdO1xuICAgIH1cbiAgICBjb25zdCBtYXhUZXh0dXJlU2l6ZSA9IHRoaXMubWF4VGV4dHVyZVNpemU7XG4gICAgaWYgKHByZWZzICYmIHByZWZzLmJyZWFrQXhpcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBjaGVjayB0byBzZWUgaWYgZGltcyBmaXRcbiAgICAgIGNvbnN0IHdzaXplID0gcHJlZnMuYnJlYWtBeGlzID49IHNoYXBlLmxlbmd0aCA/IDEgOiBzaGFwZS5zbGljZShwcmVmcy5icmVha0F4aXMpLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgY29uc3QgaHNpemUgPSBwcmVmcy5icmVha0F4aXMgPD0gMCA/IDEgOiBzaGFwZS5zbGljZSgwLCBwcmVmcy5icmVha0F4aXMpLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgaWYgKHdzaXplID4gbWF4VGV4dHVyZVNpemUgfHwgaHNpemUgPiBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgICAvLyBpZ25vcmUgcHJlZmVyZW5jZXNcbiAgICAgICAgLy8gY29udGludWUgd2l0aCBkZWZhdWx0IGxheW91dFxuICAgICAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgICAgICAnVGV4dHVyZUxheW91dCcsXG4gICAgICAgICAgYEdpdmVuIHdpZHRoL2hlaWdodCBwcmVmZXJlbmNlcyB3ZXJlIHVuYXR0YWluYWJsZTogc2hhcGU6JHtzaGFwZX0sIGJyZWFrQXhpczoke3ByZWZzLmJyZWFrQXhpc31gLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFt3c2l6ZSwgaHNpemVdO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCB0b3RhbFNpemUgPSBzaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcblxuICAgIGxldCB3aWR0aCA9IE1hdGguZmxvb3IoTWF0aC5zcXJ0KHRvdGFsU2l6ZSkpO1xuXG4gICAgZm9yICg7IHdpZHRoIDwgbWF4VGV4dHVyZVNpemUgJiYgd2lkdGggPCB0b3RhbFNpemU7IHdpZHRoKyspIHtcbiAgICAgIGlmICh0b3RhbFNpemUgJSB3aWR0aCA9PT0gMCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAod2lkdGggPj0gbWF4VGV4dHVyZVNpemUgfHwgdG90YWxTaXplICUgd2lkdGggIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGdpdmVuIGRpbWVuc2lvbnMgYXJlIG91dHNpZGUgdGhpcyBHUFUncyBib3VuZGFyaWVzOiAke3NoYXBlfWApO1xuICAgIH1cbiAgICByZXR1cm4gW3dpZHRoLCB0b3RhbFNpemUgLyB3aWR0aF07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFByZWZlckxvZ2ljYWxTdHJhdGVneSBpbXBsZW1lbnRzIFRleHR1cmVMYXlvdXRTdHJhdGVneSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBtYXhUZXh0dXJlU2l6ZTogbnVtYmVyKSB7fVxuICBjb21wdXRlVGV4dHVyZVdIKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3Qgd2ggPSB0aGlzLmNvbXB1dGVUZXh0dXJlKHNoYXBlLCBwcmVmcyk7XG4gICAgaWYgKHByZWZzICYmIHByZWZzLmlzUGFja2VkKSB7XG4gICAgICB3aFswXSAvPSAyO1xuICAgICAgd2hbMV0gLz0gMjtcbiAgICB9XG4gICAgaWYgKHByZWZzICYmIHByZWZzLnJldmVyc2VXSCkge1xuICAgICAgcmV0dXJuIFt3aFsxXSwgd2hbMF1dO1xuICAgIH1cbiAgICByZXR1cm4gd2g7XG4gIH1cblxuICBjb21wdXRlVGV4dHVyZShzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGNvbnN0IGlzUGFja2VkID0gcHJlZnMgJiYgcHJlZnMuaXNQYWNrZWQ7XG4gICAgLy8gc2NhbGFyIHRlbnNvclxuICAgIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBpc1BhY2tlZCA/IFsyLCAyXSA6IFsxLCAxXTtcbiAgICB9XG4gICAgbGV0IG1heFRleHR1cmVTaXplID0gdGhpcy5tYXhUZXh0dXJlU2l6ZTtcbiAgICBpZiAocHJlZnMgJiYgcHJlZnMuYnJlYWtBeGlzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiBkaW1zIGZpdFxuICAgICAgY29uc3Qgd3NpemUgPSBwcmVmcy5icmVha0F4aXMgPj0gc2hhcGUubGVuZ3RoID8gMSA6IHNoYXBlLnNsaWNlKHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBjb25zdCBoc2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA8PSAwID8gMSA6IHNoYXBlLnNsaWNlKDAsIHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBpZiAod3NpemUgPiBtYXhUZXh0dXJlU2l6ZSB8fCBoc2l6ZSA+IG1heFRleHR1cmVTaXplKSB7XG4gICAgICAgIC8vIGlnbm9yZSBwcmVmZXJlbmNlc1xuICAgICAgICAvLyBjb250aW51ZSB3aXRoIGRlZmF1bHQgbGF5b3V0XG4gICAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICdUZXh0dXJlTGF5b3V0JyxcbiAgICAgICAgICBgR2l2ZW4gd2lkdGgvaGVpZ2h0IHByZWZlcmVuY2VzIHdlcmUgdW5hdHRhaW5hYmxlOiBzaGFwZToke3NoYXBlfSwgYnJlYWtBeGlzOiR7cHJlZnMuYnJlYWtBeGlzfWAsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gW3dzaXplLCBoc2l6ZV07XG4gICAgICB9XG4gICAgfVxuICAgIGxldCBsb2dTaGFwZSA9IHNoYXBlLnNsaWNlKDApO1xuICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgbWF4VGV4dHVyZVNpemUgPSBtYXhUZXh0dXJlU2l6ZSAqIDI7XG5cbiAgICAgIC8vIFRoaXMgbG9naWMgZW5zdXJlcyB3ZSBhY2N1cmF0ZWx5IGNvdW50IHRoZSBudW1iZXIgb2YgcGFja2VkIHRleGVscyBuZWVkZWRcbiAgICAgIC8vIHRvIGFjY29tbW9kYXRlIHRoZSB0ZW5zb3IuIFdlIGNhbiBvbmx5IHBhY2sgdmFsdWVzIGluIHRoZSBzYW1lIHRleGVsIGlmXG4gICAgICAvLyB0aGV5IGFyZSBmcm9tIGFkamFjZW50IHBhaXJzIG9mIHJvd3MvY29scyB3aXRoaW4gdGhlIHNhbWUgYmF0Y2guIFNvIGlmIGFcbiAgICAgIC8vIHRlbnNvciBoYXMgMyByb3dzLCB3ZSBwcmV0ZW5kIGl0IGhhcyA0IHJvd3MgaW4gb3JkZXIgdG8gYWNjb3VudCBmb3IgdGhlXG4gICAgICAvLyBmYWN0IHRoYXQgdGhlIHRleGVscyBjb250YWluaW5nIHRoZSB0aGlyZCByb3cgYXJlIGhhbGYgZW1wdHkuXG4gICAgICBsb2dTaGFwZSA9IGxvZ1NoYXBlLm1hcCgoX2QsIGkpID0+XG4gICAgICAgIGkgPj0gbG9nU2hhcGUubGVuZ3RoIC0gMiA/IChsb2dTaGFwZVtpXSAlIDIgPT09IDAgPyBsb2dTaGFwZVtpXSA6IGxvZ1NoYXBlW2ldICsgMSkgOiBsb2dTaGFwZVtpXSxcbiAgICAgICk7XG5cbiAgICAgIC8vIFBhY2tlZCB0ZXh0dXJlIGhlaWdodCBpcyBhdCBsZWFzdCAyICh0aGUgY2hhbm5lbCBoZWlnaHQgb2YgYSBzaW5nbGVcbiAgICAgIC8vIHRleGVsKS5cbiAgICAgIGlmIChsb2dTaGFwZS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgbG9nU2hhcGUgPSBbMiwgbG9nU2hhcGVbMF1dO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIGxvZ2ljYWwgc2hhcGUgaXMgMiwgd2UgZG9uJ3Qgc3F1ZWV6ZSwgc2luY2Ugd2Ugd2FudCB0byBtYXRjaCBwaHlzaWNhbC5cbiAgICBpZiAobG9nU2hhcGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICBjb25zdCBzcXVlZXplUmVzdWx0ID0gc3F1ZWV6ZVNoYXBlKGxvZ1NoYXBlKTtcbiAgICAgIGxvZ1NoYXBlID0gc3F1ZWV6ZVJlc3VsdC5uZXdTaGFwZTtcbiAgICB9XG5cbiAgICBjb25zdCBzaXplID0gc2l6ZUZyb21TaGFwZShsb2dTaGFwZSk7XG4gICAgaWYgKGxvZ1NoYXBlLmxlbmd0aCA8PSAxICYmIHNpemUgPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBbMSwgc2l6ZV07XG4gICAgfSBlbHNlIGlmIChsb2dTaGFwZS5sZW5ndGggPT09IDIgJiYgbG9nU2hhcGVbMF0gPD0gbWF4VGV4dHVyZVNpemUgJiYgbG9nU2hhcGVbMV0gPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBsb2dTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdO1xuICAgIH0gZWxzZSBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAzICYmIGxvZ1NoYXBlWzBdICogbG9nU2hhcGVbMV0gPD0gbWF4VGV4dHVyZVNpemUgJiYgbG9nU2hhcGVbMl0gPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBbbG9nU2hhcGVbMF0gKiBsb2dTaGFwZVsxXSwgbG9nU2hhcGVbMl1dO1xuICAgIH0gZWxzZSBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAzICYmIGxvZ1NoYXBlWzBdIDw9IG1heFRleHR1cmVTaXplICYmIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBbbG9nU2hhcGVbMF0sIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl1dO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBsb2dTaGFwZS5sZW5ndGggPT09IDQgJiZcbiAgICAgIGxvZ1NoYXBlWzBdICogbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJlxuICAgICAgbG9nU2hhcGVbM10gPD0gbWF4VGV4dHVyZVNpemVcbiAgICApIHtcbiAgICAgIHJldHVybiBbbG9nU2hhcGVbMF0gKiBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdLCBsb2dTaGFwZVszXV07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGxvZ1NoYXBlLmxlbmd0aCA9PT0gNCAmJlxuICAgICAgbG9nU2hhcGVbMF0gPD0gbWF4VGV4dHVyZVNpemUgJiZcbiAgICAgIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gKiBsb2dTaGFwZVszXSA8PSBtYXhUZXh0dXJlU2l6ZVxuICAgICkge1xuICAgICAgcmV0dXJuIFtsb2dTaGFwZVswXSwgbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSAqIGxvZ1NoYXBlWzNdXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICAgIC8vIEZvciBwYWNrZWQgdGV4dHVyZXMgc2l6ZSBlcXVhbHMgdGhlIG51bWJlciBvZiBjaGFubmVscyByZXF1aXJlZCB0b1xuICAgICAgICAvLyBhY2NvbW1vZGF0ZSB0aGUgdGV4dHVyZSBkYXRhLiBIb3dldmVyIGluIG9yZGVyIHRvIHNxdWFyaWZ5IHN1Y2ggdGhhdFxuICAgICAgICAvLyBpbm5lciBkaW1lbnNpb25zIHN0YXkgZXZlbiwgd2UgcmV3cml0ZSBzaXplIHRvIGVxdWFsIHRoZSBudW1iZXIgb2ZcbiAgICAgICAgLy8gdGV4ZWxzLiBUaGVuIGluIHRoZSByZXR1cm4gc3RhdGVtZW50IHdlIHJlaHlkcmF0ZSB0aGUgc3F1YXJpZmllZFxuICAgICAgICAvLyBkaW1lbnNpb25zIHRvIGNoYW5uZWwgdW5pdHMuXG4gICAgICAgIHJldHVybiBzaXplVG9TcXVhcmlzaFNoYXBlKHNpemUgLyA0KS5tYXAoKGQpID0+IGQgKiAyKSBhcyBbbnVtYmVyLCBudW1iZXJdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNpemVUb1NxdWFyaXNoU2hhcGUoc2l6ZSk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzcXVlZXplU2hhcGUoc2hhcGU6IG51bWJlcltdLCBheGlzPzogbnVtYmVyW10pOiB7IG5ld1NoYXBlOiBudW1iZXJbXTsga2VwdERpbXM6IG51bWJlcltdIH0ge1xuICBjb25zdCBuZXdTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgY29uc3Qga2VwdERpbXM6IG51bWJlcltdID0gW107XG4gIGNvbnN0IGlzRW1wdHlBcnJheSA9IGF4aXMgIT0gbnVsbCAmJiBBcnJheS5pc0FycmF5KGF4aXMpICYmIGF4aXMubGVuZ3RoID09PSAwO1xuICBjb25zdCBheGVzID0gYXhpcyA9PSBudWxsIHx8IGlzRW1wdHlBcnJheSA/IG51bGwgOiBwYXJzZUF4aXNQYXJhbShheGlzLCBzaGFwZSkuc29ydCgpO1xuICBsZXQgaiA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2hhcGUubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoYXhlcyAhPSBudWxsKSB7XG4gICAgICBpZiAoYXhlc1tqXSA9PT0gaSAmJiBzaGFwZVtpXSAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbid0IHNxdWVlemUgYXhpcyAke2l9IHNpbmNlIGl0cyBkaW0gJyR7c2hhcGVbaV19JyBpcyBub3QgMWApO1xuICAgICAgfVxuICAgICAgaWYgKChheGVzW2pdID09IG51bGwgfHwgYXhlc1tqXSA+IGkpICYmIHNoYXBlW2ldID09PSAxKSB7XG4gICAgICAgIG5ld1NoYXBlLnB1c2goc2hhcGVbaV0pO1xuICAgICAgICBrZXB0RGltcy5wdXNoKGkpO1xuICAgICAgfVxuICAgICAgaWYgKGF4ZXNbal0gPD0gaSkge1xuICAgICAgICBqKys7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzaGFwZVtpXSAhPT0gMSkge1xuICAgICAgbmV3U2hhcGUucHVzaChzaGFwZVtpXSk7XG4gICAgICBrZXB0RGltcy5wdXNoKGkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4geyBuZXdTaGFwZSwga2VwdERpbXMgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQXhpc1BhcmFtKGF4aXM6IG51bWJlciB8IG51bWJlcltdLCBzaGFwZTogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgLy8gTm9ybWFsaXplIGlucHV0XG4gIGF4aXMgPSBheGlzID09IG51bGwgPyBzaGFwZS5tYXAoKF9zLCBpKSA9PiBpKSA6IChbXSBhcyBudW1iZXJbXSkuY29uY2F0KGF4aXMpO1xuXG4gIC8vIENoZWNrIGZvciB2YWxpZCByYW5nZVxuICBhc3NlcnQoXG4gICAgYXhpcy5ldmVyeSgoYXgpID0+IGF4ID49IC1yYW5rICYmIGF4IDwgcmFuayksXG4gICAgKCkgPT4gYEFsbCB2YWx1ZXMgaW4gYXhpcyBwYXJhbSBtdXN0IGJlIGluIHJhbmdlIFstJHtyYW5rfSwgJHtyYW5rfSkgYnV0IGAgKyBgZ290IGF4aXMgJHtheGlzfWAsXG4gICk7XG5cbiAgLy8gQ2hlY2sgZm9yIG9ubHkgaW50ZWdlcnNcbiAgYXNzZXJ0KGF4aXMuZXZlcnkoaXNJbnQpLCAoKSA9PiAnQWxsIHZhbHVlcyBpbiBheGlzIHBhcmFtIG11c3QgYmUgaW50ZWdlcnMgYnV0ICcgKyBgZ290IGF4aXMgJHtheGlzfWApO1xuXG4gIC8vIEhhbmRsZSBuZWdhdGl2ZSBheGlzLlxuICByZXR1cm4gYXhpcy5tYXAoKGEpID0+IChhIDwgMCA/IHJhbmsgKyBhIDogYSkpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGlzSW50KGE6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gYSAlIDEgPT09IDA7XG59XG5leHBvcnQgZnVuY3Rpb24gc2l6ZUZyb21TaGFwZShzaGFwZTogbnVtYmVyW10pOiBudW1iZXIge1xuICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gU2NhbGFyLlxuICAgIHJldHVybiAxO1xuICB9XG4gIGxldCBzaXplID0gc2hhcGVbMF07XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgc2hhcGUubGVuZ3RoOyBpKyspIHtcbiAgICBzaXplICo9IHNoYXBlW2ldO1xuICB9XG4gIHJldHVybiBzaXplO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvd3NDb2xzKHNoYXBlOiBudW1iZXJbXSk6IFtudW1iZXIsIG51bWJlcl0ge1xuICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Nhbm5vdCBnZXQgcm93cyBhbmQgY29sdW1ucyBvZiBhbiBlbXB0eSBzaGFwZSBhcnJheS4nKTtcbiAgfVxuXG4gIHJldHVybiBbc2hhcGUubGVuZ3RoID4gMSA/IHNoYXBlW3NoYXBlLmxlbmd0aCAtIDJdIDogMSwgc2hhcGVbc2hhcGUubGVuZ3RoIC0gMV1dO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNpemVUb1NxdWFyaXNoU2hhcGUoc2l6ZTogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGNvbnN0IHdpZHRoID0gTWF0aC5jZWlsKE1hdGguc3FydChzaXplKSk7XG4gIHJldHVybiBbd2lkdGgsIE1hdGguY2VpbChzaXplIC8gd2lkdGgpXTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYXRjaERpbShzaGFwZTogbnVtYmVyW10sIGRpbXNUb1NraXAgPSAyKTogbnVtYmVyIHtcbiAgcmV0dXJuIHNpemVGcm9tU2hhcGUoc2hhcGUuc2xpY2UoMCwgc2hhcGUubGVuZ3RoIC0gZGltc1RvU2tpcCkpO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBBcnJheVV0aWwsIEJyb2FkY2FzdFV0aWwsIFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmUgfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgZ2V0R2xzbCB9IGZyb20gJy4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHsgc3F1ZWV6ZVNoYXBlIH0gZnJvbSAnLi90ZXh0dXJlLWxheW91dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBUZXh0dXJlTGF5b3V0IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge1xuICBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUsXG4gIGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZUF0T3V0Q29vcmRzLFxuICBnZXRDb29yZHNEYXRhVHlwZSxcbiAgZ2V0R2xDaGFubmVscyxcbiAgZ2V0U3F1ZWV6ZWRQYXJhbXMsXG4gIHNxdWVlemVJbnB1dFNoYXBlLFxufSBmcm9tICcuL3V0aWxzJztcblxuLyoqXG4gKiBHTFNMIExpYnJhcnkgcmVzcG9uc2libGUgZm9yIGRhdGEgdHlwZXMgYW5kIHJvdXRpbmVzIGZvciBtYW5pcHVsYXRpbmdcbiAqIGNvb3JkaW5hdGVzIGFuZCBtYXBwaW5nIHRvL2Zyb20gdGVuc29yIGluZGljZXNcbiAqL1xuZXhwb3J0IGNsYXNzIENvb3Jkc0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgcmV0dXJuVHlwZTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEdsc2xDb250ZXh0KSB7XG4gICAgc3VwZXIoY29udGV4dCk7XG4gIH1cbiAgZ2V0RnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLm9mZnNldFRvQ29vcmRzKCksXG4gICAgICAuLi50aGlzLmNvb3Jkc1RvT2Zmc2V0KCksXG4gICAgICAuLi50aGlzLnRvVmVjKCksXG4gICAgICAuLi50aGlzLnZhbHVlRnJvbSgpLFxuICAgICAgLy8gVE9ETyByZXR1cm4gdGhlc2Ugb25seSB3aGVuIHBhY2tpbmcgaXMgZW5hYmxlZC5cbiAgICAgIC4uLnRoaXMuZ2V0Q29tbW9uVXRpbEZ1bmNzKCksXG4gICAgICAuLi50aGlzLmdldElucHV0c1NhbXBsaW5nU25pcHBldHMoKSxcbiAgICAgIC4uLnRoaXMuZ2V0T3V0cHV0U2FtcGxpbmdTbmlwcGV0KCksXG4gICAgfTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpIHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEgZnVuY3Rpb24gdGhhdCBjYW4gbWFwIGZyb21cbiAgICogMkQgbm9ybWFsemllZCBjb29yZGluYXRlcyAocyx0KSB0byBhIGZsYXQgb2Zmc2V0XG4gICAqL1xuICBwcm90ZWN0ZWQgb2Zmc2V0VG9Db29yZHMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgZnVuY05hbWUgPSAnb2Zmc2V0VG9Db29yZHMnO1xuICAgIHJldHVybiB7XG4gICAgICBvZmZzZXRUb0Nvb3JkczogbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgJHtmdW5jTmFtZX0oaW50IG9mZnNldCwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7XG4gICAgICAgIGludCB0ID0gb2Zmc2V0IC8gd2lkdGg7XG4gICAgICAgIGludCBzID0gb2Zmc2V0IC0gdCp3aWR0aDtcbiAgICAgICAgdmVjMiBjb29yZHMgPSAodmVjMihzLHQpICsgdmVjMigwLjUsMC41KSkgLyB2ZWMyKHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICByZXR1cm4gY29vcmRzO1xuICAgICAgfVxuICAgICAgYCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIGZ1bmN0aW9uIHRoYXQgY2FuIG1hcCBmcm9tXG4gICAqIDJEIG5vcm1hbHppZWQgY29vcmRpbmF0ZXMgKHMsdCkgdG8gYSBmbGF0IG9mZnNldFxuICAgKi9cbiAgcHJvdGVjdGVkIGNvb3Jkc1RvT2Zmc2V0KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ2Nvb3Jkc1RvT2Zmc2V0JztcbiAgICByZXR1cm4ge1xuICAgICAgY29vcmRzVG9PZmZzZXQ6IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICBpbnQgJHtmdW5jTmFtZX0odmVjMiBjb29yZHMsIGludCB3aWR0aCwgaW50IGhlaWdodCkge1xuICAgICAgICBmbG9hdCBzID0gY29vcmRzLnMgKiBmbG9hdCh3aWR0aCk7XG4gICAgICAgIGZsb2F0IHQgPSBjb29yZHMudCAqIGZsb2F0KGhlaWdodCk7XG4gICAgICAgIGludCBvZmZzZXQgPSBpbnQodCkgKiB3aWR0aCArIGludChzKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICAgIH1cbiAgICAgIGApLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGNvZGUgZm9yIG91dHB1dCBzYW1wbGVyLlxuICAgKi9cblxuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0U2FtcGxpbmdTbmlwcGV0KCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGlmIChvdXRwdXRMYXlvdXQuaXNQYWNrZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZE91dHB1dFNhbXBsaW5nU25pcHBldChvdXRwdXRMYXlvdXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZE91dHB1dFNhbXBsaW5nU25pcHBldChvdXRwdXRMYXlvdXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3IgcGFja2VkIG91dHB1dCBzYW1wbGVyLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZE91dHB1dFNhbXBsaW5nU25pcHBldChvdXRwdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFRleFNoYXBlID0gW291dHB1dExheW91dC53aWR0aCwgb3V0cHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgY29uc3QgZnVuY05hbWUgPSAnZ2V0T3V0cHV0Q29vcmRzJztcbiAgICBzd2l0Y2ggKG91dFNoYXBlLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRTY2FsYXJDb29yZHMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFBhY2tlZDFEQ29vcmRzKG91dFNoYXBlIGFzIFtudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFBhY2tlZDJEQ29vcmRzKG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0UGFja2VkM0RDb29yZHMoXG4gICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0UGFja2VkTkRDb29yZHMob3V0U2hhcGUsIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgIH1cbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIC8vIFRPRE8gd2UgbmVlZCB0aGlzIHRvIHByb3Blcmx5IHJldHVybiBhIHBhY2tlZCB2ZWM0IGZyb20ga2VybmVscy5cbiAgICAvLyBSZXBsYWNlIGFsbCAne2dsc2wub3V0cHV0fSA9IHJlc3VsdCcgd2l0aCAnc2V0T3V0cHV0KHJlc3VsdCknIGluIGFsbCBrZXJuZWxzLlxuICAgIGNvbnN0IGZsb2F0VGV4dHVyZVNldFJHQkFTb3VyY2UgPSBgXG4gICAgICB2b2lkIHNldE91dHB1dCh2ZWM0IHZhbCkge1xuICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZhbDtcbiAgICAgIH1cbiAgICBgO1xuICAgIGNvbnN0IGZsb2F0VGV4dHVyZVNldFJHQkFGdW5jTmFtZSA9ICdmbG9hdFRleHR1cmVTZXRSR0JBJztcbiAgICByZXN1bHRbZmxvYXRUZXh0dXJlU2V0UkdCQUZ1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShmbG9hdFRleHR1cmVTZXRSR0JBU291cmNlKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciB1bnBhY2tlZCBvdXRwdXQgc2FtcGxlci5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZE91dHB1dFNhbXBsaW5nU25pcHBldChvdXRwdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFRleFNoYXBlID0gW291dHB1dExheW91dC53aWR0aCwgb3V0cHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgY29uc3QgZnVuY05hbWUgPSAnZ2V0T3V0cHV0Q29vcmRzJztcbiAgICBzd2l0Y2ggKG91dFNoYXBlLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRTY2FsYXJDb29yZHMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkMURDb29yZHMob3V0U2hhcGUgYXMgW251bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQyRENvb3JkcyhcbiAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDNEQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQ0RENvb3JkcyhcbiAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNTpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQ1RENvb3JkcyhcbiAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICAgIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA2OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDZEQ29vcmRzKFxuICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICAgICAgICBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgb3V0cHV0IGRpbWVuc2lvbmFsaXR5OiAke291dFNoYXBlLmxlbmd0aH1gKTtcbiAgICB9XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAvLyBUT0RPIHdlIG5lZWQgdGhpcyB0byBwcm9wZXJseSByZXR1cm4gYSBwYWNrZWQgdmVjNCBmcm9tIGtlcm5lbHMuXG4gICAgLy8gUmVwbGFjZSBhbGwgJ3tnbHNsLm91dHB1dH0gPSByZXN1bHQnIHdpdGggJ3NldE91dHB1dChyZXN1bHQpJyBpbiBhbGwga2VybmVscy5cbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSU291cmNlID0gYFxuICAgICAgICB2b2lkIHNldE91dHB1dChmbG9hdCB2YWwpIHtcbiAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQodmFsLCAwLCAwLCAwKTtcbiAgICAgICAgfVxuICAgIGA7XG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UkZ1bmNOYW1lID0gJ2Zsb2F0VGV4dHVyZVNldFInO1xuICAgIHJlc3VsdFtmbG9hdFRleHR1cmVTZXRSRnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGZsb2F0VGV4dHVyZVNldFJTb3VyY2UpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogU2NhbGFyIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRTY2FsYXJDb29yZHMoKTogR2xzbExpYlJvdXRpbmUge1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgYCk7XG4gIH1cblxuICAvKipcbiAgICogMUQgcGFja2VkIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRQYWNrZWQxRENvb3Jkcyhfc2hhcGU6IFtudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IHRleFNoYXBlO1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBpZiAocGFja2VkVGV4U2hhcGVbMF0gPT09IDEpIHtcbiAgICAgIHNvdXJjZSA9IGBcbiAgICAgICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIDIgKiBpbnQoVGV4Q29vcmRzLnkgKiAke3BhY2tlZFRleFNoYXBlWzFdfS4wKTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gICAgfVxuXG4gICAgaWYgKHBhY2tlZFRleFNoYXBlWzFdID09PSAxKSB7XG4gICAgICBzb3VyY2UgPSBgXG4gICAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICAgIHJldHVybiAyICogaW50KFRleENvb3Jkcy54ICogJHtwYWNrZWRUZXhTaGFwZVswXX0uMCk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICAgIH1cblxuICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIHJldHVybiAyICogKHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLngpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAyRCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZDJEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgaWYgKEFycmF5VXRpbC5hcnJheXNFcXVhbChzaGFwZSwgdGV4U2hhcGUpKSB7XG4gICAgICBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICByZXR1cm4gMiAqIGl2ZWMyKFRleENvb3Jkcy54eSAqIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gICAgfVxuXG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSB0ZXhTaGFwZTtcbiAgICAvLyB0ZXhlbHMgbmVlZGVkIHRvIGFjY29tbW9kYXRlIGEgbG9naWNhbCByb3dcbiAgICBjb25zdCB0ZXhlbHNJbkxvZ2ljYWxSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcblxuICAgIC8qKlxuICAgICAqIGdldE91dHB1dENvb3Jkc1xuICAgICAqXG4gICAgICogcmVzVGV4UkM6IFRoZSByb3dzIGFuZCBjb2x1bW5zIG9mIHRoZSB0ZXhlbHMuIElmIHlvdSBtb3ZlIG92ZXIgb25lXG4gICAgICogdGV4ZWwgdG8gdGhlIHJpZ2h0IGluIHRoZSBwYWNrZWQgdGV4dHVyZSwgeW91IGFyZSBtb3Zpbmcgb3ZlciBvbmUgY29sdW1uXG4gICAgICogKG5vdCB0d28pLlxuICAgICAqXG4gICAgICogaW5kZXg6IFRoZSB0ZXhlbCBpbmRleFxuICAgICAqL1xuICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcblxuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG5cbiAgICAgICAgICAvLyByZXZlcnNlIHIgYW5kIGMgb3JkZXIgZm9yIHBhY2tlZCB0ZXh0dXJlXG4gICAgICAgICAgaW50IHIgPSBpbW9kKGluZGV4LCAke3RleGVsc0luTG9naWNhbFJvd30pICogMjtcbiAgICAgICAgICBpbnQgYyA9IDIgKiAoaW5kZXggLyAke3RleGVsc0luTG9naWNhbFJvd30pO1xuXG4gICAgICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAzRCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZDNEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG4gICAgY29uc3QgdGV4ZWxzSW5Mb2dpY2FsUm93ID0gTWF0aC5jZWlsKHNoYXBlWzJdIC8gMik7XG4gICAgY29uc3QgdGV4ZWxzSW5CYXRjaCA9IHRleGVsc0luTG9naWNhbFJvdyAqIE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzMgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuXG4gICAgICAgICAgaW50IGIgPSBpbmRleCAvICR7dGV4ZWxzSW5CYXRjaH07XG4gICAgICAgICAgaW5kZXggLT0gYiAqICR7dGV4ZWxzSW5CYXRjaH07XG5cbiAgICAgICAgICAvLyByZXZlcnNlIHIgYW5kIGMgb3JkZXIgZm9yIHBhY2tlZCB0ZXh0dXJlXG4gICAgICAgICAgaW50IHIgPSBpbW9kKGluZGV4LCAke3RleGVsc0luTG9naWNhbFJvd30pICogMjtcbiAgICAgICAgICBpbnQgYyA9IDIgKiAoaW5kZXggLyAke3RleGVsc0luTG9naWNhbFJvd30pO1xuXG4gICAgICAgICAgcmV0dXJuIGl2ZWMzKGIsIHIsIGMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBORCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZE5EQ29vcmRzKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSBbdGV4U2hhcGVbMF0sIHRleFNoYXBlWzFdXTtcblxuICAgIGNvbnN0IHRleGVsc0luTG9naWNhbFJvdyA9IE1hdGguY2VpbChzaGFwZVtzaGFwZS5sZW5ndGggLSAxXSAvIDIpO1xuICAgIGNvbnN0IHRleGVsc0luQmF0Y2ggPSB0ZXhlbHNJbkxvZ2ljYWxSb3cgKiBNYXRoLmNlaWwoc2hhcGVbc2hhcGUubGVuZ3RoIC0gMl0gLyAyKTtcbiAgICBsZXQgdGV4ZWxzSW5CYXRjaE4gPSB0ZXhlbHNJbkJhdGNoO1xuICAgIGxldCBiYXRjaGVzID0gJyc7XG4gICAgbGV0IGNvb3JkcyA9ICdiLCByLCBjJztcblxuICAgIGZvciAobGV0IGIgPSAyOyBiIDwgc2hhcGUubGVuZ3RoIC0gMTsgYisrKSB7XG4gICAgICB0ZXhlbHNJbkJhdGNoTiAqPSBzaGFwZVtzaGFwZS5sZW5ndGggLSBiIC0gMV07XG4gICAgICBiYXRjaGVzID1cbiAgICAgICAgYFxuICAgICAgaW50IGIke2J9ID0gaW5kZXggLyAke3RleGVsc0luQmF0Y2hOfTtcbiAgICAgIGluZGV4IC09IGIke2J9ICogJHt0ZXhlbHNJbkJhdGNoTn07XG4gICAgYCArIGJhdGNoZXM7XG4gICAgICBjb29yZHMgPSBgYiR7Yn0sIGAgKyBjb29yZHM7XG4gICAgfVxuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgIGl2ZWMke3NoYXBlLmxlbmd0aH0gZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuXG4gICAgICAgICR7YmF0Y2hlc31cblxuICAgICAgICBpbnQgYiA9IGluZGV4IC8gJHt0ZXhlbHNJbkJhdGNofTtcbiAgICAgICAgaW5kZXggLT0gYiAqICR7dGV4ZWxzSW5CYXRjaH07XG5cbiAgICAgICAgLy8gcmV2ZXJzZSByIGFuZCBjIG9yZGVyIGZvciBwYWNrZWQgdGV4dHVyZVxuICAgICAgICBpbnQgciA9IGltb2QoaW5kZXgsICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSkgKiAyO1xuICAgICAgICBpbnQgYyA9IDIgKiAoaW5kZXggLyAke3RleGVsc0luTG9naWNhbFJvd30pO1xuXG4gICAgICAgIHJldHVybiBpdmVjJHtzaGFwZS5sZW5ndGh9KCR7Y29vcmRzfSk7XG4gICAgICB9XG4gICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMUQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkMURDb29yZHMoX3NoYXBlOiBbbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICByZXR1cm4gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMkQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkMkRDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgIGludCByID0gaW5kZXggLyAke3NoYXBlWzFdfTtcbiAgICAgICAgICBpbnQgYyA9IGluZGV4IC0gciAqICR7c2hhcGVbMV19O1xuICAgICAgICAgIHJldHVybiBpdmVjMihyLCBjKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgM0Qgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkM0RDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJ107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICBjb25zdCBsaW5lMiA9XG4gICAgICAgICAgaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxXG4gICAgICAgICAgICA/IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YFxuICAgICAgICAgICAgOiBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMzIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICAke2Nvb3Jkc0Zyb21JbmRleFNuaXBwZXR9XG4gICAgICAgICAgcmV0dXJuIGl2ZWMzKHIsIGMsIGQpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA0RCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQ0RENvb3JkcyhcbiAgICBzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0sXG4gICk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAgIGxldCBzdHJpZGVzID0gbnVsbDtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHN0cmlkZXMgPSBbXTtcbiAgICB9XG5cbiAgICBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmsgLSAxKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IHNoYXBlW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBzaGFwZVtpICsgMV07XG4gICAgfVxuICAgIGNvbnN0IGNvb3Jkc1RvQ29tcHV0ZSA9IFsncicsICdjJywgJ2QnLCAnZDInXTtcbiAgICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID0gc3RyaWRlc1xuICAgICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gPSBpbmRleCAvICR7c3RyaWRlfWA7XG4gICAgICAgIGNvbnN0IGxpbmUyID1cbiAgICAgICAgICBpID09PSBzdHJpZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICAgID8gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpICsgMV19ID0gaW5kZXggLSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gXG4gICAgICAgICAgICA6IGBpbmRleCAtPSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gO1xuICAgICAgICByZXR1cm4gYCR7bGluZTF9OyAke2xpbmUyfTtgO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcnKTtcblxuICAgIHNvdXJjZSA9IGBcbiAgICAgIGl2ZWM0IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICAke2Nvb3Jkc0Zyb21JbmRleFNuaXBwZXR9XG4gICAgICAgICAgcmV0dXJuIGl2ZWM0KHIsIGMsIGQsIGQyKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNUQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkNURDb29yZHMoXG4gICAgc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0sXG4gICk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAgIGxldCBzdHJpZGVzID0gbnVsbDtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHN0cmlkZXMgPSBbXTtcbiAgICB9XG5cbiAgICBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmsgLSAxKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IHNoYXBlW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBzaGFwZVtpICsgMV07XG4gICAgfVxuICAgIGNvbnN0IGNvb3Jkc1RvQ29tcHV0ZSA9IFsncicsICdjJywgJ2QnLCAnZDInLCAnZDMnXTtcbiAgICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID0gc3RyaWRlc1xuICAgICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gPSBpbmRleCAvICR7c3RyaWRlfWA7XG4gICAgICAgIGNvbnN0IGxpbmUyID1cbiAgICAgICAgICBpID09PSBzdHJpZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICAgID8gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpICsgMV19ID0gaW5kZXggLSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gXG4gICAgICAgICAgICA6IGBpbmRleCAtPSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gO1xuICAgICAgICByZXR1cm4gYCR7bGluZTF9OyAke2xpbmUyfTtgO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcnKTtcblxuICAgIHNvdXJjZSA9IGBcbiAgICAgIGl2ZWM1IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICAke2Nvb3Jkc0Zyb21JbmRleFNuaXBwZXR9XG4gICAgICAgICAgcmV0dXJuIGl2ZWM1KHIsIGMsIGQsIGQyLCBkMyk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDZEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDZEQ29vcmRzKFxuICAgIHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0sXG4gICk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAgIGxldCBzdHJpZGVzID0gbnVsbDtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHN0cmlkZXMgPSBbXTtcbiAgICB9XG5cbiAgICBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmsgLSAxKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IHNoYXBlW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBzaGFwZVtpICsgMV07XG4gICAgfVxuICAgIGNvbnN0IGNvb3Jkc1RvQ29tcHV0ZSA9IFsncicsICdjJywgJ2QnLCAnZDInLCAnZDMnLCAnZDQnXTtcbiAgICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID0gc3RyaWRlc1xuICAgICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gPSBpbmRleCAvICR7c3RyaWRlfWA7XG4gICAgICAgIGNvbnN0IGxpbmUyID1cbiAgICAgICAgICBpID09PSBzdHJpZGVzLmxlbmd0aCAtIDFcbiAgICAgICAgICAgID8gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpICsgMV19ID0gaW5kZXggLSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gXG4gICAgICAgICAgICA6IGBpbmRleCAtPSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gO1xuICAgICAgICByZXR1cm4gYCR7bGluZTF9OyAke2xpbmUyfTtgO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcnKTtcblxuICAgIHNvdXJjZSA9IGBcbiAgICAgaXZlYzYgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgcmV0dXJuIGl2ZWM2KHIsIGMsIGQsIGQyLCBkMywgZDQpO1xuICAgICAgIH1cbiAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGNvZGUgZm9yIGNvbW1vbiBVViBjb29yZHMgY29tcHV0YXRpb24gdXRpbGl0eSBmdW5jdGlvbnMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0Q29tbW9uVXRpbEZ1bmNzKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIGxldCBmdW5jTmFtZSA9ICd1dkZyb21GbGF0JztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICB2ZWMyIHV2RnJvbUZsYXQoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLCBpbnQgaW5kZXgpIHtcbiAgICAgIGludCB0ZXhDID0gaW5kZXggLyB0ZXhOdW1SO1xuICAgICAgaW50IHRleFIgPSBpbmRleCAtIHRleEMgKiB0ZXhOdW1SO1xuICAgICAgLy8gVE9ETzogc3dhcCB0ZXhSLCB0ZXhDIG9yZGVyIGluIGZvbGxvd2luZyBmdW5jdGlvbiBzbyByb3cgaXMgY29ycmVzcG9uZGluZyB0byB1IGFuZCBjb2x1bW4gaXMgY29ycmVzcG9uZGluZyB0b1xuICAgICAgLy8gICAgICAgdi5cbiAgICAgIHJldHVybiAodmVjMih0ZXhSLCB0ZXhDKSArIGhhbGZDUikgLyB2ZWMyKHRleE51bVIsIHRleE51bUMpO1xuICAgIH1cbiAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdwYWNrZWRVVmZyb20xRCc7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICB2ZWMyIHBhY2tlZFVWZnJvbTFEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQywgaW50IGluZGV4KSB7XG4gICAgICAgIGludCB0ZXhlbEluZGV4ID0gaW5kZXggLyAyO1xuICAgICAgICBpbnQgdGV4UiA9IHRleGVsSW5kZXggLyB0ZXhOdW1DO1xuICAgICAgICBpbnQgdGV4QyA9IHRleGVsSW5kZXggLSB0ZXhSICogdGV4TnVtQztcbiAgICAgICAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7XG4gICAgICB9XG4gICAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdwYWNrZWRVVmZyb20yRCc7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICB2ZWMyIHBhY2tlZFVWZnJvbTJEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQywgaW50IHRleGVsc0luTG9naWNhbFJvdywgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICBpbnQgdGV4ZWxJbmRleCA9IChyb3cgLyAyKSAqIHRleGVsc0luTG9naWNhbFJvdyArIChjb2wgLyAyKTtcbiAgICAgICAgaW50IHRleFIgPSB0ZXhlbEluZGV4IC8gdGV4TnVtQztcbiAgICAgICAgaW50IHRleEMgPSB0ZXhlbEluZGV4IC0gdGV4UiAqIHRleE51bUM7XG4gICAgICAgIHJldHVybiAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKHRleE51bUMsIHRleE51bVIpO1xuICAgICAgfVxuICAgICAgYCk7XG4gICAgZnVuY05hbWUgPSAncGFja2VkVVZmcm9tM0QnO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgdmVjMiBwYWNrZWRVVmZyb20zRChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsXG4gICAgICAgICAgaW50IHRleGVsc0luQmF0Y2gsIGludCB0ZXhlbHNJbkxvZ2ljYWxSb3csIGludCBiLFxuICAgICAgICAgIGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgaW50IGluZGV4ID0gYiAqIHRleGVsc0luQmF0Y2ggKyAocm93IC8gMikgKiB0ZXhlbHNJbkxvZ2ljYWxSb3cgKyAoY29sIC8gMik7XG4gICAgICAgIGludCB0ZXhSID0gaW5kZXggLyB0ZXhOdW1DO1xuICAgICAgICBpbnQgdGV4QyA9IGluZGV4IC0gdGV4UiAqIHRleE51bUM7XG4gICAgICAgIHJldHVybiAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKHRleE51bUMsIHRleE51bVIpO1xuICAgICAgfVxuICAgICAgYCk7XG4gICAgZnVuY05hbWUgPSAnc2FtcGxlVGV4dHVyZSc7XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgICAgZmxvYXQgc2FtcGxlVGV4dHVyZShzYW1wbGVyMkQgdGV4dHVyZVNhbXBsZXIsIHZlYzIgdXYpIHtcbiAgICAgICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSh0ZXh0dXJlU2FtcGxlciwgdXYpLnI7XG4gICAgICAgIH1gKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3IgaW5wdXRzXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0SW5wdXRzU2FtcGxpbmdTbmlwcGV0cygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChzYW1wbGVyTmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3QgaW5wdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXTtcbiAgICAgIGNvbnN0IGZ1bmNOYW1lID0gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lKHNhbXBsZXJOYW1lKTtcbiAgICAgIGlmIChpbnB1dExheW91dC5pc1BhY2tlZCkge1xuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRQYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBzYW1wbGVyTmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBzYW1wbGVyTmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvdXRDb29yZEZ1bmNOYW1lID0gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lQXRPdXRDb29yZHMoc2FtcGxlck5hbWUpO1xuICAgICAgaWYgKGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoIDw9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aCkge1xuICAgICAgICBpZiAoaW5wdXRMYXlvdXQuaXNQYWNrZWQpIHtcbiAgICAgICAgICByZXN1bHRbb3V0Q29vcmRGdW5jTmFtZV0gPSB0aGlzLmdldFBhY2tlZFNhbXBsZXJBdE91dHB1dENvb3JkcyhcbiAgICAgICAgICAgIG91dENvb3JkRnVuY05hbWUsXG4gICAgICAgICAgICBpbnB1dExheW91dCxcbiAgICAgICAgICAgIG91dHB1dExheW91dCxcbiAgICAgICAgICAgIHNhbXBsZXJOYW1lLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W291dENvb3JkRnVuY05hbWVdID0gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJBdE91dHB1dENvb3JkcyhcbiAgICAgICAgICAgIG91dENvb3JkRnVuY05hbWUsXG4gICAgICAgICAgICBpbnB1dExheW91dCxcbiAgICAgICAgICAgIG91dHB1dExheW91dCxcbiAgICAgICAgICAgIHNhbXBsZXJOYW1lLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciBvdXRwdXQgY29vcmRpbmF0ZXMgb2Ygc2FtcGxlcnNcbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyQXRPdXRwdXRDb29yZHMoXG4gICAgZnVuY05hbWU6IHN0cmluZyxcbiAgICBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBvdXRwdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgbmFtZTogc3RyaW5nLFxuICApOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgaW5TaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgb3V0U2hhcGUgPSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCB0ZXhOYW1lID0gbmFtZTtcbiAgICBjb25zdCB0ZXhGdW5jU25pcHBldCA9IGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZSh0ZXhOYW1lKTtcblxuICAgIGNvbnN0IGluUmFuayA9IGluU2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IG91dFJhbmsgPSBvdXRTaGFwZS5sZW5ndGg7XG5cbiAgICBjb25zdCBicm9hZGNhc3REaW1zID0gQnJvYWRjYXN0VXRpbC5nZXRCcm9hZGNhc3REaW1zKGluU2hhcGUsIG91dFNoYXBlKTtcblxuICAgIGNvbnN0IHR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShvdXRSYW5rKTtcbiAgICBjb25zdCByYW5rRGlmZiA9IG91dFJhbmsgLSBpblJhbms7XG4gICAgbGV0IGNvb3Jkc1NuaXBwZXQ6IHN0cmluZztcbiAgICBjb25zdCBmaWVsZHMgPSBnZXRHbENoYW5uZWxzKCk7XG5cbiAgICBpZiAoaW5SYW5rID09PSAwKSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gJyc7XG4gICAgfSBlbHNlIGlmIChvdXRSYW5rIDwgMiAmJiBicm9hZGNhc3REaW1zLmxlbmd0aCA+PSAxKSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gJ2Nvb3JkcyA9IDA7JztcbiAgICB9IGVsc2Uge1xuICAgICAgY29vcmRzU25pcHBldCA9IGJyb2FkY2FzdERpbXMubWFwKChkKSA9PiBgY29vcmRzLiR7ZmllbGRzW2QgKyByYW5rRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgICB9XG4gICAgbGV0IHVucGFja2VkQ29vcmRzU25pcHBldCA9ICcnO1xuICAgIGlmIChvdXRSYW5rIDwgMiAmJiBpblJhbmsgPiAwKSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnY29vcmRzJztcbiAgICB9IGVsc2Uge1xuICAgICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gaW5TaGFwZS5tYXAoKF9zLCBpKSA9PiBgY29vcmRzLiR7ZmllbGRzW2kgKyByYW5rRGlmZl19YCkuam9pbignLCAnKTtcbiAgICB9XG5cbiAgICBsZXQgb3V0cHV0ID0gJ3JldHVybiBvdXRwdXRWYWx1ZTsnO1xuICAgIGNvbnN0IGluU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGluU2hhcGUpO1xuICAgIGNvbnN0IGlzSW5wdXRTY2FsYXIgPSBpblNpemUgPT09IDE7XG4gICAgY29uc3Qgb3V0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dFNoYXBlKTtcbiAgICBjb25zdCBpc091dHB1dFNjYWxhciA9IG91dFNpemUgPT09IDE7XG5cbiAgICBpZiAoaW5SYW5rID09PSAxICYmICFpc0lucHV0U2NhbGFyICYmICFpc091dHB1dFNjYWxhcikge1xuICAgICAgb3V0cHV0ID0gYFxuICAgICAgICByZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54eSwgb3V0cHV0VmFsdWUueHkpO1xuICAgICAgYDtcbiAgICB9IGVsc2UgaWYgKGlzSW5wdXRTY2FsYXIgJiYgIWlzT3V0cHV0U2NhbGFyKSB7XG4gICAgICBpZiAob3V0UmFuayA9PT0gMSkge1xuICAgICAgICBvdXRwdXQgPSBgXG4gICAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueCwgMC4sIDAuKTtcbiAgICAgICAgYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dCA9IGBcbiAgICAgICAgICByZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54KTtcbiAgICAgICAgYDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGJyb2FkY2FzdERpbXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCByb3dzID0gaW5SYW5rIC0gMjtcbiAgICAgIGNvbnN0IGNvbHMgPSBpblJhbmsgLSAxO1xuXG4gICAgICBpZiAoYnJvYWRjYXN0RGltcy5pbmRleE9mKHJvd3MpID4gLTEgJiYgYnJvYWRjYXN0RGltcy5pbmRleE9mKGNvbHMpID4gLTEpIHtcbiAgICAgICAgb3V0cHV0ID0gJ3JldHVybiB2ZWM0KG91dHB1dFZhbHVlLngpOyc7XG4gICAgICB9IGVsc2UgaWYgKGJyb2FkY2FzdERpbXMuaW5kZXhPZihyb3dzKSA+IC0xKSB7XG4gICAgICAgIG91dHB1dCA9ICdyZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54LCBvdXRwdXRWYWx1ZS55LCAnICsgJ291dHB1dFZhbHVlLngsIG91dHB1dFZhbHVlLnkpOyc7XG4gICAgICB9IGVsc2UgaWYgKGJyb2FkY2FzdERpbXMuaW5kZXhPZihjb2xzKSA+IC0xKSB7XG4gICAgICAgIG91dHB1dCA9ICdyZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54eCwgb3V0cHV0VmFsdWUuenopOyc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc3dhcExhc3REaW1zU25pcHBldCA9IGBcbiAgICAgICAgaW50IGxhc3REaW0gPSBjb29yZHMuJHtmaWVsZHNbb3V0UmFuayAtIDFdfTtcbiAgICAgICAgY29vcmRzLiR7ZmllbGRzW291dFJhbmsgLSAxXX0gPSBjb29yZHMuJHtmaWVsZHNbb3V0UmFuayAtIDJdfTtcbiAgICAgICAgY29vcmRzLiR7ZmllbGRzW291dFJhbmsgLSAyXX0gPSBsYXN0RGltO1xuICAgICAgYDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICB2ZWM0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAke3R5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgICAgICAke3N3YXBMYXN0RGltc1NuaXBwZXR9XG4gICAgICAgICR7Y29vcmRzU25pcHBldH1cbiAgICAgICAgdmVjNCBvdXRwdXRWYWx1ZSA9ICR7dGV4RnVuY1NuaXBwZXR9KCR7dW5wYWNrZWRDb29yZHNTbmlwcGV0fSk7XG4gICAgICAgICR7b3V0cHV0fVxuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuZ2V0T3V0cHV0Q29vcmRzJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3IgdW5wYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzIG9mIHNhbXBsZXJzXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyQXRPdXRwdXRDb29yZHMoXG4gICAgZnVuY05hbWU6IHN0cmluZyxcbiAgICBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCxcbiAgICBvdXRwdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsXG4gICAgbmFtZTogc3RyaW5nLFxuICApOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgb3V0VGV4U2hhcGUgPSBbb3V0cHV0TGF5b3V0LndpZHRoLCBvdXRwdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBpblRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IGluUmFuayA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IG91dFJhbmsgPSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgaW5TaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgb3V0U2hhcGUgPSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCB0ZXhGdW5jU25pcHBldCA9IGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZShuYW1lKTtcblxuICAgIGlmIChpblJhbmsgPT09IG91dFJhbmsgJiYgQXJyYXlVdGlsLmFycmF5c0VxdWFsKGluVGV4U2hhcGUsIG91dFRleFNoYXBlKSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgVGV4Q29vcmRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cblxuICAgIGNvbnN0IHR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShvdXRSYW5rKTtcbiAgICBjb25zdCBicm9hZGNhc3REaW1zID0gQnJvYWRjYXN0VXRpbC5nZXRCcm9hZGNhc3REaW1zKGluU2hhcGUsIG91dFNoYXBlKTtcbiAgICBjb25zdCByYW5rRGlmZiA9IG91dFJhbmsgLSBpblJhbms7XG4gICAgbGV0IGNvb3Jkc1NuaXBwZXQ6IHN0cmluZztcbiAgICBjb25zdCBmaWVsZHMgPSBnZXRHbENoYW5uZWxzKCk7XG5cbiAgICBpZiAoaW5SYW5rID09PSAwKSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gJyc7XG4gICAgfSBlbHNlIGlmIChvdXRSYW5rIDwgMiAmJiBicm9hZGNhc3REaW1zLmxlbmd0aCA+PSAxKSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gJ2Nvb3JkcyA9IDA7JztcbiAgICB9IGVsc2Uge1xuICAgICAgY29vcmRzU25pcHBldCA9IGJyb2FkY2FzdERpbXMubWFwKChkKSA9PiBgY29vcmRzLiR7ZmllbGRzW2QgKyByYW5rRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgICB9XG4gICAgbGV0IHVucGFja2VkQ29vcmRzU25pcHBldCA9ICcnO1xuICAgIGlmIChvdXRSYW5rIDwgMiAmJiBpblJhbmsgPiAwKSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnY29vcmRzJztcbiAgICB9IGVsc2Uge1xuICAgICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5tYXAoKF9zLCBpKSA9PiBgY29vcmRzLiR7ZmllbGRzW2kgKyByYW5rRGlmZl19YCkuam9pbignLCAnKTtcbiAgICB9XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICAke3R5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgICAgICAgICR7Y29vcmRzU25pcHBldH1cbiAgICAgICAgICByZXR1cm4gJHt0ZXhGdW5jU25pcHBldH0oJHt1bnBhY2tlZENvb3Jkc1NuaXBwZXR9KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5nZXRPdXRwdXRDb29yZHMnXSk7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciBwYWNrZWQgb3BlcmF0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgc3dpdGNoIChpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lLCBuYW1lKTtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXIyRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyM0QoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXJORChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIHVucGFja2VkIG9wZXJhdGlvbnMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIHN3aXRjaCAoc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlclNjYWxhcihmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXIxRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXIyRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXIzRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgY2FzZSA0OlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXI0RChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgY2FzZSA1OlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXI1RChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgY2FzZSA2OlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXI2RChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gVE9ETyBzdXBwb3J0IG1vcmUgZGltZW5zaW9uYWxpdGllc1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGRpbWVuc2lvbiAke3NoYXBlLmxlbmd0aH0tRGApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgc2NhbGFyIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlclNjYWxhcihmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgdmVjNCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCBoYWxmQ1IpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogUGFja2VkIDFEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSBbdGV4U2hhcGVbMV0sIHRleFNoYXBlWzBdXTtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuXG4gICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGB2ZWM0ICR7ZnVuY05hbWV9KGludCBpbmRleCkge1xuICAgICAgdmVjMiB1diA9IHBhY2tlZFVWZnJvbTFEKFxuICAgICAgJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7cGFja2VkVGV4U2hhcGVbMV19LCBpbmRleCk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgIH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMucGFja2VkVVZmcm9tMUQnXSk7XG4gIH1cblxuICAvKipcbiAgICogUGFja2VkIDJEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgY29uc3QgdGV4TnVtUiA9IHRleFNoYXBlWzBdO1xuICAgIGNvbnN0IHRleE51bUMgPSB0ZXhTaGFwZVsxXTtcblxuICAgIGlmICh0ZXhTaGFwZSAhPSBudWxsICYmIEFycmF5VXRpbC5hcnJheXNFcXVhbChzaGFwZSwgdGV4U2hhcGUpKSB7XG4gICAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICB2ZWMyIHV2ID0gKHZlYzIoY29sLCByb3cpICsgaGFsZkNSKSAvIHZlYzIoJHt0ZXhOdW1DfS4wLCAke3RleE51bVJ9LjApO1xuICAgICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgICAgfWA7XG5cbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUocGFja2VkU2FtcGxlcik7XG4gICAgfVxuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gdGV4U2hhcGU7XG4gICAgY29uc3QgdmFsdWVzUGVyUm93ID0gTWF0aC5jZWlsKHNoYXBlWzFdIC8gMik7XG4gICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGB2ZWM0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgIHZlYzIgdXYgPSBwYWNrZWRVVmZyb20yRCgke3BhY2tlZFRleFNoYXBlWzFdfSwgJHtwYWNrZWRUZXhTaGFwZVswXX0sICR7dmFsdWVzUGVyUm93fSwgcm93LCBjb2wpO1xuICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTtcbiAgICB9YDtcbiAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnBhY2tlZFVWZnJvbTJEJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhY2tlZCAzRCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXIzRChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCB0ZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV1dO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICBpZiAoc2hhcGVbMF0gPT09IDEpIHtcbiAgICAgIGNvbnN0IHNxdWVlemVkU2hhcGUgPSBzaGFwZS5zbGljZSgxKTtcbiAgICAgIGNvbnN0IGtlcHREaW1zID0gWzEsIDJdO1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBzcXVlZXplZFNoYXBlKTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IFsnYicsICdyb3cnLCAnY29sJ107XG4gICAgICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuICAgICAgY29uc3Qgc2FtcGxlclJvdXRpbmUgPSB0aGlzLmdldFBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KTtcbiAgICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgJHtzYW1wbGVyUm91dGluZS5yb3V0aW5lQm9keX1cbiAgICAgIHZlYzQgJHtmdW5jTmFtZX0oaW50IGIsIGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgcmV0dXJuICR7ZnVuY05hbWV9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zLCBrZXB0RGltcyl9KTtcbiAgICAgIH0gYDtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgc2FtcGxlclJvdXRpbmUuZGVwZW5kZW5jaWVzKTtcbiAgICB9XG4gICAgY29uc3QgdGV4TnVtUiA9IHBhY2tlZFRleFNoYXBlWzBdO1xuICAgIGNvbnN0IHRleE51bUMgPSBwYWNrZWRUZXhTaGFwZVsxXTtcblxuICAgIGNvbnN0IHZhbHVlc1BlclJvdyA9IE1hdGguY2VpbChzaGFwZVsyXSAvIDIpO1xuICAgIGNvbnN0IHRleGVsc0luQmF0Y2ggPSB2YWx1ZXNQZXJSb3cgKiBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcblxuICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfShpbnQgYiwgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgdmVjMiB1diA9IHBhY2tlZFVWZnJvbTNEKFxuICAgICAgICAke3RleE51bUN9LCAke3RleE51bVJ9LCAke3RleGVsc0luQmF0Y2h9LCAke3ZhbHVlc1BlclJvd30sIGIsIHJvdywgY29sKTtcbiAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7fWA7XG4gICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5wYWNrZWRVVmZyb20zRCddKTtcbiAgfVxuICAvKlxuICAgKiBQYWNrZWQgTkQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyTkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCB0ZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuXG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSBbdGV4U2hhcGVbMF0sIHRleFNoYXBlWzFdXTtcbiAgICBjb25zdCB0ZXhOdW1SID0gcGFja2VkVGV4U2hhcGVbMV07XG4gICAgY29uc3QgdGV4TnVtQyA9IHBhY2tlZFRleFNoYXBlWzBdO1xuICAgIGNvbnN0IHZhbHVlc1BlclJvdyA9IE1hdGguY2VpbChzaGFwZVtyYW5rIC0gMV0gLyAyKTtcbiAgICBsZXQgdGV4ZWxzSW5CYXRjaCA9IHZhbHVlc1BlclJvdyAqIE1hdGguY2VpbChzaGFwZVtyYW5rIC0gMl0gLyAyKTtcbiAgICBsZXQgcGFyYW1zID0gJ2ludCBiLCBpbnQgcm93LCBpbnQgY29sJztcbiAgICBsZXQgaW5kZXggPSBgYiAqICR7dGV4ZWxzSW5CYXRjaH0gKyAocm93IC8gMikgKiAke3ZhbHVlc1BlclJvd30gKyAoY29sIC8gMilgO1xuICAgIGZvciAobGV0IGIgPSAyOyBiIDwgcmFuayAtIDE7IGIrKykge1xuICAgICAgcGFyYW1zID0gYGludCBiJHtifSwgYCArIHBhcmFtcztcbiAgICAgIHRleGVsc0luQmF0Y2ggKj0gc2hhcGVbcmFuayAtIGIgLSAxXTtcbiAgICAgIGluZGV4ID0gYGIke2J9ICogJHt0ZXhlbHNJbkJhdGNofSArIGAgKyBpbmRleDtcbiAgICB9XG4gICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGB2ZWM0ICR7ZnVuY05hbWV9KCR7cGFyYW1zfSkge1xuICAgICAgaW50IGluZGV4ID0gJHtpbmRleH07XG4gICAgICBpbnQgdGV4UiA9IGluZGV4IC8gJHt0ZXhOdW1DfTtcbiAgICAgIGludCB0ZXhDID0gaW5kZXggLSB0ZXhSICogJHt0ZXhOdW1DfTtcbiAgICAgIHZlYzIgdXYgPSAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKCR7dGV4TnVtQ30sICR7dGV4TnVtUn0pO1xuICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTtcbiAgICB9YDtcbiAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCBzY2FsYXIgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXJTY2FsYXIoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBbdGV4TnVtUiwgdGV4TnVtQ10gPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgaWYgKHRleE51bVIgPT09IDEgJiYgdGV4TnVtQyA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgaGFsZkNSKTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cblxuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgaW50IG9mZnNldF8ke25hbWV9ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke3RleE51bVJ9LCAke3RleE51bUN9KTtcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBvZmZzZXRfJHtuYW1lfSk7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbXG4gICAgICAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsXG4gICAgICAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsXG4gICAgICAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDFEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyMUQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCB0TnVtUiA9IGlucHV0TGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IHROdW1DID0gaW5wdXRMYXlvdXQuaGVpZ2h0O1xuXG4gICAgaWYgKHROdW1DID09PSAxICYmIHROdW1SID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCBpbmRleCkge1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIGhhbGZDUik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cblxuICAgIGlmICh0TnVtQyA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCBpbmRleCkge1xuICAgICAgICAgICAgdmVjMiB1diA9IHZlYzIoKGZsb2F0KGluZGV4KSArIDAuNSkgLyAke3ROdW1SfS4wLCAwLjUpO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuICAgIGlmICh0TnVtUiA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCBpbmRleCkge1xuICAgICAgICAgICAgdmVjMiB1diA9IHZlYzIoMC41LCAoZmxvYXQoaW5kZXgpICsgMC41KSAvICR7dE51bUN9LjApO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0TnVtUn0sICR7dE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAyRCBzbmlwcGV0LlxuICAgKi9cblxuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyMkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG5cbiAgICAvLyBUT0RPOiBtb2RpZnkgcm93L2NvbCBvcmRlciBmb3Igb3RoZXIgZGltZW5zaW9ucy5cbiAgICBjb25zdCB0ZXhTaGFwZSA9IFtpbnB1dExheW91dC5oZWlnaHQsIGlucHV0TGF5b3V0LndpZHRoXTtcblxuICAgIGlmICh0ZXhTaGFwZSAhPSBudWxsICYmIEFycmF5VXRpbC5hcnJheXNFcXVhbChzaGFwZSwgdGV4U2hhcGUpKSB7XG4gICAgICBjb25zdCB0ZXhOdW1SID0gdGV4U2hhcGVbMV07XG4gICAgICBjb25zdCB0ZXhOdW1DID0gdGV4U2hhcGVbMF07XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgICAgdmVjMiB1diA9ICh2ZWMyKHJvdywgY29sKSArIGhhbGZDUikgLyB2ZWMyKCR7dGV4TnVtUn0uMCwgJHt0ZXhOdW1DfS4wKTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cblxuICAgIGNvbnN0IHsgbmV3U2hhcGUsIGtlcHREaW1zIH0gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIGNvbnN0IHNxdWVlemVkU2hhcGUgPSBuZXdTaGFwZTtcbiAgICBpZiAoc3F1ZWV6ZWRTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgc3F1ZWV6ZWRTaGFwZSk7XG4gICAgICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ2NvbCcsICdyb3cnXTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgICAgcmV0dXJuICR7ZnVuY05hbWV9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zLCBrZXB0RGltcyl9KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cblxuICAgIGNvbnN0IHRleE51bVIgPSB0ZXhTaGFwZVsxXTtcbiAgICBjb25zdCB0ZXhOdW1DID0gdGV4U2hhcGVbMF07XG4gICAgaWYgKHRleE51bUMgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICBpbnQgb2Zmc2V0XyR7bmFtZX0gPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7dGV4TnVtUn0sICR7dGV4TnVtQ30pO1xuICAgICAgICAgICAgZmxvYXQgaW5kZXggPSBkb3QodmVjMyhyb3csIGNvbCwgb2Zmc2V0XyR7bmFtZX0pLCB2ZWMzKCR7c2hhcGVbMV19LCAxLCAxKSk7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdmVjMigwLjUsIChpbmRleCArIDAuNSkgLyAke3RleE51bVJ9LjApO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSk7XG4gICAgfVxuXG4gICAgaWYgKHRleE51bVIgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICBpbnQgb2Zmc2V0XyR7bmFtZX0gPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7dGV4TnVtUn0sICR7dGV4TnVtQ30pO1xuICAgICAgICAgICAgZmxvYXQgaW5kZXggPSBkb3QodmVjMyhyb3csIGNvbCwgb2Zmc2V0XyR7bmFtZX0pLCB2ZWMzKCR7c2hhcGVbMV19LCAxLCAxKSk7XG4gICAgICAgICAgICB2ZWMyIHV2ID0gdmVjMigoaW5kZXggKyAwLjUpIC8gJHt0ZXhOdW1DfS4wLCAwLjUpO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgaW50IGluZGV4ID0gY29sICogJHtzaGFwZVsxXX0gKyByb3c7XG4gICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgW1xuICAgICAgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0JyxcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAzRCBzbmlwcGV0LlxuICAgKi9cblxuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyM0QoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlMCA9IHNoYXBlWzFdICogc2hhcGVbMl07XG4gICAgY29uc3Qgc3RyaWRlMSA9IHNoYXBlWzJdO1xuXG4gICAgY29uc3QgeyBuZXdTaGFwZSwga2VwdERpbXMgfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgY29uc3Qgc3F1ZWV6ZWRTaGFwZSA9IG5ld1NoYXBlO1xuICAgIGlmIChzcXVlZXplZFNoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBzcXVlZXplZFNoYXBlKTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IFsnYmF0Y2gnLCAnY29sJywgJ3JvdyddO1xuICAgICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcbiAgICAgIGNvbnN0IHJvdXRpbmUgPSB0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpO1xuICAgICAgLy8gVE9ETzogcmV2aXNpdCB0aGUgbG9naWMgaGVyZSB0byBtYWtlIGl0IHNpbXBsZXJcbiAgICAgIGNvbnN0IHJldkRpbXMgPSBrZXB0RGltcy5yZXZlcnNlKCk7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgJHtyb3V0aW5lLnJvdXRpbmVCb2R5fVxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCBiYXRjaCwgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgICAgcmV0dXJuICR7ZnVuY05hbWV9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zLCByZXZEaW1zKX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCByb3V0aW5lLmRlcGVuZGVuY2llcyk7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IGlucHV0TGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IHRleE51bUMgPSBpbnB1dExheW91dC5oZWlnaHQ7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCBkZXB0aCwgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICAgICAgLy8gRXhwbGljaXRseSB1c2UgaW50ZWdlciBvcGVyYXRpb25zIGFzIGRvdCgpIG9ubHkgd29ya3Mgb24gZmxvYXRzLlxuICAgICAgICAgICAgaW50IGluZGV4ID0gZGVwdGggKiAke3N0cmlkZTB9ICsgY29sICogJHtzdHJpZGUxfSArIHJvdztcbiAgICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbXG4gICAgICAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsXG4gICAgICAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsXG4gICAgICAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDREIHNuaXBwZXQuXG4gICAqL1xuXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXI0RChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBzdHJpZGUyID0gc2hhcGVbM107XG4gICAgY29uc3Qgc3RyaWRlMSA9IHNoYXBlWzJdICogc3RyaWRlMjtcbiAgICBjb25zdCBzdHJpZGUwID0gc2hhcGVbMV0gKiBzdHJpZGUxO1xuXG4gICAgLy9cbiAgICAvLyBUT0RPOiByZS1lbmFibGUgdGhpcyBzaG9ydGN1dCBvbmNlIHRoZSBpbmRleCBjYWxjdWxhdGlvbiBidWcgaXMgZml4ZWQuXG4gICAgLy9cbiAgICAvLyBjb25zdCB7bmV3U2hhcGUsIGtlcHREaW1zfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgLy8gaWYgKG5ld1NoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgIC8vICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBuZXdTaGFwZSk7XG4gICAgLy8gICBjb25zdCBwYXJhbXMgPSBbJ3JvdycsICdjb2wnLCAnZGVwdGgnLCAnZGVwdGgyJ107XG4gICAgLy8gICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgLy8gICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAvLyAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuICAgIC8vICAgY29uc3Qgc291cmNlID0gYFxuICAgIC8vICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAvLyAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIpIHtcbiAgICAvLyAgICAgICAgIHJldHVybiAke2Z1bmNOYW1lfSgke2dldFNxdWVlemVkUGFyYW1zKHBhcmFtcywga2VwdERpbXMpfSk7XG4gICAgLy8gICAgICAgfVxuICAgIC8vICAgICBgO1xuICAgIC8vICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShcbiAgICAvLyAgICAgICBzb3VyY2UsIFsnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0J10pO1xuICAgIC8vIH1cblxuICAgIGNvbnN0IHRleE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0ZXhOdW1DID0gaW5wdXRMYXlvdXQuaGVpZ2h0O1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7XG4gICAgICAgICAgaW50IGluZGV4ID0gcm93ICogJHtzdHJpZGUwfSArIGNvbCAqICR7c3RyaWRlMX0gK1xuICAgICAgICAgICAgICBkZXB0aDIgKiAke3N0cmlkZTJ9ICsgZGVwdGg7XG4gICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy51dkZyb21GbGF0JywgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNUQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXI1RChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBzdHJpZGUzID0gc2hhcGVbNF07XG4gICAgY29uc3Qgc3RyaWRlMiA9IHNoYXBlWzNdICogc3RyaWRlMztcbiAgICBjb25zdCBzdHJpZGUxID0gc2hhcGVbMl0gKiBzdHJpZGUyO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHN0cmlkZTE7XG5cbiAgICBjb25zdCB7IG5ld1NoYXBlLCBrZXB0RGltcyB9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICBpZiAobmV3U2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIG5ld1NoYXBlKTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IFsncm93JywgJ2NvbCcsICdkZXB0aCcsICdkZXB0aDInLCAnZGVwdGgzJ107XG4gICAgICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuXG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgJHt0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpLnJvdXRpbmVCb2R5fVxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMiwgaW50IGRlcHRoMykge1xuICAgICAgICAgICAgcmV0dXJuICR7ZnVuY05hbWV9KCR7Z2V0U3F1ZWV6ZWRQYXJhbXMocGFyYW1zLCBrZXB0RGltcyl9KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IGlucHV0TGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IHRleE51bUMgPSBpbnB1dExheW91dC5oZWlnaHQ7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sLCBpbnQgZGVwdGgsIGludCBkZXB0aDIsIGludCBkZXB0aDMpIHtcbiAgICAgICAgICBpbnQgaW5kZXggPSByb3cgKiAke3N0cmlkZTB9ICsgY29sICogJHtzdHJpZGUxfSArIGRlcHRoICogJHtzdHJpZGUyfSArXG4gICAgICAgICAgZGVwdGgzICogJHtzdHJpZGUzfSArIGRlcHRoMjtcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA2RCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjZEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHN0cmlkZTQgPSBzaGFwZVs1XTtcbiAgICBjb25zdCBzdHJpZGUzID0gc2hhcGVbNF0gKiBzdHJpZGU0O1xuICAgIGNvbnN0IHN0cmlkZTIgPSBzaGFwZVszXSAqIHN0cmlkZTM7XG4gICAgY29uc3Qgc3RyaWRlMSA9IHNoYXBlWzJdICogc3RyaWRlMjtcbiAgICBjb25zdCBzdHJpZGUwID0gc2hhcGVbMV0gKiBzdHJpZGUxO1xuXG4gICAgY29uc3QgeyBuZXdTaGFwZSwga2VwdERpbXMgfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgaWYgKG5ld1NoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBuZXdTaGFwZSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ3JvdycsICdjb2wnLCAnZGVwdGgnLCAnZGVwdGgyJywgJ2RlcHRoMycsICdkZXB0aDQnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCxcbiAgICAgICAgICAgICAgaW50IGRlcHRoMiwgaW50IGRlcHRoMywgaW50IGRlcHRoNCkge1xuICAgICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IGlucHV0TGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IHRleE51bUMgPSBpbnB1dExheW91dC5oZWlnaHQ7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCxcbiAgICAgICAgICAgIGludCBkZXB0aDIsIGludCBkZXB0aDMsIGludCBkZXB0aDQpIHtcbiAgICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgZGVwdGggKiAke3N0cmlkZTJ9ICtcbiAgICAgICAgICAgIGRlcHRoMiAqICR7c3RyaWRlM30gKyBkZXB0aDMgKiAke3N0cmlkZTR9ICsgZGVwdGg0O1xuICAgICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgW1xuICAgICAgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLFxuICAgICAgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0JyxcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGlzIHRoZSBtYWluIGZ1bmN0aW9uIHRvIG1hcCBmcm9tIHRoZSBnaXZlbiB0ZXh0dXJlIGNvb3JkaW5hdGVzIChzLHQpXG4gICAqIHRvIGxvZ2ljYWwgaW5kaWNlcyBmb3IgdGhlIG91dHB1dFxuICAgKiBUaGVyZSB3aWxsIG9ubHkgYmUgb25lIHNpbmdsZSB2YXJpYXRpb24gb2YgdGhpc1xuICAgKiBBbHNvIHNlZSBjb29yZHNUb09mZnNldCBhbmQgb2Zmc2V0VG9JbmRpY2VzIGZvciBpbnB1dC1zcGVjaWZpYyB2ZXJzaW9uc1xuICAgKi9cbiAgcHJvdGVjdGVkIHRvVmVjKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHN0cmlkZXMgPSBvdXRwdXQuc3RyaWRlcztcbiAgICBjb25zdCB4U2NhbGUgPSBvdXRwdXQud2lkdGg7XG4gICAgY29uc3QgeVNjYWxlID0gb3V0cHV0LmhlaWdodDtcblxuICAgIGNvbnN0IHN0cmlkZXNCbG9jayA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBjWyR7aX1dID0gb2Zmc2V0IC8gJHtzdHJpZGVzW2ldfTtgKTtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgICAgb2Zmc2V0IC09IGNbJHtpfV0gKiAke3N0cmlkZXNbaV19O2ApO1xuICAgIH1cbiAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICAgIGNbJHtyYW5rIC0gMX1dID0gb2Zmc2V0O2ApO1xuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICB2b2lkIHRvVmVjKHZlYzIgdGV4Q29vcmRzLCBvdXQgaW50IGNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IGNvb3Jkc1RvT2Zmc2V0KHRleENvb3JkcywgJHt4U2NhbGV9LCAke3lTY2FsZX0pO1xuICAgICAgICAke3N0cmlkZXNCbG9jay5qb2luKCcnKX1cbiAgICAgIH1cbiAgICAgIHZvaWQgdG9WZWMoaW50IG9mZnNldCwgb3V0IGludCBjWyR7cmFua31dKSB7XG4gICAgICAgICR7c3RyaWRlc0Jsb2NrLmpvaW4oJycpfVxuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIHsgdG9WZWM6IG5ldyBHbHNsTGliUm91dGluZShib2R5LCBbJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0J10pIH07XG4gIH1cbiAgLyoqXG4gICAqIFRoZXNlIGFyZSB2YWx1ZSBnZXR0ZXIgZnVuY3Rpb25zIGdlbmVyYXRlZCBmb3IgZWFjaCBpbnB1dFxuICAgKiBFYWNoIGZ1bmN0aW9uIGlzIGhhcmR3aXJlZCB0byB0aGUgbmFtZSBhbmQgZGltZW5zaW9ucyBvZiB0aGUgaW5wdXRcbiAgICogQW4gJ19UJyB2YXJpYXRpb24gaXMgYWxzbyBwcm9kdWNlZCB3aGljaCBhY2Nlc3NlcyB2YWx1ZXMgYXMgaWYgdGhlXG4gICAqIGlucHV0IHdhcyB0cmFuc3Bvc2VkXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsdWVGcm9tKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IGxheW91dCA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldO1xuICAgICAgY29uc3Qgc2hhcGUgPSBsYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGggPiAwID8gbGF5b3V0LnVucGFja2VkU2hhcGUgOiBsYXlvdXQuc2hhcGU7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgbGV0IGZ1bmNOYW1lID0gYF8ke25hbWV9YDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUodGhpcy5nZXRWYWx1ZUZyb21TaW5nbGUobmFtZSwgcmFuaywgbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0LCBmYWxzZSksIFtcbiAgICAgICAgYHNoYXBlVXRpbHMuaW5kaWNlc1RvT2Zmc2V0JHtmdW5jTmFtZX1gLFxuICAgICAgICAnY29vcmRpbmF0ZXMub2Zmc2V0VG9Db29yZHMnLFxuICAgICAgICAnZnJhZ2NvbG9yLmdldENvbG9yQXNGbG9hdCcsXG4gICAgICBdKTtcbiAgICAgIGZ1bmNOYW1lID0gZnVuY05hbWUgKyAnX1QnO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZSh0aGlzLmdldFZhbHVlRnJvbVNpbmdsZShuYW1lLCByYW5rLCBsYXlvdXQud2lkdGgsIGxheW91dC5oZWlnaHQsIHRydWUpLCBbXG4gICAgICAgIGBzaGFwZVV0aWxzLmluZGljZXNUb09mZnNldCR7ZnVuY05hbWV9YCxcbiAgICAgICAgJ2Nvb3JkaW5hdGVzLm9mZnNldFRvQ29vcmRzJyxcbiAgICAgICAgJ2ZyYWdjb2xvci5nZXRDb2xvckFzRmxvYXQnLFxuICAgICAgXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICAvKipcbiAgICogUHJvZHVjZXMgb25lIHZhbHVlIGdldHRlciBmdW5jdGlvbiBmb3IgdGhlIG5hbWUgYW5kIHJhbmsgZ2l2ZW5cbiAgICogSWYgYSB0cmFuc3Bvc2UgaXMgc2V0IHByb3BlciBvZmZzZXRUb0Nvb3JkcyBtYXBwaW5nIHdpbGwgYmUgdXNlZFxuICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHRoZSBmdW5jdGlvblxuICAgKiBAcGFyYW0gcmFuayByYW5rIG9mIHRoZSBpbnB1dFxuICAgKiBAcGFyYW0gdHJhbnNwb3NlIHdoZXRoZXIgb3Igbm90IHNob3VsZCBnZW5lcmF0ZSBhIHRyYW5zcG9zZSB2YXJpYXRpb25cbiAgICovXG4gIHByb3RlY3RlZCBnZXRWYWx1ZUZyb21TaW5nbGUoXG4gICAgdmFyTmFtZTogc3RyaW5nLFxuICAgIHJhbms6IG51bWJlcixcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIHRyYW5zcG9zZTogYm9vbGVhbixcbiAgKTogc3RyaW5nIHtcbiAgICBsZXQgbmFtZSA9IGBfJHt2YXJOYW1lfWA7XG4gICAgaWYgKHRyYW5zcG9zZSkge1xuICAgICAgbmFtZSA9IG5hbWUgKyAnX1QnO1xuICAgIH1cbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJldHVybiBgXG4gICAgICAgIGZsb2F0ICR7bmFtZX0oaW50IG1bJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgb2Zmc2V0ID0gaW5kaWNlc1RvT2Zmc2V0JHtuYW1lfShtKTtcbiAgICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oJHt2YXJOYW1lfSwgY29vcmRzKSk7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGA7XG4gIH1cblxuICAvKipcbiAgICogUHJvZHVjZXMgYSBwYWNrZWQgdmFsdWUgZ2V0dGVyIGZ1bmN0aW9uIGZvciB0aGUgbmFtZSBhbmQgcmFuayBnaXZlblxuICAgKiBJZiBhIHRyYW5zcG9zZSBpcyBzZXQgcHJvcGVyIG9mZnNldFRvQ29vcmRzIG1hcHBpbmcgd2lsbCBiZSB1c2VkXG4gICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSByYW5rIHJhbmsgb2YgdGhlIGlucHV0XG4gICAqIEBwYXJhbSB0cmFuc3Bvc2Ugd2hldGhlciBvciBub3Qgc2hvdWxkIGdlbmVyYXRlIGEgdHJhbnNwb3NlIHZhcmlhdGlvblxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFZhbHVlRnJvbShcbiAgICB2YXJOYW1lOiBzdHJpbmcsXG4gICAgcmFuazogbnVtYmVyLFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgdHJhbnNwb3NlOiBib29sZWFuLFxuICApOiBzdHJpbmcge1xuICAgIGxldCBuYW1lID0gYF8ke3Zhck5hbWV9X1BhY2tgO1xuICAgIGlmICh0cmFuc3Bvc2UpIHtcbiAgICAgIG5hbWUgPSBuYW1lICsgJ19UJztcbiAgICB9XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICByZXR1cm4gYFxuICAgICAgICB2ZWM0ICR7bmFtZX0oaW50IG1bJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgb2Zmc2V0ID0gaW5kaWNlc1RvT2Zmc2V0XyR7dmFyTmFtZX0obSk7XG4gICAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7d2lkdGh9LCAke2hlaWdodH0pO1xuICAgICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke3Zhck5hbWV9LCBjb29yZHMpO1xuICAgICAgICB9XG4gICAgICAgIGA7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcblxuLyoqXG4gKiBUaGlzIEdMU0wgbGlicmFyeSBoYW5kbGVzIHJvdXRpbmVzIGNvbnZlcnRpbmdcbiAqIGZsb2F0MzIgdG8vZnJvbSBVbnNpZ25lZCBieXRlIG9yIGZsb2F0IDE2XG4gKi9cbmV4cG9ydCBjbGFzcyBFbmNvZGluZ0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHsgLi4udGhpcy5lbmNvZGVGbG9hdDMyKCksIC4uLnRoaXMuZGVjb2RlRmxvYXQzMigpIH07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBwcm90ZWN0ZWQgZW5jb2RlRmxvYXQzMigpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4ge1xuICAgICAgZW5jb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYGhpZ2hwIHZlYzQgZW5jb2RlKGhpZ2hwIGZsb2F0IGYpIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoZiwgMC4wLCAwLjAsIDAuMCk7XG4gICAgICB9XG4gICAgICAgIGApLFxuICAgIH07XG4gIH1cbiAgcHJvdGVjdGVkIGRlY29kZUZsb2F0MzIoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRlY29kZTogbmV3IEdsc2xMaWJSb3V0aW5lKGBoaWdocCBmbG9hdCBkZWNvZGUoaGlnaHAgdmVjNCByZ2JhKSB7XG4gICAgICAgIHJldHVybiByZ2JhLnI7XG4gICAgICB9XG4gICAgICAgIGApLFxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIHJldHVybnMgdGhlIHJvdXRpbmUgdG8gZW5jb2RlIGVuY29kZSBhIDMyYml0IGZsb2F0IHRvIGEgdmVjNCAob2YgdW5zaWduZWQgYnl0ZXMpXG4gICAqIEBjcmVkaXQ6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzcwNTk5NjIvaG93LWRvLWktY29udmVydC1hLXZlYzQtcmdiYS12YWx1ZS10by1hLWZsb2F0XG4gICAqL1xuICBwcm90ZWN0ZWQgZW5jb2RlVWludDgoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgZW5kaWFubmVzcyA9IEVuY29kaW5nR2xzbExpYi5pc0xpdHRsZUVuZGlhbigpID8gJ3JnYmEucmdiYT1yZ2JhLmFiZ3I7JyA6ICcnO1xuICAgIHJldHVybiB7XG4gICAgICBlbmNvZGU6IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICBoaWdocCB2ZWM0IGVuY29kZShoaWdocCBmbG9hdCBmKSB7XG4gICAgICAgIGhpZ2hwIGZsb2F0IEYgPSBhYnMoZik7XG4gICAgICAgIGhpZ2hwIGZsb2F0IFNpZ24gPSBzdGVwKDAuMCwtZik7XG4gICAgICAgIGhpZ2hwIGZsb2F0IEV4cG9uZW50ID0gZmxvb3IobG9nMihGKSk7XG4gICAgICAgIGhpZ2hwIGZsb2F0IE1hbnRpc3NhID0gKGV4cDIoLSBFeHBvbmVudCkgKiBGKTtcbiAgICAgICAgRXhwb25lbnQgPSBmbG9vcihsb2cyKEYpICsgMTI3LjApICsgZmxvb3IobG9nMihNYW50aXNzYSkpO1xuICAgICAgICBoaWdocCB2ZWM0IHJnYmE7XG4gICAgICAgIHJnYmFbMF0gPSAxMjguMCAqIFNpZ24gICsgZmxvb3IoRXhwb25lbnQqZXhwMigtMS4wKSk7XG4gICAgICAgIHJnYmFbMV0gPSAxMjguMCAqIG1vZChFeHBvbmVudCwyLjApICsgbW9kKGZsb29yKE1hbnRpc3NhKjEyOC4wKSwxMjguMCk7XG4gICAgICAgIHJnYmFbMl0gPSBmbG9vcihtb2QoZmxvb3IoTWFudGlzc2EqZXhwMigyMy4wIC04LjApKSxleHAyKDguMCkpKTtcbiAgICAgICAgcmdiYVszXSA9IGZsb29yKGV4cDIoMjMuMCkqbW9kKE1hbnRpc3NhLGV4cDIoLTE1LjApKSk7XG4gICAgICAgICR7ZW5kaWFubmVzc31cbiAgICAgICAgcmdiYSA9IHJnYmEgLyAyNTUuMDsgLy8gdmFsdWVzIG5lZWQgdG8gYmUgbm9ybWFsaXplZCB0byBbMCwxXVxuICAgICAgICByZXR1cm4gcmdiYTtcbiAgICB9XG4gICAgICAgIGApLFxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIHJldHVybnMgdGhlIHJvdXRpbmUgdG8gZW5jb2RlIGEgdmVjNCBvZiB1bnNpZ25lZCBieXRlcyB0byBmbG9hdDMyXG4gICAqIEBjcmVkaXQ6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzcwNTk5NjIvaG93LWRvLWktY29udmVydC1hLXZlYzQtcmdiYS12YWx1ZS10by1hLWZsb2F0XG4gICAqL1xuICBwcm90ZWN0ZWQgZGVjb2RlVWludDgoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgZW5kaWFubmVzcyA9IEVuY29kaW5nR2xzbExpYi5pc0xpdHRsZUVuZGlhbigpID8gJ3JnYmEucmdiYT1yZ2JhLmFiZ3I7JyA6ICcnO1xuICAgIHJldHVybiB7XG4gICAgICBkZWNvZGU6IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICAgIGhpZ2hwIGZsb2F0IGRlY29kZShoaWdocCB2ZWM0IHJnYmEpIHtcbiAgICAgICAgICByZ2JhID0gcmdiYSAqIDI1NS4wOyAvLyB2YWx1ZXMgbmVlZCB0byBiZSBkZS1ub3JtYWxpemVkIGZyb20gWzAsMV0gdG8gWzAsMjU1XVxuICAgICAgICAgICR7ZW5kaWFubmVzc31cbiAgICAgICAgICBoaWdocCBmbG9hdCBTaWduID0gMS4wIC0gc3RlcCgxMjguMCxyZ2JhWzBdKSoyLjA7XG4gICAgICAgICAgaGlnaHAgZmxvYXQgRXhwb25lbnQgPSAyLjAgKiBtb2QocmdiYVswXSwxMjguMCkgKyBzdGVwKDEyOC4wLHJnYmFbMV0pIC0gMTI3LjA7XG4gICAgICAgICAgaGlnaHAgZmxvYXQgTWFudGlzc2EgPSBtb2QocmdiYVsxXSwxMjguMCkqNjU1MzYuMCArIHJnYmFbMl0qMjU2LjAgK3JnYmFbM10gKyBmbG9hdCgweDgwMDAwMCk7XG4gICAgICAgICAgaGlnaHAgZmxvYXQgUmVzdWx0ID0gIFNpZ24gKiBleHAyKEV4cG9uZW50KSAqIChNYW50aXNzYSAqIGV4cDIoLTIzLjAgKSk7XG4gICAgICAgICAgcmV0dXJuIFJlc3VsdDtcbiAgICAgIH1cbiAgICAgICAgYCksXG4gICAgfTtcbiAgfVxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBpZiB0aGUgbWFjaGluZSBpcyBsaXR0bGUgZW5kaWFuIG9yIG5vdFxuICAgKiBAY3JlZGl0OiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9Ub29UYWxsTmF0ZS80NzUwOTUzXG4gICAqL1xuICBzdGF0aWMgaXNMaXR0bGVFbmRpYW4oKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYiA9IG5ldyBBcnJheUJ1ZmZlcig0KTtcbiAgICBjb25zdCBhID0gbmV3IFVpbnQzMkFycmF5KGIpO1xuICAgIGNvbnN0IGMgPSBuZXcgVWludDhBcnJheShiKTtcbiAgICBhWzBdID0gMHhkZWFkYmVlZjtcbiAgICBpZiAoY1swXSA9PT0gMHhlZikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChjWzBdID09PSAweGRlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBlbmRpYW5uZXNzJyk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgR2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lIH0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7IGdldEdsc2wgfSBmcm9tICcuL2dsc2wtc291cmNlJztcblxuLyoqXG4gKiBUaGlzIEdMU0wgbGlicmFyeSBoYW5kbGVzIHJvdXRpbmVzIGFyb3VuZCByZWFkaW5nIGEgdGV4bGV0IGFuZCB3cml0aW5nIHRvIGl0XG4gKiBSZWFkaW5nIGFuZCB3cml0aW5nIGNvdWxkIGJlIG1vcmUgdGhhbiBqdXN0IGRlYWxpbmcgd2l0aCBvbmUgY2hhbm5lbFxuICogSXQgbWF5IHJlcXVpcmUgZW5jb2RpbmcvZGVjb2RpbmcgdG8vZnJvbSA0IGNoYW5uZWxzIGludG8gb25lXG4gKi9cbmV4cG9ydCBjbGFzcyBGcmFnQ29sb3JHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEdsc2xDb250ZXh0KSB7XG4gICAgc3VwZXIoY29udGV4dCk7XG4gIH1cbiAgZ2V0RnVuY3Rpb25zKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIHJldHVybiB7IC4uLnRoaXMuc2V0RnJhZ0NvbG9yKCksIC4uLnRoaXMuZ2V0Q29sb3JBc0Zsb2F0KCkgfTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIHByb3RlY3RlZCBzZXRGcmFnQ29sb3IoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICByZXR1cm4ge1xuICAgICAgc2V0RnJhZ0NvbG9yOiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgIGBcbiAgICAgICAgdm9pZCBzZXRGcmFnQ29sb3IoZmxvYXQgdmFsdWUpIHtcbiAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gZW5jb2RlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBgLFxuICAgICAgICBbJ2VuY29kaW5nLmVuY29kZSddLFxuICAgICAgKSxcbiAgICB9O1xuICB9XG4gIHByb3RlY3RlZCBnZXRDb2xvckFzRmxvYXQoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGdldENvbG9yQXNGbG9hdDogbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICBgXG4gICAgICAgIGZsb2F0IGdldENvbG9yQXNGbG9hdCh2ZWM0IGNvbG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVjb2RlKGNvbG9yKTtcbiAgICAgICAgfVxuICAgICAgICBgLFxuICAgICAgICBbJ2VuY29kaW5nLmRlY29kZSddLFxuICAgICAgKSxcbiAgICB9O1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZSB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5cbi8qKlxuICogR0xTTCBMaWJyYXJ5IHJlc3BvbnNpYmxlIGZvciBkYXRhIHR5cGVzIGFuZCByb3V0aW5lcyBmb3IgbWFuaXB1bGF0aW5nXG4gKiBjb29yZGluYXRlcyBhbmQgbWFwcGluZyB0by9mcm9tIHRlbnNvciBpbmRpY2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBTaGFwZVV0aWxzR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5iY2FzdEluZGV4KCksXG4gICAgICAuLi50aGlzLmJjYXN0TWF0bXVsSW5kZXgoKSxcbiAgICAgIC4uLnRoaXMub2Zmc2V0VG9JbmRpY2VzKCksXG4gICAgICAuLi50aGlzLmluZGljZXNUb09mZnNldCgpLFxuICAgICAgLi4udGhpcy5pbmNyZW1lbnRJbmRpY2VzKCksXG4gICAgfTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpIHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgcHJvdGVjdGVkIGJjYXN0SW5kZXgoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0UmFuayA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnVucGFja2VkU2hhcGU7XG4gICAgICBpZiAoc2hhcGUubGVuZ3RoIDw9IG91dHB1dFJhbmspIHtcbiAgICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgICAgY29uc3QgZGltT2Zmc2V0ID0gb3V0cHV0UmFuayAtIHJhbms7XG4gICAgICAgIGNvbnN0IGZ1bmNOYW1lID0gYGJjYXN0SW5kaWNlc18ke25hbWV9YDtcbiAgICAgICAgbGV0IGJsb2NrID0gJyc7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICAgICAgYmxvY2sgKz0gYFxuICAgICAgICAgIHJlYWxJbmRpY2VzWyR7aX1dID0gaW50KCBtb2QoZmxvYXQoYmNhc3RlZEluZGljZXNbJHtkaW1PZmZzZXQgKyBpfV0pLCAke3NoYXBlW2ldfS4wKSApO1xuICAgICAgICAgIGA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYm9keSA9IGBcbiAgICAgICAgdm9pZCAke2Z1bmNOYW1lfSAoaW50IGJjYXN0ZWRJbmRpY2VzWyR7b3V0cHV0UmFua31dLCBvdXQgaW50IHJlYWxJbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgJHtibG9ja31cbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcHJvdGVjdGVkIGJjYXN0TWF0bXVsSW5kZXgoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0UmFuayA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgaWYgKCEoc2hhcGUubGVuZ3RoIDwgMiB8fCBzaGFwZS5sZW5ndGggPiBvdXRwdXRSYW5rKSkge1xuICAgICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgICBjb25zdCBkaW1PZmZzZXQgPSBvdXRwdXRSYW5rIC0gcmFuaztcbiAgICAgICAgY29uc3QgZnVuY05hbWUgPSBgYmNhc3RNYXRtdWxJbmRpY2VzXyR7bmFtZX1gO1xuICAgICAgICBsZXQgYmxvY2sgPSAnJztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMjsgKytpKSB7XG4gICAgICAgICAgYmxvY2sgKz0gYFxuICAgICAgICAgIHJlYWxJbmRpY2VzWyR7aX1dID0gaW50KCBtb2QoZmxvYXQoYmNhc3RlZEluZGljZXNbJHtkaW1PZmZzZXQgKyBpfV0pLCAke3NoYXBlW2ldfS4wKSApO1xuICAgICAgICAgIGA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYm9keSA9IGBcbiAgICAgICAgdm9pZCAke2Z1bmNOYW1lfShpbnQgYmNhc3RlZEluZGljZXNbJHtvdXRwdXRSYW5rfV0sIG91dCBpbnQgcmVhbEluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICAke2Jsb2NrfVxuICAgICAgICAgIHJlYWxJbmRpY2VzWyR7cmFuayAtIDF9XSA9IGJjYXN0ZWRJbmRpY2VzWyR7b3V0cHV0UmFuayAtIDF9XTtcbiAgICAgICAgICByZWFsSW5kaWNlc1ske3JhbmsgLSAyfV0gPSBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmsgLSAyfV07XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShib2R5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHByb3RlY3RlZCBpbmRpY2VzVG9PZmZzZXQoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zaGFwZTtcbiAgICAgIGNvbnN0IHN0cmlkZXMgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zdHJpZGVzO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBmdW5jTmFtZSA9IGBpbmRpY2VzVG9PZmZzZXRfJHtuYW1lfWA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKFNoYXBlVXRpbHNHbHNsTGliLmluZGV4VG9PZmZzZXRTaW5nbGUoZnVuY05hbWUsIHJhbmssIHN0cmlkZXMpKTtcbiAgICAgIGZ1bmNOYW1lID0gYGluZGljZXNUb09mZnNldF8ke25hbWV9X1RgO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgU2hhcGVVdGlsc0dsc2xMaWIuaW5kZXhUb09mZnNldFNpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcy5zbGljZSgpLnJldmVyc2UoKSksXG4gICAgICApO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgc3RhdGljIGluZGV4VG9PZmZzZXRTaW5nbGUobmFtZTogc3RyaW5nLCByYW5rOiBudW1iZXIsIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdKTogc3RyaW5nIHtcbiAgICBsZXQgYmxvY2sgPSAnJztcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBibG9jayArPSBgXG4gICAgICAgIG9mZnNldCArPSBpbmRpY2VzWyR7aX1dICogJHtzdHJpZGVzW2ldfTtcbiAgICAgICAgYDtcbiAgICB9XG4gICAgcmV0dXJuIGBcbiAgICAgIGludCAke25hbWV9KGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgICByZXR1cm4gb2Zmc2V0O1xuICAgICAgfVxuICAgICAgYDtcbiAgfVxuICBwcm90ZWN0ZWQgb2Zmc2V0VG9JbmRpY2VzKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBjb25zdCBzdHJpZGVzID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc3RyaWRlcztcbiAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICBsZXQgZnVuY05hbWUgPSBgb2Zmc2V0VG9JbmRpY2VzXyR7bmFtZX1gO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShTaGFwZVV0aWxzR2xzbExpYi5vZmZzZXRUb0luZGljZXNTaW5nbGUoZnVuY05hbWUsIHJhbmssIHN0cmlkZXMpKTtcbiAgICAgIGZ1bmNOYW1lID0gYG9mZnNldFRvSW5kaWNlc18ke25hbWV9X1RgO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgU2hhcGVVdGlsc0dsc2xMaWIub2Zmc2V0VG9JbmRpY2VzU2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzLnNsaWNlKCkucmV2ZXJzZSgpKSxcbiAgICAgICk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBzdGF0aWMgb2Zmc2V0VG9JbmRpY2VzU2luZ2xlKG5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RyaWRlc0Jsb2NrID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMTsgKytpKSB7XG4gICAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICBpbmRpY2VzWyR7aX1dID0gb2Zmc2V0IC8gJHtzdHJpZGVzW2ldfTtgKTtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgICAgb2Zmc2V0IC09IGluZGljZXNbJHtpfV0gKiAke3N0cmlkZXNbaV19O2ApO1xuICAgIH1cbiAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICBpbmRpY2VzWyR7cmFuayAtIDF9XSA9IG9mZnNldDtgKTtcbiAgICByZXR1cm4gYFxuICAgICAgdm9pZCAke25hbWV9KGludCBvZmZzZXQsIG91dCBpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAke3N0cmlkZXNCbG9jay5qb2luKCcnKX1cbiAgICAgIH1cbiAgICAgIGA7XG4gIH1cbiAgcHJvdGVjdGVkIGluY3JlbWVudEluZGljZXMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zaGFwZTtcbiAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICBjb25zdCBmdW5jTmFtZSA9IGBpbmNyZW1lbnRJbmRpY2VzXyR7bmFtZX1gO1xuICAgICAgbGV0IHNoYXBlSW5pdCA9ICcnO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAgICAgc2hhcGVJbml0ICs9IGBcbiAgICAgICAgc2hhcGVbJHtpfV0gPSAke3NoYXBlW2ldfTtgO1xuICAgICAgfVxuICAgICAgY29uc3QgYm9keSA9IGBcbiAgICAgICAgdm9pZCAke2Z1bmNOYW1lfShpbnQgYXhpcywgb3V0IGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IHNoYXBlWyR7cmFua31dO1xuICAgICAgICAgICR7c2hhcGVJbml0fTtcbiAgICAgICAgICBmb3IoaW50IGkgPSAke3Jhbmt9IC0xIDsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmKGkgPiBheGlzKSBjb250aW51ZTtcbiAgICAgICAgICAgIGluZGljZXNbaV0gKz0gMTtcbiAgICAgICAgICAgIGlmKGluZGljZXNbaV0gPCBzaGFwZVtpXSkge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGluZGljZXNbaV0gPSAwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShib2R5KTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZSB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5cbi8qKlxuICogR0xTTCBMaWJyYXJ5IHJlc3BvbnNpYmxlIGZvciB2ZWMgcm91dGluZXNcbiAqIFZlYyBpcyBhbiB2YXJpYmxlIGxlbmd0aCBpbnQgYXJyYXkuIFRoZSBsZW5ndGggaXMgZml4ZWQgYXQgdGhlIHRpbWUgb2ZcbiAqIGdlbmVyYXRpbmcgdGhlIGxpYnJhcnkgZnVuY3Rpb25zIGZyb20gdGhlIGRpbWVuc2lvbnMgb2YgdGhlIG91dHB1dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICByZXR1cm4geyAuLi50aGlzLmJpbmFyeVZlY0Z1bmN0aW9ucygpLCAuLi50aGlzLmNvcHlWZWMoKSwgLi4udGhpcy5zZXRWZWNJdGVtKCksIC4uLnRoaXMuZ2V0VmVjSXRlbSgpIH07XG4gIH1cbiAgcHJvdGVjdGVkIGJpbmFyeVZlY0Z1bmN0aW9ucygpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBuYW1lT3A6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9ID0geyBhZGQ6ICcrPScsIHN1YjogJy09JywgbXVsOiAnKj0nLCBkaXY6ICcvPScgfTtcbiAgICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gbmFtZU9wKSB7XG4gICAgICBjb25zdCBmbmFtZSA9IGAke25hbWV9VmVjYDtcbiAgICAgIGxldCBhc3NpZ25tZW50QmxvY2sgPSAnJztcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICAgIGFzc2lnbm1lbnRCbG9jayArPSBgXG4gICAgICAgICAgZGVzdFske2l9XSAke25hbWVPcFtuYW1lXX0gc3JjWyR7aX1dO1xuICAgICAgICAgIGA7XG4gICAgICB9XG4gICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7Zm5hbWV9KGludCBzcmNbJHtyYW5rfV0sIG91dCBpbnQgZGVzdFske3Jhbmt9XSkge1xuICAgICAgICAgICR7YXNzaWdubWVudEJsb2NrfVxuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXN1bHRbZm5hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcHJvdGVjdGVkIGNvcHlWZWMoKTogeyBbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmUgfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgbGV0IGFzc2lnbm1lbnRCbG9jayA9ICcnO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICBhc3NpZ25tZW50QmxvY2sgKz0gYFxuICAgICAgICBkZXN0WyR7aX1dID0gc3JjWyR7aX1dO1xuICAgICAgICBgO1xuICAgIH1cbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgdm9pZCBjb3B5VmVjKGludCBzcmNbJHtyYW5rfV0sIG91dCBpbnQgZGVzdFske3Jhbmt9XSkge1xuICAgICAgICAke2Fzc2lnbm1lbnRCbG9ja31cbiAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIHsgY29weVZlYzogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0VmVjSXRlbSgpOiB7IFtuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZSB9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBsZXQgYmxvY2sgPSBgXG4gICAgICAgIGlmKGluZGV4IDwgMClcbiAgICAgICAgICAgIGluZGV4ID0ke3Jhbmt9ICsgaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA9PSAwKVxuICAgICAgICAgICAgbVswXSA9IHZhbHVlO1xuICAgICAgICBgO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PSAke2l9KVxuICAgICAgICAgICAgbVske2l9XSA9IHZhbHVlO1xuICAgICAgICAgICAgYDtcbiAgICB9XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBtWyR7cmFuayAtIDF9XSA9IHZhbHVlO1xuICAgICAgICBgO1xuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICB2b2lkIHNldFZlY0l0ZW0ob3V0IGludCBtWyR7cmFua31dLCBpbnQgaW5kZXgsIGludCB2YWx1ZSkge1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgfVxuICAgICAgICBgO1xuICAgIHJldHVybiB7IHNldFZlY0l0ZW06IG5ldyBHbHNsTGliUm91dGluZShib2R5KSB9O1xuICB9XG4gIHByb3RlY3RlZCBnZXRWZWNJdGVtKCk6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lIH0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGxldCBibG9jayA9IGBcbiAgICAgICAgaWYoaW5kZXggPCAwKVxuICAgICAgICAgICAgaW5kZXggPSAke3Jhbmt9ICsgaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIG1bMF07XG4gICAgICBgO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PSAke2l9KVxuICAgICAgICAgICAgcmV0dXJuIG1bJHtpfV07XG4gICAgICBgO1xuICAgIH1cbiAgICBibG9jayArPSBgXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBtWyR7cmFuayAtIDF9XTtcbiAgICAgICAgYDtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgaW50IGdldFZlY0l0ZW0oaW50IG1bJHtyYW5rfV0sIGludCBpbmRleCkge1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIHsgZ2V0VmVjSXRlbTogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpIH07XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQ29vcmRzR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1jb29yZGluYXRlLWxpYic7XG5pbXBvcnQgeyBHbHNsQ29udGV4dCwgR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBFbmNvZGluZ0dsc2xMaWIgfSBmcm9tICcuL2dsc2wtZW5jb2RpbmctbGliJztcbmltcG9ydCB7IEZyYWdDb2xvckdsc2xMaWIgfSBmcm9tICcuL2dsc2wtZnJhZ2NvbG9yLWxpYic7XG5pbXBvcnQgeyBTaGFwZVV0aWxzR2xzbExpYiB9IGZyb20gJy4vZ2xzbC1zaGFwZS11dGlscy1saWInO1xuaW1wb3J0IHsgVmVjR2xzbExpYiB9IGZyb20gJy4vZ2xzbC12ZWMtbGliJztcblxuZXhwb3J0IGNvbnN0IGdsc2xSZWdpc3RyeTogeyBbbmFtZTogc3RyaW5nXTogbmV3IChjb250ZXh0OiBHbHNsQ29udGV4dCkgPT4gR2xzbExpYiB9ID0ge1xuICBlbmNvZGluZzogRW5jb2RpbmdHbHNsTGliLFxuICBmcmFnY29sb3I6IEZyYWdDb2xvckdsc2xMaWIsXG4gIHZlYzogVmVjR2xzbExpYixcbiAgc2hhcGVVdGlsczogU2hhcGVVdGlsc0dsc2xMaWIsXG4gIGNvb3JkaW5hdGVzOiBDb29yZHNHbHNsTGliLFxuICAvLyAgJ2FycmF5cyc6IEFycmF5R2xzbFNMaWJcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEdsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZU5vZGUsIFRvcG9sb2dpY2FsU29ydEdsc2xSb3V0aW5lcyB9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyByZXBsYWNlSW5saW5lcyB9IGZyb20gJy4vZ2xzbC1mdW5jdGlvbi1pbmxpbmVyJztcbmltcG9ydCB7IGdsc2xSZWdpc3RyeSB9IGZyb20gJy4vZ2xzbC1yZWdpc3RlcmVkLWxpYnMnO1xuaW1wb3J0IHsgZ2V0RGVmYXVsdEZyYWdTaGFkZXJNYWluLCBnZXRGcmFnU2hhZGVyUHJlYW1ibGUgfSBmcm9tICcuL2dsc2wtc291cmNlJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBUZXh0dXJlTGF5b3V0LCBWYXJpYWJsZUluZm8gfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qKlxuICogUHJlcHJvY2Vzc29yIGZvciB0aGUgYWRkaXRpb25zIHRvIHRoZSBHTFNMIGxhbmd1YWdlXG4gKiBJdCBkZWFscyB3aXRoOlxuICogIEBpbmNsdWRlIGRpcmVjdGl2ZXNcbiAqICBAaW5saW5lXG4gKiAgTG9vcCB1bnJvbGxpbmcgKG5vdCBpbXBsZW1lbnRlZClcbiAqICBNYWNybyByZXNvbHV0aW9uIChub3QgaW1wbGVtZW50ZWQpXG4gKi9cbmV4cG9ydCBjbGFzcyBHbHNsUHJlcHJvY2Vzc29yIHtcbiAgcmVhZG9ubHkgY29udGV4dDogR2xzbENvbnRleHQ7XG4gIHJlYWRvbmx5IGxpYnM6IHsgW25hbWU6IHN0cmluZ106IEdsc2xMaWIgfSA9IHt9O1xuICByZWFkb25seSBnbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaDogeyBbcm91dGluZU5hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lTm9kZSB9ID0ge307XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvLFxuICAgIGlucHV0VGV4dHVyZUxheW91dHM6IFRleHR1cmVMYXlvdXRbXSxcbiAgICBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICApIHtcbiAgICB0aGlzLmNvbnRleHQgPSBuZXcgR2xzbENvbnRleHQoZ2xDb250ZXh0LCBwcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlTGF5b3V0cywgb3V0cHV0VGV4dHVyZUxheW91dCk7XG5cbiAgICAvLyBjb25zdHJ1Y3QgR2xzbExpYnNcbiAgICBPYmplY3Qua2V5cyhnbHNsUmVnaXN0cnkpLmZvckVhY2goKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbGliID0gbmV3IGdsc2xSZWdpc3RyeVtuYW1lXSh0aGlzLmNvbnRleHQpO1xuICAgICAgdGhpcy5saWJzW25hbWVdID0gbGliO1xuICAgIH0pO1xuXG4gICAgLy8gY29uc3RydWN0IEdsc2xSb3V0aW5lRGVwZW5kZW5jeUdyYXBoXG4gICAgY29uc3QgbWFwID0gdGhpcy5nbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaDtcbiAgICBmb3IgKGNvbnN0IGxpYk5hbWUgaW4gdGhpcy5saWJzKSB7XG4gICAgICBjb25zdCBsaWIgPSB0aGlzLmxpYnNbbGliTmFtZV07XG4gICAgICBjb25zdCByb3V0aW5lc0luTGliID0gbGliLmdldEZ1bmN0aW9ucygpO1xuICAgICAgZm9yIChjb25zdCByb3V0aW5lIGluIHJvdXRpbmVzSW5MaWIpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gbGliTmFtZSArICcuJyArIHJvdXRpbmU7XG4gICAgICAgIGxldCBjdXJyZW50Tm9kZTogR2xzbExpYlJvdXRpbmVOb2RlO1xuICAgICAgICBpZiAobWFwW2tleV0pIHtcbiAgICAgICAgICBjdXJyZW50Tm9kZSA9IG1hcFtrZXldO1xuICAgICAgICAgIGN1cnJlbnROb2RlLnJvdXRpbmVCb2R5ID0gcm91dGluZXNJbkxpYltyb3V0aW5lXS5yb3V0aW5lQm9keTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50Tm9kZSA9IG5ldyBHbHNsTGliUm91dGluZU5vZGUoa2V5LCByb3V0aW5lc0luTGliW3JvdXRpbmVdLnJvdXRpbmVCb2R5KTtcbiAgICAgICAgICBtYXBba2V5XSA9IGN1cnJlbnROb2RlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IHJvdXRpbmVzSW5MaWJbcm91dGluZV0uZGVwZW5kZW5jaWVzO1xuICAgICAgICBpZiAoZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXBlbmRlbmNpZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICghbWFwW2RlcGVuZGVuY2llc1tpXV0pIHtcbiAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IG5ldyBHbHNsTGliUm91dGluZU5vZGUoZGVwZW5kZW5jaWVzW2ldKTtcbiAgICAgICAgICAgICAgbWFwW2RlcGVuZGVuY2llc1tpXV0gPSBub2RlO1xuICAgICAgICAgICAgICBjdXJyZW50Tm9kZS5hZGREZXBlbmRlbmN5KG5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY3VycmVudE5vZGUuYWRkRGVwZW5kZW5jeShtYXBbZGVwZW5kZW5jaWVzW2ldXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJlcHJvY2VzcygpOiBzdHJpbmcge1xuICAgIGNvbnN0IHByb2dyYW1JbmZvID0gdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvO1xuICAgIGxldCBzb3VyY2UgPSBwcm9ncmFtSW5mby5zaGFkZXJTb3VyY2U7XG5cbiAgICAvLyBhcHBlbmQgbWFpbigpIGZ1bmN0aW9uXG4gICAgaWYgKCF0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaGFzTWFpbikge1xuICAgICAgc291cmNlID0gYCR7c291cmNlfVxuICAgICAgJHtnZXREZWZhdWx0RnJhZ1NoYWRlck1haW4odGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uLCB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dC5zaGFwZS5sZW5ndGgpfWA7XG4gICAgfVxuICAgIC8vIHJlcGxhY2UgaW5saW5lc1xuICAgIHNvdXJjZSA9IHJlcGxhY2VJbmxpbmVzKHNvdXJjZSk7XG5cbiAgICAvLyBjb25jYXQgZmluYWwgc291cmNlIHN0cmluZ1xuICAgIHJldHVybiBgJHtnZXRGcmFnU2hhZGVyUHJlYW1ibGUodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKX1cbiAgICAke3RoaXMuZ2V0VW5pZm9ybXMocHJvZ3JhbUluZm8uaW5wdXROYW1lcywgcHJvZ3JhbUluZm8udmFyaWFibGVzKX1cbiAgICAke3RoaXMuZ2V0SW1wb3J0cyhzb3VyY2UpfVxuICAgICR7c291cmNlfWA7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0SW1wb3J0cyhzY3JpcHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3Qgcm91dGluZXNJbmNsdWRlZCA9IHRoaXMuc2VsZWN0R2xzbExpYlJvdXRpbmVzVG9CZUluY2x1ZGVkKHNjcmlwdCk7XG5cbiAgICBpZiAocm91dGluZXNJbmNsdWRlZC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBsZXQgcm91dGluZXMgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvdXRpbmVzSW5jbHVkZWQubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChyb3V0aW5lc0luY2x1ZGVkW2ldLnJvdXRpbmVCb2R5KSB7XG4gICAgICAgIHJvdXRpbmVzICs9IHJvdXRpbmVzSW5jbHVkZWRbaV0ucm91dGluZUJvZHkgKyAnXFxuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyBib2R5IGZvciB0aGUgR2xzbCBMaWJyYXJ5IHJvdXRpbmU6ICR7cm91dGluZXNJbmNsdWRlZFtpXS5uYW1lfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByb3V0aW5lcztcbiAgfVxuICBwcml2YXRlIHNlbGVjdEdsc2xMaWJSb3V0aW5lc1RvQmVJbmNsdWRlZChzY3JpcHQ6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lTm9kZVtdIHtcbiAgICBjb25zdCBub2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10gPSBbXTtcblxuICAgIE9iamVjdC5rZXlzKHRoaXMuZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGgpLmZvckVhY2goKGNsYXNzQW5kUm91dGluZSkgPT4ge1xuICAgICAgY29uc3Qgcm91dGluZSA9IGNsYXNzQW5kUm91dGluZS5zcGxpdCgnLicpWzFdO1xuICAgICAgaWYgKHNjcmlwdC5pbmRleE9mKHJvdXRpbmUpICE9PSAtMSkge1xuICAgICAgICBub2Rlcy5wdXNoKHRoaXMuZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGhbY2xhc3NBbmRSb3V0aW5lXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gVG9wb2xvZ2ljYWxTb3J0R2xzbFJvdXRpbmVzLnJldHVybk9yZGVyZWROb2Rlcyhub2Rlcyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0VW5pZm9ybXMoc2FtcGxlcnM/OiBzdHJpbmdbXSwgdmFyaWFibGVzPzogVmFyaWFibGVJbmZvW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHVuaWZvcm1MaW5lczogc3RyaW5nW10gPSBbXTtcbiAgICBpZiAoc2FtcGxlcnMpIHtcbiAgICAgIGZvciAoY29uc3Qgc2FtcGxlciBvZiBzYW1wbGVycykge1xuICAgICAgICB1bmlmb3JtTGluZXMucHVzaChgdW5pZm9ybSBzYW1wbGVyMkQgJHtzYW1wbGVyfTtgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHZhcmlhYmxlcykge1xuICAgICAgZm9yIChjb25zdCB2YXJpYWJsZSBvZiB2YXJpYWJsZXMpIHtcbiAgICAgICAgdW5pZm9ybUxpbmVzLnB1c2goXG4gICAgICAgICAgYHVuaWZvcm0gJHt2YXJpYWJsZS50eXBlfSAke3ZhcmlhYmxlLm5hbWV9JHt2YXJpYWJsZS5hcnJheUxlbmd0aCA/IGBbJHt2YXJpYWJsZS5hcnJheUxlbmd0aH1dYCA6ICcnfTtgLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5pZm9ybUxpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IExvZ2dlciwgUHJvZmlsZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcblxuaW1wb3J0IHsgR2xzbFByZXByb2Nlc3NvciB9IGZyb20gJy4vZ2xzbC1wcmVwcm9jZXNzb3InO1xuaW1wb3J0IHsgZ2V0VmVydGV4U2hhZGVyU291cmNlIH0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQgeyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kgfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7IEFydGlmYWN0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVZhcmlhYmxlLCBUZXh0dXJlRGF0YSwgVGV4dHVyZUxheW91dCwgVmFyaWFibGVJbmZvIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsLWNvbnRleHQnO1xuXG4vKipcbiAqIFByb2dyYW1NYW5hZ2VyIGlzIHRoZSBtYWluIGNsYXNzIGJlaGluZCBydW5uaW5nIGNvbXB1dGF0aW9uc1xuICogSXQgYnVpbGRzIFByb2dyYW1JbmZvJ3MgaW50byBBcnRpZmFjdHNcbiAqIEl0IGNvbXBpbGVzIGdpdmVuIFByb2dyYW1JbmZvJ3MgaW50byBXZWJHTCBQcm9yYW1zIChjYWNoZWQgYXMgQXJ0aWZhY3RzKVxuICogVXNlcyB0aGUgYXJ0aWZhY3QgdG8gcnVuIHRoZSBjb21wdXRhdGlvbiBieSBjYWxsaW5nIERyYXcgb25cbiAqIHRoZSBXZWJHTCBkcmF3aW5nIGJ1ZmZlclxuICogUHJvZ3JhbU1hbmFnZXIgYXV0b21hdGljYWxseSBtYXBzIChiaW5kcykgaW5wdXQgdmFyaWFibGVzIHRvIHRoZWlyXG4gKiBjb3JyZXNwb25kaW5nIExvY2F0aW9uJ3MgaW4gdGhlIGJpbmFyeSBwcm9ncmFtXG4gKi9cbmV4cG9ydCBjbGFzcyBQcm9ncmFtTWFuYWdlciB7XG4gIHJlcG86IE1hcDx1bmtub3duLCBBcnRpZmFjdD47IC8vIHRoaXMgc2hvdWxkIGJlIHBlci1zZXNzaW9uIG9iamVjdFxuICB2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyO1xuICBhdHRyaWJ1dGVzQm91bmQ6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj4sXG4gICAgcHVibGljIGdsQ29udGV4dDogV2ViR0xDb250ZXh0LFxuICAgIHB1YmxpYyB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgKSB7XG4gICAgdGhpcy5yZXBvID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuYXR0cmlidXRlc0JvdW5kID0gZmFsc2U7XG4gIH1cbiAgZ2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duKTogQXJ0aWZhY3QgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJlcG8uZ2V0KGtleSk7XG4gIH1cbiAgc2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duLCBhcnRpZmFjdDogQXJ0aWZhY3QpOiB2b2lkIHtcbiAgICB0aGlzLnJlcG8uc2V0KGtleSwgYXJ0aWZhY3QpO1xuICB9XG4gIHJ1bihidWlsZEFydGlmYWN0OiBBcnRpZmFjdCwgaW5wdXRzOiBUZXh0dXJlRGF0YVtdLCBvdXRwdXQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgdGhpcy5wcm9maWxlci5ldmVudChcbiAgICAgICdvcCcsXG4gICAgICBgUHJvZ3JhbU1hbmFnZXIucnVuICR7YnVpbGRBcnRpZmFjdC5wcm9ncmFtSW5mby5uYW1lID8/ICd1bmtub3duIGtlcm5lbCd9YCxcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICAgICAgY29uc3QgcHJvZ3JhbSA9IGJ1aWxkQXJ0aWZhY3QucHJvZ3JhbTtcbiAgICAgICAgZ2wudXNlUHJvZ3JhbShwcm9ncmFtKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmJpbmRPdXRwdXQob3V0cHV0KTtcbiAgICAgICAgICBpZiAoIXRoaXMuYXR0cmlidXRlc0JvdW5kKSB7XG4gICAgICAgICAgICB0aGlzLmJpbmRBdHRyaWJ1dGVzKGJ1aWxkQXJ0aWZhY3QuYXR0cmliTG9jYXRpb25zKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5iaW5kVW5pZm9ybXMoYnVpbGRBcnRpZmFjdC51bmlmb3JtTG9jYXRpb25zLCBidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLnZhcmlhYmxlcyA/PyBbXSwgaW5wdXRzKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgTG9nZ2VyLmVycm9yKCdQcm9ncmFtTWFuYWdlcicsIGJ1aWxkQXJ0aWZhY3QucHJvZ3JhbUluZm8uc2hhZGVyU291cmNlKTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdHbENvbnRleHQuZHJhdygpJywgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuZ2xDb250ZXh0LmRyYXcoKTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgdGhpcy5nbENvbnRleHQsXG4gICAgKTtcbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZlcnRleFNoYWRlcikge1xuICAgICAgdGhpcy5nbENvbnRleHQuZGVsZXRlU2hhZGVyKHRoaXMudmVydGV4U2hhZGVyKTtcbiAgICB9XG4gICAgdGhpcy5yZXBvLmZvckVhY2goKGEpID0+IHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVByb2dyYW0oYS5wcm9ncmFtKSk7XG4gIH1cbiAgYnVpbGQocHJvZ3JhbUluZm86IFByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVMYXlvdXRzOiBUZXh0dXJlTGF5b3V0W10sIG91dHB1dFRleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBBcnRpZmFjdCB7XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnUHJvZ3JhbU1hbmFnZXIuYnVpbGQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcmVwcm9jZXNzb3IgPSBuZXcgR2xzbFByZXByb2Nlc3Nvcih0aGlzLmdsQ29udGV4dCwgcHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZUxheW91dHMsIG91dHB1dFRleHR1cmVMYXlvdXQpO1xuICAgICAgY29uc3QgZnJhZ1NjcmlwdCA9IHByZXByb2Nlc3Nvci5wcmVwcm9jZXNzKCk7XG4gICAgICBjb25zdCBwcm9ncmFtID0gdGhpcy5jb21waWxlKGZyYWdTY3JpcHQpO1xuICAgICAgY29uc3QgYXJ0aWZhY3QgPSB7XG4gICAgICAgIHByb2dyYW1JbmZvLFxuICAgICAgICBwcm9ncmFtLFxuICAgICAgICB1bmlmb3JtTG9jYXRpb25zOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbnMoXG4gICAgICAgICAgcHJvZ3JhbSxcbiAgICAgICAgICBwcmVwcm9jZXNzb3IuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLFxuICAgICAgICAgIHByZXByb2Nlc3Nvci5jb250ZXh0LnByb2dyYW1JbmZvLnZhcmlhYmxlcyxcbiAgICAgICAgKSxcbiAgICAgICAgYXR0cmliTG9jYXRpb25zOiB0aGlzLmdldEF0dHJpYkxvY2F0aW9ucyhwcm9ncmFtKSxcbiAgICAgIH07XG4gICAgICByZXR1cm4gYXJ0aWZhY3Q7XG4gICAgfSk7XG4gIH1cbiAgcHJvdGVjdGVkIGNvbXBpbGUoZnJhZ1NoYWRlclNjcmlwdDogc3RyaW5nKTogV2ViR0xQcm9ncmFtIHtcbiAgICBpZiAoIXRoaXMudmVydGV4U2hhZGVyKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnUHJvcmdyYW1NYW5hZ2VyJywgJ0NvbXBpbGluZyBhbmQgY2FjaGluZyBWZXJ0ZXggc2hhZGVyIGZvciB0aGUgZmlyc3QgdGltZScpO1xuICAgICAgY29uc3QgdmVydGV4U2hhZGVyU2NyaXB0ID0gZ2V0VmVydGV4U2hhZGVyU291cmNlKHRoaXMuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgdGhpcy52ZXJ0ZXhTaGFkZXIgPSB0aGlzLmdsQ29udGV4dC5jb21waWxlU2hhZGVyKHZlcnRleFNoYWRlclNjcmlwdCwgdGhpcy5nbENvbnRleHQuZ2wuVkVSVEVYX1NIQURFUik7XG4gICAgfVxuICAgIGlmIChlbnYuZGVidWcpIHtcbiAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAnUHJvcmdyYW1NYW5hZ2VyJyxcbiAgICAgICAgYEZyYWdTaGFkZXI6XG4ke2ZyYWdTaGFkZXJTY3JpcHR9XG5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZnJhZ1NoYWRlciA9IHRoaXMuZ2xDb250ZXh0LmNvbXBpbGVTaGFkZXIoZnJhZ1NoYWRlclNjcmlwdCwgdGhpcy5nbENvbnRleHQuZ2wuRlJBR01FTlRfU0hBREVSKTtcbiAgICBjb25zdCBwcm9ncmFtID0gdGhpcy5nbENvbnRleHQuY3JlYXRlUHJvZ3JhbSh0aGlzLnZlcnRleFNoYWRlciwgZnJhZ1NoYWRlcik7XG4gICAgdGhpcy5nbENvbnRleHQuZGVsZXRlU2hhZGVyKGZyYWdTaGFkZXIpO1xuICAgIHJldHVybiBwcm9ncmFtO1xuICB9XG4gIGJpbmRPdXRwdXQodGQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgY29uc3Qgd2lkdGggPSB0ZC53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0ZC5oZWlnaHQ7XG4gICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAnUHJvcmdyYW1NYW5hZ2VyJyxcbiAgICAgIGBCaW5kaW5nIG91dHB1dCB0ZXh0dXJlIHRvIEZyYW1lYnVmZmVyOiB3L2g9JHt3aWR0aH0vJHtoZWlnaHR9LCBzaGFwZT0ke3RkLnNoYXBlfSwgdHlwZT0ke3RkLnRlbnNvci50eXBlfWAsXG4gICAgKTtcbiAgICB0aGlzLmdsQ29udGV4dC5hdHRhY2hGcmFtZWJ1ZmZlcih0ZC50ZXh0dXJlLCB3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuICBiaW5kQXR0cmlidXRlcyhhdHRyaWJMb2NhdGlvbnM6IEFydGlmYWN0LkF0dHJpYkxvY2F0aW9ucyk6IHZvaWQge1xuICAgIGNvbnN0IHBvc2l0aW9uSGFuZGxlID0gYXR0cmliTG9jYXRpb25zLnBvc2l0aW9uO1xuICAgIGNvbnN0IHRleHR1cmVDb29yZEhhbmRsZSA9IGF0dHJpYkxvY2F0aW9ucy50ZXh0dXJlQ29vcmQ7XG4gICAgdGhpcy5nbENvbnRleHQuc2V0VmVydGV4QXR0cmlidXRlcyhwb3NpdGlvbkhhbmRsZSwgdGV4dHVyZUNvb3JkSGFuZGxlKTtcbiAgICB0aGlzLmF0dHJpYnV0ZXNCb3VuZCA9IHRydWU7XG4gIH1cbiAgYmluZFVuaWZvcm1zKFxuICAgIHVuaWZvcm1Mb2NhdGlvbnM6IEFydGlmYWN0LlVuaWZvcm1Mb2NhdGlvbnMsXG4gICAgdmFyaWFibGVzOiBQcm9ncmFtVmFyaWFibGVbXSxcbiAgICB0ZXh0dXJlczogVGV4dHVyZURhdGFbXSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICBsZXQgdGV4dHVyZVBvc2l0aW9uID0gMDtcbiAgICBmb3IgKGNvbnN0IHsgbmFtZSwgdHlwZSwgbG9jYXRpb24sIGFycmF5TGVuZ3RoIH0gb2YgdW5pZm9ybUxvY2F0aW9ucykge1xuICAgICAgY29uc3QgdmFsdWUgPSB2YXJpYWJsZXMuZmluZCgodikgPT4gdi5uYW1lID09PSBuYW1lKT8uZGF0YTtcbiAgICAgIGlmICh0eXBlICE9PSAnc2FtcGxlcjJEJyAmJiAhdmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB2YXJpYWJsZSAnJHtuYW1lfScgZG9lcyBub3QgaGF2ZSBkYXRhIGRlZmluZWQgaW4gcHJvZ3JhbSBpbmZvYCk7XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSAnc2FtcGxlcjJEJzpcbiAgICAgICAgICB0aGlzLmJpbmRUZXh0dXJlKHRleHR1cmVzW3RleHR1cmVQb3NpdGlvbl0sIGxvY2F0aW9uLCB0ZXh0dXJlUG9zaXRpb24pO1xuICAgICAgICAgIHRleHR1cmVQb3NpdGlvbisrO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdmbG9hdCc6XG4gICAgICAgICAgaWYgKGFycmF5TGVuZ3RoKSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWZ2KGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXJbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xZihsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2ludCc6XG4gICAgICAgICAgaWYgKGFycmF5TGVuZ3RoKSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWl2KGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXJbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xaShsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmlmb3JtIG5vdCBpbXBsZW1lbnRlZDogJHt0eXBlfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBiaW5kVGV4dHVyZSh0ZDogVGV4dHVyZURhdGEsIHVuaWZvcm1IYW5kbGU6IFdlYkdMVW5pZm9ybUxvY2F0aW9uLCBwb3NpdGlvbjogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5nbENvbnRleHQuYmluZFRleHR1cmVUb1VuaWZvcm0odGQudGV4dHVyZSwgcG9zaXRpb24sIHVuaWZvcm1IYW5kbGUpO1xuICB9XG4gIGdldEF0dHJpYkxvY2F0aW9ucyhwcm9ncmFtOiBXZWJHTFByb2dyYW0pOiBBcnRpZmFjdC5BdHRyaWJMb2NhdGlvbnMge1xuICAgIHJldHVybiB7XG4gICAgICBwb3NpdGlvbjogdGhpcy5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAncG9zaXRpb24nKSxcbiAgICAgIHRleHR1cmVDb29yZDogdGhpcy5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAndGV4dHVyZUNvb3JkJyksXG4gICAgfTtcbiAgfVxuICBnZXRVbmlmb3JtTG9jYXRpb25zKFxuICAgIHByb2dyYW06IFdlYkdMUHJvZ3JhbSxcbiAgICBzYW1wbGVycz86IHN0cmluZ1tdLFxuICAgIHZhcmlhYmxlcz86IFZhcmlhYmxlSW5mb1tdLFxuICApOiBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zIHtcbiAgICBjb25zdCB1bmlmb3JtTG9jYXRpb25zOiBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zID0gW107XG4gICAgaWYgKHNhbXBsZXJzKSB7XG4gICAgICBmb3IgKGNvbnN0IHNhbXBsZXIgb2Ygc2FtcGxlcnMpIHtcbiAgICAgICAgdW5pZm9ybUxvY2F0aW9ucy5wdXNoKHtcbiAgICAgICAgICBuYW1lOiBzYW1wbGVyLFxuICAgICAgICAgIHR5cGU6ICdzYW1wbGVyMkQnLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBzYW1wbGVyKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh2YXJpYWJsZXMpIHtcbiAgICAgIGZvciAoY29uc3QgdmFyaWFibGUgb2YgdmFyaWFibGVzKSB7XG4gICAgICAgIHVuaWZvcm1Mb2NhdGlvbnMucHVzaCh7IC4uLnZhcmlhYmxlLCBsb2NhdGlvbjogdGhpcy5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgdmFyaWFibGUubmFtZSkgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmlmb3JtTG9jYXRpb25zO1xuICB9XG4gIGdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtOiBXZWJHTFByb2dyYW0sIG5hbWU6IHN0cmluZyk6IFdlYkdMVW5pZm9ybUxvY2F0aW9uIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2xDb250ZXh0LmdsO1xuICAgIGNvbnN0IHJlZmVyZW5jZSA9IGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBuYW1lKTtcbiAgICBpZiAocmVmZXJlbmNlID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuaWZvcm0gJHtuYW1lfSBub3QgZm91bmQuYCk7XG4gICAgfVxuICAgIHJldHVybiByZWZlcmVuY2U7XG4gIH1cbiAgZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCBuYW1lOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbENvbnRleHQuZ2w7XG4gICAgY29uc3QgYXR0cmlidXRlTG9jYXRpb246IG51bWJlciA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sIG5hbWUpO1xuICAgIHJldHVybiBhdHRyaWJ1dGVMb2NhdGlvbjtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBMb2dnZXIsIFByb2ZpbGVyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuXG5pbXBvcnQgeyBFbmNvZGVyLCBFbmNvZGVyVXNhZ2UgfSBmcm9tICcuL3RleHR1cmUtZGF0YS1lbmNvZGVyJztcbmltcG9ydCB7IFRleHR1cmVMYXlvdXRTdHJhdGVneSB9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHsgVGV4dHVyZURhdGEsIFRleHR1cmVMYXlvdXQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZU1hbmFnZXJDb25maWcge1xuICByZXVzZVRleHR1cmVzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUZXh0dXJlTWFuYWdlciBpcyB0aGUgbWFpbmx5IHJlc3BvbnNpYmxlIGZvciBjYWNoaW5nIFRleHR1cmVzXG4gKiBUZXh0dXJlcyBhcmUgY2FjaGVkIGluIDIgbGV2ZWxzOlxuICogICAxLiB0aGUgdGV4dXJlcyB3aGljaCBhcmUgYXNzb2NpYXRlZCB3aXRoIGEgZGF0YUlkIChmcm9tIFRlbnNvcilcbiAqICAgIENhY2hpbmcgdGhlc2UgaXMgY3J1Y2lhbCB0byBwZXJmb3JtYW5jZS4gVGhlc2UgYXJlIEluLXVzZSBUZXh0dXJlc1xuICogICAyLiB0ZXh0dXJlcyB3aGljaCBhcmUgbm90IGluIHVzZSBieSBhbnkgY3VycmVudCBQcm9ncmFtSW5mby9UZW5zb3JcbiAqICAgICBUaGVzZSBhcmUgY2FsbGVkIEZyZWUgVGV4dHVyZXNcbiAqIFRleHR1cmVNYW5hZ2VyIGlzIGFsc28gdXNlZCB0byBoZWxwIGNyZWF0aW5nIHRleHR1cmVzLiBGb3IgdGhpcyBpdFxuICogdXNlcyBXZWJHTENvbnRleHQgYW5kIFRleHR1cmVMYXlvdXRTdHJhdGVneVxuICovXG5leHBvcnQgY2xhc3MgVGV4dHVyZU1hbmFnZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGluVXNlVGV4dHVyZXM6IE1hcDxzdHJpbmcsIFdlYkdMVGV4dHVyZVtdPjtcbiAgcHJpdmF0ZSByZWFkb25seSBpZGxlVGV4dHVyZXM6IE1hcDxzdHJpbmcsIFdlYkdMVGV4dHVyZVtdPjtcbiAgcHJpdmF0ZSByZWFkb25seSB0ZXh0dXJlTG9va3VwOiBNYXA8V2ViR0xUZXh0dXJlLCBzdHJpbmc+O1xuICBwcml2YXRlIHJlYWRvbmx5IHBlbmRpbmdSZWFkOiBNYXA8VGVuc29yLklkLCBBcnJheTwoYXJyOiBUZW5zb3IuTnVtYmVyVHlwZSkgPT4gdm9pZD4+ID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBnbENvbnRleHQ6IFdlYkdMQ29udGV4dCxcbiAgICBwdWJsaWMgbGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSxcbiAgICBwdWJsaWMgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPixcbiAgICBwcml2YXRlIGNvbmZpZzogVGV4dHVyZU1hbmFnZXJDb25maWcsXG4gICkge1xuICAgIGlmIChjb25maWcucmV1c2VUZXh0dXJlcykge1xuICAgICAgdGhpcy5pblVzZVRleHR1cmVzID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5pZGxlVGV4dHVyZXMgPSBuZXcgTWFwKCk7XG4gICAgICB0aGlzLnRleHR1cmVMb29rdXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICB9XG4gIGNyZWF0ZVRleHR1cmVGcm9tTGF5b3V0KFxuICAgIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsXG4gICAgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LFxuICAgIGRhdGE/OiBUZW5zb3IuTnVtYmVyVHlwZSxcbiAgICB1c2FnZT86IEVuY29kZXJVc2FnZSxcbiAgKSB7XG4gICAgY29uc3QgdGV4dHVyZURhdGFUeXBlID0gdGhpcy50b0VuY29kZXJUeXBlKGRhdGFUeXBlKTtcblxuICAgIGNvbnN0IGVuY29kZXIgPSB0aGlzLmdsQ29udGV4dC5nZXRFbmNvZGVyKHRleHR1cmVEYXRhVHlwZSwgbGF5b3V0LmNoYW5uZWxzIHx8IDEsIHVzYWdlKTtcbiAgICBpZiAobGF5b3V0LmlzUGFja2VkICYmIHVzYWdlID09PSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG4gICAgY29uc3Qgd2lkdGggPSBsYXlvdXQud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gbGF5b3V0LmhlaWdodDtcblxuICAgIGxldCBrZXk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgaW5Vc2VUZXh0dXJlczogV2ViR0xUZXh0dXJlW10gfCB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIGtleSA9IGAke3dpZHRofXgke2hlaWdodH1fJHtlbmNvZGVyLmZvcm1hdH1fJHtlbmNvZGVyLmludGVybmFsRm9ybWF0fV8ke2VuY29kZXIudGV4dHVyZVR5cGV9YDtcbiAgICAgIGluVXNlVGV4dHVyZXMgPSB0aGlzLmluVXNlVGV4dHVyZXMuZ2V0KGtleSk7XG4gICAgICBpZiAoIWluVXNlVGV4dHVyZXMpIHtcbiAgICAgICAgaW5Vc2VUZXh0dXJlcyA9IFtdO1xuICAgICAgICB0aGlzLmluVXNlVGV4dHVyZXMuc2V0KGtleSwgaW5Vc2VUZXh0dXJlcyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGlkbGVUZXh0dXJlcyA9IHRoaXMuaWRsZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgaWYgKGlkbGVUZXh0dXJlcyAmJiBpZGxlVGV4dHVyZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCB0ZXh0dXJlID0gaWRsZVRleHR1cmVzLnBvcCgpITtcbiAgICAgICAgaW5Vc2VUZXh0dXJlcy5wdXNoKHRleHR1cmUpO1xuICAgICAgICBpZiAodXNhZ2UgPT09IEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5KSB7XG4gICAgICAgICAgdGhpcy5nbENvbnRleHQudXBkYXRlVGV4dHVyZSh0ZXh0dXJlLCB3aWR0aCwgaGVpZ2h0LCBlbmNvZGVyLCB0aGlzLnRvVGV4dHVyZURhdGEoZGF0YVR5cGUsIGRhdGEpISk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRleHR1cmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgTG9nZ2VyLnZlcmJvc2UoJ1RleHR1cmVNYW5hZ2VyJywgYENyZWF0aW5nIG5ldyB0ZXh0dXJlIG9mIHNpemUgJHtsYXlvdXQud2lkdGh9eCR7bGF5b3V0LmhlaWdodH1gKTtcbiAgICBjb25zdCB0ZXh0dXJlID0gdGhpcy5nbENvbnRleHQuYWxsb2NhdGVUZXh0dXJlKHdpZHRoLCBoZWlnaHQsIGVuY29kZXIsIHRoaXMudG9UZXh0dXJlRGF0YShkYXRhVHlwZSwgZGF0YSkpO1xuXG4gICAgaWYgKHRoaXMuY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIGluVXNlVGV4dHVyZXMhLnB1c2godGV4dHVyZSk7XG4gICAgICB0aGlzLnRleHR1cmVMb29rdXAuc2V0KHRleHR1cmUsIGtleSEpO1xuICAgIH1cbiAgICByZXR1cm4gdGV4dHVyZTtcbiAgfVxuICByZWFkVGV4dHVyZSh0ZDogVGV4dHVyZURhdGEsIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGNoYW5uZWxzPzogbnVtYmVyKTogVGVuc29yLk51bWJlclR5cGUge1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnVGV4dHVyZU1hbmFnZXIucmVhZFRleHR1cmUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkYXRhU2l6ZSA9IHRkLnNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpICogY2hhbm5lbHMhO1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2xDb250ZXh0LnJlYWRUZXh0dXJlKFxuICAgICAgICB0ZC50ZXh0dXJlLFxuICAgICAgICB0ZC53aWR0aCxcbiAgICAgICAgdGQuaGVpZ2h0LFxuICAgICAgICBkYXRhU2l6ZSxcbiAgICAgICAgdGhpcy50b0VuY29kZXJUeXBlKGRhdGFUeXBlKSxcbiAgICAgICAgY2hhbm5lbHMhLFxuICAgICAgKTtcbiAgICAgIHJldHVybiB0aGlzLnRvVGVuc29yRGF0YShkYXRhVHlwZSwgZGF0YSk7XG4gICAgfSk7XG4gIH1cbiAgYXN5bmMgcmVhZFRleHR1cmVBc3luYyh0ZDogVGV4dHVyZURhdGEsIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGNoYW5uZWxzPzogbnVtYmVyKTogUHJvbWlzZTxUZW5zb3IuTnVtYmVyVHlwZT4ge1xuICAgIGNvbnN0IGRhdGFJZCA9IHRkLnRlbnNvci5kYXRhSWQ7XG4gICAgaWYgKCFjaGFubmVscykge1xuICAgICAgY2hhbm5lbHMgPSAxO1xuICAgIH1cbiAgICBpZiAodGhpcy5wZW5kaW5nUmVhZC5oYXMoZGF0YUlkKSkge1xuICAgICAgY29uc3Qgc3Vic2NyaWJlcnMgPSB0aGlzLnBlbmRpbmdSZWFkLmdldChkYXRhSWQpO1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFRlbnNvci5OdW1iZXJUeXBlPigocmVzb2x2ZSkgPT4gc3Vic2NyaWJlcnM/LnB1c2gocmVzb2x2ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdUZXh0dXJlTWFuYWdlci5yZWFkVGV4dHVyZUFzeW5jJywgYXN5bmMgKCkgPT4ge1xuICAgICAgdGhpcy5wZW5kaW5nUmVhZC5zZXQoZGF0YUlkLCBbXSk7XG4gICAgICBjb25zdCBkYXRhU2l6ZSA9IHRkLnNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpICogY2hhbm5lbHMhO1xuICAgICAgLy8gYWRkIGEgZmVuY2Ugd2FpdGluZyBmb3IgdGhlIGRhdGEgdG8gYmUgcmVhZHlcbiAgICAgIGF3YWl0IHRoaXMuZ2xDb250ZXh0LmNyZWF0ZUFuZFdhaXRGb3JGZW5jZSgpO1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuZ2xDb250ZXh0LnJlYWRUZXh0dXJlKFxuICAgICAgICB0ZC50ZXh0dXJlLFxuICAgICAgICB0ZC53aWR0aCxcbiAgICAgICAgdGQuaGVpZ2h0LFxuICAgICAgICBkYXRhU2l6ZSxcbiAgICAgICAgdGhpcy50b0VuY29kZXJUeXBlKGRhdGFUeXBlKSxcbiAgICAgICAgY2hhbm5lbHMhLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHRlbnNvckRhdGEgPSB0aGlzLnRvVGVuc29yRGF0YShkYXRhVHlwZSwgZGF0YSk7XG4gICAgICBjb25zdCBzdWJzY3JpYmVycyA9IHRoaXMucGVuZGluZ1JlYWQuZ2V0KGRhdGFJZCk7XG4gICAgICB0aGlzLnBlbmRpbmdSZWFkLmRlbGV0ZShkYXRhSWQpO1xuICAgICAgc3Vic2NyaWJlcnM/LmZvckVhY2goKHJlc29sdmUpID0+IHJlc29sdmUodGVuc29yRGF0YSkpO1xuICAgICAgcmV0dXJuIHRlbnNvckRhdGE7XG4gICAgfSk7XG4gIH1cbiAgcmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQodGQ6IFRleHR1cmVEYXRhKTogRmxvYXQzMkFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdUZXh0dXJlTWFuYWdlci5yZWFkVWludDhUZXh0dXJlQXNGbG9hdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGFTaXplID0gdGQuc2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5nbENvbnRleHQucmVhZFRleHR1cmUodGQudGV4dHVyZSwgdGQud2lkdGgsIHRkLmhlaWdodCwgZGF0YVNpemUgKiA0LCAnYnl0ZScsIDQpO1xuICAgICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgZGF0YVNpemUpO1xuICAgIH0pO1xuICB9XG4gIHJlbGVhc2VUZXh0dXJlKHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSwgZGVsZXRlVGV4dHVyZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBsZXQga2V5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIGtleSA9IHRoaXMudGV4dHVyZUxvb2t1cC5nZXQodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICBpZiAoa2V5KSB7XG4gICAgICAgIGlmIChkZWxldGVUZXh0dXJlKSB7XG4gICAgICAgICAgdGhpcy50ZXh0dXJlTG9va3VwLmRlbGV0ZShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGluVXNlVGV4dHVyZXMgPSB0aGlzLmluVXNlVGV4dHVyZXMuZ2V0KGtleSk7XG4gICAgICAgIGlmIChpblVzZVRleHR1cmVzKSB7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSBpblVzZVRleHR1cmVzLmluZGV4T2YodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgaW5Vc2VUZXh0dXJlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgbGV0IGlkbGVUZXh0dXJlcyA9IHRoaXMuaWRsZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgICAgICAgaWYgKCFpZGxlVGV4dHVyZXMpIHtcbiAgICAgICAgICAgICAgaWRsZVRleHR1cmVzID0gW107XG4gICAgICAgICAgICAgIHRoaXMuaWRsZVRleHR1cmVzLnNldChrZXksIGlkbGVUZXh0dXJlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZGxlVGV4dHVyZXMucHVzaCh0ZXh0dXJlRGF0YS50ZXh0dXJlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWtleSB8fCBkZWxldGVUZXh0dXJlKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnVGV4dHVyZU1hbmFnZXInLCBgRGVsZXRpbmcgdGV4dHVyZSBvZiBzaXplICR7dGV4dHVyZURhdGEud2lkdGh9eCR7dGV4dHVyZURhdGEuaGVpZ2h0fWApO1xuICAgICAgdGhpcy5nbENvbnRleHQuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlRGF0YS50ZXh0dXJlKTtcbiAgICB9XG4gIH1cbiAgdG9UZW5zb3JEYXRhKGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGRhdGE6IEVuY29kZXIuRGF0YUFycmF5VHlwZSk6IFRlbnNvci5OdW1iZXJUeXBlIHtcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50MTZBcnJheSA/IGRhdGEgOiBJbnQxNkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50MzJBcnJheSA/IGRhdGEgOiBJbnQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBJbnQ4QXJyYXkgPyBkYXRhIDogSW50OEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIFVpbnQxNkFycmF5ID8gZGF0YSA6IFVpbnQxNkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIFVpbnQzMkFycmF5ID8gZGF0YSA6IFVpbnQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5ID8gZGF0YSA6IFVpbnQ4QXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IGRhdGEgOiBGbG9hdDMyQXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGRhdGEgOiBGbG9hdDY0QXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yRGF0YSB0eXBlICR7ZGF0YVR5cGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH1cbiAgdG9UZXh0dXJlRGF0YShfZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgZGF0YTogVGVuc29yLk51bWJlclR5cGUgfCB1bmRlZmluZWQpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUgfCB1bmRlZmluZWQge1xuICAgIGlmICghZGF0YSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBkYXRhIDogbmV3IEZsb2F0MzJBcnJheShkYXRhKTtcbiAgICAvKlxuICAgIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gKGRhdGEuY29uc3RydWN0b3IgPT09IFVpbnQzMkFycmF5KSA/IGRhdGEgYXMgVWludDMyQXJyYXkgOiBuZXcgVWludDMyQXJyYXkoZGF0YSk7XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgICByZXR1cm4gKGRhdGEuY29uc3RydWN0b3IgPT09IFVpbnQ4QXJyYXkpID8gZGF0YSBhcyBVaW50OEFycmF5IDogbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gKGRhdGEuY29uc3RydWN0b3IgPT09IEZsb2F0MzJBcnJheSkgPyBkYXRhIGFzIEZsb2F0MzJBcnJheSA6IG5ldyBGbG9hdDMyQXJyYXkoZGF0YSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckRhdGEgdHlwZSAke2RhdGFUeXBlfSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gICAgfVxuICAgICovXG4gIH1cbiAgdG9FbmNvZGVyVHlwZShfZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSk6IEVuY29kZXIuRGF0YVR5cGUge1xuICAgIHJldHVybiAnZmxvYXQnO1xuICAgIC8vIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICAvLyAgIGNhc2UgJ2ludDE2JzpcbiAgICAvLyAgIGNhc2UgJ2ludDMyJzpcbiAgICAvLyAgIGNhc2UgJ3VpbnQxNic6XG4gICAgLy8gICBjYXNlICd1aW50MzInOlxuICAgIC8vICAgICByZXR1cm4gJ2ludCc7XG4gICAgLy8gICBjYXNlICd1aW50OCc6XG4gICAgLy8gICBjYXNlICdib29sJzpcbiAgICAvLyAgICAgcmV0dXJuICdieXRlJztcbiAgICAvLyAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgIC8vICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgLy8gICAgIHJldHVybiAnZmxvYXQnO1xuICAgIC8vICAgZGVmYXVsdDpcbiAgICAvLyAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JEYXRhIHR5cGUgJHtkYXRhVHlwZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIC8vIH1cbiAgfVxuICBjbGVhckFjdGl2ZVRleHR1cmVzKCk6IHZvaWQge1xuICAgIHRoaXMuZ2xDb250ZXh0LmNsZWFyQWN0aXZlVGV4dHVyZXMoKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4uLy4uL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi9ncmFwaCc7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7IE9wU2V0LCByZXNvbHZlT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9vcHNldCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vc2Vzc2lvbic7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuaW1wb3J0IHsgV2ViR0xCYWNrZW5kIH0gZnJvbSAnLi4vYmFja2VuZC13ZWJnbCc7XG5cbmltcG9ydCB7IFdlYkdMSW5mZXJlbmNlSGFuZGxlciB9IGZyb20gJy4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHsgV0VCR0xfT1BfUkVTT0xWRV9SVUxFUyB9IGZyb20gJy4vb3AtcmVzb2x2ZS1ydWxlcyc7XG5pbXBvcnQgeyBQcm9ncmFtTWFuYWdlciB9IGZyb20gJy4vcHJvZ3JhbS1tYW5hZ2VyJztcbmltcG9ydCB7IFByZWZlckxvZ2ljYWxTdHJhdGVneSwgVGV4dHVyZUxheW91dFN0cmF0ZWd5IH0gZnJvbSAnLi90ZXh0dXJlLWxheW91dC1zdHJhdGVneSc7XG5pbXBvcnQgeyBUZXh0dXJlTWFuYWdlciB9IGZyb20gJy4vdGV4dHVyZS1tYW5hZ2VyJztcbmltcG9ydCB7IFRleHR1cmVEYXRhIH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBXZWJHTFNlc3Npb25IYW5kbGVyIGltcGxlbWVudHMgU2Vzc2lvbkhhbmRsZXIge1xuICBwcm9ncmFtTWFuYWdlcjogUHJvZ3JhbU1hbmFnZXI7XG4gIHRleHR1cmVNYW5hZ2VyOiBUZXh0dXJlTWFuYWdlcjtcbiAgbGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneTtcbiAgcGFja2VkVGV4dHVyZURhdGFDYWNoZTogTWFwPFRlbnNvci5JZCwgVGV4dHVyZURhdGE+O1xuICB1bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgcGFjazJ1bnBhY2tNYXA6IE1hcDxUZW5zb3IuSWQsIFRlbnNvci5JZD47XG4gIHVucGFjazJwYWNrTWFwOiBNYXA8VGVuc29yLklkLCBUZW5zb3IuSWQ+O1xuICBpbml0aWFsaXplcnM6IFNldDxUZW5zb3IuSWQ+O1xuICBwYWNrPzogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcmVhZG9ubHkgYmFja2VuZDogV2ViR0xCYWNrZW5kLFxuICAgIHB1YmxpYyByZWFkb25seSBjb250ZXh0OiBTZXNzaW9uLkNvbnRleHQsXG4gICkge1xuICAgIHRoaXMubGF5b3V0U3RyYXRlZ3kgPSBuZXcgUHJlZmVyTG9naWNhbFN0cmF0ZWd5KGJhY2tlbmQuZ2xDb250ZXh0Lm1heFRleHR1cmVTaXplKTtcbiAgICB0aGlzLnByb2dyYW1NYW5hZ2VyID0gbmV3IFByb2dyYW1NYW5hZ2VyKHRoaXMuY29udGV4dC5wcm9maWxlciwgYmFja2VuZC5nbENvbnRleHQsIHRoaXMubGF5b3V0U3RyYXRlZ3kpO1xuICAgIHRoaXMudGV4dHVyZU1hbmFnZXIgPSBuZXcgVGV4dHVyZU1hbmFnZXIoYmFja2VuZC5nbENvbnRleHQsIHRoaXMubGF5b3V0U3RyYXRlZ3ksIHRoaXMuY29udGV4dC5wcm9maWxlciwge1xuICAgICAgcmV1c2VUZXh0dXJlczogYmFja2VuZC50ZXh0dXJlQ2FjaGVNb2RlID09PSAnZnVsbCcsXG4gICAgfSk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMucGFjayA9IGJhY2tlbmQucGFjaztcbiAgICB0aGlzLnBhY2sydW5wYWNrTWFwID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrMnBhY2tNYXAgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBjcmVhdGVJbmZlcmVuY2VIYW5kbGVyKCkge1xuICAgIHJldHVybiBuZXcgV2ViR0xJbmZlcmVuY2VIYW5kbGVyKHRoaXMpO1xuICB9XG4gIG9uR3JhcGhJbml0aWFsaXplZChncmFwaDogR3JhcGgpOiB2b2lkIHtcbiAgICBjb25zdCBpbml0aWFsaXplcnMgPSBncmFwaFxuICAgICAgLmdldFZhbHVlcygpXG4gICAgICAuZmlsdGVyKCh2KSA9PiB2LmZyb20gPT09IC0xICYmIHYudGVuc29yKVxuICAgICAgLm1hcCgodikgPT4gdi50ZW5zb3IhLmRhdGFJZCk7XG4gICAgdGhpcy5pbml0aWFsaXplcnMgPSBuZXcgU2V0KGluaXRpYWxpemVycyk7XG4gIH1cbiAgaXNJbml0aWFsaXplcih0ZW5zb3JJZDogVGVuc29yLklkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaW5pdGlhbGl6ZXJzID8gdGhpcy5pbml0aWFsaXplcnMuaGFzKHRlbnNvcklkKSA6IGZhbHNlO1xuICB9XG4gIGFkZEluaXRpYWxpemVyKHRlbnNvcklkOiBUZW5zb3IuSWQpOiB2b2lkIHtcbiAgICB0aGlzLmluaXRpYWxpemVycy5hZGQodGVuc29ySWQpO1xuICB9XG4gIGdldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIGlzUGFja2VkOiBib29sZWFuKTogVGV4dHVyZURhdGEgfCB1bmRlZmluZWQge1xuICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5nZXQodGVuc29ySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKTtcbiAgICB9XG4gIH1cbiAgc2V0VGV4dHVyZURhdGEodGVuc29ySWQ6IFRlbnNvci5JZCwgdGV4dHVyZURhdGE6IFRleHR1cmVEYXRhLCBpc1BhY2tlZCA9IGZhbHNlKTogdm9pZCB7XG4gICAgTG9nZ2VyLnZlcmJvc2UoJ1dlYkdMU2Vzc2lvbkhhbmRsZXInLCAnU3RvcmluZyBUZXh0dXJlIGRhdGEgaW4gY2FjaGUnKTtcbiAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5zZXQodGVuc29ySWQsIHRleHR1cmVEYXRhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuc2V0KHRlbnNvcklkLCB0ZXh0dXJlRGF0YSk7XG4gICAgfVxuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5wcm9ncmFtTWFuYWdlci5kaXNwb3NlKCk7XG4gICAgdGhpcy50ZXh0dXJlTWFuYWdlci5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2goKHRkKSA9PiB0aGlzLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkLCB0cnVlKSk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2goKHRkKSA9PiB0aGlzLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkLCB0cnVlKSk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gIH1cbiAgcmVzb2x2ZShub2RlOiBHcmFwaC5Ob2RlLCBvcHNldHM6IHJlYWRvbmx5IE9wU2V0W10sIGdyYXBoOiBHcmFwaCk6IE9wZXJhdG9yIHtcbiAgICBjb25zdCBvcCA9IHJlc29sdmVPcGVyYXRvcihub2RlLCBvcHNldHMsIFdFQkdMX09QX1JFU09MVkVfUlVMRVMpO1xuICAgIHJldHVybiB7IGltcGw6IG9wLm9wSW1wbCwgY29udGV4dDogb3Aub3BJbml0ID8gb3Aub3BJbml0KG5vZGUsIGdyYXBoKSA6IG5vZGUgfTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBlbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgKiBhcyBEYXRhRW5jb2RlcnMgZnJvbSAnLi90ZXh0dXJlLWRhdGEtZW5jb2Rlcic7XG5pbXBvcnQgeyBEYXRhRW5jb2RlciwgRW5jb2RlciwgRW5jb2RlclVzYWdlIH0gZnJvbSAnLi90ZXh0dXJlLWRhdGEtZW5jb2Rlcic7XG5pbXBvcnQgeyByZXBlYXRlZFRyeSB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZlbmNlQ29udGV4dCB7XG4gIHF1ZXJ5OiBXZWJHTFN5bmMgfCBudWxsO1xuICBpc0ZlbmNlUGFzc2VkKCk6IGJvb2xlYW47XG59XG5cbnR5cGUgUG9sbEl0ZW0gPSB7XG4gIGlzRG9uZUZuOiAoKSA9PiBib29sZWFuO1xuICByZXNvbHZlRm46ICgpID0+IHZvaWQ7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gbGluZWFyU2VhcmNoTGFzdFRydWUoYXJyOiBBcnJheTwoKSA9PiBib29sZWFuPik6IG51bWJlciB7XG4gIGxldCBpID0gMDtcbiAgZm9yICg7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICBjb25zdCBpc0RvbmUgPSBhcnJbaV0oKTtcbiAgICBpZiAoIWlzRG9uZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBpIC0gMTtcbn1cblxuLyoqXG4gKiBBYnN0cmFjdGlvbiBhbmQgd3JhcHBlciBhcm91bmQgV2ViR0xSZW5kZXJpbmdDb250ZXh0IGFuZCBpdHMgb3BlcmF0aW9uc1xuICovXG5leHBvcnQgY2xhc3MgV2ViR0xDb250ZXh0IHtcbiAgZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dDtcbiAgdmVyc2lvbjogMSB8IDI7XG5cbiAgcHJpdmF0ZSB2ZXJ0ZXhidWZmZXI6IFdlYkdMQnVmZmVyO1xuICBwcml2YXRlIGZyYW1lYnVmZmVyOiBXZWJHTEZyYW1lYnVmZmVyO1xuXG4gIC8vIFdlYkdMIGZsYWdzIGFuZCB2aXRhbCBwYXJhbWV0ZXJzXG4gIHByaXZhdGUgaXNGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlcjogYm9vbGVhbjtcbiAgaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gIGlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZDogYm9vbGVhbjtcbiAgaXNCbGVuZFN1cHBvcnRlZDogYm9vbGVhbjtcbiAgbWF4VGV4dHVyZVNpemU6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhDb21iaW5lZFRleHR1cmVJbWFnZVVuaXRzOiBudW1iZXI7XG4gIHByaXZhdGUgbWF4VGV4dHVyZUltYWdlVW5pdHM6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhDdWJlTWFwVGV4dHVyZVNpemU6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBzaGFkaW5nTGFuZ3VhZ2VWZXJzaW9uOiBzdHJpbmc7XG4gIC8vIHByaXZhdGUgd2ViZ2xWZW5kb3I6IHN0cmluZztcbiAgLy8gcHJpdmF0ZSB3ZWJnbFZlcnNpb246IHN0cmluZztcblxuICAvLyBXZWJHTDIgZmxhZ3MgYW5kIHZpdGFsIHBhcmFtZXRlcnNcbiAgLy8gcHJpdmF0ZSBtYXgzRFRleHR1cmVTaXplOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4QXJyYXlUZXh0dXJlTGF5ZXJzOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4Q29sb3JBdHRhY2htZW50czogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heERyYXdCdWZmZXJzOiBudW1iZXI7XG5cbiAgLy8gV2ViR0wgZXh0ZW5zaW9uc1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXG4gIHRleHR1cmVGbG9hdEV4dGVuc2lvbjogT0VTX3RleHR1cmVfZmxvYXQgfCBudWxsO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXG4gIHRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb246IE9FU190ZXh0dXJlX2hhbGZfZmxvYXQgfCBudWxsO1xuXG4gIC8vIFdlYkdMMiBleHRlbnNpb25zXG4gIGNvbG9yQnVmZmVyRmxvYXRFeHRlbnNpb246IHVua25vd24gfCBudWxsO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG4gIGRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjogeyBUSU1FX0VMQVBTRURfRVhUOiBHTGVudW07IEdQVV9ESVNKT0lOVF9FWFQ6IEdMZW51bSB9IHwgbnVsbDtcblxuICBwcml2YXRlIGRpc3Bvc2VkOiBib29sZWFuO1xuICBwcml2YXRlIGZyYW1lQnVmZmVyQm91bmQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCB2ZXJzaW9uOiAxIHwgMikge1xuICAgIHRoaXMuZ2wgPSBnbDtcbiAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uO1xuXG4gICAgdGhpcy5nZXRFeHRlbnNpb25zKCk7XG4gICAgdGhpcy52ZXJ0ZXhidWZmZXIgPSB0aGlzLmNyZWF0ZVZlcnRleGJ1ZmZlcigpO1xuICAgIHRoaXMuZnJhbWVidWZmZXIgPSB0aGlzLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG4gICAgdGhpcy5xdWVyeVZpdGFsUGFyYW1ldGVycygpO1xuICB9XG5cbiAgYWxsb2NhdGVUZXh0dXJlKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBlbmNvZGVyOiBEYXRhRW5jb2RlciwgZGF0YT86IEVuY29kZXIuRGF0YUFycmF5VHlwZSk6IFdlYkdMVGV4dHVyZSB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIC8vIGNyZWF0ZSB0aGUgdGV4dHVyZVxuICAgIGNvbnN0IHRleHR1cmUgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG4gICAgLy8gYmluZCB0aGUgdGV4dHVyZSBzbyB0aGUgZm9sbG93aW5nIG1ldGhvZHMgZWZmZWN0IHRoaXMgdGV4dHVyZS5cbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUlOX0ZJTFRFUiwgZ2wuTkVBUkVTVCk7XG4gICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01BR19GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1MsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1QsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGRhdGEgPyBlbmNvZGVyLmVuY29kZShkYXRhLCB3aWR0aCAqIGhlaWdodCkgOiBudWxsO1xuICAgIGdsLnRleEltYWdlMkQoXG4gICAgICBnbC5URVhUVVJFXzJELFxuICAgICAgMCwgLy8gTGV2ZWwgb2YgZGV0YWlsLlxuICAgICAgZW5jb2Rlci5pbnRlcm5hbEZvcm1hdCxcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgMCwgLy8gQWx3YXlzIDAgaW4gT3BlbkdMIEVTLlxuICAgICAgZW5jb2Rlci5mb3JtYXQsXG4gICAgICBlbmNvZGVyLnRleHR1cmVUeXBlLFxuICAgICAgYnVmZmVyLFxuICAgICk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgcmV0dXJuIHRleHR1cmUgYXMgV2ViR0xUZXh0dXJlO1xuICB9XG4gIHVwZGF0ZVRleHR1cmUoXG4gICAgdGV4dHVyZTogV2ViR0xUZXh0dXJlLFxuICAgIHdpZHRoOiBudW1iZXIsXG4gICAgaGVpZ2h0OiBudW1iZXIsXG4gICAgZW5jb2RlcjogRGF0YUVuY29kZXIsXG4gICAgZGF0YTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgY29uc3QgYnVmZmVyID0gZW5jb2Rlci5lbmNvZGUoZGF0YSwgd2lkdGggKiBoZWlnaHQpO1xuICAgIGdsLnRleFN1YkltYWdlMkQoXG4gICAgICBnbC5URVhUVVJFXzJELFxuICAgICAgMCwgLy8gbGV2ZWxcbiAgICAgIDAsIC8vIHhvZmZzZXRcbiAgICAgIDAsIC8vIHlvZmZzZXRcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgZW5jb2Rlci5mb3JtYXQsXG4gICAgICBlbmNvZGVyLnRleHR1cmVUeXBlLFxuICAgICAgYnVmZmVyLFxuICAgICk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gIH1cbiAgYXR0YWNoRnJhbWVidWZmZXIodGV4dHVyZTogV2ViR0xUZXh0dXJlLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAvLyBNYWtlIGl0IHRoZSB0YXJnZXQgZm9yIGZyYW1lYnVmZmVyIG9wZXJhdGlvbnMgLSBpbmNsdWRpbmcgcmVuZGVyaW5nLlxuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgdGhpcy5mcmFtZWJ1ZmZlcik7XG4gICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoZ2wuRlJBTUVCVUZGRVIsIGdsLkNPTE9SX0FUVEFDSE1FTlQwLCBnbC5URVhUVVJFXzJELCB0ZXh0dXJlLCAwKTsgLy8gMCwgd2UgYXJlbid0IHVzaW5nIE1JUE1BUHNcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICBnbC52aWV3cG9ydCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICBnbC5zY2lzc29yKDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICB9XG4gIHJlYWRUZXh0dXJlKFxuICAgIHRleHR1cmU6IFdlYkdMVGV4dHVyZSxcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIGRhdGFTaXplOiBudW1iZXIsXG4gICAgZGF0YVR5cGU6IEVuY29kZXIuRGF0YVR5cGUsXG4gICAgY2hhbm5lbHM6IG51bWJlcixcbiAgKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgaWYgKCFjaGFubmVscykge1xuICAgICAgY2hhbm5lbHMgPSAxO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuZnJhbWVCdWZmZXJCb3VuZCkge1xuICAgICAgdGhpcy5hdHRhY2hGcmFtZWJ1ZmZlcih0ZXh0dXJlLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB9XG4gICAgY29uc3QgZW5jb2RlciA9IHRoaXMuZ2V0RW5jb2RlcihkYXRhVHlwZSwgY2hhbm5lbHMpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGVuY29kZXIuYWxsb2NhdGUod2lkdGggKiBoZWlnaHQpO1xuICAgIC8vIGJpbmQgdGV4dHVyZSB0byBmcmFtZWJ1ZmZlclxuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSwgMCk7IC8vIDAsIHdlIGFyZW4ndCB1c2luZyBNSVBNQVBzXG4gICAgLy8gVE9ETzogQ2hlY2sgaWYgZnJhbWVidWZmZXIgaXMgcmVhZHlcbiAgICBnbC5yZWFkUGl4ZWxzKDAsIDAsIHdpZHRoLCBoZWlnaHQsIGdsLlJHQkEsIGVuY29kZXIudGV4dHVyZVR5cGUsIGJ1ZmZlcik7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgLy8gdW5iaW5kIEZCXG4gICAgcmV0dXJuIGVuY29kZXIuZGVjb2RlKGJ1ZmZlciwgZGF0YVNpemUpO1xuICB9XG5cbiAgaXNGcmFtZWJ1ZmZlclJlYWR5KCk6IGJvb2xlYW4ge1xuICAgIC8vIFRPRE86IEltcGxlbWVudCBsb2dpYyB0byBjaGVjayBpZiB0aGUgZnJhbWVidWZmZXIgaXMgcmVhZHlcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBnZXRBY3RpdmVUZXh0dXJlKCk6IHN0cmluZyB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGNvbnN0IG4gPSBnbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5BQ1RJVkVfVEVYVFVSRSk7XG4gICAgcmV0dXJuIGBURVhUVVJFJHtuIC0gZ2wuVEVYVFVSRTB9YDtcbiAgfVxuICBnZXRUZXh0dXJlQmluZGluZygpOiBXZWJHTFRleHR1cmUge1xuICAgIHJldHVybiB0aGlzLmdsLmdldFBhcmFtZXRlcih0aGlzLmdsLlRFWFRVUkVfQklORElOR18yRCk7XG4gIH1cbiAgZ2V0RnJhbWVidWZmZXJCaW5kaW5nKCk6IFdlYkdMRnJhbWVidWZmZXIge1xuICAgIHJldHVybiB0aGlzLmdsLmdldFBhcmFtZXRlcih0aGlzLmdsLkZSQU1FQlVGRkVSX0JJTkRJTkcpO1xuICB9XG4gIHNldFZlcnRleEF0dHJpYnV0ZXMocG9zaXRpb25IYW5kbGU6IG51bWJlciwgdGV4dHVyZUNvb3JkSGFuZGxlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcihwb3NpdGlvbkhhbmRsZSwgMywgZ2wuRkxPQVQsIGZhbHNlLCAyMCwgMCk7XG4gICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25IYW5kbGUpO1xuICAgIGlmICh0ZXh0dXJlQ29vcmRIYW5kbGUgIT09IC0xKSB7XG4gICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHRleHR1cmVDb29yZEhhbmRsZSwgMiwgZ2wuRkxPQVQsIGZhbHNlLCAyMCwgMTIpO1xuICAgICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkodGV4dHVyZUNvb3JkSGFuZGxlKTtcbiAgICB9XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gIH1cbiAgY3JlYXRlUHJvZ3JhbSh2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyLCBmcmFnU2hhZGVyOiBXZWJHTFNoYWRlcik6IFdlYkdMUHJvZ3JhbSB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGNvbnN0IHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCkhO1xuXG4gICAgLy8gdGhlIHByb2dyYW0gY29uc2lzdHMgb2Ygb3VyIHNoYWRlcnNcbiAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgdmVydGV4U2hhZGVyKTtcbiAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgZnJhZ1NoYWRlcik7XG4gICAgZ2wubGlua1Byb2dyYW0ocHJvZ3JhbSk7XG4gICAgcmV0dXJuIHByb2dyYW07XG4gIH1cbiAgY29tcGlsZVNoYWRlcihzaGFkZXJTb3VyY2U6IHN0cmluZywgc2hhZGVyVHlwZTogbnVtYmVyKTogV2ViR0xTaGFkZXIge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBzaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoc2hhZGVyVHlwZSk7XG4gICAgaWYgKCFzaGFkZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY3JlYXRlU2hhZGVyKCkgcmV0dXJuZWQgbnVsbCB3aXRoIHR5cGUgJHtzaGFkZXJUeXBlfWApO1xuICAgIH1cblxuICAgIGdsLnNoYWRlclNvdXJjZShzaGFkZXIsIHNoYWRlclNvdXJjZSk7XG4gICAgZ2wuY29tcGlsZVNoYWRlcihzaGFkZXIpO1xuICAgIGlmIChnbC5nZXRTaGFkZXJQYXJhbWV0ZXIoc2hhZGVyLCBnbC5DT01QSUxFX1NUQVRVUykgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBjb21waWxlIHNoYWRlcjogJHtnbC5nZXRTaGFkZXJJbmZvTG9nKHNoYWRlcil9XG5TaGFkZXIgc291cmNlOlxuJHtzaGFkZXJTb3VyY2V9YCk7XG4gICAgfVxuICAgIHJldHVybiBzaGFkZXI7XG4gIH1cbiAgZGVsZXRlU2hhZGVyKHNoYWRlcjogV2ViR0xTaGFkZXIpOiB2b2lkIHtcbiAgICB0aGlzLmdsLmRlbGV0ZVNoYWRlcihzaGFkZXIpO1xuICB9XG4gIGJpbmRUZXh0dXJlVG9Vbmlmb3JtKHRleHR1cmU6IFdlYkdMVGV4dHVyZSwgcG9zaXRpb246IG51bWJlciwgdW5pZm9ybUhhbmRsZTogV2ViR0xVbmlmb3JtTG9jYXRpb24pOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wuYWN0aXZlVGV4dHVyZShnbC5URVhUVVJFMCArIHBvc2l0aW9uKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICBnbC51bmlmb3JtMWkodW5pZm9ybUhhbmRsZSwgcG9zaXRpb24pO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGRyYXcoKTogdm9pZCB7XG4gICAgdGhpcy5nbC5kcmF3QXJyYXlzKHRoaXMuZ2wuVFJJQU5HTEVfU1RSSVAsIDAsIDQpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGNoZWNrRXJyb3IoKTogdm9pZCB7XG4gICAgaWYgKGVudi5kZWJ1Zykge1xuICAgICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgICAgY29uc3QgZXJyb3IgPSBnbC5nZXRFcnJvcigpO1xuICAgICAgbGV0IGxhYmVsID0gJyc7XG4gICAgICBzd2l0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNhc2UgZ2wuTk9fRVJST1I6XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjYXNlIGdsLklOVkFMSURfRU5VTTpcbiAgICAgICAgICBsYWJlbCA9ICdJTlZBTElEX0VOVU0nO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGdsLklOVkFMSURfVkFMVUU6XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9WQUxVRSc7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgZ2wuSU5WQUxJRF9PUEVSQVRJT046XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9PUEVSQVRJT04nO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGdsLklOVkFMSURfRlJBTUVCVUZGRVJfT1BFUkFUSU9OOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfRlJBTUVCVUZGRVJfT1BFUkFUSU9OJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBnbC5PVVRfT0ZfTUVNT1JZOlxuICAgICAgICAgIGxhYmVsID0gJ09VVF9PRl9NRU1PUlknO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGdsLkNPTlRFWFRfTE9TVF9XRUJHTDpcbiAgICAgICAgICBsYWJlbCA9ICdDT05URVhUX0xPU1RfV0VCR0wnO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGxhYmVsID0gYFVua25vd24gV2ViR0wgRXJyb3I6ICR7ZXJyb3IudG9TdHJpbmcoMTYpfWA7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IobGFiZWwpO1xuICAgIH1cbiAgfVxuICBkZWxldGVUZXh0dXJlKHRleHR1cmU6IFdlYkdMVGV4dHVyZSk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlKTtcbiAgfVxuICBkZWxldGVQcm9ncmFtKHByb2dyYW06IFdlYkdMUHJvZ3JhbSk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZGVsZXRlUHJvZ3JhbShwcm9ncmFtKTtcbiAgfVxuICBnZXRFbmNvZGVyKGRhdGFUeXBlOiBFbmNvZGVyLkRhdGFUeXBlLCBjaGFubmVsczogbnVtYmVyLCB1c2FnZTogRW5jb2RlclVzYWdlID0gRW5jb2RlclVzYWdlLkRlZmF1bHQpOiBEYXRhRW5jb2RlciB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuUmVkRmxvYXQzMkRhdGFFbmNvZGVyKHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dCwgY2hhbm5lbHMpO1xuICAgIH1cblxuICAgIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICAgIGNhc2UgJ2Zsb2F0JzpcbiAgICAgICAgaWYgKHVzYWdlID09PSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSB8fCB0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCkge1xuICAgICAgICAgIHJldHVybiBuZXcgRGF0YUVuY29kZXJzLlJHQkFGbG9hdERhdGFFbmNvZGVyKHRoaXMuZ2wsIGNoYW5uZWxzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5SR0JBRmxvYXREYXRhRW5jb2RlcihcbiAgICAgICAgICAgIHRoaXMuZ2wsXG4gICAgICAgICAgICBjaGFubmVscyxcbiAgICAgICAgICAgIHRoaXMudGV4dHVyZUhhbGZGbG9hdEV4dGVuc2lvbiEuSEFMRl9GTE9BVF9PRVMsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgY2FzZSAnaW50JzpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKTtcbiAgICAgIGNhc2UgJ2J5dGUnOlxuICAgICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5VaW50OERhdGFFbmNvZGVyKHRoaXMuZ2wsIGNoYW5uZWxzKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkYXRhVHlwZTogJHtkYXRhVHlwZX1gKTtcbiAgICB9XG4gIH1cbiAgY2xlYXJBY3RpdmVUZXh0dXJlcygpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZm9yIChsZXQgdW5pdCA9IDA7IHVuaXQgPCB0aGlzLm1heFRleHR1cmVJbWFnZVVuaXRzOyArK3VuaXQpIHtcbiAgICAgIGdsLmFjdGl2ZVRleHR1cmUoZ2wuVEVYVFVSRTAgKyB1bml0KTtcbiAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgIH1cbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIG51bGwpO1xuICAgIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKHRoaXMuZnJhbWVidWZmZXIpO1xuICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCBudWxsKTtcbiAgICBnbC5kZWxldGVCdWZmZXIodGhpcy52ZXJ0ZXhidWZmZXIpO1xuICAgIGdsLmJpbmRCdWZmZXIoZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIG51bGwpO1xuICAgIGdsLmZpbmlzaCgpO1xuICAgIHRoaXMuZGlzcG9zZWQgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVEZWZhdWx0R2VvbWV0cnkoKTogRmxvYXQzMkFycmF5IHtcbiAgICAvLyBTZXRzIG9mIHgseSx6KD0wKSxzLHQgY29vcmRpbmF0ZXMuXG4gICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoW1xuICAgICAgLTEuMCxcbiAgICAgIDEuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIDEuMCwgLy8gdXBwZXIgbGVmdFxuICAgICAgLTEuMCxcbiAgICAgIC0xLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjAsIC8vIGxvd2VyIGxlZnRcbiAgICAgIDEuMCxcbiAgICAgIDEuMCxcbiAgICAgIDAuMCxcbiAgICAgIDEuMCxcbiAgICAgIDEuMCwgLy8gdXBwZXIgcmlnaHRcbiAgICAgIDEuMCxcbiAgICAgIC0xLjAsXG4gICAgICAwLjAsXG4gICAgICAxLjAsXG4gICAgICAwLjAsIC8vIGxvd2VyIHJpZ2h0XG4gICAgXSk7XG4gIH1cbiAgcHJpdmF0ZSBjcmVhdGVWZXJ0ZXhidWZmZXIoKTogV2ViR0xCdWZmZXIge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBidWZmZXIgPSBnbC5jcmVhdGVCdWZmZXIoKTtcbiAgICBpZiAoIWJ1ZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjcmVhdGVCdWZmZXIoKSByZXR1cm5lZCBudWxsJyk7XG4gICAgfVxuICAgIGNvbnN0IGdlb21ldHJ5ID0gdGhpcy5jcmVhdGVEZWZhdWx0R2VvbWV0cnkoKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgYnVmZmVyKTtcbiAgICBnbC5idWZmZXJEYXRhKGdsLkFSUkFZX0JVRkZFUiwgZ2VvbWV0cnksIGdsLlNUQVRJQ19EUkFXKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICByZXR1cm4gYnVmZmVyO1xuICB9XG4gIHByaXZhdGUgY3JlYXRlRnJhbWVidWZmZXIoKTogV2ViR0xGcmFtZWJ1ZmZlciB7XG4gICAgY29uc3QgZmIgPSB0aGlzLmdsLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG4gICAgaWYgKCFmYikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjcmVhdGVGcmFtZWJ1ZmZlciByZXR1cm5lZCBudWxsJyk7XG4gICAgfVxuICAgIHJldHVybiBmYjtcbiAgfVxuXG4gIHByaXZhdGUgcXVlcnlWaXRhbFBhcmFtZXRlcnMoKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuXG4gICAgdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyID0gdGhpcy5jaGVja0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyKCk7XG4gICAgdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQgPSB0aGlzLmNoZWNrUmVuZGVyRmxvYXQzMigpO1xuICAgIHRoaXMuaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQgPSB0aGlzLmNoZWNrRmxvYXQzMkRvd25sb2FkKCk7XG5cbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAxICYmICF0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24gJiYgIXRoaXMuaXNSZW5kZXJGbG9hdDMyU3VwcG9ydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2JvdGggZmxvYXQzMiBhbmQgZmxvYXQxNiBUZXh0dXJlVHlwZSBhcmUgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cblxuICAgIHRoaXMuaXNCbGVuZFN1cHBvcnRlZCA9ICF0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCB8fCB0aGlzLmNoZWNrRmxvYXQzMkJsZW5kKCk7XG5cbiAgICAvLyB0aGlzLm1heENvbWJpbmVkVGV4dHVyZUltYWdlVW5pdHMgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX0NPTUJJTkVEX1RFWFRVUkVfSU1BR0VfVU5JVFMpO1xuICAgIHRoaXMubWF4VGV4dHVyZVNpemUgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX1RFWFRVUkVfU0laRSk7XG4gICAgdGhpcy5tYXhUZXh0dXJlSW1hZ2VVbml0cyA9IGdsLmdldFBhcmFtZXRlcihnbC5NQVhfVEVYVFVSRV9JTUFHRV9VTklUUyk7XG4gICAgLy8gdGhpcy5tYXhDdWJlTWFwVGV4dHVyZVNpemUgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX0NVQkVfTUFQX1RFWFRVUkVfU0laRSk7XG4gICAgLy8gdGhpcy5zaGFkaW5nTGFuZ3VhZ2VWZXJzaW9uID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLlNIQURJTkdfTEFOR1VBR0VfVkVSU0lPTik7XG4gICAgLy8gdGhpcy53ZWJnbFZlbmRvciA9IGdsLmdldFBhcmFtZXRlcihnbC5WRU5ET1IpO1xuICAgIC8vIHRoaXMud2ViZ2xWZXJzaW9uID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLlZFUlNJT04pO1xuXG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgLy8gdGhpcy5tYXgzRFRleHR1cmVTaXplID0gZ2wuZ2V0UGFyYW1ldGVyKFdlYkdMMlJlbmRlcmluZ0NvbnRleHQuTUFYXzNEX1RFWFRVUkVfU0laRSk7XG4gICAgICAvLyB0aGlzLm1heEFycmF5VGV4dHVyZUxheWVycyA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF9BUlJBWV9URVhUVVJFX0xBWUVSUyk7XG4gICAgICAvLyB0aGlzLm1heENvbG9yQXR0YWNobWVudHMgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfQ09MT1JfQVRUQUNITUVOVFMpO1xuICAgICAgLy8gdGhpcy5tYXhEcmF3QnVmZmVycyA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF9EUkFXX0JVRkZFUlMpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGdldEV4dGVuc2lvbnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgdGhpcy5jb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ0VYVF9jb2xvcl9idWZmZXJfZmxvYXQnKTtcbiAgICAgIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ0VYVF9kaXNqb2ludF90aW1lcl9xdWVyeV93ZWJnbDInKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24gPSB0aGlzLmdsLmdldEV4dGVuc2lvbignT0VTX3RleHR1cmVfZmxvYXQnKTtcbiAgICAgIHRoaXMudGV4dHVyZUhhbGZGbG9hdEV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0Jyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyKCk6IGJvb2xlYW4ge1xuICAgIC8vIHRlc3Qgd2hldGhlciBGbG9hdDMyIHRleHR1cmUgaXMgc3VwcG9ydGVkOlxuICAgIC8vIFNURVAuMSBjcmVhdGUgYSBmbG9hdCB0ZXh0dXJlXG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGNvbnN0IHRleHR1cmUgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICAgIGNvbnN0IGludGVybmFsRm9ybWF0ID0gdGhpcy52ZXJzaW9uID09PSAyID8gKGdsIGFzIHVua25vd24gYXMgeyBSR0JBMzJGOiBudW1iZXIgfSkuUkdCQTMyRiA6IGdsLlJHQkE7XG4gICAgZ2wudGV4SW1hZ2UyRChnbC5URVhUVVJFXzJELCAwLCBpbnRlcm5hbEZvcm1hdCwgMSwgMSwgMCwgZ2wuUkdCQSwgZ2wuRkxPQVQsIG51bGwpO1xuICAgIC8vIFNURVAuMiBiaW5kIGEgZnJhbWUgYnVmZmVyXG4gICAgY29uc3QgZnJhbWVCdWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgZnJhbWVCdWZmZXIpO1xuICAgIC8vIFNURVAuMyBhdHRhY2ggdGV4dHVyZSB0byBmcmFtZWJ1ZmZlclxuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSwgMCk7XG4gICAgLy8gU1RFUC40IHRlc3Qgd2hldGhlciBmcmFtZWJ1ZmZlciBpcyBjb21wbGV0ZVxuICAgIGNvbnN0IGlzQ29tcGxldGUgPSBnbC5jaGVja0ZyYW1lYnVmZmVyU3RhdHVzKGdsLkZSQU1FQlVGRkVSKSA9PT0gZ2wuRlJBTUVCVUZGRVJfQ09NUExFVEU7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgbnVsbCk7XG4gICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICBnbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuICAgIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKGZyYW1lQnVmZmVyKTtcbiAgICByZXR1cm4gaXNDb21wbGV0ZTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tSZW5kZXJGbG9hdDMyKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIGlmICghdGhpcy5jb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLnRleHR1cmVGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXI7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrRmxvYXQzMkRvd25sb2FkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIGlmICghdGhpcy5jb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLnRleHR1cmVGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdXRUJHTF9jb2xvcl9idWZmZXJfZmxvYXQnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXI7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciBHTF9CTEVORCBpcyBzdXBwb3J0ZWRcbiAgICovXG4gIHByaXZhdGUgY2hlY2tGbG9hdDMyQmxlbmQoKTogYm9vbGVhbiB7XG4gICAgLy8gaXQgbG9va3MgbGlrZSBjdXJyZW50bHkgKDIwMTktMDUtMDgpIHRoZXJlIGlzIG5vIGVhc3kgd2F5IHRvIGRldGVjdCB3aGV0aGVyIEJMRU5EIGlzIHN1cHBvcnRlZFxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueGpzL2lzc3Vlcy8xNDVcblxuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcblxuICAgIGxldCB0ZXh0dXJlOiBXZWJHTFRleHR1cmUgfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIGxldCBmcmFtZUJ1ZmZlcjogV2ViR0xGcmFtZWJ1ZmZlciB8IG51bGwgfCB1bmRlZmluZWQ7XG4gICAgbGV0IHZlcnRleFNoYWRlcjogV2ViR0xTaGFkZXIgfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIGxldCBmcmFnbWVudFNoYWRlcjogV2ViR0xTaGFkZXIgfCBudWxsIHwgdW5kZWZpbmVkO1xuICAgIGxldCBwcm9ncmFtOiBXZWJHTFByb2dyYW0gfCBudWxsIHwgdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIHRleHR1cmUgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG4gICAgICBmcmFtZUJ1ZmZlciA9IGdsLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG4gICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICAgICAgY29uc3QgaW50ZXJuYWxGb3JtYXQgPSB0aGlzLnZlcnNpb24gPT09IDIgPyAoZ2wgYXMgdW5rbm93biBhcyB7IFJHQkEzMkY6IG51bWJlciB9KS5SR0JBMzJGIDogZ2wuUkdCQTtcbiAgICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgaW50ZXJuYWxGb3JtYXQsIDEsIDEsIDAsIGdsLlJHQkEsIGdsLkZMT0FULCBudWxsKTtcblxuICAgICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBmcmFtZUJ1ZmZlcik7XG4gICAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApO1xuXG4gICAgICBnbC5lbmFibGUoZ2wuQkxFTkQpO1xuXG4gICAgICB2ZXJ0ZXhTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoZ2wuVkVSVEVYX1NIQURFUik7XG4gICAgICBpZiAoIXZlcnRleFNoYWRlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBnbC5zaGFkZXJTb3VyY2UodmVydGV4U2hhZGVyLCAndm9pZCBtYWluKCl7fScpO1xuICAgICAgZ2wuY29tcGlsZVNoYWRlcih2ZXJ0ZXhTaGFkZXIpO1xuXG4gICAgICBmcmFnbWVudFNoYWRlciA9IGdsLmNyZWF0ZVNoYWRlcihnbC5GUkFHTUVOVF9TSEFERVIpO1xuICAgICAgaWYgKCFmcmFnbWVudFNoYWRlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBnbC5zaGFkZXJTb3VyY2UoZnJhZ21lbnRTaGFkZXIsICdwcmVjaXNpb24gaGlnaHAgZmxvYXQ7dm9pZCBtYWluKCl7Z2xfRnJhZ0NvbG9yPXZlYzQoMC41KTt9Jyk7XG4gICAgICBnbC5jb21waWxlU2hhZGVyKGZyYWdtZW50U2hhZGVyKTtcblxuICAgICAgcHJvZ3JhbSA9IGdsLmNyZWF0ZVByb2dyYW0oKTtcbiAgICAgIGlmICghcHJvZ3JhbSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgdmVydGV4U2hhZGVyKTtcbiAgICAgIGdsLmF0dGFjaFNoYWRlcihwcm9ncmFtLCBmcmFnbWVudFNoYWRlcik7XG4gICAgICBnbC5saW5rUHJvZ3JhbShwcm9ncmFtKTtcbiAgICAgIGdsLnVzZVByb2dyYW0ocHJvZ3JhbSk7XG5cbiAgICAgIGdsLmRyYXdBcnJheXMoZ2wuUE9JTlRTLCAwLCAxKTtcbiAgICAgIHJldHVybiBnbC5nZXRFcnJvcigpID09PSBnbC5OT19FUlJPUjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZ2wuZGlzYWJsZShnbC5CTEVORCk7XG5cbiAgICAgIGlmIChwcm9ncmFtKSB7XG4gICAgICAgIGdsLmRlbGV0ZVByb2dyYW0ocHJvZ3JhbSk7XG4gICAgICB9XG4gICAgICBpZiAodmVydGV4U2hhZGVyKSB7XG4gICAgICAgIGdsLmRlbGV0ZVNoYWRlcih2ZXJ0ZXhTaGFkZXIpO1xuICAgICAgfVxuICAgICAgaWYgKGZyYWdtZW50U2hhZGVyKSB7XG4gICAgICAgIGdsLmRlbGV0ZVNoYWRlcihmcmFnbWVudFNoYWRlcik7XG4gICAgICB9XG4gICAgICBpZiAoZnJhbWVCdWZmZXIpIHtcbiAgICAgICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICAgICAgZ2wuZGVsZXRlRnJhbWVidWZmZXIoZnJhbWVCdWZmZXIpO1xuICAgICAgfVxuICAgICAgaWYgKHRleHR1cmUpIHtcbiAgICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgbnVsbCk7XG4gICAgICAgIGdsLmRlbGV0ZVRleHR1cmUodGV4dHVyZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYmVnaW5UaW1lcigpOiBXZWJHTFF1ZXJ5IHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyICYmIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICBjb25zdCBleHQgPSB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjtcblxuICAgICAgY29uc3QgcXVlcnkgPSBnbDIuY3JlYXRlUXVlcnkoKSBhcyBXZWJHTFF1ZXJ5O1xuICAgICAgZ2wyLmJlZ2luUXVlcnkoZXh0LlRJTUVfRUxBUFNFRF9FWFQsIHF1ZXJ5KTtcbiAgICAgIHJldHVybiBxdWVyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgfVxuICB9XG5cbiAgZW5kVGltZXIoKSB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMiAmJiB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgY29uc3QgZXh0ID0gdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb247XG4gICAgICBnbDIuZW5kUXVlcnkoZXh0LlRJTUVfRUxBUFNFRF9FWFQpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfVxuXG4gIGlzVGltZXJSZXN1bHRBdmFpbGFibGUocXVlcnk6IFdlYkdMUXVlcnkpOiBib29sZWFuIHtcbiAgICBsZXQgYXZhaWxhYmxlID0gZmFsc2UsXG4gICAgICBkaXNqb2ludCA9IGZhbHNlO1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIgJiYgdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb24pIHtcbiAgICAgIGNvbnN0IGdsMiA9IHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICAgIGNvbnN0IGV4dCA9IHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uO1xuXG4gICAgICBhdmFpbGFibGUgPSBnbDIuZ2V0UXVlcnlQYXJhbWV0ZXIocXVlcnksIGdsMi5RVUVSWV9SRVNVTFRfQVZBSUxBQkxFKTtcbiAgICAgIGRpc2pvaW50ID0gZ2wyLmdldFBhcmFtZXRlcihleHQuR1BVX0RJU0pPSU5UX0VYVCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRPRE86IGFkZCB3ZWJnbCAxIGhhbmRsaW5nLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHTDEgcHJvZmlsaW5nIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF2YWlsYWJsZSAmJiAhZGlzam9pbnQ7XG4gIH1cblxuICBnZXRUaW1lclJlc3VsdChxdWVyeTogV2ViR0xRdWVyeSk6IG51bWJlciB7XG4gICAgbGV0IHRpbWVFbGFwc2VkID0gMDtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICB0aW1lRWxhcHNlZCA9IGdsMi5nZXRRdWVyeVBhcmFtZXRlcihxdWVyeSwgZ2wyLlFVRVJZX1JFU1VMVCk7XG4gICAgICBnbDIuZGVsZXRlUXVlcnkocXVlcnkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgICAvLyByZXR1cm4gbWlsaXNlY29uZHNcbiAgICByZXR1cm4gdGltZUVsYXBzZWQgLyAxMDAwMDAwO1xuICB9XG5cbiAgYXN5bmMgd2FpdEZvclF1ZXJ5QW5kR2V0VGltZShxdWVyeTogV2ViR0xRdWVyeSk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgYXdhaXQgcmVwZWF0ZWRUcnkoKCkgPT4gdGhpcy5pc1RpbWVyUmVzdWx0QXZhaWxhYmxlKHF1ZXJ5KSk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VGltZXJSZXN1bHQocXVlcnkpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGNyZWF0ZUFuZFdhaXRGb3JGZW5jZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmZW5jZUNvbnRleHQgPSB0aGlzLmNyZWF0ZUZlbmNlKHRoaXMuZ2wpO1xuICAgIHJldHVybiB0aGlzLnBvbGxGZW5jZShmZW5jZUNvbnRleHQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVGZW5jZShnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0KTogRmVuY2VDb250ZXh0IHtcbiAgICBsZXQgaXNGZW5jZVBhc3NlZDogKCkgPT4gYm9vbGVhbjtcbiAgICBjb25zdCBnbDIgPSBnbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgIGNvbnN0IHF1ZXJ5ID0gZ2wyLmZlbmNlU3luYyhnbDIuU1lOQ19HUFVfQ09NTUFORFNfQ09NUExFVEUsIDApO1xuICAgIGdsLmZsdXNoKCk7XG4gICAgaWYgKHF1ZXJ5ID09PSBudWxsKSB7XG4gICAgICBpc0ZlbmNlUGFzc2VkID0gKCkgPT4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaXNGZW5jZVBhc3NlZCA9ICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gZ2wyLmNsaWVudFdhaXRTeW5jKHF1ZXJ5LCAwLCAwKTtcbiAgICAgICAgcmV0dXJuIHN0YXR1cyA9PT0gZ2wyLkFMUkVBRFlfU0lHTkFMRUQgfHwgc3RhdHVzID09PSBnbDIuQ09ORElUSU9OX1NBVElTRklFRDtcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7IHF1ZXJ5LCBpc0ZlbmNlUGFzc2VkIH07XG4gIH1cblxuICBhc3luYyBwb2xsRmVuY2UoZmVuY2VDb250ZXh0OiBGZW5jZUNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgIHZvaWQgdGhpcy5hZGRJdGVtVG9Qb2xsKFxuICAgICAgICAoKSA9PiBmZW5jZUNvbnRleHQuaXNGZW5jZVBhc3NlZCgpLFxuICAgICAgICAoKSA9PiByZXNvbHZlKCksXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpdGVtc1RvUG9sbDogUG9sbEl0ZW1bXSA9IFtdO1xuXG4gIHBvbGxJdGVtcygpOiB2b2lkIHtcbiAgICAvLyBGaW5kIHRoZSBsYXN0IHF1ZXJ5IHRoYXQgaGFzIGZpbmlzaGVkLlxuICAgIGNvbnN0IGluZGV4ID0gbGluZWFyU2VhcmNoTGFzdFRydWUodGhpcy5pdGVtc1RvUG9sbC5tYXAoKHgpID0+IHguaXNEb25lRm4pKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBpbmRleDsgKytpKSB7XG4gICAgICBjb25zdCB7IHJlc29sdmVGbiB9ID0gdGhpcy5pdGVtc1RvUG9sbFtpXTtcbiAgICAgIHJlc29sdmVGbigpO1xuICAgIH1cbiAgICB0aGlzLml0ZW1zVG9Qb2xsID0gdGhpcy5pdGVtc1RvUG9sbC5zbGljZShpbmRleCArIDEpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhZGRJdGVtVG9Qb2xsKGlzRG9uZUZuOiAoKSA9PiBib29sZWFuLCByZXNvbHZlRm46ICgpID0+IHZvaWQpIHtcbiAgICB0aGlzLml0ZW1zVG9Qb2xsLnB1c2goeyBpc0RvbmVGbiwgcmVzb2x2ZUZuIH0pO1xuICAgIGlmICh0aGlzLml0ZW1zVG9Qb2xsLmxlbmd0aCA+IDEpIHtcbiAgICAgIC8vIFdlIGFscmVhZHkgaGF2ZSBhIHJ1bm5pbmcgbG9vcCB0aGF0IHBvbGxzLlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBTdGFydCBhIG5ldyBsb29wIHRoYXQgcG9sbHMuXG4gICAgYXdhaXQgcmVwZWF0ZWRUcnkoKCkgPT4ge1xuICAgICAgdGhpcy5wb2xsSXRlbXMoKTtcbiAgICAgIC8vIEVuZCB0aGUgbG9vcCBpZiBubyBtb3JlIGl0ZW1zIHRvIHBvbGwuXG4gICAgICByZXR1cm4gdGhpcy5pdGVtc1RvUG9sbC5sZW5ndGggPT09IDA7XG4gICAgfSk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5cbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbmNvbnN0IGNhY2hlOiB7IFtjb250ZXh0SWQ6IHN0cmluZ106IFdlYkdMQ29udGV4dCB9ID0ge307XG5cbi8qKlxuICogVGhpcyBmYWN0b3J5IGZ1bmN0aW9uIGNyZWF0ZXMgcHJvcGVyIFdlYkdMUmVuZGVyaW5nQ29udGV4dCBiYXNlZCBvblxuICogdGhlIGN1cnJlbnQgYnJvd3NlcnMgY2FwYWJpbGl0aWVzXG4gKiBUaGUgb3JkZXIgaXMgZnJvbSBoaWdoZXIvbW9zdCByZWNlbnQgdmVyc2lvbnMgdG8gbW9zdCBiYXNpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlV2ViR0xDb250ZXh0KGNvbnRleHRJZD86ICd3ZWJnbCcgfCAnd2ViZ2wyJyk6IFdlYkdMQ29udGV4dCB7XG4gIGxldCBjb250ZXh0OiBXZWJHTENvbnRleHQgfCB1bmRlZmluZWQ7XG4gIGlmICgoIWNvbnRleHRJZCB8fCBjb250ZXh0SWQgPT09ICd3ZWJnbDInKSAmJiAnd2ViZ2wyJyBpbiBjYWNoZSkge1xuICAgIGNvbnRleHQgPSBjYWNoZS53ZWJnbDI7XG4gIH0gZWxzZSBpZiAoKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wnKSAmJiAnd2ViZ2wnIGluIGNhY2hlKSB7XG4gICAgY29udGV4dCA9IGNhY2hlLndlYmdsO1xuICB9XG5cbiAgaWYgKCFjb250ZXh0KSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIHRyeSB0byBjcmVhdGUgd2ViZ2wgY29udGV4dCBmcm9tIGFuIG9mZnNjcmVlbiBjYW52YXNcbiAgICAgIGNvbnN0IG9mZnNjcmVlbkNhbnZhcyA9IGNyZWF0ZU9mZnNjcmVlbkNhbnZhcygpO1xuICAgICAgY29udGV4dCA9IGNyZWF0ZU5ld1dlYkdMQ29udGV4dChvZmZzY3JlZW5DYW52YXMsIGNvbnRleHRJZCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gaWYgZmFpbGVkLCBmYWxsYmFjayB0byB0cnkgdG8gdXNlIGEgbm9ybWFsIGNhbnZhcyBlbGVtZW50XG4gICAgICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcbiAgICAgIGNvbnRleHQgPSBjcmVhdGVOZXdXZWJHTENvbnRleHQoY2FudmFzLCBjb250ZXh0SWQpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnRleHRJZCA9IGNvbnRleHRJZCB8fCBjb250ZXh0LnZlcnNpb24gPT09IDEgPyAnd2ViZ2wnIDogJ3dlYmdsMic7XG4gIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICBjYWNoZVtjb250ZXh0SWRdID0gY29udGV4dDtcblxuICBpZiAoZ2wuaXNDb250ZXh0TG9zdCgpKSB7XG4gICAgZGVsZXRlIGNhY2hlW2NvbnRleHRJZF07XG4gICAgcmV0dXJuIGNyZWF0ZVdlYkdMQ29udGV4dChjb250ZXh0SWQpO1xuICB9XG5cbiAgZ2wuZGlzYWJsZShnbC5ERVBUSF9URVNUKTtcbiAgZ2wuZGlzYWJsZShnbC5TVEVOQ0lMX1RFU1QpO1xuICBnbC5kaXNhYmxlKGdsLkJMRU5EKTtcbiAgZ2wuZGlzYWJsZShnbC5ESVRIRVIpO1xuICBnbC5kaXNhYmxlKGdsLlBPTFlHT05fT0ZGU0VUX0ZJTEwpO1xuICBnbC5kaXNhYmxlKGdsLlNBTVBMRV9DT1ZFUkFHRSk7XG4gIGdsLmVuYWJsZShnbC5TQ0lTU09SX1RFU1QpO1xuICBnbC5lbmFibGUoZ2wuQ1VMTF9GQUNFKTtcbiAgZ2wuY3VsbEZhY2UoZ2wuQkFDSyk7XG5cbiAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOZXdXZWJHTENvbnRleHQoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCwgY29udGV4dElkPzogJ3dlYmdsJyB8ICd3ZWJnbDInKTogV2ViR0xDb250ZXh0IHtcbiAgY29uc3QgY29udGV4dEF0dHJpYnV0ZXM6IFdlYkdMQ29udGV4dEF0dHJpYnV0ZXMgPSB7XG4gICAgYWxwaGE6IGZhbHNlLFxuICAgIGRlcHRoOiBmYWxzZSxcbiAgICBhbnRpYWxpYXM6IGZhbHNlLFxuICAgIHN0ZW5jaWw6IGZhbHNlLFxuICAgIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogZmFsc2UsXG4gICAgcHJlbXVsdGlwbGllZEFscGhhOiBmYWxzZSxcbiAgICBmYWlsSWZNYWpvclBlcmZvcm1hbmNlQ2F2ZWF0OiBmYWxzZSxcbiAgfTtcbiAgbGV0IGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQgfCBudWxsO1xuICBjb25zdCBjYSA9IGNvbnRleHRBdHRyaWJ1dGVzO1xuICBpZiAoIWNvbnRleHRJZCB8fCBjb250ZXh0SWQgPT09ICd3ZWJnbDInKSB7XG4gICAgZ2wgPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wyJywgY2EpO1xuICAgIGlmIChnbCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBXZWJHTENvbnRleHQoZ2wsIDIpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIExvZ2dlci53YXJuaW5nKCdHbENvbnRleHRGYWN0b3J5JywgYGZhaWxlZCB0byBjcmVhdGUgV2ViR0xDb250ZXh0IHVzaW5nIGNvbnRleHRJZCAnd2ViZ2wyJy4gRXJyb3I6ICR7ZXJyfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoIWNvbnRleHRJZCB8fCBjb250ZXh0SWQgPT09ICd3ZWJnbCcpIHtcbiAgICBnbCA9IGNhbnZhcy5nZXRDb250ZXh0KCd3ZWJnbCcsIGNhKSB8fCAoY2FudmFzLmdldENvbnRleHQoJ2V4cGVyaW1lbnRhbC13ZWJnbCcsIGNhKSBhcyBXZWJHTFJlbmRlcmluZ0NvbnRleHQpO1xuICAgIGlmIChnbCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBXZWJHTENvbnRleHQoZ2wsIDEpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIExvZ2dlci53YXJuaW5nKFxuICAgICAgICAgICdHbENvbnRleHRGYWN0b3J5JyxcbiAgICAgICAgICBgZmFpbGVkIHRvIGNyZWF0ZSBXZWJHTENvbnRleHQgdXNpbmcgY29udGV4dElkICd3ZWJnbCcgb3IgJ2V4cGVyaW1lbnRhbC13ZWJnbCcuIEVycm9yOiAke2Vycn1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignV2ViR0wgaXMgbm90IHN1cHBvcnRlZCcpO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5kZWNsYXJlIGxldCBPZmZzY3JlZW5DYW52YXM6IHsgbmV3ICh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IEhUTUxDYW52YXNFbGVtZW50IH07XG5cbmZ1bmN0aW9uIGNyZWF0ZUNhbnZhcygpOiBIVE1MQ2FudmFzRWxlbWVudCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZmFpbGVkIHRvIGNyZWF0ZSBjYW52YXM6IGRvY3VtZW50IGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuICBjb25zdCBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gIGNhbnZhcy53aWR0aCA9IDE7XG4gIGNhbnZhcy5oZWlnaHQgPSAxO1xuICByZXR1cm4gY2FudmFzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVPZmZzY3JlZW5DYW52YXMoKTogSFRNTENhbnZhc0VsZW1lbnQge1xuICBpZiAodHlwZW9mIE9mZnNjcmVlbkNhbnZhcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdmYWlsZWQgdG8gY3JlYXRlIG9mZnNjcmVlbiBjYW52YXM6IE9mZnNjcmVlbkNhbnZhcyBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbiAgcmV0dXJuIG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSk7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IEJhY2tlbmQsIFNlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi4vYmFja2VuZCc7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi9pbnN0cnVtZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi9zZXNzaW9uJztcblxuaW1wb3J0IHsgV2ViR0xTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4vd2ViZ2wvc2Vzc2lvbi1oYW5kbGVyJztcbmltcG9ydCB7IFdlYkdMQ29udGV4dCB9IGZyb20gJy4vd2ViZ2wvd2ViZ2wtY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVXZWJHTENvbnRleHQgfSBmcm9tICcuL3dlYmdsL3dlYmdsLWNvbnRleHQtZmFjdG9yeSc7XG5cbi8qKlxuICogV2ViR0xCYWNrZW5kIGlzIHRoZSBlbnRyeSBwb2ludCBmb3IgYWxsIFdlYkdMIG9wZWFydGlvbnNcbiAqIFdoZW4gaXQgc3RhcnRzIGl0IGNyZWF0ZWQgdGhlIFdlYkdMUmVuZGVyaW5nQ29udGV4dFxuICogYW5kIG90aGVyIG1haW4gZnJhbWV3b3JrIGNvbXBvbmVudHMgc3VjaCBhcyBQcm9ncmFtIGFuZCBUZXh0dXJlIE1hbmFnZXJzXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJHTEJhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHtcbiAgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQ7XG5cbiAgZ2V0IGNvbnRleHRJZCgpOiAnd2ViZ2wnIHwgJ3dlYmdsMicgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wuY29udGV4dElkO1xuICB9XG4gIHNldCBjb250ZXh0SWQodmFsdWU6ICd3ZWJnbCcgfCAnd2ViZ2wyJyB8IHVuZGVmaW5lZCkge1xuICAgIGVudi53ZWJnbC5jb250ZXh0SWQgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBtYXRtdWxNYXhCYXRjaFNpemUoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLm1hdG11bE1heEJhdGNoU2l6ZTtcbiAgfVxuICBzZXQgbWF0bXVsTWF4QmF0Y2hTaXplKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wubWF0bXVsTWF4QmF0Y2hTaXplID0gdmFsdWU7XG4gIH1cblxuICBnZXQgdGV4dHVyZUNhY2hlTW9kZSgpOiAnaW5pdGlhbGl6ZXJPbmx5JyB8ICdmdWxsJyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC50ZXh0dXJlQ2FjaGVNb2RlO1xuICB9XG4gIHNldCB0ZXh0dXJlQ2FjaGVNb2RlKHZhbHVlOiAnaW5pdGlhbGl6ZXJPbmx5JyB8ICdmdWxsJyB8IHVuZGVmaW5lZCkge1xuICAgIGVudi53ZWJnbC50ZXh0dXJlQ2FjaGVNb2RlID0gdmFsdWU7XG4gIH1cblxuICBnZXQgcGFjaygpOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLnBhY2s7XG4gIH1cbiAgc2V0IHBhY2sodmFsdWU6IGJvb2xlYW4gfCB1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wucGFjayA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGFzeW5jKCk6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wuYXN5bmM7XG4gIH1cbiAgc2V0IGFzeW5jKHZhbHVlOiBib29sZWFuIHwgdW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLmFzeW5jID0gdmFsdWU7XG4gIH1cblxuICBpbml0aWFsaXplKCk6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLmdsQ29udGV4dCA9IGNyZWF0ZVdlYkdMQ29udGV4dCh0aGlzLmNvbnRleHRJZCk7XG4gICAgICBpZiAodHlwZW9mIHRoaXMubWF0bXVsTWF4QmF0Y2hTaXplICE9PSAnbnVtYmVyJykge1xuICAgICAgICB0aGlzLm1hdG11bE1heEJhdGNoU2l6ZSA9IDE2O1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB0aGlzLnRleHR1cmVDYWNoZU1vZGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMudGV4dHVyZUNhY2hlTW9kZSA9ICdmdWxsJztcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdGhpcy5wYWNrICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhpcy5wYWNrID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHRoaXMuYXN5bmMgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aGlzLmFzeW5jID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIExvZ2dlci5zZXRXaXRoRW52KGVudik7XG5cbiAgICAgIGlmICghZW52LndlYmdsLmNvbnRleHQpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVudi53ZWJnbCwgJ2NvbnRleHQnLCB7IHZhbHVlOiB0aGlzLmdsQ29udGV4dC5nbCB9KTtcbiAgICAgIH1cblxuICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICdXZWJHTEJhY2tlbmQnLFxuICAgICAgICBgQ3JlYXRlZCBXZWJHTENvbnRleHQ6ICR7dHlwZW9mIHRoaXMuZ2xDb250ZXh0fSB3aXRoIG1hdG11bE1heEJhdGNoU2l6ZTogJHtcbiAgICAgICAgICB0aGlzLm1hdG11bE1heEJhdGNoU2l6ZVxuICAgICAgICB9OyB0ZXh0dXJlQ2FjaGVNb2RlOiAke3RoaXMudGV4dHVyZUNhY2hlTW9kZX07IHBhY2s6ICR7dGhpcy5wYWNrfTsgYXN5bmM6ICR7dGhpcy5hc3luY30uYCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBMb2dnZXIud2FybmluZygnV2ViR0xCYWNrZW5kJywgYFVuYWJsZSB0byBpbml0aWFsaXplIFdlYkdMQmFja2VuZC4gJHtlfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICBjcmVhdGVTZXNzaW9uSGFuZGxlcihjb250ZXh0OiBTZXNzaW9uLkNvbnRleHQpOiBTZXNzaW9uSGFuZGxlciB7XG4gICAgcmV0dXJuIG5ldyBXZWJHTFNlc3Npb25IYW5kbGVyKHRoaXMsIGNvbnRleHQpO1xuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5nbENvbnRleHQuZGlzcG9zZSgpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFdlYkdMQmFja2VuZCB9IGZyb20gJy4vYmFja2VuZHMvYmFja2VuZC13ZWJnbCc7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgT3BlcmF0b3IgfSBmcm9tICcuL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPcFNldCB9IGZyb20gJy4vb3BzZXQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vc2Vzc2lvbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlSGFuZGxlciB7XG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBpbmZlcmVuY2UgaGFuZGxlci4gaXQgd2lsbCBiZSBjYWxsZWQgYXMgdGhlIGxhc3Qgc3RlcCBpbiBTZXNzaW9uLnJ1bigpXG4gICAqL1xuICBkaXNwb3NlKCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvbkhhbmRsZXIge1xuICAvKipcbiAgICogdHJhbnNmb3JtIHRoZSBncmFwaCBhdCBpbml0aWFsaXphdGlvbiB0aW1lXG4gICAqIEBwYXJhbSBncmFwaFRyYW5zZm9ybWVyIHRoZSBncmFwaCB0cmFuc2Zvcm1lciB0byBtYW5pcHVsYXRlIHRoZSBtb2RlbCBncmFwaFxuICAgKi9cbiAgdHJhbnNmb3JtR3JhcGg/KGdyYXBoVHJhbnNmb3JtZXI6IEdyYXBoLlRyYW5zZm9ybWVyKTogdm9pZDtcblxuICAvKipcbiAgICogY3JlYXRlIGFuIGluc3RhbmNlIG9mIEluZmVyZW5jZUhhbmRsZXIgdG8gdXNlIGluIGEgU2Vzc2lvbi5ydW4oKSBjYWxsXG4gICAqL1xuICBjcmVhdGVJbmZlcmVuY2VIYW5kbGVyKCk6IEluZmVyZW5jZUhhbmRsZXI7XG5cbiAgLyoqXG4gICAqIGRpc3Bvc2UgdGhlIHNlc3Npb24gaGFuZGxlci4gaXQgd2lsbCBiZSBjYWxsZWQgd2hlbiBhIHNlc3Npb24gaXMgYmVpbmcgZGlzcG9zZWQgZXhwbGljaXRseVxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgb3BlcmF0b3IgZnJvbSB0aGUgbmFtZSBhbmQgb3BzZXQgdmVyc2lvbjsgYmFja2VuZCBzcGVjaWZpY1xuICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSB0byByZXNvbHZlXG4gICAqIEBwYXJhbSBvcHNldHMgYSBsaXN0IG9mIG9wc2V0cyB0aGF0IGV4cG9ydGVkIGZyb20gdGhlIG1vZGVsXG4gICAqIEBwYXJhbSBncmFwaCB0aGUgY29tcGxldGVseSBpbml0aWFsaXplZCBncmFwaFxuICAgKi9cbiAgcmVzb2x2ZShub2RlOiBHcmFwaC5Ob2RlLCBvcHNldHM6IHJlYWRvbmx5IE9wU2V0W10sIGdyYXBoOiBHcmFwaCk6IE9wZXJhdG9yO1xuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBsZXQncyB0aGUgc2Vzc2lvbkhhbmRsZXIga25vdyB0aGF0IHRoZSBncmFwaCBpbml0aWFsaXphdGlvbiBpcyBjb21wbGV0ZVxuICAgKiBAcGFyYW0gZ3JhcGggdGhlIGNvbXBsZXRlbHkgaW5pdGlhbGl6ZWQgZ3JhcGhcbiAgICovXG4gIG9uR3JhcGhJbml0aWFsaXplZD8oZ3JhcGg6IEdyYXBoKTogdm9pZDtcblxuICAvKipcbiAgICogYSByZWZlcmVuY2UgdG8gdGhlIGNvcnJlc3BvbmRpbmcgYmFja2VuZFxuICAgKi9cbiAgcmVhZG9ubHkgYmFja2VuZDogQmFja2VuZDtcblxuICAvKipcbiAgICogYSByZWZlcmVuY2UgdG8gdGhlIHNlc3Npb24gY29udGV4dFxuICAgKi9cbiAgcmVhZG9ubHkgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tlbmQge1xuICAvKipcbiAgICogaW5pdGlhbGl6ZSB0aGUgYmFja2VuZC4gd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLCB3aGVuIHRoZSBmaXJzdCB0aW1lIHRoZVxuICAgKiBiYWNrZW5kIGl0IHRvIGJlIHVzZWRcbiAgICovXG4gIGluaXRpYWxpemUoKTogYm9vbGVhbiB8IFByb21pc2U8Ym9vbGVhbj47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBTZXNzaW9uSGFuZGxlciB0byB1c2UgaW4gYSBTZXNzaW9uIG9iamVjdCdzIGxpZmVjeWNsZVxuICAgKi9cbiAgY3JlYXRlU2Vzc2lvbkhhbmRsZXIoY29udGV4dDogU2Vzc2lvbi5Db250ZXh0KTogU2Vzc2lvbkhhbmRsZXI7XG5cbiAgLyoqXG4gICAqIGRpc3Bvc2UgdGhlIGJhY2tlbmQuIGN1cnJlbnRseSB0aGlzIHdpbGwgbm90IGJlIGNhbGxlZFxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xufVxuXG4vLyBjYWNoZXMgYWxsIGluaXRpYWxpemVkIGJhY2tlbmQgaW5zdGFuY2VzXG5jb25zdCBiYWNrZW5kc0NhY2hlOiBNYXA8c3RyaW5nLCBCYWNrZW5kPiA9IG5ldyBNYXAoKTtcblxuZXhwb3J0IGNvbnN0IGJhY2tlbmQ6IHsgW25hbWU6IHN0cmluZ106IEJhY2tlbmQgfSA9IHtcbiAgd2ViZ2w6IG5ldyBXZWJHTEJhY2tlbmQoKSxcbn07XG5cbi8qKlxuICogUmVzb2x2ZSBhIHJlZmVyZW5jZSB0byB0aGUgYmFja2VuZC4gSWYgYSBoaW50IGlzIHNwZWNpZmllZCwgdGhlIGNvcnJlc3BvbmRpbmdcbiAqIGJhY2tlbmQgd2lsbCBiZSB1c2VkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUJhY2tlbmQoaGludD86IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTxCYWNrZW5kPiB7XG4gIGlmICghaGludCkge1xuICAgIHJldHVybiByZXNvbHZlQmFja2VuZChbJ3dlYmdsJ10pO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGhpbnRzID0gdHlwZW9mIGhpbnQgPT09ICdzdHJpbmcnID8gW2hpbnRdIDogaGludDtcblxuICAgIGZvciAoY29uc3QgYmFja2VuZEhpbnQgb2YgaGludHMpIHtcbiAgICAgIGNvbnN0IGNhY2hlID0gYmFja2VuZHNDYWNoZS5nZXQoYmFja2VuZEhpbnQpO1xuICAgICAgaWYgKGNhY2hlKSB7XG4gICAgICAgIHJldHVybiBjYWNoZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHRyeUxvYWRCYWNrZW5kKGJhY2tlbmRIaW50KTtcbiAgICAgIGlmIChiYWNrZW5kKSB7XG4gICAgICAgIHJldHVybiBiYWNrZW5kO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignbm8gYXZhaWxhYmxlIGJhY2tlbmQgdG8gdXNlJyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRyeUxvYWRCYWNrZW5kKGJhY2tlbmRIaW50OiBzdHJpbmcpOiBQcm9taXNlPEJhY2tlbmQgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgYmFja2VuZE9iaiA9IGJhY2tlbmQ7XG5cbiAgaWYgKHR5cGVvZiBiYWNrZW5kT2JqW2JhY2tlbmRIaW50XSAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNCYWNrZW5kKGJhY2tlbmRPYmpbYmFja2VuZEhpbnRdKSkge1xuICAgIGNvbnN0IGJhY2tlbmQgPSBiYWNrZW5kT2JqW2JhY2tlbmRIaW50XTtcbiAgICBsZXQgaW5pdCA9IGJhY2tlbmQuaW5pdGlhbGl6ZSgpO1xuICAgIGlmICh0eXBlb2YgaW5pdCA9PT0gJ29iamVjdCcgJiYgJ3RoZW4nIGluIGluaXQpIHtcbiAgICAgIGluaXQgPSBhd2FpdCBpbml0O1xuICAgIH1cbiAgICBpZiAoaW5pdCkge1xuICAgICAgYmFja2VuZHNDYWNoZS5zZXQoYmFja2VuZEhpbnQsIGJhY2tlbmQpO1xuICAgICAgcmV0dXJuIGJhY2tlbmQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNCYWNrZW5kKG9iajogdW5rbm93bikge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBjb25zdCBvID0gb2JqIGFzIGFueTtcblxuICAvLyBjaGVjayBpZiBhbiBvYmplY3QgaXMgYSBCYWNrZW5kIGluc3RhbmNlXG4gIGlmIChcbiAgICAnaW5pdGlhbGl6ZScgaW4gbyAmJlxuICAgIHR5cGVvZiBvLmluaXRpYWxpemUgPT09ICdmdW5jdGlvbicgJiYgLy8gaW5pdGlhbGl6ZSgpXG4gICAgJ2NyZWF0ZVNlc3Npb25IYW5kbGVyJyBpbiBvICYmXG4gICAgdHlwZW9mIG8uY3JlYXRlU2Vzc2lvbkhhbmRsZXIgPT09ICdmdW5jdGlvbicgJiYgLy8gY3JlYXRlU2Vzc2lvbkhhbmRsZXIoKVxuICAgICdkaXNwb3NlJyBpbiBvICYmXG4gICAgdHlwZW9mIG8uZGlzcG9zZSA9PT0gJ2Z1bmN0aW9uJyAvLyBkaXNwb3NlKClcbiAgKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCB0eXBlIEJhY2tlbmRUeXBlID0gQmFja2VuZDtcbmV4cG9ydCB0eXBlIFNlc3Npb25IYW5kbGVyVHlwZSA9IFJldHVyblR5cGU8QmFja2VuZFR5cGVbJ2NyZWF0ZVNlc3Npb25IYW5kbGVyJ10+O1xuZXhwb3J0IHR5cGUgSW5mZXJlbmNlSGFuZGxlclR5cGUgPSBSZXR1cm5UeXBlPFNlc3Npb25IYW5kbGVyVHlwZVsnY3JlYXRlSW5mZXJlbmNlSGFuZGxlciddPjtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgU2Vzc2lvbkhhbmRsZXIgfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7IExvZ2dlciwgUHJvZmlsZXIgfSBmcm9tICcuL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgT3BlcmF0b3IgfSBmcm9tICcuL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5cbmNsYXNzIEtlcm5lbE9wIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG9wOiBPcGVyYXRvcixcbiAgICBwdWJsaWMgbm9kZTogR3JhcGguTm9kZSxcbiAgKSB7fVxufVxuXG5leHBvcnQgY2xhc3MgRXhlY3V0aW9uUGxhbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZ3JhcGg6IEdyYXBoLFxuICAgIG9wczogT3BlcmF0b3JbXSxcbiAgICBwcml2YXRlIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj4sXG4gICkge1xuICAgIHRoaXMuaW5pdGlhbGl6ZShvcHMpO1xuICB9XG5cbiAgaW5pdGlhbGl6ZShvcHM6IE9wZXJhdG9yW10pIHtcbiAgICB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ0V4ZWN1dGlvblBsYW4uaW5pdGlhbGl6ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGdyYXBoTm9kZXMgPSB0aGlzLmdyYXBoLmdldE5vZGVzKCk7XG4gICAgICBpZiAoZ3JhcGhOb2Rlcy5sZW5ndGggIT09IG9wcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgc2l6ZSBvZiBub2RlcyBhbmQgT1BzIGRvIG5vdCBtYXRjaC4nKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fb3BzID0gb3BzLm1hcCgob3AsIGkpID0+IG5ldyBLZXJuZWxPcChvcCwgZ3JhcGhOb2Rlc1tpXSkpO1xuICAgICAgdGhpcy5yZXNldCgpO1xuXG4gICAgICAvLyBsb29rIGZvciBzdGFydGVyIG5vZGUocylcbiAgICAgIHRoaXMuX3N0YXJ0ZXIgPSBbXTtcbiAgICAgIHRoaXMuX29wcy5mb3JFYWNoKChvcCwgaSkgPT4ge1xuICAgICAgICBsZXQgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICBmb3IgKGNvbnN0IGlucHV0IG9mIG9wLm5vZGUuaW5wdXRzKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIXRoaXMuX3ZhbHVlc1tpbnB1dF0gJiYgLy8gbm90IGFuIGluaXRpYWxpemVkIGlucHV0XG4gICAgICAgICAgICB0aGlzLmdyYXBoLmdldElucHV0SW5kaWNlcygpLmluZGV4T2YoaW5wdXQpID09PSAtMSAvLyBub3QgbW9kZWwgaW5wdXRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJlc29sdmVkID0gZmFsc2U7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc29sdmVkKSB7XG4gICAgICAgICAgdGhpcy5fc3RhcnRlci5wdXNoKGkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlc2V0KCkge1xuICAgIHRoaXMuX3ZhbHVlcyA9IHRoaXMuZ3JhcGguZ2V0VmFsdWVzKCkubWFwKChpKSA9PiBpLnRlbnNvcik7XG4gIH1cblxuICBhc3luYyBleGVjdXRlKHNlc3Npb25IYW5kbGVyOiBTZXNzaW9uSGFuZGxlciwgbW9kZWxJbnB1dHM6IFRlbnNvcltdKTogUHJvbWlzZTxUZW5zb3JbXT4ge1xuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ0V4ZWN1dGlvblBsYW4uZXhlY3V0ZScsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIHJlc2V0IG1lZGllbSByZXN1bHRcbiAgICAgIHRoaXMucmVzZXQoKTtcblxuICAgICAgLy8gY3JlYXRlIGluZmVyZW5jZSBoYW5kbGVyXG4gICAgICBjb25zdCBpbmZlcmVuY2VIYW5kbGVyID0gc2Vzc2lvbkhhbmRsZXIuY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpO1xuXG4gICAgICAvLyBwb3B1bGF0ZSBpbnB1dHMgdmFsdWVcbiAgICAgIGNvbnN0IGdyYXBoSW5wdXRzID0gdGhpcy5ncmFwaC5nZXRJbnB1dEluZGljZXMoKTtcbiAgICAgIGlmIChtb2RlbElucHV0cy5sZW5ndGggIT09IGdyYXBoSW5wdXRzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYG51bWJlciBvZiBpbnB1dCB0ZW5zb3JzIGRvbid0IG1hdGNoIHRoZSBudW1iZXIgb2YgaW5wdXRzIHRvIHRoZSBtb2RlbDogYWN0dWFsOiAke1xuICAgICAgICAgICAgbW9kZWxJbnB1dHMubGVuZ3RoXG4gICAgICAgICAgfSBleHBlY3RlZDogJHtncmFwaElucHV0cy5sZW5ndGh9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgbW9kZWxJbnB1dHMuZm9yRWFjaCgoaW5wdXQsIGkpID0+IHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBncmFwaElucHV0c1tpXTtcbiAgICAgICAgdGhpcy5fdmFsdWVzW2luZGV4XSA9IGlucHV0O1xuICAgICAgfSk7XG5cbiAgICAgIC8vIHByZXBhcmUgcnVubmluZyBzZXF1ZW5jZVxuICAgICAgY29uc3Qgc2VxdWVuY2U6IG51bWJlcltdID0gdGhpcy5fc3RhcnRlci5zbGljZSgwKTtcblxuICAgICAgLy8gZXhlY3V0aW9uIGl0ZXJhdGlvbnNcbiAgICAgIGNvbnN0IGdyYXBoVmFsdWVzID0gdGhpcy5ncmFwaC5nZXRWYWx1ZXMoKTtcbiAgICAgIGNvbnN0IGdyYXBoTm9kZXMgPSB0aGlzLmdyYXBoLmdldE5vZGVzKCk7XG5cbiAgICAgIGxldCByZWFyID0gMDtcbiAgICAgIHdoaWxlIChyZWFyIDwgc2VxdWVuY2UubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHRoaXNPcEluZGV4ID0gc2VxdWVuY2VbcmVhcisrXTtcbiAgICAgICAgY29uc3QgdGhpc09wID0gdGhpcy5fb3BzW3RoaXNPcEluZGV4XTtcblxuICAgICAgICAvLyBjaGVjayBpbnB1dFxuICAgICAgICBjb25zdCBpbnB1dExpc3QgPSB0aGlzT3Aubm9kZS5pbnB1dHMubWFwKChpKSA9PiB0aGlzLl92YWx1ZXNbaV0pO1xuICAgICAgICBpZiAoaW5wdXRMaXN0LmluZGV4T2YodW5kZWZpbmVkKSAhPT0gLTEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVzb2x2ZWQgaW5wdXQgZGV0ZWN0ZWQ6IG9wOiAke3RoaXNPcC5ub2RlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcnVuXG4gICAgICAgIGNvbnN0IGlucHV0VGVuc29ycyA9IGlucHV0TGlzdCBhcyBUZW5zb3JbXTtcbiAgICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgJ0V4ZWNQbGFuJyxcbiAgICAgICAgICBgUnVubmluZyBvcDoke3RoaXNPcC5ub2RlLm5hbWV9ICgke2lucHV0VGVuc29yc1xuICAgICAgICAgICAgLm1hcCgodCwgaSkgPT4gYCcke3RoaXNPcC5ub2RlLmlucHV0c1tpXX0nOiAke3QudHlwZX1bJHt0LmRpbXMuam9pbignLCcpfV1gKVxuICAgICAgICAgICAgLmpvaW4oJywgJyl9KWAsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0TGlzdCA9IGF3YWl0IHRoaXMucHJvZmlsZXIuZXZlbnQoJ25vZGUnLCB0aGlzT3Aubm9kZS5uYW1lLCBhc3luYyAoKSA9PlxuICAgICAgICAgIHRoaXNPcC5vcC5pbXBsKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0VGVuc29ycywgdGhpc09wLm9wLmNvbnRleHQpLFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIGNoZWNrIG91dHB1dFxuICAgICAgICBpZiAob3V0cHV0TGlzdC5sZW5ndGggIT09IHRoaXNPcC5ub2RlLm91dHB1dHMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgc2l6ZSBvZiBvdXRwdXQgZG9lcyBub3QgbWF0Y2ggbW9kZWwgZGVmaW5pdGlvbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZpbGwgdmFsdWVcbiAgICAgICAgb3V0cHV0TGlzdC5mb3JFYWNoKChvdXRwdXQsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBqID0gdGhpc09wLm5vZGUub3V0cHV0c1tpXTtcbiAgICAgICAgICBpZiAodGhpcy5fdmFsdWVzW2pdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dCBbJHtqfV0gYWxyZWFkeSBoYXMgdmFsdWU6IG9wOiR7dGhpc09wLm5vZGUubmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5fdmFsdWVzW2pdID0gb3V0cHV0O1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyByZXNvbHZlIGRvd25zdHJlYW0gbm9kZXNcbiAgICAgICAgY29uc3QgZG93bnN0cmVhbU5vZGVzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgICAgIG91dHB1dExpc3QuZm9yRWFjaCgoX291dHB1dCwgaSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGogPSB0aGlzT3Aubm9kZS5vdXRwdXRzW2ldO1xuICAgICAgICAgIGZvciAoY29uc3QgY3VycmVudERvd25zdHJlYW1Ob2RlSW5kZXggb2YgZ3JhcGhWYWx1ZXNbal0udG8pIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnREb3duc3RyZWFtTm9kZSA9IGdyYXBoTm9kZXNbY3VycmVudERvd25zdHJlYW1Ob2RlSW5kZXhdO1xuICAgICAgICAgICAgbGV0IHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgayBvZiBjdXJyZW50RG93bnN0cmVhbU5vZGUuaW5wdXRzKSB7XG4gICAgICAgICAgICAgIGlmICghdGhpcy5fdmFsdWVzW2tdKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJlc29sdmVkKSB7XG4gICAgICAgICAgICAgIGRvd25zdHJlYW1Ob2Rlcy5hZGQoY3VycmVudERvd25zdHJlYW1Ob2RlSW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHNlcXVlbmNlLnB1c2goLi4uZG93bnN0cmVhbU5vZGVzKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb3V0cHV0OiBUZW5zb3JbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmdyYXBoLmdldE91dHB1dEluZGljZXMoKS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBvdXRwdXRJbmRleCA9IHRoaXMuZ3JhcGguZ2V0T3V0cHV0SW5kaWNlcygpW2ldO1xuICAgICAgICBjb25zdCBvdXRwdXRUZW5zb3IgPSB0aGlzLl92YWx1ZXNbb3V0cHV0SW5kZXhdO1xuICAgICAgICBpZiAob3V0cHV0VGVuc29yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlcXVpcmVkIG91dHB1dCBbJHtvdXRwdXRJbmRleH1dIGRvZXMgbm90IGhhdmUgdmFsdWVgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3V0cHV0SW5kZXggPT09IDApIHtcbiAgICAgICAgICBhd2FpdCBvdXRwdXRUZW5zb3IuZ2V0RGF0YSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcbiAgICAgICAgICBvdXRwdXRUZW5zb3IuZGF0YTtcbiAgICAgICAgfVxuICAgICAgICBvdXRwdXQucHVzaChvdXRwdXRUZW5zb3IpO1xuICAgICAgfVxuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ0V4ZWNQbGFuJywgJ2Rpc3Bvc2luZyBvZiBpbmZlcmVuY2VIYW5kbGVyJyk7XG4gICAgICBpbmZlcmVuY2VIYW5kbGVyLmRpc3Bvc2UoKTtcbiAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfSk7XG4gIH1cblxuICBfdmFsdWVzOiBBcnJheTxUZW5zb3IgfCB1bmRlZmluZWQ+O1xuICBfb3BzOiBLZXJuZWxPcFtdO1xuICBfc3RhcnRlcjogbnVtYmVyW107XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCBMb25nIGZyb20gJ2xvbmcnO1xuXG5pbXBvcnQgKiBhcyBvcnRGYnMgZnJvbSAnLi9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ydC1nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgb25ueCB9IGZyb20gJy4vb3J0LXNjaGVtYS9wcm90b2J1Zi9vbm54JztcbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJy4vdGVuc29yJztcbmltcG9ydCB7IGRlY29kZVV0ZjhTdHJpbmcsIExvbmdVdGlsIH0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEF0dHJpYnV0ZSB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgRGF0YVR5cGVNYXAge1xuICAgIGZsb2F0OiBudW1iZXI7XG4gICAgaW50OiBudW1iZXI7XG4gICAgc3RyaW5nOiBzdHJpbmc7XG4gICAgdGVuc29yOiBUZW5zb3I7XG4gICAgZmxvYXRzOiBudW1iZXJbXTtcbiAgICBpbnRzOiBudW1iZXJbXTtcbiAgICBzdHJpbmdzOiBzdHJpbmdbXTtcbiAgICB0ZW5zb3JzOiBUZW5zb3JbXTtcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIERhdGFUeXBlID0ga2V5b2YgRGF0YVR5cGVNYXA7XG59XG5cbnR5cGUgVmFsdWVUeXBlcyA9IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFtBdHRyaWJ1dGUuRGF0YVR5cGVdO1xuXG50eXBlIFZhbHVlID0gW1ZhbHVlVHlwZXMsIEF0dHJpYnV0ZS5EYXRhVHlwZV07XG5cbmV4cG9ydCBjbGFzcyBBdHRyaWJ1dGUge1xuICBjb25zdHJ1Y3RvcihhdHRyaWJ1dGVzOiBvbm54LklBdHRyaWJ1dGVQcm90b1tdIHwgb3J0RmJzLkF0dHJpYnV0ZVtdIHwgbnVsbCB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuX2F0dHJpYnV0ZXMgPSBuZXcgTWFwKCk7XG4gICAgaWYgKGF0dHJpYnV0ZXMgIT09IG51bGwgJiYgYXR0cmlidXRlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmb3IgKGNvbnN0IGF0dHIgb2YgYXR0cmlidXRlcykge1xuICAgICAgICBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8pIHtcbiAgICAgICAgICB0aGlzLl9hdHRyaWJ1dGVzLnNldChhdHRyLm5hbWUsIFtBdHRyaWJ1dGUuZ2V0VmFsdWUoYXR0ciksIEF0dHJpYnV0ZS5nZXRUeXBlKGF0dHIpXSk7XG4gICAgICAgIH0gZWxzZSBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICAgICAgICB0aGlzLl9hdHRyaWJ1dGVzLnNldChhdHRyLm5hbWUoKSEsIFtBdHRyaWJ1dGUuZ2V0VmFsdWUoYXR0ciksIEF0dHJpYnV0ZS5nZXRUeXBlKGF0dHIpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9hdHRyaWJ1dGVzLnNpemUgPCBhdHRyaWJ1dGVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2R1cGxpY2F0ZWQgYXR0cmlidXRlIG5hbWVzJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc2V0KGtleTogc3RyaW5nLCB0eXBlOiBBdHRyaWJ1dGUuRGF0YVR5cGUsIHZhbHVlOiBWYWx1ZVR5cGVzKTogdm9pZCB7XG4gICAgdGhpcy5fYXR0cmlidXRlcy5zZXQoa2V5LCBbdmFsdWUsIHR5cGVdKTtcbiAgfVxuICBkZWxldGUoa2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl9hdHRyaWJ1dGVzLmRlbGV0ZShrZXkpO1xuICB9XG4gIGdldEZsb2F0KGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ2Zsb2F0J10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnZmxvYXQnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0SW50KGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ2ludCddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ2ludCcsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRTdHJpbmcoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnc3RyaW5nJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnc3RyaW5nJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldFRlbnNvcihrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWyd0ZW5zb3InXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICd0ZW5zb3InLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0RmxvYXRzKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ2Zsb2F0cyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ2Zsb2F0cycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRJbnRzKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ2ludHMnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdpbnRzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldFN0cmluZ3Moa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnc3RyaW5ncyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3N0cmluZ3MnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0VGVuc29ycyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWyd0ZW5zb3JzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAndGVuc29ycycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIGdldDxWIGV4dGVuZHMgQXR0cmlidXRlLkRhdGFUeXBlTWFwW0F0dHJpYnV0ZS5EYXRhVHlwZV0+KFxuICAgIGtleTogc3RyaW5nLFxuICAgIHR5cGU6IEF0dHJpYnV0ZS5EYXRhVHlwZSxcbiAgICBkZWZhdWx0VmFsdWU/OiBWLFxuICApOiBWIHtcbiAgICBjb25zdCB2YWx1ZUFuZFR5cGUgPSB0aGlzLl9hdHRyaWJ1dGVzLmdldChrZXkpO1xuICAgIGlmICh2YWx1ZUFuZFR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlcXVpcmVkIGF0dHJpYnV0ZSBub3QgZm91bmQ6ICR7a2V5fWApO1xuICAgIH1cbiAgICBpZiAodmFsdWVBbmRUeXBlWzFdICE9PSB0eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHR5cGUgbWlzbWF0Y2g6IGV4cGVjdGVkICR7dHlwZX0gYnV0IGdvdCAke3ZhbHVlQW5kVHlwZVsxXX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlQW5kVHlwZVswXSBhcyBWO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VHlwZShhdHRyOiBvbm54LklBdHRyaWJ1dGVQcm90byB8IG9ydEZicy5BdHRyaWJ1dGUpOiBBdHRyaWJ1dGUuRGF0YVR5cGUge1xuICAgIGNvbnN0IHR5cGUgPSBhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90byA/IGF0dHIudHlwZSA6IChhdHRyIGFzIG9ydEZicy5BdHRyaWJ1dGUpLnR5cGUoKTtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkZMT0FUOlxuICAgICAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVDpcbiAgICAgICAgcmV0dXJuICdpbnQnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gJ3N0cmluZyc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1I6XG4gICAgICAgIHJldHVybiAndGVuc29yJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkZMT0FUUzpcbiAgICAgICAgcmV0dXJuICdmbG9hdHMnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UUzpcbiAgICAgICAgcmV0dXJuICdpbnRzJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklOR1M6XG4gICAgICAgIHJldHVybiAnc3RyaW5ncyc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1JTOlxuICAgICAgICByZXR1cm4gJ3RlbnNvcnMnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBhdHRyaWJ1dGUgdHlwZSBpcyBub3Qgc3VwcG9ydGVkIHlldDogJHtvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVbdHlwZV19YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWUoYXR0cjogb25ueC5JQXR0cmlidXRlUHJvdG8gfCBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgY29uc3QgYXR0clR5cGUgPSBhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90byA/IGF0dHIudHlwZSA6IChhdHRyIGFzIG9ydEZicy5BdHRyaWJ1dGUpLnR5cGUoKTtcbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5HUkFQSCB8fCBhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkdSQVBIUykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdncmFwaCBhdHRyaWJ1dGUgaXMgbm90IHN1cHBvcnRlZCB5ZXQnKTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0VmFsdWVOb0NoZWNrKGF0dHIpO1xuXG4gICAgLy8gY2FzdCBMT05HIHRvIG51bWJlclxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVCAmJiBMb25nVXRpbC5pc0xvbmcodmFsdWUpKSB7XG4gICAgICByZXR1cm4gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKHZhbHVlIGFzIGJpZ2ludCB8IExvbmcpO1xuICAgIH1cblxuICAgIC8vIGNhc3QgTE9OR1tdIHRvIG51bWJlcltdXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UUykge1xuICAgICAgY29uc3QgYXJyID0gdmFsdWUgYXMgQXJyYXk8bnVtYmVyIHwgTG9uZyB8IGJpZ2ludD47XG4gICAgICBjb25zdCBudW1iZXJWYWx1ZTogbnVtYmVyW10gPSBuZXcgQXJyYXk8bnVtYmVyPihhcnIubGVuZ3RoKTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgbWF5YmVMb25nID0gYXJyW2ldO1xuICAgICAgICBudW1iZXJWYWx1ZVtpXSA9IExvbmdVdGlsLmxvbmdUb051bWJlcihtYXliZUxvbmcpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVtYmVyVmFsdWU7XG4gICAgfVxuXG4gICAgLy8gY2FzdCBvbm54LlRlbnNvclByb3RvIHRvIG9ubnhqcy5UZW5zb3JcbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1IpIHtcbiAgICAgIHJldHVybiBhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICA/IFRlbnNvci5mcm9tUHJvdG8odmFsdWUgYXMgb25ueC5JVGVuc29yUHJvdG8pXG4gICAgICAgIDogVGVuc29yLmZyb21PcnRUZW5zb3IodmFsdWUgYXMgb3J0RmJzLlRlbnNvcik7XG4gICAgfVxuXG4gICAgLy8gY2FzdCBvbm54LlRlbnNvclByb3RvW10gdG8gb25ueGpzLlRlbnNvcltdXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SUykge1xuICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgIGNvbnN0IHRlbnNvclByb3RvcyA9IHZhbHVlIGFzIG9ubnguSVRlbnNvclByb3RvW107XG4gICAgICAgIHJldHVybiB0ZW5zb3JQcm90b3MubWFwKCh2YWx1ZSkgPT4gVGVuc29yLmZyb21Qcm90byh2YWx1ZSkpO1xuICAgICAgfSBlbHNlIGlmIChhdHRyIGluc3RhbmNlb2Ygb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgICAgICBjb25zdCB0ZW5zb3JQcm90b3MgPSB2YWx1ZSBhcyBvcnRGYnMuVGVuc29yW107XG4gICAgICAgIHJldHVybiB0ZW5zb3JQcm90b3MubWFwKCh2YWx1ZSkgPT4gVGVuc29yLmZyb21PcnRUZW5zb3IodmFsdWUpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjYXN0IFVpbnQ4QXJyYXkgdG8gc3RyaW5nXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HKSB7XG4gICAgICAvLyBzdHJpbmcgaW4gb25ueCBhdHRyaWJ1dGUgaXMgb2YgdWludDhhcnJheSB0eXBlLCBzbyB3ZSBuZWVkIHRvIGNvbnZlcnQgaXQgdG8gc3RyaW5nIGJlbG93LiBXaGlsZSBpbiBvcnQgZm9ybWF0LFxuICAgICAgLy8gc3RyaW5nIGF0dHJpYnV0ZXMgYXJlIHJldHVybmVkIGFzIHN0cmluZywgc28gbm8gY29udmVyc2lvbiBpcyBuZWVkZWQuXG4gICAgICBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8pIHtcbiAgICAgICAgY29uc3QgdXRmOFN0cmluZyA9IHZhbHVlIGFzIFVpbnQ4QXJyYXk7XG4gICAgICAgIHJldHVybiBkZWNvZGVVdGY4U3RyaW5nKHV0ZjhTdHJpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGNhc3QgVWludDhBcnJheVtdIHRvIHN0cmluZ1tdXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HUykge1xuICAgICAgLy8gc3RyaW5ncyBpbiBvbm54IGF0dHJpYnV0ZSBpcyByZXR1cm5lZCBhcyB1aW50OGFycmF5W10sIHNvIHdlIG5lZWQgdG8gY29udmVydCBpdCB0byBzdHJpbmdbXSBiZWxvdy4gV2hpbGUgaW4gb3J0XG4gICAgICAvLyBmb3JtYXQgc3RyaW5ncyBhdHRyaWJ1dGVzIGFyZSByZXR1cm5lZCBhcyBzdHJpbmdbXSwgc28gbm8gY29udmVyc2lvbiBpcyBuZWVkZWQuXG4gICAgICBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8pIHtcbiAgICAgICAgY29uc3QgdXRmOFN0cmluZ3MgPSB2YWx1ZSBhcyBVaW50OEFycmF5W107XG4gICAgICAgIHJldHVybiB1dGY4U3RyaW5ncy5tYXAoZGVjb2RlVXRmOFN0cmluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlIGFzIFZhbHVlVHlwZXM7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRWYWx1ZU5vQ2hlY2soYXR0cjogb25ueC5JQXR0cmlidXRlUHJvdG8gfCBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgcmV0dXJuIGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICA/IHRoaXMuZ2V0VmFsdWVOb0NoZWNrRnJvbU9ubnhGb3JtYXQoYXR0cilcbiAgICAgIDogdGhpcy5nZXRWYWx1ZU5vQ2hlY2tGcm9tT3J0Rm9ybWF0KGF0dHIgYXMgb3J0RmJzLkF0dHJpYnV0ZSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRWYWx1ZU5vQ2hlY2tGcm9tT25ueEZvcm1hdChhdHRyOiBvbm54LklBdHRyaWJ1dGVQcm90bykge1xuICAgIHN3aXRjaCAoYXR0ci50eXBlISkge1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuRkxPQVQ6XG4gICAgICAgIHJldHVybiBhdHRyLmY7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlQ6XG4gICAgICAgIHJldHVybiBhdHRyLmk7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkc6XG4gICAgICAgIHJldHVybiBhdHRyLnM7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1I6XG4gICAgICAgIHJldHVybiBhdHRyLnQ7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5HUkFQSDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkZMT0FUUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuZmxvYXRzO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuaW50cztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklOR1M6XG4gICAgICAgIHJldHVybiBhdHRyLnN0cmluZ3M7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1JTOlxuICAgICAgICByZXR1cm4gYXR0ci50ZW5zb3JzO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEhTOlxuICAgICAgICByZXR1cm4gYXR0ci5ncmFwaHM7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGF0dHJpYnV0ZSB0eXBlOiAke29ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZVthdHRyLnR5cGUhXX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRWYWx1ZU5vQ2hlY2tGcm9tT3J0Rm9ybWF0KGF0dHI6IG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICBzd2l0Y2ggKGF0dHIudHlwZSgpKSB7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLkZMT0FUOlxuICAgICAgICByZXR1cm4gYXR0ci5mKCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLklOVDpcbiAgICAgICAgcmV0dXJuIGF0dHIuaSgpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5TVFJJTkc6XG4gICAgICAgIHJldHVybiBhdHRyLnMoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuVEVOU09SOlxuICAgICAgICByZXR1cm4gYXR0ci50KCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLkdSQVBIOlxuICAgICAgICByZXR1cm4gYXR0ci5nKCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLkZMT0FUUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuZmxvYXRzQXJyYXkoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuSU5UUzoge1xuICAgICAgICBjb25zdCBpbnRzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci5pbnRzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgICAgIGludHMucHVzaChhdHRyLmludHMoaSkhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW50cztcbiAgICAgIH1cbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuU1RSSU5HUzoge1xuICAgICAgICBjb25zdCBzdHJpbmdzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci5zdHJpbmdzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgICAgIHN0cmluZ3MucHVzaChhdHRyLnN0cmluZ3MoaSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdHJpbmdzO1xuICAgICAgfVxuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5URU5TT1JTOiB7XG4gICAgICAgIGNvbnN0IHRlbnNvcnMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyLnRlbnNvcnNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgICAgdGVuc29ycy5wdXNoKGF0dHIudGVuc29ycyhpKSEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0ZW5zb3JzO1xuICAgICAgfVxuICAgICAgLy8gY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5HUkFQSFM6XG4gICAgICAvLyBUT0RPOiBTdWJncmFwaCBub3Qgc3VwcG9ydGVkIHlldC5cbiAgICAgIC8vIGNvbnN0IGdyYXBocyA9IFtdO1xuICAgICAgLy8gZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyLmdyYXBoc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIC8vICAgZ3JhcGhzLnB1c2goYXR0ci5ncmFwaHMoaSkhKTtcbiAgICAgIC8vIH1cbiAgICAgIC8vIHJldHVybiBncmFwaHM7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGF0dHJpYnV0ZSB0eXBlOiAke29ydEZicy5BdHRyaWJ1dGVUeXBlW2F0dHIudHlwZSgpXX1gKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX2F0dHJpYnV0ZXM6IE1hcDxzdHJpbmcsIFZhbHVlPjtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQXR0cmlidXRlIH0gZnJvbSAnLi9hdHRyaWJ1dGUnO1xuaW1wb3J0ICogYXMgb3J0RmJzIGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7IG9ubnggfSBmcm9tICcuL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueCc7XG5pbXBvcnQgeyBUZW5zb3IgfSBmcm9tICcuL3RlbnNvcic7XG5pbXBvcnQgeyBMb25nVXRpbCwgTUFYX0NMSVAsIE1JTl9DTElQLCBQcm90b1V0aWwgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgR3JhcGgge1xuICBleHBvcnQgaW50ZXJmYWNlIFNoYXBlIHtcbiAgICByZWFkb25seSBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFZhbHVlVHlwZSB7XG4gICAgcmVhZG9ubHkgdGVuc29yVHlwZTogVGVuc29yLkRhdGFUeXBlO1xuICAgIHJlYWRvbmx5IHNoYXBlOiBTaGFwZTtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFZhbHVlIHtcbiAgICAvLyB0aGUgdGVuc29yIGRhdGEuIGVtcHR5IGZvciBub24taW5pdGlhbGl6ZWQgaW5wdXRzXG4gICAgcmVhZG9ubHkgdGVuc29yPzogVGVuc29yO1xuXG4gICAgLy8gaW5kZXggdG8gdGhlIE5vZGUgd2hlcmUgdGhlIHZhbHVlIGNvbWVzIGZyb20uIC0xIGZvciBpbml0aWFsaXplci5cbiAgICByZWFkb25seSBmcm9tOiBudW1iZXI7XG5cbiAgICAvLyBpbmRpY2VzIHRvIHRoZSBOb2RlcyB3aGVyZSB0aGUgdmFsdWVzIGdvIHRvLlxuICAgIHJlYWRvbmx5IHRvOiByZWFkb25seSBudW1iZXJbXTtcblxuICAgIC8vIHZhbHVlIHR5cGUgc3BlY2lmaWNhdGlvbi4gZW1wdHkgZm9yIG5vbi1pbnB1dCB2YWx1ZXMuXG4gICAgcmVhZG9ubHkgdHlwZT86IFZhbHVlVHlwZTtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIE5vZGUge1xuICAgIC8vIG5hbWUgb2YgdGhlIG5vZGVcbiAgICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgICAvLyB0aGUgb3BlcmF0b3IgdHlwZVxuICAgIHJlYWRvbmx5IG9wVHlwZTogc3RyaW5nO1xuXG4gICAgLy8gaW5kaWNlcyB0byB0aGUgVmFsdWVzIHdoZXJlIHRoZSBpbnB1dHMgY29tZSBmcm9tLlxuICAgIHJlYWRvbmx5IGlucHV0czogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICAvLyBpbmRpY2VzIHRvIHRoZSBWYWx1ZXMgd2hlcmUgdGhlIG91dHB1cyBnbyB0by5cbiAgICByZWFkb25seSBvdXRwdXRzOiByZWFkb25seSBudW1iZXJbXTtcblxuICAgIC8vIHRoZSBhdHRyaWJ1dGVzIHRoYXQgdXNlZCBieSB0aGUgb3BlcmF0b3JcbiAgICByZWFkb25seSBhdHRyaWJ1dGVzOiBBdHRyaWJ1dGU7XG4gIH1cblxuICAvKipcbiAgICogYSBUcmFuc2Zvcm1lciBpcyBhbiBpbnN0YW5jZSB0aGF0IGFsbG93cyBhbGwgcG9zc2libGUgdHJhbnNmb3JtYXRpb24gb3BlcmF0aW9ucyB0aGF0IGFwcGxpZWQgdG8gYSBncmFwaFxuICAgKi9cbiAgZXhwb3J0IGludGVyZmFjZSBUcmFuc2Zvcm1lciB7XG4gICAgcmVtb3ZlQWxsSWRlbnRpdHlOb2RlcygpOiB2b2lkO1xuICAgIHJlbW92ZUFsbERyb3BvdXROb2RlcygpOiB2b2lkO1xuICAgIGZ1c2VDb252QWN0aXZhdGlvbk5vZGVzKCk6IHZvaWQ7XG4gICAgLy8gVE9ETzogYWRkIGdlbmVyaWMgZnVuY3Rpb25zIHRvIG1hbmlwdWxhdGUgdGhlIGdyYXBoXG4gIH1cblxuICAvLyBhbiBpbml0aWFsaXplciBjYW4gdXNlIHRyYW5zZm9ybWVyIHRvIHRyYW5zZm9ybSB0aGUgZ3JhcGhcbiAgZXhwb3J0IGludGVyZmFjZSBJbml0aWFsaXplciB7XG4gICAgdHJhbnNmb3JtR3JhcGgodHJhbnNmb3JtZXI6IFRyYW5zZm9ybWVyKTogdm9pZDtcbiAgfVxufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZVxuZXhwb3J0IGludGVyZmFjZSBHcmFwaCB7XG4gIGdldElucHV0SW5kaWNlcygpOiByZWFkb25seSBudW1iZXJbXTtcbiAgZ2V0SW5wdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXTtcbiAgZ2V0T3V0cHV0SW5kaWNlcygpOiByZWFkb25seSBudW1iZXJbXTtcbiAgZ2V0T3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW107XG4gIGdldFZhbHVlcygpOiByZWFkb25seSBHcmFwaC5WYWx1ZVtdO1xuICBnZXROb2RlcygpOiByZWFkb25seSBHcmFwaC5Ob2RlW107XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24sIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmVcbmV4cG9ydCBjb25zdCBHcmFwaCA9IHtcbiAgLyoqXG4gICAqIGNvbnN0cnVjdCBhIGdyYXBoIGZyb20gYSBncmFwaCBwcm90b2J1ZiB0eXBlXG4gICAqL1xuICBmcm9tOiAoZ3JhcGhQcm90bzogb25ueC5JR3JhcGhQcm90byB8IG9ydEZicy5HcmFwaCwgaW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcikgPT5cbiAgICBuZXcgR3JhcGhJbXBsKGdyYXBoUHJvdG8sIGluaXRpYWxpemVyKSxcbn07XG5cbmNsYXNzIFZhbHVlIGltcGxlbWVudHMgR3JhcGguVmFsdWUge1xuICBjb25zdHJ1Y3Rvcih2YWx1ZUluZm8/OiBvbm54LklWYWx1ZUluZm9Qcm90bykge1xuICAgIHRoaXMuX2Zyb20gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fdG8gPSBbXTtcbiAgICB0aGlzLnRlbnNvciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnR5cGUgPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAodmFsdWVJbmZvKSB7XG4gICAgICB0aGlzLnR5cGUgPSBQcm90b1V0aWwudGVuc29yVmFsdWVUeXBlRnJvbVByb3RvKHZhbHVlSW5mby50eXBlIS50ZW5zb3JUeXBlISk7XG4gICAgfVxuICB9XG5cbiAgX2Zyb20/OiBudW1iZXI7IC8vIC0xIHJlcHJlc2VudCBmcm9tIGluaXRpYWxpemVyXG4gIGdldCBmcm9tKCkge1xuICAgIHJldHVybiB0aGlzLl9mcm9tITtcbiAgfVxuICBfdG86IG51bWJlcltdO1xuICBnZXQgdG8oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RvO1xuICB9XG4gIHR5cGU/OiBHcmFwaC5WYWx1ZVR5cGU7XG4gIHRlbnNvcj86IFRlbnNvcjtcbn1cblxuY2xhc3MgTm9kZSBpbXBsZW1lbnRzIEdyYXBoLk5vZGUge1xuICBjb25zdHJ1Y3Rvcihfbm9kZVByb3RvOiBvbm54LklOb2RlUHJvdG8gfCBvcnRGYnMuTm9kZSwgbmFtZT86IHN0cmluZykge1xuICAgIGlmIChfbm9kZVByb3RvIGluc3RhbmNlb2Ygb25ueC5Ob2RlUHJvdG8pIHtcbiAgICAgIHRoaXMubmFtZSA9IF9ub2RlUHJvdG8ubmFtZTtcbiAgICAgIHRoaXMub3BUeXBlID0gX25vZGVQcm90by5vcFR5cGU7XG4gICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlKF9ub2RlUHJvdG8uYXR0cmlidXRlKTtcbiAgICB9IGVsc2UgaWYgKF9ub2RlUHJvdG8gaW5zdGFuY2VvZiBvcnRGYnMuTm9kZSkge1xuICAgICAgdGhpcy5uYW1lID0gbmFtZSA/PyBfbm9kZVByb3RvLm5hbWUoKSE7XG4gICAgICB0aGlzLm9wVHlwZSA9IF9ub2RlUHJvdG8ub3BUeXBlKCkhO1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZShQcm90b1V0aWwudGVuc29yQXR0cmlidXRlc0Zyb21PUlRGb3JtYXQoX25vZGVQcm90bykpO1xuICAgIH1cblxuICAgIHRoaXMuaW5wdXRzID0gW107XG4gICAgdGhpcy5vdXRwdXRzID0gW107XG4gICAgdGhpcy5leGVjdXRlTm9kZSA9IHRydWU7XG4gIH1cblxuICBuYW1lOiBzdHJpbmc7XG4gIG9wVHlwZTogc3RyaW5nO1xuICBpbnB1dHM6IG51bWJlcltdO1xuICBvdXRwdXRzOiBudW1iZXJbXTtcbiAgYXR0cmlidXRlczogQXR0cmlidXRlO1xuICBleGVjdXRlTm9kZTogYm9vbGVhbjtcbn1cblxuY2xhc3MgR3JhcGhJbXBsIGltcGxlbWVudHMgR3JhcGgsIEdyYXBoLlRyYW5zZm9ybWVyIHtcbiAgcHJpdmF0ZSBfYWxsRGF0YTogVmFsdWVbXTtcblxuICBwcml2YXRlIF9hbGxJbnB1dEluZGljZXM6IG51bWJlcltdO1xuICBwcml2YXRlIF9hbGxJbnB1dE5hbWVzOiBzdHJpbmdbXTtcblxuICBwcml2YXRlIF9hbGxPdXRwdXRJbmRpY2VzOiBudW1iZXJbXTtcbiAgcHJpdmF0ZSBfYWxsT3V0cHV0TmFtZXM6IHN0cmluZ1tdO1xuXG4gIHByaXZhdGUgX25vZGVzOiBOb2RlW107XG5cbiAgY29uc3RydWN0b3IoZ3JhcGg6IG9ubnguSUdyYXBoUHJvdG8gfCBvcnRGYnMuR3JhcGgsIGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcikge1xuICAgIGlmICghZ3JhcGgpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2dyYXBoIGlzIGVtcHR5Jyk7XG4gICAgfVxuXG4gICAgLy8gYnVpbGQgdGhlIGdyYXBoIC0gd2lsbCB0aHJvdyBleGNlcHRpb25zIGlmIHNvbWV0aGluZyBmYXRhbCBpcyBkZXRlY3RlZFxuICAgIHRoaXMuYnVpbGRHcmFwaChncmFwaCk7XG5cbiAgICAvLyBleGVjdXRlIGFueSB0cmFuc2Zvcm1hdGlvbiBsb2dpYyBmb3IgdGhlIGdyYXBoIChpZiBhcHBsaWNhYmxlKVxuICAgIHRoaXMudHJhbnNmb3JtR3JhcGgoZ3JhcGhJbml0aWFsaXplcik7XG5cbiAgICAvLyBjaGVjayBmb3IgY3ljbGVzIGFuZCBvdGhlciBpbmNvbnNpc3RlbmNpZXMgLSB3aWxsIHRocm93IGV4Y2VwdGlvbnMgaWYgc29tZXRoaW5nIGZhdGFsIGlzIGRldGVjdGVkXG4gICAgdGhpcy5jaGVja0lzQWN5Y2xpYygpO1xuICB9XG5cbiAgZ2V0SW5wdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsSW5wdXRJbmRpY2VzO1xuICB9XG5cbiAgZ2V0SW5wdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsbElucHV0TmFtZXM7XG4gIH1cblxuICBnZXRPdXRwdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsT3V0cHV0SW5kaWNlcztcbiAgfVxuXG4gIGdldE91dHB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsT3V0cHV0TmFtZXM7XG4gIH1cblxuICBnZXRWYWx1ZXMoKTogcmVhZG9ubHkgR3JhcGguVmFsdWVbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2FsbERhdGE7XG4gIH1cblxuICBnZXROb2RlcygpOiByZWFkb25seSBHcmFwaC5Ob2RlW10ge1xuICAgIHJldHVybiB0aGlzLl9ub2RlcztcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRHcmFwaChncmFwaDogb25ueC5JR3JhcGhQcm90byB8IG9ydEZicy5HcmFwaCkge1xuICAgIC8vIGJ1aWxkIHRoZSBncmFwaCAtIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBpZiBzb21ldGhpbmcgZmF0YWwgaXMgZGV0ZWN0ZWRcbiAgICBpZiAoZ3JhcGggaW5zdGFuY2VvZiBvbm54LkdyYXBoUHJvdG8pIHtcbiAgICAgIHRoaXMuYnVpbGRHcmFwaEZyb21Pbm54Rm9ybWF0KGdyYXBoKTtcbiAgICB9IGVsc2UgaWYgKGdyYXBoIGluc3RhbmNlb2Ygb3J0RmJzLkdyYXBoKSB7XG4gICAgICB0aGlzLmJ1aWxkR3JhcGhGcm9tT3J0Rm9ybWF0KGdyYXBoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignR3JhcGggdHlwZSBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGJ1aWxkR3JhcGhGcm9tT25ueEZvcm1hdChncmFwaDogb25ueC5JR3JhcGhQcm90bykge1xuICAgIGNvbnN0IGRhdGFJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICB0aGlzLl9hbGxEYXRhID0gW107XG5cbiAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMgPSBbXTtcbiAgICB0aGlzLl9hbGxJbnB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMgPSBbXTtcblxuICAgIHRoaXMuX25vZGVzID0gW107XG5cbiAgICBjb25zdCBub2Rlc0luZGljZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG4gICAgLy8gc2NhbiBhbGwgaW5wdXRzXG4gICAgaWYgKCFncmFwaC5pbnB1dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBpbnB1dCcpO1xuICAgIH1cbiAgICBjb25zdCBpbnB1dFZhbHVlTmFtZXMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGkgb2YgZ3JhcGguaW5wdXQpIHtcbiAgICAgIGlmIChkYXRhSW5kaWNlcy5oYXMoaS5uYW1lISkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIGlucHV0IG5hbWU6ICR7aS5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZShpKSkgLSAxO1xuICAgICAgZGF0YUluZGljZXMuc2V0KGkubmFtZSEsIGN1cnJlbnRJbmRleCk7XG4gICAgICBpbnB1dFZhbHVlTmFtZXMucHVzaChpLm5hbWUhKTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBpbml0aWFsaXplcnNcbiAgICBpZiAoIWdyYXBoLmluaXRpYWxpemVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IGluaXRpYWxpemVyJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgaSBvZiBncmFwaC5pbml0aWFsaXplcikge1xuICAgICAgbGV0IGluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGkubmFtZSEpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBuZXcgVmFsdWUoKTtcbiAgICAgICAgdmFsdWUudHlwZSA9IHtcbiAgICAgICAgICBzaGFwZTogeyBkaW1zOiBQcm90b1V0aWwudGVuc29yRGltc0Zyb21Qcm90byhpLmRpbXMhKSB9LFxuICAgICAgICAgIHRlbnNvclR5cGU6IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhpLmRhdGFUeXBlISksXG4gICAgICAgIH07XG4gICAgICAgIGluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKHZhbHVlKSAtIDE7XG4gICAgICAgIGRhdGFJbmRpY2VzLnNldChpLm5hbWUhLCBpbmRleCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgdGhpcy5fYWxsRGF0YVtpbmRleF0udGVuc29yID0gVGVuc29yLmZyb21Qcm90byhpKTtcbiAgICB9XG5cbiAgICAvLyBmaWx0ZXIgb3V0IGlucHV0IGluZGljZXNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2FsbERhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghdGhpcy5fYWxsRGF0YVtpXS50ZW5zb3IpIHtcbiAgICAgICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzLnB1c2goaSk7XG4gICAgICAgIHRoaXMuX2FsbElucHV0TmFtZXMucHVzaChpbnB1dFZhbHVlTmFtZXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNjYW4gYWxsIG91dHB1dHNcbiAgICBpZiAoIWdyYXBoLm91dHB1dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBvdXRwdXQnKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBpIG9mIGdyYXBoLm91dHB1dCkge1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhpLm5hbWUhKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgb3V0cHV0IG5hbWU6ICR7aS5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZShpKSkgLSAxO1xuICAgICAgZGF0YUluZGljZXMuc2V0KGkubmFtZSEsIGN1cnJlbnRJbmRleCk7XG4gICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLnB1c2goY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzLnB1c2goaS5uYW1lISk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgbm9kZXNcbiAgICBpZiAoIWdyYXBoLm5vZGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogbm9kZScpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG5vZGVQcm90byBvZiBncmFwaC5ub2RlKSB7XG4gICAgICBpZiAoIW5vZGVQcm90by5uYW1lKSB7XG4gICAgICAgIC8vIGFzc2lnbiBhIG5hbWUgdG8gdGhlIG5vZGUgaWYgaXQgZG9lc24ndCBoYXZlIG9uZVxuICAgICAgICBmb3IgKGxldCBwaWNrID0gMDsgOyBwaWNrKyspIHtcbiAgICAgICAgICBjb25zdCBuYW1lID0gYHVubmFtZWRfJHtub2RlUHJvdG8ub3BUeXBlfV8ke3BpY2t9YDtcbiAgICAgICAgICBpZiAoIW5vZGVzSW5kaWNlcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIG5vZGVQcm90by5uYW1lID0gbmFtZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobm9kZXNJbmRpY2VzLmhhcyhub2RlUHJvdG8ubmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIG5vZGUgbmFtZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX25vZGVzLnB1c2gobmV3IE5vZGUobm9kZVByb3RvKSkgLSAxO1xuICAgICAgbm9kZXNJbmRpY2VzLnNldChub2RlUHJvdG8ubmFtZSwgY3VycmVudEluZGV4KTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIG5vZGUncyBvdXRwdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZVtpXTtcbiAgICAgIGlmICghbm9kZVByb3RvLm91dHB1dCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG1pc3Npbmcgb3V0cHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBvdXRwdXQgb2Ygbm9kZVByb3RvLm91dHB1dCkge1xuICAgICAgICBsZXQgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KG91dHB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGRhdGFJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoKSkgLSAxO1xuICAgICAgICAgIGRhdGFJbmRpY2VzLnNldChvdXRwdXQsIGRhdGFJbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5vdXRwdXRzLnB1c2goZGF0YUluZGV4KTtcblxuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG11bHRpcGxlIG5vZGVzIG91dHB1dCB0byBvbmUgZGF0YSB2YWx1ZTogJHtkYXRhSW5kZXh9YCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tID0gaTtcblxuICAgICAgICAvLyBmb3IgdGhlICdDb25zdGFudCcgb3BlcmF0b3IsIGp1c3QgY3JlYXRlIGEgbmV3IGVkZ2UgaW4gdGhlIGdyYXBoIGNvcnJlc3BvbmRpbmcgdG8gdGhlICdvdXRwdXQnIG9mIHRoZVxuICAgICAgICAvLyBvcGVyYXRvciBhbmQgaWdub3JlIHRoZSBub2RlIGZyb20gdGhlIGdyYXBoXG4gICAgICAgIGlmIChub2RlUHJvdG8ub3BUeXBlID09PSAnQ29uc3RhbnQnKSB7XG4gICAgICAgICAgaWYgKCFub2RlUHJvdG8uYXR0cmlidXRlIHx8IG5vZGVQcm90by5hdHRyaWJ1dGUubGVuZ3RoICE9PSAxIHx8ICFub2RlUHJvdG8uYXR0cmlidXRlWzBdLnQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBhdHRyaWJ1dGVzIG9yIG1pc3NpbmcgdGVuc29yIHZhbHVlIGluIGF0dHJpYnV0ZXMgZm9yIHRoaXMgQ29uc3RhbnQgb3BlcmF0b3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFub2RlUHJvdG8ub3V0cHV0IHx8IG5vZGVQcm90by5vdXRwdXQubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3Npbmcgb3V0cHV0IG9yIGluY29ycmVjdCBudW1iZXIgb2Ygb3V0cHV0cyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBub2RlLm91dHB1dHMucG9wKCk7XG4gICAgICAgICAgbm9kZS5leGVjdXRlTm9kZSA9IGZhbHNlO1xuXG4gICAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tID0gLTE7XG4gICAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLnRlbnNvciA9IFRlbnNvci5mcm9tUHJvdG8obm9kZVByb3RvLmF0dHJpYnV0ZVswXS50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNjYW4gbm9kZSdzIGlucHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVbaV07XG5cbiAgICAgIGlmICghbm9kZVByb3RvLmlucHV0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBpbnB1dCBmb3Igbm9kZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgaW5wdXQgb2Ygbm9kZVByb3RvLmlucHV0KSB7XG4gICAgICAgIGNvbnN0IGRhdGFJbmRleCA9IGRhdGFJbmRpY2VzLmdldChpbnB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIC8vIGhhbmRsZSBleGNlcHRpb24gd2hlbiBvcHNldCA+IDkgYW5kIHJvaSAvIHNjYWxlcyBub3QgZ2l2ZW5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBpbnB1dCA9PT0gJycgJiZcbiAgICAgICAgICAgIChub2RlUHJvdG8uaW5wdXQubGVuZ3RoID09PSAzIHx8IG5vZGVQcm90by5pbnB1dC5sZW5ndGggPT09IDQpICYmXG4gICAgICAgICAgICBub2RlUHJvdG8ub3BUeXBlID09PSAnUmVzaXplJ1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5yZWNvZ25pemVkIGlucHV0ICcke2lucHV0fScgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5pbnB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fdG8ucHVzaChpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRHcmFwaEZyb21PcnRGb3JtYXQoZ3JhcGg6IG9ydEZicy5HcmFwaCkge1xuICAgIGNvbnN0IGRhdGFJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICB0aGlzLl9hbGxEYXRhID0gW107XG5cbiAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMgPSBbXTtcbiAgICB0aGlzLl9hbGxJbnB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMgPSBbXTtcblxuICAgIHRoaXMuX25vZGVzID0gW107XG5cbiAgICBjb25zdCBub2Rlc0luZGljZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG4gICAgLy8gc2NhbiBhbGwgaW5wdXRzXG4gICAgY29uc3QgaW5wdXRWYWx1ZU5hbWVzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5pbnB1dHNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBjb25zdCBpbnB1dE5hbWUgPSBncmFwaC5pbnB1dHMoaSk7XG4gICAgICBpZiAoZGF0YUluZGljZXMuaGFzKGlucHV0TmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIGlucHV0IG5hbWU6ICR7aW5wdXROYW1lfWApO1xuICAgICAgfVxuICAgICAgLy8gRmluZCB0aGUgaW5wdXQgdHlwZUluZm8gZnJvbSBub2RlYXJnc1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBncmFwaC5ub2RlQXJnc0xlbmd0aCgpOyBqKyspIHtcbiAgICAgICAgaWYgKGdyYXBoLm5vZGVBcmdzKGopPy5uYW1lKCkgPT09IGlucHV0TmFtZSkge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gbmV3IFZhbHVlKCk7XG4gICAgICAgICAgY29uc3QgdmFsdWVUeXBlID0gZ3JhcGgubm9kZUFyZ3Moaik/LnR5cGUoKT8udmFsdWVUeXBlKCk7XG4gICAgICAgICAgaWYgKHZhbHVlVHlwZSAhPT0gb3J0RmJzLlR5cGVJbmZvVmFsdWUudGVuc29yX3R5cGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCB2YWx1ZSB0eXBlIGZvciB0aGUgbm9kZUFyZy4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgdmFsdWVJbmZvID0gZ3JhcGgubm9kZUFyZ3MoaikhLnR5cGUoKSEudmFsdWUobmV3IG9ydEZicy5UZW5zb3JUeXBlQW5kU2hhcGUoKSkhO1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odmFsdWVJbmZvLmVsZW1UeXBlKCkpO1xuICAgICAgICAgIGNvbnN0IHNoYXBlID0gdmFsdWVJbmZvLnNoYXBlKCkhO1xuICAgICAgICAgIGNvbnN0IGRpbXMgPSBbXTtcbiAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHNoYXBlLmRpbUxlbmd0aCgpITsgaysrKSB7XG4gICAgICAgICAgICBkaW1zLnB1c2goTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKHNoYXBlLmRpbShrKSEudmFsdWUoKSEuZGltVmFsdWUoKSEpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFsdWUudHlwZSA9IHsgc2hhcGU6IHsgZGltcyB9LCB0ZW5zb3JUeXBlOiB0eXBlIH07XG4gICAgICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKHZhbHVlKSAtIDE7XG4gICAgICAgICAgZGF0YUluZGljZXMuc2V0KGlucHV0TmFtZSwgY3VycmVudEluZGV4KTtcbiAgICAgICAgICBpbnB1dFZhbHVlTmFtZXMucHVzaChpbnB1dE5hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNoZWNrIGluaXRpYWxpemVyc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGguaW5pdGlhbGl6ZXJzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3QgaW5pdGlhbGl6ZXIgPSBncmFwaC5pbml0aWFsaXplcnMoaSkhO1xuICAgICAgbGV0IGluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGluaXRpYWxpemVyLm5hbWUoKSEpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBuZXcgVmFsdWUoKTtcbiAgICAgICAgY29uc3QgZGltcyA9IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbU9SVEZvcm1hdChpbml0aWFsaXplcik7XG4gICAgICAgIGNvbnN0IHR5cGUgPSBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8oaW5pdGlhbGl6ZXIuZGF0YVR5cGUoKSk7XG4gICAgICAgIHZhbHVlLnR5cGUgPSB7IHNoYXBlOiB7IGRpbXMgfSwgdGVuc29yVHlwZTogdHlwZSB9O1xuICAgICAgICBpbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaCh2YWx1ZSkgLSAxO1xuICAgICAgICBkYXRhSW5kaWNlcy5zZXQoaW5pdGlhbGl6ZXIubmFtZSgpISwgaW5kZXgpO1xuICAgICAgfVxuICAgICAgdGhpcy5fYWxsRGF0YVtpbmRleF0uX2Zyb20gPSAtMTtcbiAgICAgIHRoaXMuX2FsbERhdGFbaW5kZXhdLnRlbnNvciA9IFRlbnNvci5mcm9tT3J0VGVuc29yKGluaXRpYWxpemVyKTtcbiAgICB9XG5cbiAgICAvLyBmaWx0ZXIgb3V0IGlucHV0IGluZGljZXNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2FsbERhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghdGhpcy5fYWxsRGF0YVtpXS50ZW5zb3IpIHtcbiAgICAgICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzLnB1c2goaSk7XG4gICAgICAgIHRoaXMuX2FsbElucHV0TmFtZXMucHVzaChpbnB1dFZhbHVlTmFtZXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNjYW4gYWxsIG91dHB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoLm91dHB1dHNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBjb25zdCBvdXRwdXROYW1lID0gZ3JhcGgub3V0cHV0cyhpKTtcbiAgICAgIGlmIChkYXRhSW5kaWNlcy5oYXMob3V0cHV0TmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIG91dHB1dCBuYW1lOiAke291dHB1dE5hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2gobmV3IFZhbHVlKCkpIC0gMTtcbiAgICAgIGRhdGFJbmRpY2VzLnNldChvdXRwdXROYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5wdXNoKGN1cnJlbnRJbmRleCk7XG4gICAgICB0aGlzLl9hbGxPdXRwdXROYW1lcy5wdXNoKG91dHB1dE5hbWUpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gYWxsIG5vZGVzXG4gICAgaWYgKCFncmFwaC5ub2Rlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBub2RlJyk7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGgubm9kZXNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlcyhpKTtcbiAgICAgIGxldCBuYW1lID0gbm9kZVByb3RvIS5uYW1lKCk7XG4gICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgLy8gYXNzaWduIGEgbmFtZSB0byB0aGUgbm9kZSBpZiBpdCBkb2Vzbid0IGhhdmUgb25lXG4gICAgICAgIGZvciAobGV0IHBpY2sgPSAwOyA7IHBpY2srKykge1xuICAgICAgICAgIG5hbWUgPSBgdW5uYW1lZF8ke25vZGVQcm90byEub3BUeXBlKCl9XyR7cGlja31gO1xuICAgICAgICAgIGlmICghbm9kZXNJbmRpY2VzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgLy8gYW4gdW5pcXVlIG5hbWUgaXMgZm91bmQuIGJyZWFrLlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChub2Rlc0luZGljZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBub2RlIG5hbWU6ICR7bmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX25vZGVzLnB1c2gobmV3IE5vZGUobm9kZVByb3RvISwgbmFtZSkpIC0gMTtcbiAgICAgIG5vZGVzSW5kaWNlcy5zZXQobmFtZSwgY3VycmVudEluZGV4KTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIG5vZGUncyBvdXRwdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZXMoaSk7XG4gICAgICBpZiAobm9kZVByb3RvID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBub2RlIGV4aXN0cyBhdCBpbmRleCAke2l9YCk7XG4gICAgICB9XG4gICAgICBpZiAobm9kZVByb3RvPy5vdXRwdXRzTGVuZ3RoKCkgPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIG91dHB1dCBmb3Igbm9kZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbm9kZVByb3RvPy5vdXRwdXRzTGVuZ3RoKCk7IGorKykge1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBub2RlUHJvdG8/Lm91dHB1dHMoaik7XG4gICAgICAgIGxldCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQob3V0cHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgZGF0YUluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZSgpKSAtIDE7XG4gICAgICAgICAgZGF0YUluZGljZXMuc2V0KG91dHB1dCwgZGF0YUluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLm91dHB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbXVsdGlwbGUgbm9kZXMgb3V0cHV0IHRvIG9uZSBkYXRhIHZhbHVlOiAke2RhdGFJbmRleH1gKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSBpO1xuXG4gICAgICAgIC8vIGZvciB0aGUgJ0NvbnN0YW50JyBvcGVyYXRvciwganVzdCBjcmVhdGUgYSBuZXcgZWRnZSBpbiB0aGUgZ3JhcGggY29ycmVzcG9uZGluZyB0byB0aGUgJ291dHB1dCcgb2YgdGhlXG4gICAgICAgIC8vIG9wZXJhdG9yIGFuZCBpZ25vcmUgdGhlIG5vZGUgZnJvbSB0aGUgZ3JhcGhcbiAgICAgICAgaWYgKG5vZGVQcm90by5vcFR5cGUoKSA9PT0gJ0NvbnN0YW50Jykge1xuICAgICAgICAgIGlmIChub2RlUHJvdG8uYXR0cmlidXRlc0xlbmd0aCgpICE9PSAxIHx8ICFub2RlUHJvdG8uYXR0cmlidXRlcygwKSEudCgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYXR0cmlidXRlcyBvciBtaXNzaW5nIHRlbnNvciB2YWx1ZSBpbiBhdHRyaWJ1dGVzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChub2RlUHJvdG8ub3V0cHV0c0xlbmd0aCgpICE9PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3Npbmcgb3V0cHV0IG9yIGluY29ycmVjdCBudW1iZXIgb2Ygb3V0cHV0cyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBub2RlLm91dHB1dHMucG9wKCk7XG4gICAgICAgICAgbm9kZS5leGVjdXRlTm9kZSA9IGZhbHNlO1xuXG4gICAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tID0gLTE7XG4gICAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLnRlbnNvciA9IFRlbnNvci5mcm9tT3J0VGVuc29yKG5vZGVQcm90by5hdHRyaWJ1dGVzKDApIS50KCkhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNjYW4gbm9kZSdzIGlucHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVzKGkpITtcblxuICAgICAgaWYgKG5vZGVQcm90by5pbnB1dHNMZW5ndGgoKSA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG1pc3NpbmcgaW5wdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG5vZGVQcm90by5pbnB1dHNMZW5ndGgoKSE7IGorKykge1xuICAgICAgICBjb25zdCBpbnB1dCA9IG5vZGVQcm90by5pbnB1dHMoaikhO1xuICAgICAgICBjb25zdCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQoaW5wdXQpO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBpbnB1dCAnJHtpbnB1dH0nIGZvciBub2RlOiAke25vZGVQcm90byEubmFtZSgpfWApO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUuaW5wdXRzLnB1c2goZGF0YUluZGV4KTtcblxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX3RvLnB1c2goaSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0lzQWN5Y2xpYygpIHtcbiAgICAvLyBnbyB0aHJvdWdoIHRoZSBncmFwaCBhbmQgY2hlY2sgZm9yIGN5Y2xlcyBvciBvdGhlciBmYXRhbCBpbmNvbnNpc3RlbmNpZXNcbiAgICBjb25zdCBzdGFydGVyczogU2V0PG51bWJlcj4gPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2FsbERhdGFbaV07XG4gICAgICBkYXRhLl90by5mb3JFYWNoKChqKSA9PiB7XG4gICAgICAgIHN0YXJ0ZXJzLmFkZChqKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gSXRlcmF0aXZlIERGUyB0byBjaGVjayBmb3IgY3ljbGVzXG4gICAgY29uc3Qgbm9kZXNTdGFjayA9IEFycmF5LmZyb20oc3RhcnRlcnMpO1xuICAgIGNvbnN0IG5vZGVzU3RhdGUgPSBuZXcgQXJyYXk8c3RyaW5nPih0aGlzLl9ub2Rlcy5sZW5ndGgpLmZpbGwoJ3doaXRlJyk7XG5cbiAgICB3aGlsZSAobm9kZXNTdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBub2RlSW5kZXggPSBub2Rlc1N0YWNrLnBvcCgpITtcbiAgICAgIC8vIHRoaXMgbm9kZSBoYXMgbm93IGJlZW4gcHJvY2Vzc2VkIGNvbXBsZXRlbHkuIE1hcmsgdGhpcyBub2RlICdibGFjaycgdG8gZGVub3RlIHRoaXMuXG4gICAgICBpZiAobm9kZXNTdGF0ZVtub2RlSW5kZXhdID09PSAnZ3JheScpIHtcbiAgICAgICAgbm9kZXNTdGF0ZVtub2RlSW5kZXhdID0gJ2JsYWNrJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHRoaXMgbm9kZSBpcyB1bmRlciBwcm9jZXNzaW5nIHN0YWdlLiBtYXJrIHRoaXMgbm9kZSAnZ3JheScgdG8gZGVub3RlIHRoaXMuXG4gICAgICAgIG5vZGVzU3RhY2sucHVzaChub2RlSW5kZXgpO1xuICAgICAgICBub2Rlc1N0YXRlW25vZGVJbmRleF0gPSAnZ3JheSc7XG5cbiAgICAgICAgdGhpcy5fbm9kZXNbbm9kZUluZGV4XS5vdXRwdXRzLmZvckVhY2goKG91dGdvaW5nRWRnZUluZGV4KSA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2FsbERhdGFbb3V0Z29pbmdFZGdlSW5kZXhdO1xuICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS50ZW5zb3IgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vZGUgb3V0cHV0cyBzaG91bGQgbm90IGJlIGluaXRpYWxpemVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkYXRhLl9mcm9tICE9PSBub2RlSW5kZXgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImZyb20gcHJvcGVydHkgb2YgdGhlIFZhbHVlIG9iamVjdCBkb2Vzbid0IG1hdGNoIGluZGV4IG9mIE5vZGUgYmVpbmcgcHJvY2Vzc2VkXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkYXRhLl90by5mb3JFYWNoKChkb3duc3RyZWFtTm9kZUluZGV4KSA9PiB7XG4gICAgICAgICAgICAvLyBiYWNrIGVkZ2UgZm91bmQgLSBjeWNsaWNcbiAgICAgICAgICAgIGlmIChub2Rlc1N0YXRlW2Rvd25zdHJlYW1Ob2RlSW5kZXhdID09PSAnZ3JheScpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtb2RlbCBncmFwaCBpcyBjeWNsaWMnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRyZWUgZWRnZSBmb3VuZCAtIGNvbnRpbnVlIHByb2Nlc3NpbmcgYnkgYWRkaW5nIGl0IHRvIHN0YWNrXG4gICAgICAgICAgICBlbHNlIGlmIChub2Rlc1N0YXRlW2Rvd25zdHJlYW1Ob2RlSW5kZXhdID09PSAnd2hpdGUnKSB7XG4gICAgICAgICAgICAgIG5vZGVzU3RhY2sucHVzaChkb3duc3RyZWFtTm9kZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0cmFuc2Zvcm1HcmFwaChncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpOiB2b2lkIHtcbiAgICAvLyBhcHBseSBjb21tb24gdHJhbnNmb3JtXG4gICAgdGhpcy5yZW1vdmVBbGxJZGVudGl0eU5vZGVzKCk7XG4gICAgdGhpcy5yZW1vdmVBbGxEcm9wb3V0Tm9kZXMoKTtcbiAgICB0aGlzLmZ1c2VDb252QWN0aXZhdGlvbk5vZGVzKCk7XG4gICAgLy8gYXBwbHkgaW5pdGlhbGl6ZXIgc3BlY2lmaWMgdHJhbnNmb3JtXG4gICAgaWYgKGdyYXBoSW5pdGlhbGl6ZXIpIHtcbiAgICAgIGdyYXBoSW5pdGlhbGl6ZXIudHJhbnNmb3JtR3JhcGgodGhpcyk7XG4gICAgfVxuXG4gICAgLy8gZmluYWxpemUgZ3JhcGhcbiAgICB0aGlzLmZpbmFsaXplR3JhcGgoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBmaW5hbGl6ZSB0aGUgZ3JhcGguXG4gICAqXG4gICAqIHRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCBhZnRlciBhbGwgdGhlIHRyYW5zZm9ybWF0aW9uIGNvbXBsZXRlZC5cbiAgICogdGhpcyBmdW5jdGlvbiByZW1vdmVzIGFsbCB1bm5lY2Vzc2FyeSBub2RlcyBhbmQgdmFsdWVzIGZyb20gdGhlIGdyYXBoXG4gICAqL1xuICBmaW5hbGl6ZUdyYXBoKCkge1xuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIC8vIGRlbGV0ZSBhbGwgbm9kZXMgdGhhdCBhcmUgbm90IGJlaW5nIGV4ZWN1dGVkXG4gICAgLy8gVGhlIGdyYXBoIGlzIHJlcHJlc2VudGVkIHVzaW5nIHRoZXNlIHR3byBhcnJheXNcbiAgICAvLyB0aGlzLl9ub2RlcyAtIEFycmF5IGhvbGRpbmcgdGhlIGtlcm5lbHMgdG8gZXhlY3V0ZSAtIGVhY2ggZW50cnkgaXMgYSBrZXJuZWwgcG9pbnRpbmcgdG8gdGhpcy5fYWxsRGF0YVxuICAgIC8vIHRoaXMuX2FsbERhdGEgLSBob2xkIDIgZmllbGRzIC0gdG8gW10gJiBmcm9tIC0gdGhlc2UgZmVpbGVkcyBob2xkIHRoZSBncmFwaCBtYXAgZm9yIGlucHV0cyBhbmQgb3V0cHV0cyBwZXIgbm9kZVxuICAgIC8vIG5ld0luZGljZXMgLSByZW1hcHBpbmcgdGhlIGdyYXBoIGFmdGVyIHJlYWRpbmcgdGhlIGZsYWcgJ2V4ZWN1dGVOb2RlJ1xuICAgIGNvbnN0IG5ld0luZGljZXMgPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLl9ub2Rlcy5sZW5ndGgsIDApO1xuICAgIGxldCBub2RlUG9zc2l0aW9uID0gMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vIGdpdmluZyBuZXcgaW5kZXhlcyB0byB0aGUgbm9kZXMgYmFzZWQgb24gZXhlY3V0aW9uIGZsYWdcbiAgICAgIG5ld0luZGljZXNbaV0gPSBub2RlUG9zc2l0aW9uO1xuICAgICAgaWYgKHRoaXMuX25vZGVzW2ldLmV4ZWN1dGVOb2RlKSB7XG4gICAgICAgIGlmIChub2RlUG9zc2l0aW9uICE9PSBpKSB7XG4gICAgICAgICAgdGhpcy5fbm9kZXNbbm9kZVBvc3NpdGlvbl0gPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgICAgfVxuICAgICAgICBub2RlUG9zc2l0aW9uKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBkZWxldGUgYWxsIG91dHB1dCB2YWx1ZXNcbiAgICAgICAgdGhpcy5fbm9kZXNbaV0ub3V0cHV0cy5mb3JFYWNoKChpbmQpID0+IHtcbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2luZF0uX2Zyb20gPSAtMjtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZpbmcgdGhlIHVudXNlZCBub2Rlc1xuICAgIHRoaXMuX25vZGVzLnNwbGljZShub2RlUG9zc2l0aW9uLCB0aGlzLl9ub2Rlcy5sZW5ndGggLSBub2RlUG9zc2l0aW9uKTtcblxuICAgIC8vIFVwZGF0aW5nIHRoaXMuX2FsbERhdGEgYWNjb3JkaW5nIHRvIHRoZSBuZXcgdGhpcy5fbm9kZXNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2FsbERhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGN1cnJlbnREYXRhID0gdGhpcy5fYWxsRGF0YVtpXTtcbiAgICAgIGlmIChjdXJyZW50RGF0YS5fZnJvbSAhPT0gdW5kZWZpbmVkICYmIGN1cnJlbnREYXRhLl9mcm9tICE9PSAtMSAmJiBjdXJyZW50RGF0YS5fZnJvbSAhPT0gLTIpIHtcbiAgICAgICAgY3VycmVudERhdGEuX2Zyb20gPSBuZXdJbmRpY2VzW2N1cnJlbnREYXRhLl9mcm9tXTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjdXJyZW50RGF0YS5fdG8ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKGN1cnJlbnREYXRhLl90b1tqXSA+PSAwKSB7XG4gICAgICAgICAgY3VycmVudERhdGEuX3RvW2pdID0gbmV3SW5kaWNlc1tjdXJyZW50RGF0YS5fdG9bal1dO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVHJ5aW5nIHRvIHVwZGF0ZSBhIHJlbW92ZWQgbm9kZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgb2Zmc2V0ID0gMDtcbiAgICAvLyBkZWxldGUgYWxsIHZhbHVlcyB0aGF0IGFyZSBub3QgYmVpbmcgcmVmZXJlbmNlZFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgLy8gaWYgY3VycmVudCB2YWx1ZSBpcyBuZWl0aGVyIGxpbmtlZCB0byBuZXh0IG5vZGUsIG5vciBhbiBvdXRwdXQgdmFsdWUsIHJlbW92ZSBpdC5cbiAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2ldLmZyb20gPT09IC0yICYmIHRoaXMuX2FsbE91dHB1dEluZGljZXMuaW5kZXhPZihpICsgb2Zmc2V0KSA9PT0gLTEpIHtcbiAgICAgICAgb2Zmc2V0Kys7XG4gICAgICAgIHRoaXMuX2FsbERhdGEuc3BsaWNlKGksIDEpO1xuICAgICAgICBpLS07XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKG9mZnNldCA+IDApIHtcbiAgICAgICAgbGV0IGluZCA9IC0xO1xuICAgICAgICAvLyBpZiBjdXJyZW50IHZhbHVlIGlzIG5laXRoZXIgYW4gaW5wdXQgdmFsdWUgbm9yIGFuIGluaXRpYWxpemVyLCBmaW5kIHRoZSBub2RlIGl0J3NcbiAgICAgICAgLy8gY29taW5nIGZyb20gYW5kIHVwZGF0ZSB0aGUgY29ycmVzcG9uZGluZyBub2RlIG91dHB1dFxuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtpXS5mcm9tICE9PSB1bmRlZmluZWQgJiYgdGhpcy5fYWxsRGF0YVtpXS5mcm9tICE9PSAtMSkge1xuICAgICAgICAgIGluZCA9IHRoaXMuX25vZGVzW3RoaXMuX2FsbERhdGFbaV0uZnJvbV0ub3V0cHV0cy5pbmRleE9mKGkgKyBvZmZzZXQpO1xuICAgICAgICAgIGlmIChpbmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9ub2Rlc1t0aGlzLl9hbGxEYXRhW2ldLmZyb21dLm91dHB1dHNbaW5kXSA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgYW4gaW5wdXQgdmFsdWUsIHVwZGF0ZSBpdHMgcmVmZXJlbmNlIGluIGlucHV0SW5kaWNlc1xuICAgICAgICAgIGluZCA9IHRoaXMuX2FsbElucHV0SW5kaWNlcy5pbmRleE9mKGkgKyBvZmZzZXQpO1xuICAgICAgICAgIGlmIChpbmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9hbGxJbnB1dEluZGljZXNbaW5kXSA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZmluZCB0aGUgbm9kZSB0aGF0IHRoZSBjdXJyZW50IHZhbHVlIGlzIGxpbmtpbmcgdG8gYW5kIHVwZGF0ZSBpdHMgaW5wdXQgcmVmZXJlbmNlXG4gICAgICAgIHRoaXMuX2FsbERhdGFbaV0udG8uZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgICAgIGluZCA9IHRoaXMuX25vZGVzW25vZGVdLmlucHV0cy5pbmRleE9mKGkgKyBvZmZzZXQpO1xuICAgICAgICAgIGlmIChpbmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9ub2Rlc1tub2RlXS5pbnB1dHNbaW5kXSA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbaV0udG8ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgLy8gaWYgY3VycmVudCB2YWx1ZSBpcyBhIGdyYXBoIG91dHB1dCwgdXBkYXRlIGl0cyByZWZlcmVuY2UgaW4gb3V0cHV0SW5kaWNlc1xuICAgICAgICAgIGluZCA9IHRoaXMuX2FsbE91dHB1dEluZGljZXMuaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlc1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBzcGVjaWZpZWQgbm9kZS4gQXNzdW1lIHRoZSBub2RlIGhhcyBvbmUgaW5jb21pbmcgaW5wdXQgYW5kIHRoZSBmaXJzdCBvdXRwdXQgY29ubmVjdGVkIHRvIG90aGVyIG5vZGVzLlxuICAgKiBBbiBpbnB1dCB2YWxpZGF0aW9uIG11c3QgYmUgZG9uZSBiZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLlxuICAgKiBAcGFyYW0gbm9kZUluZGV4IFRoZSBpbmRleCBvZiBub2RlIHRvIGJlIGRlbGV0ZWRcbiAgICovXG4gIHByaXZhdGUgZGVsZXRlTm9kZShub2RlSW5kZXg6IG51bWJlcikge1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tub2RlSW5kZXhdO1xuICAgIGlmIChub2RlLm91dHB1dHMubGVuZ3RoID4gMSkge1xuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBub2RlLm91dHB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbbm9kZS5vdXRwdXRzW2ldXS50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb2RlIGRlbGV0aW9uIHdpdGggbW9yZSB0aGFuIG9uZSBvdXRwdXQgY29ubmVjdGVkIHRvIG90aGVyIG5vZGVzIGlzIG5vdCBzdXBwb3J0ZWQuICcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhpcyBub2RlIHdpbCBub3QgYmUgZXhlY3V0ZWRcbiAgICBub2RlLmV4ZWN1dGVOb2RlID0gZmFsc2U7XG4gICAgY29uc3QgaW5wdXRWYWx1ZUluZGV4ID0gbm9kZS5pbnB1dHNbMF07XG4gICAgY29uc3Qgb3V0cHV0VmFsdWVJbmRleCA9IG5vZGUub3V0cHV0c1swXTtcbiAgICBjb25zdCBub2Rlc0NvbnN1bWluZ091dHB1dCA9IHRoaXMuX2FsbERhdGFbb3V0cHV0VmFsdWVJbmRleF0udG87XG5cbiAgICAvLyByZW1vdmUgdGhpcyBub2RlIGZyb20gdGhlIHRvIHByb3BlcnR5IG9mIHRoZSBpbnB1dCBWYWx1ZVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5pbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGRlbEluZGV4ID0gdGhpcy5fYWxsRGF0YVtub2RlLmlucHV0c1tpXV0udG8uaW5kZXhPZihub2RlSW5kZXgpO1xuICAgICAgLy8gc2hvdWxkIG5vdCBoYXBwZW5cbiAgICAgIGlmIChkZWxJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIFZhbHVlIG9iamVjdCBkb2Vzbid0IGhhdmUgdGhlIGN1cnJlbnQgTm9kZSBpbiBpdCdzICd0bycgcHJvcGVydHkgXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5fYWxsRGF0YVtub2RlLmlucHV0c1tpXV0udG8uc3BsaWNlKGRlbEluZGV4LCAxKTtcbiAgICB9XG5cbiAgICAvLyBjbGVhciBub2RlIGluZGljZXMgY29uc3VtaW5nIHRoaXMgb3V0cHV0IFZhbHVlXG4gICAgdGhpcy5fYWxsRGF0YVtvdXRwdXRWYWx1ZUluZGV4XS5fdG8gPSBbXTtcblxuICAgIC8vIGlmIHRoZSBvdXRwdXQgb2YgdGhpcyBub2RlIGlzIGEgZ3JhcGggb3V0cHV0LCBhZGp1c3QgdGhlIGluZGV4IGFwcHJvcHJpYXRlbHlcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuX2FsbE91dHB1dEluZGljZXMuaW5kZXhPZihvdXRwdXRWYWx1ZUluZGV4KTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzW2luZGV4XSA9IGlucHV0VmFsdWVJbmRleDtcbiAgICB9XG5cbiAgICAvLyBvdmVycmlkZSB0aGUgaW5wdXRzIGZvciBub2RlcyBjb25zdW1pbmcgdGhpcyBub2RlJ3Mgb3V0cHV0IHdpdGggdGhlIGlucHV0IHRvIHRoaXMgbm9kZVxuICAgIGlmIChub2Rlc0NvbnN1bWluZ091dHB1dCAmJiBub2Rlc0NvbnN1bWluZ091dHB1dC5sZW5ndGggPiAwKSB7XG4gICAgICBmb3IgKGNvbnN0IG5vZGVJbmRleCBvZiBub2Rlc0NvbnN1bWluZ091dHB1dCkge1xuICAgICAgICBjb25zdCByZXBsYWNlSW5kZXggPSB0aGlzLl9ub2Rlc1tub2RlSW5kZXhdLmlucHV0cy5pbmRleE9mKG91dHB1dFZhbHVlSW5kZXgpO1xuICAgICAgICAvLyBzaG91bGQgbm90IGhhcHBlblxuICAgICAgICBpZiAocmVwbGFjZUluZGV4ID09PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBOb2RlIG9iamVjdCBkb2Vzbid0IGhhdmUgdGhlIG91dHB1dCBWYWx1ZSBpbiBpdCdzICdpbnB1dHMnIHByb3BlcnR5IFwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9ub2Rlc1tub2RlSW5kZXhdLmlucHV0c1tyZXBsYWNlSW5kZXhdID0gaW5wdXRWYWx1ZUluZGV4O1xuICAgICAgICB0aGlzLl9hbGxEYXRhW2lucHV0VmFsdWVJbmRleF0udG8ucHVzaChub2RlSW5kZXgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZUFsbERyb3BvdXROb2RlcygpIHtcbiAgICBsZXQgbm9kZUluZGV4ID0gMDtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fbm9kZXMpIHtcbiAgICAgIC8vIHdlZWQgb3V0ICdEcm9wb3V0JyBub2RlcyBzbyB0aGF0IG5vIHRpbWUgaXMgd2FzdGVkIGluIGV4ZWN1dGlvblxuICAgICAgaWYgKG5vZGUub3BUeXBlID09PSAnRHJvcG91dCcpIHtcbiAgICAgICAgLy8gdGhlIG5vZGUgc2hvdWxkIGhhdmUgZXhhY3RseSAxIGlucHV0IGFuZCAxIG9yIDIgb3V0cHV0c1xuICAgICAgICBpZiAobm9kZS5pbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEcm9wb3V0IG5vZGVzIHNob3VsZCBvbmx5IGNvbnRhaW4gb25lIGlucHV0LiAnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZS5vdXRwdXRzLmxlbmd0aCAhPT0gMSAmJiBub2RlLm91dHB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEcm9wb3V0IG5vZGVzIHNob3VsZCBjb250YWluIGVpdGhlciAxIG9yIDIgb3V0cHV0KHMpJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhlIHNlY29uZCBvdXRwdXQgc2hvdWxkIG5vdCBiZSByZWZlcmVuY2VkIGJ5IGFueSBvdGhlciBub2RlXG4gICAgICAgIGlmIChub2RlLm91dHB1dHMubGVuZ3RoID09PSAyICYmIHRoaXMuX2FsbERhdGFbbm9kZS5vdXRwdXRzWzFdXS5fdG8ubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRHJvcG91dCBub2RlcydzIHNlY29uZCBvdXRwdXQgc2hvdWxkIG5vdCBiZSByZWZlcmVuY2VkIGJ5IG90aGVyIG5vZGVzXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGVsZXRlTm9kZShub2RlSW5kZXgpO1xuICAgICAgfVxuICAgICAgbm9kZUluZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlQWxsSWRlbnRpdHlOb2RlcygpIHtcbiAgICBsZXQgbm9kZUluZGV4ID0gMDtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fbm9kZXMpIHtcbiAgICAgIC8vIHdlZWQgb3V0ICdJZGVudGl0eScgbm9kZXMgc28gdGhhdCBubyB0aW1lIGlzIHdhc3RlZCBpbiBleGVjdXRpb25cbiAgICAgIGlmIChub2RlLm9wVHlwZSA9PT0gJ0lkZW50aXR5Jykge1xuICAgICAgICB0aGlzLmRlbGV0ZU5vZGUobm9kZUluZGV4KTtcbiAgICAgIH1cbiAgICAgIG5vZGVJbmRleCsrO1xuICAgIH1cbiAgfVxuXG4gIGlzQWN0aXZhdGlvbihuOiBOb2RlKTogYm9vbGVhbiB7XG4gICAgc3dpdGNoIChuLm9wVHlwZSkge1xuICAgICAgLy8gVE9ETzogYWRkIG90aGVyIGFjdGl2YXRpb24gbWV0aG9kc1xuICAgICAgY2FzZSAnUmVsdSc6XG4gICAgICBjYXNlICdTaWdtb2lkJzpcbiAgICAgIGNhc2UgJ0NsaXAnOlxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBmdXNlQ29udkFjdGl2YXRpb25Ob2RlcygpIHtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fbm9kZXMpIHtcbiAgICAgIGlmIChub2RlLm9wVHlwZSA9PT0gJ0NvbnYnKSB7XG4gICAgICAgIGNvbnN0IG5leHQgPSB0aGlzLl9hbGxEYXRhW25vZGUub3V0cHV0c1swXV0uX3RvO1xuICAgICAgICBpZiAobmV4dC5sZW5ndGggPT09IDEgJiYgdGhpcy5pc0FjdGl2YXRpb24odGhpcy5fbm9kZXNbbmV4dFswXV0pKSB7XG4gICAgICAgICAgY29uc3QgY2hpbGQgPSB0aGlzLl9ub2Rlc1tuZXh0WzBdXTtcbiAgICAgICAgICBpZiAoY2hpbGQub3BUeXBlID09PSAnQ2xpcCcpIHtcbiAgICAgICAgICAgIGlmIChjaGlsZC5pbnB1dHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnNldCgnYWN0aXZhdGlvbl9wYXJhbXMnLCAnZmxvYXRzJywgW1xuICAgICAgICAgICAgICAgICAgY2hpbGQuYXR0cmlidXRlcy5nZXRGbG9hdCgnbWluJyksXG4gICAgICAgICAgICAgICAgICBjaGlsZC5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtYXgnKSxcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb25fcGFyYW1zJywgJ2Zsb2F0cycsIFtNSU5fQ0xJUCwgTUFYX0NMSVBdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgY2hpbGQuaW5wdXRzLmxlbmd0aCA+PSAzICYmXG4gICAgICAgICAgICAgIHRoaXMuX2FsbERhdGFbY2hpbGQuaW5wdXRzWzFdXS50ZW5zb3IgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1syXV0udGVuc29yICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuc2V0KCdhY3RpdmF0aW9uX3BhcmFtcycsICdmbG9hdHMnLCBbXG4gICAgICAgICAgICAgICAgdGhpcy5fYWxsRGF0YVtjaGlsZC5pbnB1dHNbMV1dLnRlbnNvciEuZmxvYXREYXRhWzBdLFxuICAgICAgICAgICAgICAgIHRoaXMuX2FsbERhdGFbY2hpbGQuaW5wdXRzWzJdXS50ZW5zb3IhLmZsb2F0RGF0YVswXSxcbiAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBTa2lwIGZ1c2lvbiB3aXRoIGNsaXAgbm9kZSBzaW5jZSBjbGlwIG1pbiBhbmQgY2xpcCBtYXggYXJlIG5vdCBjb21pbmcgZnJvbSBpbml0aWFsaXplclxuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnNldCgnYWN0aXZhdGlvbicsICdzdHJpbmcnLCBjaGlsZC5vcFR5cGUpO1xuICAgICAgICAgIHRoaXMuZGVsZXRlTm9kZShuZXh0WzBdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgKiBhcyBmbGF0YnVmZmVycyBmcm9tICdmbGF0YnVmZmVycyc7XG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQgeyBPcFNldCB9IGZyb20gJy4vb3BzZXQnO1xuaW1wb3J0ICogYXMgb3J0RmJzIGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7IG9ubnggfSBmcm9tICcuL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueCc7XG5pbXBvcnQgeyBMb25nVXRpbCB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBjbGFzcyBNb2RlbCB7XG4gIC8vIGVtcHR5IG1vZGVsXG4gIGNvbnN0cnVjdG9yKCkge31cblxuICBsb2FkKGJ1ZjogVWludDhBcnJheSwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyLCBpc09ydEZvcm1hdD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBsZXQgb25ueEVycm9yOiBFcnJvciB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIWlzT3J0Rm9ybWF0KSB7XG4gICAgICAvLyBpc09ydEZvcm1hdCA9PT0gZmFsc2UgfHwgaXNPcnRGb3JtYXQgPT09IHVuZGVmaW5lZFxuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5sb2FkRnJvbU9ubnhGb3JtYXQoYnVmLCBncmFwaEluaXRpYWxpemVyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoaXNPcnRGb3JtYXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgb25ueEVycm9yID0gZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5sb2FkRnJvbU9ydEZvcm1hdChidWYsIGdyYXBoSW5pdGlhbGl6ZXIpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChpc09ydEZvcm1hdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgICAvLyBUcmllZCBib3RoIGZvcm1hdHMgYW5kIGZhaWxlZCAod2hlbiBpc09ydEZvcm1hdCA9PT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbG9hZCBtb2RlbCBhcyBPTk5YIGZvcm1hdDogJHtvbm54RXJyb3J9XFxuYXMgT1JUIGZvcm1hdDogJHtlfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZyb21Pbm54Rm9ybWF0KGJ1ZjogVWludDhBcnJheSwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKTogdm9pZCB7XG4gICAgY29uc3QgbW9kZWxQcm90byA9IG9ubnguTW9kZWxQcm90by5kZWNvZGUoYnVmKTtcbiAgICBjb25zdCBpclZlcnNpb24gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIobW9kZWxQcm90by5pclZlcnNpb24pO1xuICAgIGlmIChpclZlcnNpb24gPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgc3VwcG9ydCBPTk5YIG1vZGVsIHdpdGggSVJfVkVSU0lPTj49MycpO1xuICAgIH1cblxuICAgIHRoaXMuX29wc2V0cyA9IG1vZGVsUHJvdG8ub3BzZXRJbXBvcnQubWFwKChpKSA9PiAoe1xuICAgICAgZG9tYWluOiBpLmRvbWFpbiBhcyBzdHJpbmcsXG4gICAgICB2ZXJzaW9uOiBMb25nVXRpbC5sb25nVG9OdW1iZXIoaS52ZXJzaW9uISksXG4gICAgfSkpO1xuXG4gICAgdGhpcy5fZ3JhcGggPSBHcmFwaC5mcm9tKG1vZGVsUHJvdG8uZ3JhcGghLCBncmFwaEluaXRpYWxpemVyKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZyb21PcnRGb3JtYXQoYnVmOiBVaW50OEFycmF5LCBncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBmYiA9IG5ldyBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKGJ1Zik7XG4gICAgY29uc3Qgb3J0TW9kZWwgPSBvcnRGYnMuSW5mZXJlbmNlU2Vzc2lvbi5nZXRSb290QXNJbmZlcmVuY2VTZXNzaW9uKGZiKS5tb2RlbCgpITtcbiAgICBjb25zdCBpclZlcnNpb24gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIob3J0TW9kZWwuaXJWZXJzaW9uKCkpO1xuICAgIGlmIChpclZlcnNpb24gPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgc3VwcG9ydCBPTk5YIG1vZGVsIHdpdGggSVJfVkVSU0lPTj49MycpO1xuICAgIH1cbiAgICB0aGlzLl9vcHNldHMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ydE1vZGVsLm9wc2V0SW1wb3J0TGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgb3BzZXRJZCA9IG9ydE1vZGVsLm9wc2V0SW1wb3J0KGkpITtcbiAgICAgIHRoaXMuX29wc2V0cy5wdXNoKHsgZG9tYWluOiBvcHNldElkPy5kb21haW4oKSBhcyBzdHJpbmcsIHZlcnNpb246IExvbmdVdGlsLmxvbmdUb051bWJlcihvcHNldElkLnZlcnNpb24oKSEpIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX2dyYXBoID0gR3JhcGguZnJvbShvcnRNb2RlbC5ncmFwaCgpISwgZ3JhcGhJbml0aWFsaXplcik7XG4gIH1cblxuICBwcml2YXRlIF9ncmFwaDogR3JhcGg7XG4gIGdldCBncmFwaCgpOiBHcmFwaCB7XG4gICAgcmV0dXJuIHRoaXMuX2dyYXBoO1xuICB9XG5cbiAgcHJpdmF0ZSBfb3BzZXRzOiBPcFNldFtdO1xuICBnZXQgb3BzZXRzKCk6IHJlYWRvbmx5IE9wU2V0W10ge1xuICAgIHJldHVybiB0aGlzLl9vcHNldHM7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgcmVzb2x2ZUJhY2tlbmQsIFNlc3Npb25IYW5kbGVyVHlwZSB9IGZyb20gJy4vYmFja2VuZCc7XG5pbXBvcnQgeyBFeGVjdXRpb25QbGFuIH0gZnJvbSAnLi9leGVjdXRpb24tcGxhbic7XG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHsgUHJvZmlsZXIgfSBmcm9tICcuL2luc3RydW1lbnQnO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tICcuL21vZGVsJztcbmltcG9ydCB7IE9wZXJhdG9yIH0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgU2Vzc2lvbiB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnIHtcbiAgICBiYWNrZW5kSGludD86IHN0cmluZztcbiAgICBwcm9maWxlcj86IFByb2ZpbGVyLkNvbmZpZztcbiAgfVxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29udGV4dCB7XG4gICAgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPjtcbiAgICBncmFwaElucHV0VHlwZXM/OiBUZW5zb3IuRGF0YVR5cGVbXTtcbiAgICBncmFwaElucHV0RGltcz86IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPjtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogU2Vzc2lvbi5Db25maWcgPSB7fSkge1xuICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgdGhpcy5iYWNrZW5kSGludCA9IGNvbmZpZy5iYWNrZW5kSGludDtcbiAgICB0aGlzLnByb2ZpbGVyID0gUHJvZmlsZXIuY3JlYXRlKGNvbmZpZy5wcm9maWxlcik7XG4gICAgdGhpcy5jb250ZXh0ID0geyBwcm9maWxlcjogdGhpcy5wcm9maWxlciwgZ3JhcGhJbnB1dFR5cGVzOiBbXSwgZ3JhcGhJbnB1dERpbXM6IFtdIH07XG4gIH1cblxuICBnZXQgaW5wdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX21vZGVsLmdyYXBoLmdldElucHV0TmFtZXMoKTtcbiAgfVxuICBnZXQgb3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9tb2RlbC5ncmFwaC5nZXRPdXRwdXROYW1lcygpO1xuICB9XG5cbiAgc3RhcnRQcm9maWxpbmcoKSB7XG4gICAgdGhpcy5wcm9maWxlci5zdGFydCgpO1xuICB9XG5cbiAgZW5kUHJvZmlsaW5nKCkge1xuICAgIHRoaXMucHJvZmlsZXIuc3RvcCgpO1xuICB9XG5cbiAgYXN5bmMgbG9hZE1vZGVsKHVyaTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPjtcbiAgYXN5bmMgbG9hZE1vZGVsKGJ1ZmZlcjogQXJyYXlCdWZmZXIsIGJ5dGVPZmZzZXQ/OiBudW1iZXIsIGxlbmd0aD86IG51bWJlcik6IFByb21pc2U8dm9pZD47XG4gIGFzeW5jIGxvYWRNb2RlbChidWZmZXI6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPHZvaWQ+O1xuICBhc3luYyBsb2FkTW9kZWwoYXJnOiBzdHJpbmcgfCBBcnJheUJ1ZmZlciB8IFVpbnQ4QXJyYXksIGJ5dGVPZmZzZXQ/OiBudW1iZXIsIGxlbmd0aD86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnU2Vzc2lvbi5sb2FkTW9kZWwnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyByZXNvbHZlIGJhY2tlbmQgYW5kIHNlc3Npb24gaGFuZGxlclxuICAgICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHJlc29sdmVCYWNrZW5kKHRoaXMuYmFja2VuZEhpbnQpO1xuICAgICAgdGhpcy5zZXNzaW9uSGFuZGxlciA9IGJhY2tlbmQuY3JlYXRlU2Vzc2lvbkhhbmRsZXIodGhpcy5jb250ZXh0KTtcblxuICAgICAgdGhpcy5fbW9kZWwgPSBuZXcgTW9kZWwoKTtcbiAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zdCBpc09ydEZvcm1hdCA9IGFyZy5lbmRzV2l0aCgnLm9ydCcpO1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MudmVyc2lvbnMgJiYgcHJvY2Vzcy52ZXJzaW9ucy5ub2RlKSB7XG4gICAgICAgICAgLy8gbm9kZVxuICAgICAgICAgIGNvbnN0IHsgcmVhZEZpbGUgfSA9IHJlcXVpcmUoJ25vZGU6ZnMvcHJvbWlzZXMnKTtcbiAgICAgICAgICBjb25zdCBidWYgPSBhd2FpdCByZWFkRmlsZShhcmcpO1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZShidWYsIGlzT3J0Rm9ybWF0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBicm93c2VyXG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChhcmcpO1xuICAgICAgICAgIGNvbnN0IGJ1ZiA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7XG4gICAgICAgICAgdGhpcy5pbml0aWFsaXplKG5ldyBVaW50OEFycmF5KGJ1ZiksIGlzT3J0Rm9ybWF0KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghQXJyYXlCdWZmZXIuaXNWaWV3KGFyZykpIHtcbiAgICAgICAgLy8gbG9hZCBtb2RlbCBmcm9tIEFycmF5QnVmZmVyXG4gICAgICAgIGNvbnN0IGFyciA9IG5ldyBVaW50OEFycmF5KGFyZywgYnl0ZU9mZnNldCB8fCAwLCBsZW5ndGggfHwgYXJnLmJ5dGVMZW5ndGgpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoYXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGxvYWQgbW9kZWwgZnJvbSBVaW50OGFycmF5XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZShhcmcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplKG1vZGVsUHJvdG9CbG9iOiBVaW50OEFycmF5LCBpc09ydEZvcm1hdD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBpbml0aWFsaXplZCcpO1xuICAgIH1cblxuICAgIHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnU2Vzc2lvbi5pbml0aWFsaXplJywgKCkgPT4ge1xuICAgICAgLy8gbG9hZCBncmFwaFxuICAgICAgY29uc3QgZ3JhcGhJbml0aWFsaXplciA9IHRoaXMuc2Vzc2lvbkhhbmRsZXIudHJhbnNmb3JtR3JhcGhcbiAgICAgICAgPyAodGhpcy5zZXNzaW9uSGFuZGxlciBhcyBHcmFwaC5Jbml0aWFsaXplcilcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLl9tb2RlbC5sb2FkKG1vZGVsUHJvdG9CbG9iLCBncmFwaEluaXRpYWxpemVyLCBpc09ydEZvcm1hdCk7XG5cbiAgICAgIC8vIGdyYXBoIGlzIGNvbXBsZXRlbHkgaW5pdGlhbHppZWQgYXQgdGhpcyBzdGFnZSAsIGxldCB0aGUgaW50ZXJlc3RlZCBoYW5kbGVycyBrbm93XG4gICAgICBpZiAodGhpcy5zZXNzaW9uSGFuZGxlci5vbkdyYXBoSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uSGFuZGxlci5vbkdyYXBoSW5pdGlhbGl6ZWQodGhpcy5fbW9kZWwuZ3JhcGgpO1xuICAgICAgfVxuICAgICAgLy8gaW5pdGlhbGl6ZSBlYWNoIG9wZXJhdG9yIGluIHRoZSBncmFwaFxuICAgICAgdGhpcy5pbml0aWFsaXplT3BzKHRoaXMuX21vZGVsLmdyYXBoKTtcblxuICAgICAgLy8gaW5zdGFudGlhdGUgYW4gRXhlY3V0aW9uUGxhbiBvYmplY3QgdG8gYmUgdXNlZCBieSB0aGUgU2Vzc2lvbiBvYmplY3RcbiAgICAgIHRoaXMuX2V4ZWN1dGlvblBsYW4gPSBuZXcgRXhlY3V0aW9uUGxhbih0aGlzLl9tb2RlbC5ncmFwaCwgdGhpcy5fb3BzLCB0aGlzLnByb2ZpbGVyKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX2luaXRpYWxpemVkID0gdHJ1ZTtcbiAgfVxuXG4gIGFzeW5jIHJ1bihpbnB1dHM6IE1hcDxzdHJpbmcsIFRlbnNvcj4gfCBUZW5zb3JbXSk6IFByb21pc2U8TWFwPHN0cmluZywgVGVuc29yPj4ge1xuICAgIGlmICghdGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2Vzc2lvbiBub3QgaW5pdGlhbGl6ZWQgeWV0Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnU2Vzc2lvbi5ydW4nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBpbnB1dFRlbnNvcnMgPSB0aGlzLm5vcm1hbGl6ZUFuZFZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgICAgIGNvbnN0IG91dHB1dFRlbnNvcnMgPSBhd2FpdCB0aGlzLl9leGVjdXRpb25QbGFuLmV4ZWN1dGUodGhpcy5zZXNzaW9uSGFuZGxlciwgaW5wdXRUZW5zb3JzKTtcblxuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlT3V0cHV0KG91dHB1dFRlbnNvcnMpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBub3JtYWxpemVBbmRWYWxpZGF0ZUlucHV0cyhpbnB1dHM6IE1hcDxzdHJpbmcsIFRlbnNvcj4gfCBUZW5zb3JbXSk6IFRlbnNvcltdIHtcbiAgICBjb25zdCBtb2RlbElucHV0TmFtZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRJbnB1dE5hbWVzKCk7XG5cbiAgICAvLyBub3JtYWxpemUgaW5wdXRzXG4gICAgLy8gaW5wdXRzOiBUZW5zb3JbXVxuICAgIGlmIChBcnJheS5pc0FycmF5KGlucHV0cykpIHtcbiAgICAgIGlmIChpbnB1dHMubGVuZ3RoICE9PSBtb2RlbElucHV0TmFtZXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5jb3JyZWN0IGlucHV0IGFycmF5IGxlbmd0aDogZXhwZWN0ZWQgJHttb2RlbElucHV0TmFtZXMubGVuZ3RofSBidXQgZ290ICR7aW5wdXRzLmxlbmd0aH1gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY29udmVydCBtYXAgdG8gYXJyYXlcbiAgICAvLyBpbnB1dHM6IE1hcDxzdHJpbmcsIFRlbnNvcj5cbiAgICBlbHNlIHtcbiAgICAgIGlmIChpbnB1dHMuc2l6ZSAhPT0gbW9kZWxJbnB1dE5hbWVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGluY29ycmVjdCBpbnB1dCBtYXAgc2l6ZTogZXhwZWN0ZWQgJHttb2RlbElucHV0TmFtZXMubGVuZ3RofSBidXQgZ290ICR7aW5wdXRzLnNpemV9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNvcnRlZElucHV0cyA9IG5ldyBBcnJheTxUZW5zb3I+KGlucHV0cy5zaXplKTtcbiAgICAgIGxldCBzb3J0ZWRJbnB1dHNJbmRleCA9IDA7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1vZGVsSW5wdXROYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICBjb25zdCB0ZW5zb3IgPSBpbnB1dHMuZ2V0KG1vZGVsSW5wdXROYW1lc1tpXSk7XG4gICAgICAgIGlmICghdGVuc29yKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGlucHV0IHRlbnNvciBmb3I6ICcke25hbWV9J2ApO1xuICAgICAgICB9XG4gICAgICAgIHNvcnRlZElucHV0c1tzb3J0ZWRJbnB1dHNJbmRleCsrXSA9IHRlbnNvcjtcbiAgICAgIH1cblxuICAgICAgaW5wdXRzID0gc29ydGVkSW5wdXRzO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIGRpbXMgcmVxdWlyZW1lbnRzXG4gICAgLy8gRmlyc3Qgc2Vzc2lvbiBydW4gLSBncmFwaCBpbnB1dCBkYXRhIGlzIG5vdCBjYWNoZWQgZm9yIHRoZSBzZXNzaW9uXG4gICAgaWYgKFxuICAgICAgIXRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMgfHxcbiAgICAgIHRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMubGVuZ3RoID09PSAwIHx8XG4gICAgICAhdGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zIHx8XG4gICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dERpbXMubGVuZ3RoID09PSAwXG4gICAgKSB7XG4gICAgICBjb25zdCBtb2RlbElucHV0SW5kaWNlcyA9IHRoaXMuX21vZGVsLmdyYXBoLmdldElucHV0SW5kaWNlcygpO1xuICAgICAgY29uc3QgbW9kZWxWYWx1ZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRWYWx1ZXMoKTtcblxuICAgICAgY29uc3QgZ3JhcGhJbnB1dERpbXMgPSBuZXcgQXJyYXk8cmVhZG9ubHkgbnVtYmVyW10+KG1vZGVsSW5wdXRJbmRpY2VzLmxlbmd0aCk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9kZWxJbnB1dEluZGljZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3QgZ3JhcGhJbnB1dCA9IG1vZGVsVmFsdWVzW21vZGVsSW5wdXRJbmRpY2VzW2ldXTtcbiAgICAgICAgZ3JhcGhJbnB1dERpbXNbaV0gPSBncmFwaElucHV0LnR5cGUhLnNoYXBlLmRpbXM7XG5cbiAgICAgICAgLy8gY2FjaGVkIGZvciBzZWNvbmQgYW5kIHN1YnNlcXVlbnQgcnVucy5cbiAgICAgICAgLy8gU29tZSBwYXJ0cyBvZiB0aGUgZnJhbWV3b3JrIHdvcmtzIG9uIHRoZSBhc3N1bXB0aW9uIHRoYXQgdGhlIGdyYXBoIGFuZCB0eXBlcyBhbmQgc2hhcGVzIGFyZSBzdGF0aWNcbiAgICAgICAgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXRUeXBlcyEucHVzaChncmFwaElucHV0LnR5cGUhLnRlbnNvclR5cGUpO1xuICAgICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dERpbXMhLnB1c2goaW5wdXRzW2ldLmRpbXMpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnZhbGlkYXRlSW5wdXRUZW5zb3JEaW1zKGdyYXBoSW5wdXREaW1zLCBpbnB1dHMsIHRydWUpO1xuICAgIH1cblxuICAgIC8vIFNlY29uZCBhbmQgc3Vic2VxdWVudCBzZXNzaW9uIHJ1bnMgLSBncmFwaCBpbnB1dCBkYXRhIGlzIGNhY2hlZCBmb3IgdGhlIHNlc3Npb25cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMudmFsaWRhdGVJbnB1dFRlbnNvckRpbXModGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zLCBpbnB1dHMsIGZhbHNlKTtcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSB0eXBlcyByZXF1aXJlbWVudFxuICAgIHRoaXMudmFsaWRhdGVJbnB1dFRlbnNvclR5cGVzKHRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMhLCBpbnB1dHMpO1xuXG4gICAgcmV0dXJuIGlucHV0cztcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVJbnB1dFRlbnNvclR5cGVzKGdyYXBoSW5wdXRUeXBlczogVGVuc29yLkRhdGFUeXBlW10sIGdpdmVuSW5wdXRzOiBUZW5zb3JbXSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ2l2ZW5JbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IGdyYXBoSW5wdXRUeXBlc1tpXTtcbiAgICAgIGNvbnN0IGFjdHVhbFR5cGUgPSBnaXZlbklucHV0c1tpXS50eXBlO1xuICAgICAgaWYgKGV4cGVjdGVkVHlwZSAhPT0gYWN0dWFsVHlwZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0IHRlbnNvclske2l9XSBjaGVjayBmYWlsZWQ6IGV4cGVjdGVkIHR5cGUgJyR7ZXhwZWN0ZWRUeXBlfScgYnV0IGdvdCAke2FjdHVhbFR5cGV9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUlucHV0VGVuc29yRGltcyhcbiAgICBncmFwaElucHV0RGltczogQXJyYXk8cmVhZG9ubHkgbnVtYmVyW10+LFxuICAgIGdpdmVuSW5wdXRzOiBUZW5zb3JbXSxcbiAgICBub25lRGltU3VwcG9ydGVkOiBib29sZWFuLFxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdpdmVuSW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBleHBlY3RlZERpbXMgPSBncmFwaElucHV0RGltc1tpXTtcbiAgICAgIGNvbnN0IGFjdHVhbERpbXMgPSBnaXZlbklucHV0c1tpXS5kaW1zO1xuICAgICAgaWYgKCF0aGlzLmNvbXBhcmVUZW5zb3JEaW1zKGV4cGVjdGVkRGltcywgYWN0dWFsRGltcywgbm9uZURpbVN1cHBvcnRlZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBpbnB1dCB0ZW5zb3JbJHtpfV0gY2hlY2sgZmFpbGVkOiBleHBlY3RlZCBzaGFwZSAnWyR7ZXhwZWN0ZWREaW1zLmpvaW4oJywnKX1dJyBidXQgZ290IFske2FjdHVhbERpbXMuam9pbihcbiAgICAgICAgICAgICcsJyxcbiAgICAgICAgICApfV1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29tcGFyZVRlbnNvckRpbXMoXG4gICAgZXhwZWN0ZWREaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBhY3R1YWxEaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBub25lRGltU3VwcG9ydGVkOiBib29sZWFuLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoZXhwZWN0ZWREaW1zLmxlbmd0aCAhPT0gYWN0dWFsRGltcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkRGltcy5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKGV4cGVjdGVkRGltc1tpXSAhPT0gYWN0dWFsRGltc1tpXSAmJiAoIW5vbmVEaW1TdXBwb3J0ZWQgfHwgZXhwZWN0ZWREaW1zW2ldICE9PSAwKSkge1xuICAgICAgICAvLyBkYXRhIHNoYXBlIG1pcy1tYXRjaCBBTkQgbm90IGEgJ05vbmUnIGRpbWVuc2lvbi5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVPdXRwdXQob3V0cHV0VGVuc29yczogVGVuc29yW10pOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHtcbiAgICBjb25zdCBtb2RlbE91dHB1dE5hbWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0T3V0cHV0TmFtZXMoKTtcbiAgICBpZiAob3V0cHV0VGVuc29ycy5sZW5ndGggIT09IG1vZGVsT3V0cHV0TmFtZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIG51bWJlciBvZiBvdXRwdXRzIGRvIG5vdCBtYXRjaCBudW1iZXIgb2YgZ2VuZXJhdGVkIG91dHB1dHMnKTtcbiAgICB9XG5cbiAgICBjb25zdCBvdXRwdXQgPSBuZXcgTWFwPHN0cmluZywgVGVuc29yPigpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9kZWxPdXRwdXROYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgb3V0cHV0LnNldChtb2RlbE91dHB1dE5hbWVzW2ldLCBvdXRwdXRUZW5zb3JzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplT3BzKGdyYXBoOiBHcmFwaCk6IHZvaWQge1xuICAgIGNvbnN0IG5vZGVzID0gZ3JhcGguZ2V0Tm9kZXMoKTtcbiAgICB0aGlzLl9vcHMgPSBuZXcgQXJyYXkobm9kZXMubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuX29wc1tpXSA9IHRoaXMuc2Vzc2lvbkhhbmRsZXIucmVzb2x2ZShub2Rlc1tpXSwgdGhpcy5fbW9kZWwub3BzZXRzLCBncmFwaCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfbW9kZWw6IE1vZGVsO1xuICBwcml2YXRlIF9pbml0aWFsaXplZDogYm9vbGVhbjtcblxuICBwcml2YXRlIF9vcHM6IE9wZXJhdG9yW107XG4gIHByaXZhdGUgX2V4ZWN1dGlvblBsYW46IEV4ZWN1dGlvblBsYW47XG5cbiAgcHJpdmF0ZSBiYWNrZW5kSGludD86IHN0cmluZztcblxuICBwcml2YXRlIHNlc3Npb25IYW5kbGVyOiBTZXNzaW9uSGFuZGxlclR5cGU7XG4gIHByaXZhdGUgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0O1xuICBwcml2YXRlIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj47XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24sIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyLCBTZXNzaW9uSGFuZGxlciwgVGVuc29yIH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vc2Vzc2lvbic7XG5pbXBvcnQgeyBUZW5zb3IgYXMgT25ueGpzVGVuc29yIH0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgY2xhc3MgT25ueGpzU2Vzc2lvbkhhbmRsZXIgaW1wbGVtZW50cyBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbikge1xuICAgIHRoaXMuaW5wdXROYW1lcyA9IHRoaXMuc2Vzc2lvbi5pbnB1dE5hbWVzO1xuICAgIHRoaXMub3V0cHV0TmFtZXMgPSB0aGlzLnNlc3Npb24ub3V0cHV0TmFtZXM7XG4gIH1cblxuICBnZXQgaW5wdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHZXR0aW5nIG1vZGVsIG1ldGFkYXRhIGlzIG5vdCBzdXBwb3J0ZWQgaW4gd2ViZ2wgYmFja2VuZC4nKTtcbiAgfVxuXG4gIGdldCBvdXRwdXRNZXRhZGF0YSgpOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHZXR0aW5nIG1vZGVsIG1ldGFkYXRhIGlzIG5vdCBzdXBwb3J0ZWQgaW4gd2ViZ2wgYmFja2VuZC4nKTtcbiAgfVxuXG4gIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7fVxuICBpbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgb3V0cHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBhc3luYyBydW4oXG4gICAgZmVlZHM6IFNlc3Npb25IYW5kbGVyLkZlZWRzVHlwZSxcbiAgICBfZmV0Y2hlczogU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUsXG4gICAgX29wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPiB7XG4gICAgY29uc3QgaW5wdXRNYXAgPSBuZXcgTWFwPHN0cmluZywgT25ueGpzVGVuc29yPigpO1xuICAgIGZvciAoY29uc3QgbmFtZSBpbiBmZWVkcykge1xuICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKGZlZWRzLCBuYW1lKSkge1xuICAgICAgICBjb25zdCBmZWVkID0gZmVlZHNbbmFtZV07XG4gICAgICAgIGlucHV0TWFwLnNldChcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIG5ldyBPbm54anNUZW5zb3IoXG4gICAgICAgICAgICBmZWVkLmRpbXMsXG4gICAgICAgICAgICBmZWVkLnR5cGUgYXMgT25ueGpzVGVuc29yLkRhdGFUeXBlLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgZmVlZC5kYXRhIGFzIE9ubnhqc1RlbnNvci5OdW1iZXJUeXBlLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IG91dHB1dE1hcCA9IGF3YWl0IHRoaXMuc2Vzc2lvbi5ydW4oaW5wdXRNYXApO1xuICAgIGNvbnN0IG91dHB1dDogU2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZSA9IHt9O1xuICAgIG91dHB1dE1hcC5mb3JFYWNoKCh0ZW5zb3IsIG5hbWUpID0+IHtcbiAgICAgIG91dHB1dFtuYW1lXSA9IG5ldyBUZW5zb3IodGVuc29yLnR5cGUsIHRlbnNvci5kYXRhLCB0ZW5zb3IuZGltcyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxuICBzdGFydFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLnNlc3Npb24uc3RhcnRQcm9maWxpbmcoKTtcbiAgfVxuICBlbmRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uLmVuZFByb2ZpbGluZygpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1pbnRlcm5hbC1tb2R1bGVzICovXG5pbXBvcnQgeyBCYWNrZW5kLCBJbmZlcmVuY2VTZXNzaW9uLCBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL29ubnhqcy9zZXNzaW9uJztcbmltcG9ydCB7IE9ubnhqc1Nlc3Npb25IYW5kbGVyIH0gZnJvbSAnLi9vbm54anMvc2Vzc2lvbi1oYW5kbGVyLWluZmVyZW5jZSc7XG5cbmNsYXNzIE9ubnhqc0JhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICBhc3luYyBpbml0KCk6IFByb21pc2U8dm9pZD4ge31cblxuICBhc3luYyBjcmVhdGVJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcihcbiAgICBwYXRoT3JCdWZmZXI6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXI+IHtcbiAgICAvLyBOT1RFOiBTZXNzaW9uLkNvbmZpZyhmcm9tIG9ubnguanMpIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyhmcm9tXG4gICAgLy8gb25ueHJ1bnRpbWUtY29tbW9uKS5cbiAgICAvLyAgICAgICBJbiBmdXR1cmUgd2Ugc2hvdWxkIHJlbW92ZSBTZXNzaW9uLkNvbmZpZyBhbmQgdXNlIEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMuXG4gICAgLy8gICAgICAgQ3VycmVudGx5IHdlIGFsbG93IHRoaXMgdG8gaGFwcGVuIHRvIG1ha2UgdGVzdCBydW5uZXIgd29yay5cbiAgICBjb25zdCBzZXNzaW9uID0gbmV3IFNlc3Npb24ob3B0aW9ucyBhcyB1bmtub3duIGFzIFNlc3Npb24uQ29uZmlnKTtcblxuICAgIC8vIHR5cGVzY3JpcHQgY2Fubm90IG1lcmdlIG1ldGhvZCBvdmVycmlkZSBjb3JyZWN0bHkgKHNvIGZhciBpbiA0LjIuMykuIG5lZWQgaWYtZWxzZSB0byBjYWxsIHRoZSBtZXRob2QuXG4gICAgaWYgKHR5cGVvZiBwYXRoT3JCdWZmZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBhd2FpdCBzZXNzaW9uLmxvYWRNb2RlbChwYXRoT3JCdWZmZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBzZXNzaW9uLmxvYWRNb2RlbChwYXRoT3JCdWZmZXIpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgT25ueGpzU2Vzc2lvbkhhbmRsZXIoc2Vzc2lvbik7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IG9ubnhqc0JhY2tlbmQgPSBuZXcgT25ueGpzQmFja2VuZCgpO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5leHBvcnQgY29uc3QgaXNOb2RlID0gISEodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MudmVyc2lvbnMgJiYgcHJvY2Vzcy52ZXJzaW9ucy5ub2RlKTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLy8vIDxyZWZlcmVuY2UgbGliPVwid2Vid29ya2VyXCIgLz5cblxuLy9cbi8vICogdHlwZSBoYWNrIGZvciBcIkhUTUxJbWFnZUVsZW1lbnRcIlxuLy9cbi8vIGluIHR5cGVzY3JpcHQsIHRoZSB0eXBlIG9mIFwiSFRNTEltYWdlRWxlbWVudFwiIGlzIGRlZmluZWQgaW4gbGliLmRvbS5kLnRzLCB3aGljaCBpcyBjb25mbGljdCB3aXRoIGxpYi53ZWJ3b3JrZXIuZC50cy5cbi8vIHdoZW4gd2UgdXNlIHdlYndvcmtlciwgdGhlIGxpYi53ZWJ3b3JrZXIuZC50cyB3aWxsIGJlIHVzZWQsIHdoaWNoIGRvZXMgbm90IGhhdmUgSFRNTEltYWdlRWxlbWVudCBkZWZpbmVkLlxuLy9cbi8vIHdlIHdpbGwgZ2V0IHRoZSBmb2xsb3dpbmcgZXJyb3JzIGNvbXBsYWluaW5nIHRoYXQgSFRNTEltYWdlRWxlbWVudCBpcyBub3QgZGVmaW5lZDpcbi8vXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy9cbi8vIC4uL2NvbW1vbi9kaXN0L2Nqcy90ZW5zb3ItZmFjdG9yeS5kLnRzOjE4NzoyOSAtIGVycm9yIFRTMjU1MjogQ2Fubm90IGZpbmQgbmFtZSAnSFRNTEltYWdlRWxlbWVudCcuIERpZCB5b3UgbWVhblxuLy8gJ0hUTUxMSUVsZW1lbnQnP1xuLy9cbi8vIDE4NyAgICAgZnJvbUltYWdlKGltYWdlRWxlbWVudDogSFRNTEltYWdlRWxlbWVudCwgb3B0aW9ucz86IFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zKTpcbi8vIFByb21pc2U8VHlwZWRUZW5zb3I8J2Zsb2F0MzInPiB8IFR5cGVkVGVuc29yPCd1aW50OCc+Pjtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfn5+fn5+fn5+fn5+fn5+flxuLy9cbi8vIG5vZGVfbW9kdWxlcy9Ad2ViZ3B1L3R5cGVzL2Rpc3QvaW5kZXguZC50czo4Mzo3IC0gZXJyb3IgVFMyNTUyOiBDYW5ub3QgZmluZCBuYW1lICdIVE1MSW1hZ2VFbGVtZW50Jy4gRGlkIHlvdSBtZWFuXG4vLyAnSFRNTExJRWxlbWVudCc/XG4vL1xuLy8gODMgICAgIHwgSFRNTEltYWdlRWxlbWVudFxuLy8gICAgICAgICAgfn5+fn5+fn5+fn5+fn5+flxuLy9cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vL1xuLy8gYEhUTUxJbWFnZUVsZW1lbnRgIGlzIG9ubHkgdXNlZCBpbiB0eXBlIGRlY2xhcmF0aW9uIGFuZCBub3QgaW4gcmVhbCBjb2RlLiBTbyB3ZSBkZWZpbmUgaXQgYXMgYHVua25vd25gIGhlcmUgdG9cbi8vIGJ5cGFzcyB0aGUgdHlwZSBjaGVjay5cblxuLy9cbi8vICogdHlwZSBoYWNrIGZvciBcImRvY3VtZW50XCJcbi8vXG4vLyBpbiB0eXBlc2NyaXB0LCB0aGUgdHlwZSBvZiBcImRvY3VtZW50XCIgaXMgZGVmaW5lZCBpbiBsaWIuZG9tLmQudHMsIHNvIGl0J3Mgbm90IGF2YWlsYWJsZSBpbiB3ZWJ3b3JrZXIuXG4vL1xuLy8gd2Ugd2lsbCBnZXQgdGhlIGZvbGxvd2luZyBlcnJvcnMgY29tcGxhaW5pbmcgdGhhdCBkb2N1bWVudCBpcyBub3QgZGVmaW5lZDpcbi8vXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy9cbi8vIGxpYi93YXNtL3dhc20tdXRpbHMtaW1wb3J0LnRzOjc6MzMgLSBlcnJvciBUUzI1ODQ6IENhbm5vdCBmaW5kIG5hbWUgJ2RvY3VtZW50Jy4gRG8geW91IG5lZWQgdG8gY2hhbmdlIHlvdXIgdGFyZ2V0XG4vLyBsaWJyYXJ5PyBUcnkgY2hhbmdpbmcgdGhlICdsaWInIGNvbXBpbGVyIG9wdGlvbiB0byBpbmNsdWRlICdkb20nLlxuLy9cbi8vIDcgZXhwb3J0IGNvbnN0IHNjcmlwdFNyYyA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgPyAoZG9jdW1lbnQ/LmN1cnJlbnRTY3JpcHQgYXMgSFRNTFNjcmlwdEVsZW1lbnQpPy5zcmMgOlxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5+fn5+fn5+XG4vL1xuLy8gbGliL3dhc20vd2FzbS11dGlscy1pbXBvcnQudHM6Nzo2MSAtIGVycm9yIFRTMjU4NDogQ2Fubm90IGZpbmQgbmFtZSAnZG9jdW1lbnQnLiBEbyB5b3UgbmVlZCB0byBjaGFuZ2UgeW91ciB0YXJnZXRcbi8vIGxpYnJhcnk/IFRyeSBjaGFuZ2luZyB0aGUgJ2xpYicgY29tcGlsZXIgb3B0aW9uIHRvIGluY2x1ZGUgJ2RvbScuXG4vL1xuLy8gNyBleHBvcnQgY29uc3Qgc2NyaXB0U3JjID0gdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyA/IChkb2N1bWVudD8uY3VycmVudFNjcmlwdCBhcyBIVE1MU2NyaXB0RWxlbWVudCk/LnNyYyA6XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5+fn5+fn5+XG4vL1xuLy8gbGliL3dhc20vd2FzbS11dGlscy1pbXBvcnQudHM6Nzo4OCAtIGVycm9yIFRTMjU1MjogQ2Fubm90IGZpbmQgbmFtZSAnSFRNTFNjcmlwdEVsZW1lbnQnLiBEaWQgeW91IG1lYW5cbi8vICdIVE1MTElFbGVtZW50Jz9cbi8vXG4vLyA3IGV4cG9ydCBjb25zdCBzY3JpcHRTcmMgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnID8gKGRvY3VtZW50Py5jdXJyZW50U2NyaXB0IGFzIEhUTUxTY3JpcHRFbGVtZW50KT8uc3JjIDpcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfn5+fn5+fn5+fn5+fn5+fn5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vL1xuLy8gYGRvY3VtZW50YCBpcyB1c2VkIHRvIGdldCB0aGUgY3VycmVudCBzY3JpcHQgVVJMLCB3aGljaCBpcyBub3QgYXZhaWxhYmxlIGluIHdlYndvcmtlci4gVGhpcyBmaWxlIGlzIHNlcnZlZCBhcyBhXG4vLyBcImR1YWxcIiBmaWxlIGZvciBlbnRyaWVzIG9mIGJvdGggd2Vid29ya2VyIGFuZCB0aGUgZXNtIG1vZHVsZS5cbi8vXG5kZWNsYXJlIGdsb2JhbCB7XG4gIHR5cGUgSFRNTEltYWdlRWxlbWVudCA9IHVua25vd247XG4gIHR5cGUgSFRNTFNjcmlwdEVsZW1lbnQgPSB7IHNyYz86IHN0cmluZyB9O1xuICBjb25zdCBkb2N1bWVudDogdW5kZWZpbmVkIHwgeyBjdXJyZW50U2NyaXB0PzogSFRNTFNjcmlwdEVsZW1lbnQgfTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeVxuICpcbiAqIFRoaXMgZmlsZSBpcyBzZXJ2ZWQgYXMgYSBcImR1YWxcIiBmaWxlIGZvciBib3RoIGVudHJpZXMgb2YgdGhlIGZvbGxvd2luZzpcbiAqIC0gVGhlIHByb3h5IHdvcmtlciBpdHNlbGYuXG4gKiAgIC0gV2hlbiB1c2VkIGFzIGEgd29ya2VyLCBpdCBsaXN0ZW5zIHRvIHRoZSBtZXNzYWdlcyBmcm9tIHRoZSBtYWluIHRocmVhZCBhbmQgcGVyZm9ybXMgdGhlIGNvcnJlc3BvbmRpbmcgb3BlcmF0aW9ucy5cbiAqICAgLSBTaG91bGQgYmUgaW1wb3J0ZWQgZGlyZWN0bHkgdXNpbmcgYG5ldyBXb3JrZXIoKWAgaW4gdGhlIG1haW4gdGhyZWFkLlxuICpcbiAqIC0gVGhlIEVTTSBtb2R1bGUgdGhhdCBjcmVhdGVzIHRoZSBwcm94eSB3b3JrZXIgKGFzIGEgd29ya2VyIGxhdW5jaGVyKS5cbiAqICAgLSBXaGVuIHVzZWQgYXMgYSB3b3JrZXIgbGF1bmNoZXIsIGl0IGNyZWF0ZXMgdGhlIHByb3h5IHdvcmtlciBhbmQgcmV0dXJucyBpdC5cbiAqICAgLSBTaG91bGQgYmUgaW1wb3J0ZWQgdXNpbmcgYGltcG9ydCgpYCBpbiB0aGUgbWFpbiB0aHJlYWQsIHdpdGggdGhlIHF1ZXJ5IHBhcmFtZXRlciBgaW1wb3J0PTFgLlxuICpcbiAqIFRoaXMgZmlsZSB3aWxsIGJlIGFsd2F5cyBjb21waWxpbmcgaW50byBFU00gZm9ybWF0LlxuICovXG5cbmltcG9ydCB0eXBlIHsgT3J0V2FzbU1lc3NhZ2UsIFNlcmlhbGl6YWJsZVRlbnNvck1ldGFkYXRhIH0gZnJvbSAnLi4vcHJveHktbWVzc2FnZXMuanMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlU2Vzc2lvbixcbiAgY29weUZyb21FeHRlcm5hbEJ1ZmZlcixcbiAgZW5kUHJvZmlsaW5nLFxuICBleHRyYWN0VHJhbnNmZXJhYmxlQnVmZmVycyxcbiAgaW5pdEVwLFxuICBpbml0UnVudGltZSxcbiAgcmVsZWFzZVNlc3Npb24sXG4gIHJ1bixcbn0gZnJvbSAnLi4vd2FzbS1jb3JlLWltcGwuanMnO1xuaW1wb3J0IHsgaW5pdGlhbGl6ZVdlYkFzc2VtYmx5IH0gZnJvbSAnLi4vd2FzbS1mYWN0b3J5LmpzJztcbmltcG9ydCB7IHNjcmlwdFNyYyB9IGZyb20gJy4uL3dhc20tdXRpbHMtaW1wb3J0LmpzJztcblxuY29uc3QgV09SS0VSX05BTUUgPSAnb3J0LXdhc20tcHJveHktd29ya2VyJztcbmNvbnN0IGlzUHJveHlXb3JrZXIgPSBnbG9iYWxUaGlzLnNlbGY/Lm5hbWUgPT09IFdPUktFUl9OQU1FO1xuXG5pZiAoaXNQcm94eVdvcmtlcikge1xuICAvLyBXb3JrZXIgdGhyZWFkXG4gIHNlbGYub25tZXNzYWdlID0gKGV2OiBNZXNzYWdlRXZlbnQ8T3J0V2FzbU1lc3NhZ2U+KTogdm9pZCA9PiB7XG4gICAgY29uc3QgeyB0eXBlLCBpbjogbWVzc2FnZSB9ID0gZXYuZGF0YTtcbiAgICB0cnkge1xuICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgJ2luaXQtd2FzbSc6XG4gICAgICAgICAgaW5pdGlhbGl6ZVdlYkFzc2VtYmx5KG1lc3NhZ2UhLndhc20pLnRoZW4oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIGluaXRSdW50aW1lKG1lc3NhZ2UhKS50aGVuKFxuICAgICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZSB9KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZSwgZXJyIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUsIGVyciB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnaW5pdC1lcCc6IHtcbiAgICAgICAgICBjb25zdCB7IGVwTmFtZSwgZW52IH0gPSBtZXNzYWdlITtcbiAgICAgICAgICBpbml0RXAoZW52LCBlcE5hbWUpLnRoZW4oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZSB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZSwgZXJyIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2NvcHktZnJvbSc6IHtcbiAgICAgICAgICBjb25zdCB7IGJ1ZmZlciB9ID0gbWVzc2FnZSE7XG4gICAgICAgICAgY29uc3QgYnVmZmVyRGF0YSA9IGNvcHlGcm9tRXh0ZXJuYWxCdWZmZXIoYnVmZmVyKTtcbiAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUsIG91dDogYnVmZmVyRGF0YSB9IGFzIE9ydFdhc21NZXNzYWdlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdjcmVhdGUnOiB7XG4gICAgICAgICAgY29uc3QgeyBtb2RlbCwgb3B0aW9ucyB9ID0gbWVzc2FnZSE7XG4gICAgICAgICAgY3JlYXRlU2Vzc2lvbihtb2RlbCwgb3B0aW9ucykudGhlbihcbiAgICAgICAgICAgIChzZXNzaW9uTWV0YWRhdGEpID0+IHtcbiAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlLCBvdXQ6IHNlc3Npb25NZXRhZGF0YSB9IGFzIE9ydFdhc21NZXNzYWdlKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZSwgZXJyIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ3JlbGVhc2UnOlxuICAgICAgICAgIHJlbGVhc2VTZXNzaW9uKG1lc3NhZ2UhKTtcbiAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3J1bic6IHtcbiAgICAgICAgICBjb25zdCB7IHNlc3Npb25JZCwgaW5wdXRJbmRpY2VzLCBpbnB1dHMsIG91dHB1dEluZGljZXMsIG9wdGlvbnMgfSA9IG1lc3NhZ2UhO1xuICAgICAgICAgIHJ1bihzZXNzaW9uSWQsIGlucHV0SW5kaWNlcywgaW5wdXRzLCBvdXRwdXRJbmRpY2VzLCBuZXcgQXJyYXkob3V0cHV0SW5kaWNlcy5sZW5ndGgpLmZpbGwobnVsbCksIG9wdGlvbnMpLnRoZW4oXG4gICAgICAgICAgICAob3V0cHV0cykgPT4ge1xuICAgICAgICAgICAgICBpZiAob3V0cHV0cy5zb21lKChvKSA9PiBvWzNdICE9PSAnY3B1JykpIHtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUsIGVycjogJ1Byb3h5IGRvZXMgbm90IHN1cHBvcnQgbm9uLWNwdSB0ZW5zb3IgbG9jYXRpb24uJyB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAgICAgIHsgdHlwZSwgb3V0OiBvdXRwdXRzIH0gYXMgT3J0V2FzbU1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICBleHRyYWN0VHJhbnNmZXJhYmxlQnVmZmVycyhbLi4uaW5wdXRzLCAuLi5vdXRwdXRzXSBhcyBTZXJpYWxpemFibGVUZW5zb3JNZXRhZGF0YVtdKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGUsIGVyciB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdlbmQtcHJvZmlsaW5nJzpcbiAgICAgICAgICBlbmRQcm9maWxpbmcobWVzc2FnZSEpO1xuICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZSB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZSwgZXJyIH0gYXMgT3J0V2FzbU1lc3NhZ2UpO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgaXNQcm94eVdvcmtlclxuICA/IG51bGxcbiAgOiAodXJsT3ZlcnJpZGU/OiBzdHJpbmcpID0+XG4gICAgICBuZXcgV29ya2VyKHVybE92ZXJyaWRlID8/IHNjcmlwdFNyYyEsIHsgdHlwZTogQlVJTERfREVGUy5JU19FU00gPyAnbW9kdWxlJyA6ICdjbGFzc2ljJywgbmFtZTogV09SS0VSX05BTUUgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB0eXBlIHsgT3J0V2FzbU1vZHVsZSB9IGZyb20gJy4vd2FzbS10eXBlcyc7XG5pbXBvcnQgeyBpc05vZGUgfSBmcm9tICcuL3dhc20tdXRpbHMtZW52JztcblxuLyoqXG4gKiBUaGUgb3JpZ2luIG9mIHRoZSBjdXJyZW50IGxvY2F0aW9uLlxuICpcbiAqIEluIE5vZGUuanMsIHRoaXMgaXMgdW5kZWZpbmVkLlxuICovXG5jb25zdCBvcmlnaW4gPSBpc05vZGUgfHwgdHlwZW9mIGxvY2F0aW9uID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGxvY2F0aW9uLm9yaWdpbjtcblxuLyoqXG4gKiBTb21lIGJ1bmRsZXJzIChlZy4gV2VicGFjaykgd2lsbCByZXdyaXRlIGBpbXBvcnQubWV0YS51cmxgIHRvIGEgZmlsZSBVUkwgYXQgY29tcGlsZSB0aW1lLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gY2hlY2tzIGlmIGBpbXBvcnQubWV0YS51cmxgIHN0YXJ0cyB3aXRoIGBmaWxlOmAsIGJ1dCB1c2luZyB0aGUgYD5gIGFuZCBgPGAgb3BlcmF0b3JzIGluc3RlYWQgb2ZcbiAqIGBzdGFydHNXaXRoYCBmdW5jdGlvbiBzbyB0aGF0IGNvZGUgbWluaW1pemVycyBjYW4gcmVtb3ZlIHRoZSBkZWFkIGNvZGUgY29ycmVjdGx5LlxuICpcbiAqIEZvciBleGFtcGxlLCBpZiB3ZSB1c2UgdGVyc2VyIHRvIG1pbmlmeSB0aGUgZm9sbG93aW5nIGNvZGU6XG4gKiBgYGBqc1xuICogaWYgKFwiZmlsZTovL2hhcmQtY29kZWQtZmlsZW5hbWVcIi5zdGFydHNXaXRoKFwiZmlsZTpcIikpIHtcbiAqICAgY29uc29sZS5sb2coMSlcbiAqIH0gZWxzZSB7XG4gKiAgIGNvbnNvbGUubG9nKDIpXG4gKiB9XG4gKlxuICogaWYgKFwiZmlsZTovL2hhcmQtY29kZWQtZmlsZW5hbWVcIiA+IFwiZmlsZTpcIiAmJiBcImZpbGU6Ly9oYXJkLWNvZGVkLWZpbGVuYW1lXCIgPCBcImZpbGU7XCIpIHtcbiAqICAgY29uc29sZS5sb2coMylcbiAqIH0gZWxzZSB7XG4gKiAgIGNvbnNvbGUubG9nKDQpXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgbWluaWZpZWQgY29kZSB3aWxsIGJlOlxuICogYGBganNcbiAqIFwiZmlsZTovL2hhcmQtY29kZWQtZmlsZW5hbWVcIi5zdGFydHNXaXRoKFwiZmlsZTpcIik/Y29uc29sZS5sb2coMSk6Y29uc29sZS5sb2coMiksY29uc29sZS5sb2coMyk7XG4gKiBgYGBcbiAqXG4gKiAodXNlIFRlcnNlciA1LjM5LjAgd2l0aCBkZWZhdWx0IG9wdGlvbnMsIGh0dHBzOi8vdHJ5LnRlcnNlci5vcmcvKVxuICpcbiAqIEByZXR1cm5zIHRydWUgaWYgdGhlIGltcG9ydC5tZXRhLnVybCBpcyBoYXJkY29kZWQgYXMgYSBmaWxlIFVSSS5cbiAqL1xuZXhwb3J0IGNvbnN0IGlzRXNtSW1wb3J0TWV0YVVybEhhcmRjb2RlZEFzRmlsZVVyaSA9XG4gIEJVSUxEX0RFRlMuSVNfRVNNICYmIEJVSUxEX0RFRlMuRVNNX0lNUE9SVF9NRVRBX1VSTCEgPiAnZmlsZTonICYmIEJVSUxEX0RFRlMuRVNNX0lNUE9SVF9NRVRBX1VSTCEgPCAnZmlsZTsnO1xuXG5jb25zdCBnZXRTY3JpcHRTcmMgPSAoKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgLy8gaWYgTm9kZWpzLCByZXR1cm4gdW5kZWZpbmVkXG4gIGlmIChpc05vZGUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIC8vIGlmIEl0J3MgRVNNLCB1c2UgaW1wb3J0Lm1ldGEudXJsXG4gIGlmIChCVUlMRF9ERUZTLklTX0VTTSkge1xuICAgIC8vIEZvciBFU00sIGlmIHRoZSBpbXBvcnQubWV0YS51cmwgaXMgYSBmaWxlIFVSTCwgdGhpcyB1c3VhbGx5IG1lYW5zIHRoZSBidW5kbGVyIHJld3JpdGVzIGBpbXBvcnQubWV0YS51cmxgIHRvXG4gICAgLy8gdGhlIGZpbGUgcGF0aCBhdCBjb21waWxlIHRpbWUuIEluIHRoaXMgY2FzZSwgdGhpcyBmaWxlIHBhdGggY2Fubm90IGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBydW50aW1lIFVSTC5cbiAgICAvL1xuICAgIC8vIFdlIG5lZWQgdG8gdXNlIHRoZSBVUkwgY29uc3RydWN0b3IgbGlrZSB0aGlzOlxuICAgIC8vIGBgYGpzXG4gICAgLy8gbmV3IFVSTCgnYWN0dWFsLWJ1bmRsZS1uYW1lLmpzJywgaW1wb3J0Lm1ldGEudXJsKS5ocmVmXG4gICAgLy8gYGBgXG4gICAgLy8gU28gdGhhdCBidW5kbGVyIGNhbiBwcmVwcm9jZXNzIHRoZSBVUkwgY29ycmVjdGx5LlxuICAgIGlmIChpc0VzbUltcG9ydE1ldGFVcmxIYXJkY29kZWRBc0ZpbGVVcmkpIHtcbiAgICAgIC8vIGlmIHRoZSByZXdyaXR0ZW4gVVJMIGlzIGEgcmVsYXRpdmUgcGF0aCwgd2UgbmVlZCB0byB1c2UgdGhlIG9yaWdpbiB0byByZXNvbHZlIHRoZSBVUkwuXG5cbiAgICAgIC8vIFRoZSBmb2xsb3dpbmcgaXMgYSB3b3JrYXJvdW5kIGZvciBWaXRlLlxuICAgICAgLy9cbiAgICAgIC8vIFZpdGUgdXNlcyBhIGJ1bmRsZXIocm9sbHVwL3JvbGxkb3duKSB0aGF0IGRvZXMgbm90IHJld3JpdGUgYGltcG9ydC5tZXRhLnVybGAgdG8gYSBmaWxlIFVSTC4gU28gaW4gdGhlb3J5LCB0aGlzXG4gICAgICAvLyBjb2RlIHBhdGggc2hvdWxkIG5vdCBiZSBleGVjdXRlZCBpbiBWaXRlLiBIb3dldmVyLCB0aGUgYnVuZGxlciBkb2VzIG5vdCBrbm93IGl0IGFuZCBpdCBzdGlsbCB0cnkgdG8gbG9hZCB0aGVcbiAgICAgIC8vIGZvbGxvd2luZyBwYXR0ZXJuOlxuICAgICAgLy8gLSBgcmV0dXJuIG5ldyBVUkwoJ2ZpbGVuYW1lJywgaW1wb3J0Lm1ldGEudXJsKS5ocmVmYFxuICAgICAgLy9cbiAgICAgIC8vIEJ5IHJlcGxhY2luZyB0aGUgcGF0dGVybiBhYm92ZSB3aXRoIHRoZSBmb2xsb3dpbmcgY29kZSwgd2UgY2FuIHNraXAgdGhlIHJlc291cmNlIGxvYWRpbmcgYmVoYXZpb3I6XG4gICAgICAvLyAtIGBjb25zdCBVUkwyID0gVVJMOyByZXR1cm4gbmV3IFVSTDIoJ2ZpbGVuYW1lJywgaW1wb3J0Lm1ldGEudXJsKS5ocmVmO2BcbiAgICAgIC8vXG4gICAgICAvLyBBbmQgaXQgc3RpbGwgd29ya3MgaW4gV2VicGFjay5cbiAgICAgIGNvbnN0IFVSTDIgPSBVUkw7XG4gICAgICByZXR1cm4gbmV3IFVSTChuZXcgVVJMMihCVUlMRF9ERUZTLkJVTkRMRV9GSUxFTkFNRSwgQlVJTERfREVGUy5FU01fSU1QT1JUX01FVEFfVVJMKS5ocmVmLCBvcmlnaW4pLmhyZWY7XG4gICAgfVxuXG4gICAgcmV0dXJuIEJVSUxEX0RFRlMuRVNNX0lNUE9SVF9NRVRBX1VSTDtcbiAgfVxuXG4gIHJldHVybiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnXG4gICAgPyAoZG9jdW1lbnQuY3VycmVudFNjcmlwdCBhcyBIVE1MU2NyaXB0RWxlbWVudCk/LnNyY1xuICAgIDogLy8gdXNlIGBzZWxmLmxvY2F0aW9uLmhyZWZgIGlmIGF2YWlsYWJsZVxuICAgICAgdHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnXG4gICAgICA/IHNlbGYubG9jYXRpb24/LmhyZWZcbiAgICAgIDogdW5kZWZpbmVkO1xufTtcblxuLyoqXG4gKiBUaGUgY2xhc3NpYyBzY3JpcHQgc291cmNlIFVSTC4gVGhpcyBpcyBub3QgYWx3YXlzIGF2YWlsYWJsZSBpbiBub24gRVNNb2R1bGUgZW52aXJvbm1lbnRzLlxuICpcbiAqIEluIE5vZGUuanMsIHRoaXMgaXMgdW5kZWZpbmVkLlxuICovXG5leHBvcnQgY29uc3Qgc2NyaXB0U3JjID0gZ2V0U2NyaXB0U3JjKCk7XG5cbi8qKlxuICogSW5mZXIgdGhlIHdhc20gcGF0aCBwcmVmaXggZnJvbSB0aGUgc2NyaXB0IHNvdXJjZSBVUkwuXG4gKlxuICogQHJldHVybnMgVGhlIGluZmVycmVkIHdhc20gcGF0aCBwcmVmaXgsIG9yIHVuZGVmaW5lZCBpZiB0aGUgc2NyaXB0IHNvdXJjZSBVUkwgaXMgbm90IGF2YWlsYWJsZSBvciBpcyBhIGJsb2IgVVJMLlxuICovXG5leHBvcnQgY29uc3QgaW5mZXJXYXNtUGF0aFByZWZpeEZyb21TY3JpcHRTcmMgPSAoKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgaWYgKHNjcmlwdFNyYyAmJiAhc2NyaXB0U3JjLnN0YXJ0c1dpdGgoJ2Jsb2I6JykpIHtcbiAgICByZXR1cm4gc2NyaXB0U3JjLnN1YnN0cmluZygwLCBzY3JpcHRTcmMubGFzdEluZGV4T2YoJy8nKSArIDEpO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRoZSBnaXZlbiBmaWxlbmFtZSB3aXRoIHByZWZpeCBpcyBmcm9tIHRoZSBzYW1lIG9yaWdpbi5cbiAqL1xuY29uc3QgaXNTYW1lT3JpZ2luID0gKGZpbGVuYW1lOiBzdHJpbmcsIHByZWZpeE92ZXJyaWRlPzogc3RyaW5nKSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgYmFzZVVybCA9IHByZWZpeE92ZXJyaWRlID8/IHNjcmlwdFNyYztcbiAgICBjb25zdCB1cmwgPSBiYXNlVXJsID8gbmV3IFVSTChmaWxlbmFtZSwgYmFzZVVybCkgOiBuZXcgVVJMKGZpbGVuYW1lKTtcbiAgICByZXR1cm4gdXJsLm9yaWdpbiA9PT0gb3JpZ2luO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbi8qKlxuICogTm9ybWFsaXplIHRoZSBpbnB1dHMgdG8gYW4gYWJzb2x1dGUgVVJMIHdpdGggdGhlIGdpdmVuIHByZWZpeCBvdmVycmlkZS4gSWYgZmFpbGVkLCByZXR1cm4gdW5kZWZpbmVkLlxuICovXG5jb25zdCBub3JtYWxpemVVcmwgPSAoZmlsZW5hbWU6IHN0cmluZywgcHJlZml4T3ZlcnJpZGU/OiBzdHJpbmcpID0+IHtcbiAgY29uc3QgYmFzZVVybCA9IHByZWZpeE92ZXJyaWRlID8/IHNjcmlwdFNyYztcbiAgdHJ5IHtcbiAgICBjb25zdCB1cmwgPSBiYXNlVXJsID8gbmV3IFVSTChmaWxlbmFtZSwgYmFzZVVybCkgOiBuZXcgVVJMKGZpbGVuYW1lKTtcbiAgICByZXR1cm4gdXJsLmhyZWY7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgZmFsbGJhY2sgVVJMIGlmIGFuIGFic29sdXRlIFVSTCBjYW5ub3QgYmUgY3JlYXRlZCBieSB0aGUgbm9ybWFsaXplVXJsIGZ1bmN0aW9uLlxuICovXG5jb25zdCBmYWxsYmFja1VybCA9IChmaWxlbmFtZTogc3RyaW5nLCBwcmVmaXhPdmVycmlkZT86IHN0cmluZykgPT4gYCR7cHJlZml4T3ZlcnJpZGUgPz8gJy4vJ30ke2ZpbGVuYW1lfWA7XG5cbi8qKlxuICogVGhpcyBoZWxwZXIgZnVuY3Rpb24gaXMgdXNlZCB0byBwcmVsb2FkIGEgbW9kdWxlIGZyb20gYSBVUkwuXG4gKlxuICogSWYgdGhlIG9yaWdpbiBvZiB0aGUgd29ya2VyIFVSTCBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgY3VycmVudCBvcmlnaW4sIHRoZSB3b3JrZXIgY2Fubm90IGJlIGxvYWRlZCBkaXJlY3RseS5cbiAqIFNlZSBkaXNjdXNzaW9ucyBpbiBodHRwczovL2dpdGh1Yi5jb20vd2VicGFjay1jb250cmliL3dvcmtlci1sb2FkZXIvaXNzdWVzLzE1NFxuICpcbiAqIEluIHRoaXMgY2FzZSwgd2Ugd2lsbCBmZXRjaCB0aGUgd29ya2VyIFVSTCBhbmQgY3JlYXRlIGEgbmV3IEJsb2IgVVJMIHdpdGggdGhlIHNhbWUgb3JpZ2luIGFzIGEgd29ya2Fyb3VuZC5cbiAqXG4gKiBAcGFyYW0gYWJzb2x1dGVVcmwgLSBUaGUgYWJzb2x1dGUgVVJMIHRvIHByZWxvYWQuXG4gKlxuICogQHJldHVybnMgLSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIG5ldyBCbG9iIFVSTFxuICovXG5jb25zdCBwcmVsb2FkID0gYXN5bmMgKGFic29sdXRlVXJsOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGFic29sdXRlVXJsLCB7IGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nIH0pO1xuICBjb25zdCBibG9iID0gYXdhaXQgcmVzcG9uc2UuYmxvYigpO1xuICByZXR1cm4gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbn07XG5cbi8qKlxuICogVGhpcyBoZWxwZXIgZnVuY3Rpb24gaXMgdXNlZCB0byBkeW5hbWljYWxseSBpbXBvcnQgYSBtb2R1bGUgZnJvbSBhIFVSTC5cbiAqXG4gKiBUaGUgYnVpbGQgc2NyaXB0IGhhcyBzcGVjaWFsIGhhbmRsaW5nIGZvciB0aGlzIGZ1bmN0aW9uIHRvIGVuc3VyZSB0aGF0IHRoZSBVUkwgaXMgbm90IGJ1bmRsZWQgaW50byB0aGUgZmluYWwgb3V0cHV0LlxuICpcbiAqIEBwYXJhbSB1cmwgLSBUaGUgVVJMIHRvIGltcG9ydC5cbiAqXG4gKiBAcmV0dXJucyAtIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkZWZhdWx0IGV4cG9ydCBvZiB0aGUgbW9kdWxlLlxuICovXG5jb25zdCBkeW5hbWljSW1wb3J0RGVmYXVsdCA9IGFzeW5jIDxUPih1cmw6IHN0cmluZyk6IFByb21pc2U8VD4gPT5cbiAgKGF3YWl0IGltcG9ydCgvKiB3ZWJwYWNrSWdub3JlOiB0cnVlICovIHVybCkpLmRlZmF1bHQ7XG5cbi8qKlxuICogVGhlIHByb3h5IHdvcmtlciBmYWN0b3J5IGltcG9ydGVkIGZyb20gdGhlIHByb3h5IHdvcmtlciBtb2R1bGUuXG4gKlxuICogVGhpcyBpcyBvbmx5IGF2YWlsYWJsZSB3aGVuIHRoZSBXZWJBc3NlbWJseSBwcm94eSBpcyBub3QgZGlzYWJsZWQuXG4gKi9cbmNvbnN0IGNyZWF0ZVByb3h5V29ya2VyOiAoKHVybE92ZXJyaWRlPzogc3RyaW5nKSA9PiBXb3JrZXIpIHwgdW5kZWZpbmVkID1cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMsIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXNcbiAgQlVJTERfREVGUy5ESVNBQkxFX1dBU01fUFJPWFkgPyB1bmRlZmluZWQgOiByZXF1aXJlKCcuL3Byb3h5LXdvcmtlci9tYWluJykuZGVmYXVsdDtcblxuLyoqXG4gKiBJbXBvcnQgdGhlIHByb3h5IHdvcmtlci5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgcGVyZm9ybSB0aGUgZm9sbG93aW5nIHN0ZXBzOlxuICogMS4gSWYgYSBwcmVsb2FkIGlzIG5lZWRlZCwgaXQgd2lsbCBwcmVsb2FkIHRoZSBtb2R1bGUgYW5kIHJldHVybiB0aGUgb2JqZWN0IFVSTC5cbiAqIDIuIFVzZSB0aGUgcHJveHkgd29ya2VyIGZhY3RvcnkgdG8gY3JlYXRlIHRoZSBwcm94eSB3b3JrZXIuXG4gKlxuICogQHJldHVybnMgLSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHR1cGxlIG9mIDIgZWxlbWVudHM6XG4gKiAgICAgICAgICAgIC0gVGhlIG9iamVjdCBVUkwgb2YgdGhlIHByZWxvYWRlZCBtb2R1bGUsIG9yIHVuZGVmaW5lZCBpZiBubyBwcmVsb2FkIGlzIG5lZWRlZC5cbiAqICAgICAgICAgICAgLSBUaGUgcHJveHkgd29ya2VyLlxuICovXG5leHBvcnQgY29uc3QgaW1wb3J0UHJveHlXb3JrZXIgPSBhc3luYyAoKTogUHJvbWlzZTxbdW5kZWZpbmVkIHwgc3RyaW5nLCBXb3JrZXJdPiA9PiB7XG4gIGlmICghc2NyaXB0U3JjKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gbG9hZCBwcm94eSB3b3JrZXI6IGNhbm5vdCBkZXRlcm1pbmUgdGhlIHNjcmlwdCBzb3VyY2UgVVJMLicpO1xuICB9XG5cbiAgLy8gSWYgdGhlIHNjcmlwdCBzb3VyY2UgaXMgZnJvbSB0aGUgc2FtZSBvcmlnaW4sIHdlIGNhbiB1c2UgdGhlIGVtYmVkZGVkIHByb3h5IG1vZHVsZSBkaXJlY3RseS5cbiAgaWYgKGlzU2FtZU9yaWdpbihzY3JpcHRTcmMpKSB7XG4gICAgcmV0dXJuIFt1bmRlZmluZWQsIGNyZWF0ZVByb3h5V29ya2VyISgpXTtcbiAgfVxuXG4gIC8vIE90aGVyd2lzZSwgbmVlZCB0byBwcmVsb2FkXG4gIGNvbnN0IHVybCA9IGF3YWl0IHByZWxvYWQoc2NyaXB0U3JjKTtcbiAgcmV0dXJuIFt1cmwsIGNyZWF0ZVByb3h5V29ya2VyISh1cmwpXTtcbn07XG5cbi8qKlxuICogVGhlIGVtYmVkZGVkIFdlYkFzc2VtYmx5IG1vZHVsZS5cbiAqXG4gKiBUaGlzIGlzIG9ubHkgYXZhaWxhYmxlIGluIEVTTSBhbmQgd2hlbiBlbWJlZGRpbmcgaXMgbm90IGRpc2FibGVkLlxuICovXG5jb25zdCBlbWJlZGRlZFdhc21Nb2R1bGU6IEVtc2NyaXB0ZW5Nb2R1bGVGYWN0b3J5PE9ydFdhc21Nb2R1bGU+IHwgdW5kZWZpbmVkID1cbiAgQlVJTERfREVGUy5JU19FU00gJiYgQlVJTERfREVGUy5FTkFCTEVfQlVORExFX1dBU01fSlNcbiAgICA/IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG4gICAgICByZXF1aXJlKFxuICAgICAgICAhQlVJTERfREVGUy5ESVNBQkxFX0pTRVBcbiAgICAgICAgICA/ICcuLi8uLi9kaXN0L29ydC13YXNtLXNpbWQtdGhyZWFkZWQuanNlcC5tanMnXG4gICAgICAgICAgOiAnLi4vLi4vZGlzdC9vcnQtd2FzbS1zaW1kLXRocmVhZGVkLm1qcycsXG4gICAgICApLmRlZmF1bHRcbiAgICA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBJbXBvcnQgdGhlIFdlYkFzc2VtYmx5IG1vZHVsZS5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgcGVyZm9ybSB0aGUgZm9sbG93aW5nIHN0ZXBzOlxuICogMS4gSWYgdGhlIGVtYmVkZGVkIG1vZHVsZSBleGlzdHMgYW5kIG5vIGN1c3RvbSBVUkwgaXMgc3BlY2lmaWVkLCB1c2UgdGhlIGVtYmVkZGVkIG1vZHVsZS5cbiAqIDIuIElmIGEgcHJlbG9hZCBpcyBuZWVkZWQsIGl0IHdpbGwgcHJlbG9hZCB0aGUgbW9kdWxlIGFuZCByZXR1cm4gdGhlIG9iamVjdCBVUkwuXG4gKiAzLiBPdGhlcndpc2UsIGl0IHdpbGwgcGVyZm9ybSBhIGR5bmFtaWMgaW1wb3J0IG9mIHRoZSBtb2R1bGUuXG4gKlxuICogQHJldHVybnMgLSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHR1cGxlIG9mIDIgZWxlbWVudHM6XG4gKiAgICAgICAgICAgIC0gVGhlIG9iamVjdCBVUkwgb2YgdGhlIHByZWxvYWRlZCBtb2R1bGUsIG9yIHVuZGVmaW5lZCBpZiBubyBwcmVsb2FkIGlzIG5lZWRlZC5cbiAqICAgICAgICAgICAgLSBUaGUgZGVmYXVsdCBleHBvcnQgb2YgdGhlIG1vZHVsZSwgd2hpY2ggaXMgYSBmYWN0b3J5IGZ1bmN0aW9uIHRvIGNyZWF0ZSB0aGUgV2ViQXNzZW1ibHkgbW9kdWxlLlxuICovXG5leHBvcnQgY29uc3QgaW1wb3J0V2FzbU1vZHVsZSA9IGFzeW5jIChcbiAgdXJsT3ZlcnJpZGU6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgcHJlZml4T3ZlcnJpZGU6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgaXNNdWx0aVRocmVhZGVkOiBib29sZWFuLFxuKTogUHJvbWlzZTxbdW5kZWZpbmVkIHwgc3RyaW5nLCBFbXNjcmlwdGVuTW9kdWxlRmFjdG9yeTxPcnRXYXNtTW9kdWxlPl0+ID0+IHtcbiAgaWYgKCF1cmxPdmVycmlkZSAmJiAhcHJlZml4T3ZlcnJpZGUgJiYgZW1iZWRkZWRXYXNtTW9kdWxlICYmIHNjcmlwdFNyYyAmJiBpc1NhbWVPcmlnaW4oc2NyaXB0U3JjKSkge1xuICAgIHJldHVybiBbdW5kZWZpbmVkLCBlbWJlZGRlZFdhc21Nb2R1bGVdO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHdhc21Nb2R1bGVGaWxlbmFtZSA9ICFCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUFxuICAgICAgPyAnb3J0LXdhc20tc2ltZC10aHJlYWRlZC5qc2VwLm1qcydcbiAgICAgIDogJ29ydC13YXNtLXNpbWQtdGhyZWFkZWQubWpzJztcbiAgICBjb25zdCB3YXNtTW9kdWxlVXJsID0gdXJsT3ZlcnJpZGUgPz8gbm9ybWFsaXplVXJsKHdhc21Nb2R1bGVGaWxlbmFtZSwgcHJlZml4T3ZlcnJpZGUpO1xuICAgIC8vIG5lZWQgdG8gcHJlbG9hZCBpZiBhbGwgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gICAgLy8gMS4gbm90IGluIE5vZGUuanMuXG4gICAgLy8gICAgLSBOb2RlLmpzIGRvZXMgbm90IGhhdmUgdGhlIHNhbWUgb3JpZ2luIHBvbGljeSBmb3IgY3JlYXRpbmcgd29ya2Vycy5cbiAgICAvLyAyLiBtdWx0aS10aHJlYWRlZCBpcyBlbmFibGVkLlxuICAgIC8vICAgIC0gSWYgbXVsdGktdGhyZWFkZWQgaXMgZGlzYWJsZWQsIG5vIHdvcmtlciB3aWxsIGJlIGNyZWF0ZWQuIFNvIHdlIGRvbid0IG5lZWQgdG8gcHJlbG9hZCB0aGUgbW9kdWxlLlxuICAgIC8vIDMuIHRoZSBhYnNvbHV0ZSBVUkwgaXMgYXZhaWxhYmxlLlxuICAgIC8vICAgIC0gSWYgdGhlIGFic29sdXRlIFVSTCBpcyBmYWlsZWQgdG8gYmUgY3JlYXRlZCwgdGhlIG9yaWdpbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZC4gSW4gdGhpcyBjYXNlLCB3ZSB3aWxsIG5vdFxuICAgIC8vICAgIHByZWxvYWQgdGhlIG1vZHVsZS5cbiAgICAvLyA0LiB0aGUgd29ya2VyIFVSTCBpcyBub3QgZnJvbSB0aGUgc2FtZSBvcmlnaW4uXG4gICAgLy8gICAgLSBJZiB0aGUgd29ya2VyIFVSTCBpcyBmcm9tIHRoZSBzYW1lIG9yaWdpbiwgd2UgY2FuIGNyZWF0ZSB0aGUgd29ya2VyIGRpcmVjdGx5LlxuICAgIGNvbnN0IG5lZWRQcmVsb2FkID0gIWlzTm9kZSAmJiBpc011bHRpVGhyZWFkZWQgJiYgd2FzbU1vZHVsZVVybCAmJiAhaXNTYW1lT3JpZ2luKHdhc21Nb2R1bGVVcmwsIHByZWZpeE92ZXJyaWRlKTtcbiAgICBjb25zdCB1cmwgPSBuZWVkUHJlbG9hZFxuICAgICAgPyBhd2FpdCBwcmVsb2FkKHdhc21Nb2R1bGVVcmwpXG4gICAgICA6ICh3YXNtTW9kdWxlVXJsID8/IGZhbGxiYWNrVXJsKHdhc21Nb2R1bGVGaWxlbmFtZSwgcHJlZml4T3ZlcnJpZGUpKTtcbiAgICByZXR1cm4gW25lZWRQcmVsb2FkID8gdXJsIDogdW5kZWZpbmVkLCBhd2FpdCBkeW5hbWljSW1wb3J0RGVmYXVsdDxFbXNjcmlwdGVuTW9kdWxlRmFjdG9yeTxPcnRXYXNtTW9kdWxlPj4odXJsKV07XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB0eXBlIHsgT3J0V2FzbU1vZHVsZSB9IGZyb20gJy4vd2FzbS10eXBlcyc7XG5pbXBvcnQgeyBpbXBvcnRXYXNtTW9kdWxlLCBpbmZlcldhc21QYXRoUHJlZml4RnJvbVNjcmlwdFNyYyB9IGZyb20gJy4vd2FzbS11dGlscy1pbXBvcnQnO1xuXG5sZXQgd2FzbTogT3J0V2FzbU1vZHVsZSB8IHVuZGVmaW5lZDtcbmxldCBpbml0aWFsaXplZCA9IGZhbHNlO1xubGV0IGluaXRpYWxpemluZyA9IGZhbHNlO1xubGV0IGFib3J0ZWQgPSBmYWxzZTtcblxuY29uc3QgaXNNdWx0aVRocmVhZFN1cHBvcnRlZCA9ICgpOiBib29sZWFuID0+IHtcbiAgLy8gSWYgJ1NoYXJlZEFycmF5QnVmZmVyJyBpcyBub3QgYXZhaWxhYmxlLCBXZWJBc3NlbWJseSB0aHJlYWRzIHdpbGwgbm90IHdvcmsuXG4gIGlmICh0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBUZXN0IGZvciB0cmFuc2ZlcmFiaWxpdHkgb2YgU0FCcyAoZm9yIGJyb3dzZXJzLiBuZWVkZWQgZm9yIEZpcmVmb3gpXG4gICAgLy8gaHR0cHM6Ly9ncm91cHMuZ29vZ2xlLmNvbS9mb3J1bS8jIW1zZy9tb3ppbGxhLmRldi5wbGF0Zm9ybS9JSGtCWmxIRVRwQS9kd3NNTmNoV0VRQUpcbiAgICBpZiAodHlwZW9mIE1lc3NhZ2VDaGFubmVsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgbmV3IE1lc3NhZ2VDaGFubmVsKCkucG9ydDEucG9zdE1lc3NhZ2UobmV3IFNoYXJlZEFycmF5QnVmZmVyKDEpKTtcbiAgICB9XG5cbiAgICAvLyBUZXN0IGZvciBXZWJBc3NlbWJseSB0aHJlYWRzIGNhcGFiaWxpdHkgKGZvciBib3RoIGJyb3dzZXJzIGFuZCBOb2RlLmpzKVxuICAgIC8vIFRoaXMgdHlwZWQgYXJyYXkgaXMgYSBXZWJBc3NlbWJseSBwcm9ncmFtIGNvbnRhaW5pbmcgdGhyZWFkZWQgaW5zdHJ1Y3Rpb25zLlxuICAgIHJldHVybiBXZWJBc3NlbWJseS52YWxpZGF0ZShcbiAgICAgIG5ldyBVaW50OEFycmF5KFtcbiAgICAgICAgMCwgOTcsIDExNSwgMTA5LCAxLCAwLCAwLCAwLCAxLCA0LCAxLCA5NiwgMCwgMCwgMywgMiwgMSwgMCwgNSwgNCwgMSwgMywgMSwgMSwgMTAsIDExLCAxLCA5LCAwLCA2NSwgMCwgMjU0LCAxNixcbiAgICAgICAgMiwgMCwgMjYsIDExLFxuICAgICAgXSksXG4gICAgKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuY29uc3QgaXNTaW1kU3VwcG9ydGVkID0gKCk6IGJvb2xlYW4gPT4ge1xuICB0cnkge1xuICAgIC8vIFRlc3QgZm9yIFdlYkFzc2VtYmx5IFNJTUQgY2FwYWJpbGl0eSAoZm9yIGJvdGggYnJvd3NlcnMgYW5kIE5vZGUuanMpXG4gICAgLy8gVGhpcyB0eXBlZCBhcnJheSBpcyBhIFdlYkFzc2VtYmx5IHByb2dyYW0gY29udGFpbmluZyBTSU1EIGluc3RydWN0aW9ucy5cblxuICAgIC8vIFRoZSBiaW5hcnkgZGF0YSBpcyBnZW5lcmF0ZWQgZnJvbSB0aGUgZm9sbG93aW5nIGNvZGUgYnkgd2F0Mndhc206XG4gICAgLy9cbiAgICAvLyAobW9kdWxlXG4gICAgLy8gICAodHlwZSAkdDAgKGZ1bmMpKVxuICAgIC8vICAgKGZ1bmMgJGYwICh0eXBlICR0MClcbiAgICAvLyAgICAgKGRyb3BcbiAgICAvLyAgICAgICAoaTMyeDQuZG90X2kxNng4X3NcbiAgICAvLyAgICAgICAgIChpOHgxNi5zcGxhdFxuICAgIC8vICAgICAgICAgICAoaTMyLmNvbnN0IDApKVxuICAgIC8vICAgICAgICAgKHYxMjguY29uc3QgaTMyeDQgMHgwMDAwMDAwMCAweDAwMDAwMDAwIDB4MDAwMDAwMDAgMHgwMDAwMDAwMCkpKSkpXG5cbiAgICByZXR1cm4gV2ViQXNzZW1ibHkudmFsaWRhdGUoXG4gICAgICBuZXcgVWludDhBcnJheShbXG4gICAgICAgIDAsIDk3LCAxMTUsIDEwOSwgMSwgMCwgMCwgMCwgMSwgNCwgMSwgOTYsIDAsIDAsIDMsIDIsIDEsIDAsIDEwLCAzMCwgMSwgMjgsIDAsIDY1LCAwLCAyNTMsIDE1LCAyNTMsIDEyLCAwLCAwLCAwLFxuICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAyNTMsIDE4NiwgMSwgMjYsIDExLFxuICAgICAgXSksXG4gICAgKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuY29uc3QgaXNSZWxheGVkU2ltZFN1cHBvcnRlZCA9ICgpOiBib29sZWFuID0+IHtcbiAgdHJ5IHtcbiAgICAvLyBUZXN0IGZvciBXZWJBc3NlbWJseSBSZWxheGVkIFNJTUQgY2FwYWJpbGl0eSAoZm9yIGJvdGggYnJvd3NlcnMgYW5kIE5vZGUuanMpXG4gICAgLy8gVGhpcyB0eXBlZCBhcnJheSBpcyBhIFdlYkFzc2VtYmx5IHByb2dyYW0gY29udGFpbmluZyBSZWxheGVkIFNJTUQgaW5zdHJ1Y3Rpb25zLlxuXG4gICAgLy8gVGhlIGJpbmFyeSBkYXRhIGlzIGdlbmVyYXRlZCBmcm9tIHRoZSBmb2xsb3dpbmcgY29kZSBieSB3YXQyd2FzbTpcbiAgICAvLyAobW9kdWxlXG4gICAgLy8gICAoZnVuYyAocmVzdWx0IHYxMjgpXG4gICAgLy8gICAgICBpMzIuY29uc3QgMVxuICAgIC8vICAgICAgaTh4MTYuc3BsYXRcbiAgICAvLyAgICAgIGkzMi5jb25zdCAyXG4gICAgLy8gICAgICBpOHgxNi5zcGxhdFxuICAgIC8vICAgICAgaTMyLmNvbnN0IDNcbiAgICAvLyAgICAgIGk4eDE2LnNwbGF0XG4gICAgLy8gICAgICBpMzJ4NC5yZWxheGVkX2RvdF9pOHgxNl9pN3gxNl9hZGRfc1xuICAgIC8vICAgKVxuICAgIC8vICApXG4gICAgcmV0dXJuIFdlYkFzc2VtYmx5LnZhbGlkYXRlKFxuICAgICAgbmV3IFVpbnQ4QXJyYXkoW1xuICAgICAgICAwLCA5NywgMTE1LCAxMDksIDEsIDAsIDAsIDAsIDEsIDUsIDEsIDk2LCAwLCAxLCAxMjMsIDMsIDIsIDEsIDAsIDEwLCAxOSwgMSwgMTcsIDAsIDY1LCAxLCAyNTMsIDE1LCA2NSwgMiwgMjUzLFxuICAgICAgICAxNSwgNjUsIDMsIDI1MywgMTUsIDI1MywgMTQ3LCAyLCAxMSxcbiAgICAgIF0pLFxuICAgICk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBpbml0aWFsaXplV2ViQXNzZW1ibHkgPSBhc3luYyAoZmxhZ3M6IEVudi5XZWJBc3NlbWJseUZsYWdzKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGlmIChpbml0aWFsaXplZCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICBpZiAoaW5pdGlhbGl6aW5nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwibXVsdGlwbGUgY2FsbHMgdG8gJ2luaXRpYWxpemVXZWJBc3NlbWJseSgpJyBkZXRlY3RlZC5cIik7XG4gIH1cbiAgaWYgKGFib3J0ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJwcmV2aW91cyBjYWxsIHRvICdpbml0aWFsaXplV2ViQXNzZW1ibHkoKScgZmFpbGVkLlwiKTtcbiAgfVxuXG4gIGluaXRpYWxpemluZyA9IHRydWU7XG5cbiAgLy8gd2FzbSBmbGFncyBhcmUgYWxyZWFkeSBpbml0aWFsaXplZFxuICBjb25zdCB0aW1lb3V0ID0gZmxhZ3MuaW5pdFRpbWVvdXQhO1xuICBsZXQgbnVtVGhyZWFkcyA9IGZsYWdzLm51bVRocmVhZHMhO1xuXG4gIC8vIGVuc3VyZSBTSU1EIGlzIHN1cHBvcnRlZFxuICBpZiAoZmxhZ3Muc2ltZCA9PT0gZmFsc2UpIHtcbiAgICAvLyBza2lwIFNJTUQgZmVhdHVyZSBjaGVja2luZyBhcyBpdCBpcyBkaXNhYmxlZCBleHBsaWNpdGx5IGJ5IHVzZXJcbiAgfSBlbHNlIGlmIChmbGFncy5zaW1kID09PSAncmVsYXhlZCcpIHtcbiAgICAvLyBjaGVjayBpZiByZWxheGVkIFNJTUQgaXMgc3VwcG9ydGVkXG4gICAgaWYgKCFpc1JlbGF4ZWRTaW1kU3VwcG9ydGVkKCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUmVsYXhlZCBXZWJBc3NlbWJseSBTSU1EIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuJyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFpc1NpbWRTdXBwb3J0ZWQoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignV2ViQXNzZW1ibHkgU0lNRCBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50LicpO1xuICB9XG5cbiAgLy8gY2hlY2sgaWYgbXVsdGktdGhyZWFkaW5nIGlzIHN1cHBvcnRlZFxuICBjb25zdCBtdWx0aVRocmVhZFN1cHBvcnRlZCA9IGlzTXVsdGlUaHJlYWRTdXBwb3J0ZWQoKTtcbiAgaWYgKG51bVRocmVhZHMgPiAxICYmICFtdWx0aVRocmVhZFN1cHBvcnRlZCkge1xuICAgIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgJiYgIXNlbGYuY3Jvc3NPcmlnaW5Jc29sYXRlZCkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ2Vudi53YXNtLm51bVRocmVhZHMgaXMgc2V0IHRvICcgK1xuICAgICAgICAgIG51bVRocmVhZHMgK1xuICAgICAgICAgICcsIGJ1dCB0aGlzIHdpbGwgbm90IHdvcmsgdW5sZXNzIHlvdSBlbmFibGUgY3Jvc3NPcmlnaW5Jc29sYXRlZCBtb2RlLiAnICtcbiAgICAgICAgICAnU2VlIGh0dHBzOi8vd2ViLmRldi9jcm9zcy1vcmlnaW4taXNvbGF0aW9uLWd1aWRlLyBmb3IgbW9yZSBpbmZvLicsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS53YXJuKFxuICAgICAgJ1dlYkFzc2VtYmx5IG11bHRpLXRocmVhZGluZyBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50LiAnICsgJ0ZhbGxpbmcgYmFjayB0byBzaW5nbGUtdGhyZWFkaW5nLicsXG4gICAgKTtcblxuICAgIC8vIHNldCBmbGFncy5udW1UaHJlYWRzIHRvIDEgc28gdGhhdCBPcnRJbml0KCkgd2lsbCBub3QgY3JlYXRlIGEgZ2xvYmFsIHRocmVhZCBwb29sLlxuICAgIGZsYWdzLm51bVRocmVhZHMgPSBudW1UaHJlYWRzID0gMTtcbiAgfVxuXG4gIGNvbnN0IHdhc21QYXRocyA9IGZsYWdzLndhc21QYXRocztcbiAgY29uc3Qgd2FzbVByZWZpeE92ZXJyaWRlID0gdHlwZW9mIHdhc21QYXRocyA9PT0gJ3N0cmluZycgPyB3YXNtUGF0aHMgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IG1qc1BhdGhPdmVycmlkZUZsYWcgPSAod2FzbVBhdGhzIGFzIEVudi5XYXNtRmlsZVBhdGhzKT8ubWpzO1xuICBjb25zdCBtanNQYXRoT3ZlcnJpZGUgPSAobWpzUGF0aE92ZXJyaWRlRmxhZyBhcyBVUkwpPy5ocmVmID8/IG1qc1BhdGhPdmVycmlkZUZsYWc7XG4gIGNvbnN0IHdhc21QYXRoT3ZlcnJpZGVGbGFnID0gKHdhc21QYXRocyBhcyBFbnYuV2FzbUZpbGVQYXRocyk/Lndhc207XG4gIGNvbnN0IHdhc21QYXRoT3ZlcnJpZGUgPSAod2FzbVBhdGhPdmVycmlkZUZsYWcgYXMgVVJMKT8uaHJlZiA/PyB3YXNtUGF0aE92ZXJyaWRlRmxhZztcbiAgY29uc3Qgd2FzbUJpbmFyeU92ZXJyaWRlID0gZmxhZ3Mud2FzbUJpbmFyeTtcblxuICBjb25zdCBbb2JqZWN0VXJsLCBvcnRXYXNtRmFjdG9yeV0gPSBhd2FpdCBpbXBvcnRXYXNtTW9kdWxlKG1qc1BhdGhPdmVycmlkZSwgd2FzbVByZWZpeE92ZXJyaWRlLCBudW1UaHJlYWRzID4gMSk7XG5cbiAgbGV0IGlzVGltZW91dCA9IGZhbHNlO1xuXG4gIGNvbnN0IHRhc2tzOiBBcnJheTxQcm9taXNlPHZvaWQ+PiA9IFtdO1xuXG4gIC8vIHByb21pc2UgZm9yIHRpbWVvdXRcbiAgaWYgKHRpbWVvdXQgPiAwKSB7XG4gICAgdGFza3MucHVzaChcbiAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGlzVGltZW91dCA9IHRydWU7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICAvLyBwcm9taXNlIGZvciBtb2R1bGUgaW5pdGlhbGl6YXRpb25cbiAgdGFza3MucHVzaChcbiAgICBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjb25maWc6IFBhcnRpYWw8T3J0V2FzbU1vZHVsZT4gPSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIHRocmVhZHMuIFdlYkFzc2VtYmx5IHdpbGwgY3JlYXRlIChNb2R1bGUubnVtVGhyZWFkcyAtIDEpIHdvcmtlcnMuIElmIGl0IGlzIDEsIG5vIHdvcmtlciB3aWxsIGJlXG4gICAgICAgICAqIGNyZWF0ZWQuXG4gICAgICAgICAqL1xuICAgICAgICBudW1UaHJlYWRzLFxuICAgICAgfTtcblxuICAgICAgaWYgKHdhc21CaW5hcnlPdmVycmlkZSkge1xuICAgICAgICAvLyBTZXQgYSBjdXN0b20gYnVmZmVyIHdoaWNoIGNvbnRhaW5zIHRoZSBXZWJBc3NlbWJseSBiaW5hcnkuIFRoaXMgd2lsbCBza2lwIHRoZSB3YXNtIGZpbGUgZmV0Y2hpbmcuXG4gICAgICAgIGNvbmZpZy53YXNtQmluYXJ5ID0gd2FzbUJpbmFyeU92ZXJyaWRlO1xuICAgICAgfSBlbHNlIGlmICh3YXNtUGF0aE92ZXJyaWRlIHx8IHdhc21QcmVmaXhPdmVycmlkZSkge1xuICAgICAgICAvLyBBIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGxvY2F0ZSB0aGUgV2ViQXNzZW1ibHkgZmlsZS4gVGhlIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gdGhlIGZ1bGwgcGF0aCBvZiB0aGUgZmlsZS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gU2luY2UgRW1zY3JpcHRlbiAzLjEuNTgsIHRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgZm9yIHRoZSAud2FzbSBmaWxlLlxuICAgICAgICBjb25maWcubG9jYXRlRmlsZSA9IChmaWxlTmFtZSkgPT4gd2FzbVBhdGhPdmVycmlkZSA/PyB3YXNtUHJlZml4T3ZlcnJpZGUgKyBmaWxlTmFtZTtcbiAgICAgIH0gZWxzZSBpZiAobWpzUGF0aE92ZXJyaWRlICYmIG1qc1BhdGhPdmVycmlkZS5pbmRleE9mKCdibG9iOicpICE9PSAwKSB7XG4gICAgICAgIC8vIGlmIG1qcyBwYXRoIGlzIHNwZWNpZmllZCwgdXNlIGl0IGFzIHRoZSBiYXNlIHBhdGggZm9yIHRoZSAud2FzbSBmaWxlLlxuICAgICAgICBjb25maWcubG9jYXRlRmlsZSA9IChmaWxlTmFtZSkgPT4gbmV3IFVSTChmaWxlTmFtZSwgbWpzUGF0aE92ZXJyaWRlKS5ocmVmO1xuICAgICAgfSBlbHNlIGlmIChvYmplY3RVcmwpIHtcbiAgICAgICAgY29uc3QgaW5mZXJyZWRXYXNtUGF0aFByZWZpeCA9IGluZmVyV2FzbVBhdGhQcmVmaXhGcm9tU2NyaXB0U3JjKCk7XG4gICAgICAgIGlmIChpbmZlcnJlZFdhc21QYXRoUHJlZml4KSB7XG4gICAgICAgICAgLy8gaWYgdGhlIHdhc20gbW9kdWxlIGlzIHByZWxvYWRlZCwgdXNlIHRoZSBpbmZlcnJlZCB3YXNtIHBhdGggYXMgdGhlIGJhc2UgcGF0aCBmb3IgdGhlIC53YXNtIGZpbGUuXG4gICAgICAgICAgY29uZmlnLmxvY2F0ZUZpbGUgPSAoZmlsZU5hbWUpID0+IGluZmVycmVkV2FzbVBhdGhQcmVmaXggKyBmaWxlTmFtZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBvcnRXYXNtRmFjdG9yeShjb25maWcpLnRoZW4oXG4gICAgICAgIC8vIHdhc20gbW9kdWxlIGluaXRpYWxpemVkIHN1Y2Nlc3NmdWxseVxuICAgICAgICAobW9kdWxlKSA9PiB7XG4gICAgICAgICAgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG4gICAgICAgICAgaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICAgIHdhc20gPSBtb2R1bGU7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIGlmIChvYmplY3RVcmwpIHtcbiAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwob2JqZWN0VXJsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIHdhc20gbW9kdWxlIGZhaWxlZCB0byBpbml0aWFsaXplXG4gICAgICAgICh3aGF0KSA9PiB7XG4gICAgICAgICAgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG4gICAgICAgICAgYWJvcnRlZCA9IHRydWU7XG4gICAgICAgICAgcmVqZWN0KHdoYXQpO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9KSxcbiAgKTtcblxuICBhd2FpdCBQcm9taXNlLnJhY2UodGFza3MpO1xuXG4gIGlmIChpc1RpbWVvdXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFdlYkFzc2VtYmx5IGJhY2tlbmQgaW5pdGlhbGl6aW5nIGZhaWxlZCBkdWUgdG8gdGltZW91dDogJHt0aW1lb3V0fW1zYCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBnZXRJbnN0YW5jZSA9ICgpOiBPcnRXYXNtTW9kdWxlID0+IHtcbiAgaWYgKGluaXRpYWxpemVkICYmIHdhc20pIHtcbiAgICByZXR1cm4gd2FzbTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignV2ViQXNzZW1ibHkgaXMgbm90IGluaXRpYWxpemVkIHlldC4nKTtcbn07XG5cbmV4cG9ydCBjb25zdCBkaXNwb3NlID0gKCk6IHZvaWQgPT4ge1xuICBpZiAoaW5pdGlhbGl6ZWQgJiYgIWluaXRpYWxpemluZyAmJiAhYWJvcnRlZCkge1xuICAgIC8vIFRPRE86IGN1cnJlbnRseSBcIlBUaHJlYWQudGVybWluYXRlQWxsVGhyZWFkcygpXCIgaXMgbm90IGV4cG9zZWQgaW4gdGhlIHdhc20gbW9kdWxlLlxuICAgIC8vICAgICAgIEFuZCB0aGlzIGZ1bmN0aW9uIGlzIG5vdCB5ZXQgY2FsbGVkIGJ5IGFueSBjb2RlLlxuICAgIC8vICAgICAgIElmIGl0IGlzIG5lZWRlZCBpbiB0aGUgZnV0dXJlLCB3ZSBzaG91bGQgZXhwb3NlIGl0IGluIHRoZSB3YXNtIG1vZHVsZSBhbmQgdW5jb21tZW50IHRoZSBmb2xsb3dpbmcgbGluZS5cblxuICAgIC8vIHdhc20/LlBUaHJlYWQ/LnRlcm1pbmF0ZUFsbFRocmVhZHMoKTtcbiAgICB3YXNtID0gdW5kZWZpbmVkO1xuXG4gICAgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG4gICAgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZ2V0SW5zdGFuY2UgfSBmcm9tICcuL3dhc20tZmFjdG9yeSc7XG5cbmV4cG9ydCBjb25zdCBhbGxvY1dhc21TdHJpbmcgPSAoZGF0YTogc3RyaW5nLCBhbGxvY3M6IG51bWJlcltdKTogbnVtYmVyID0+IHtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG5cbiAgY29uc3QgZGF0YUxlbmd0aCA9IHdhc20ubGVuZ3RoQnl0ZXNVVEY4KGRhdGEpICsgMTtcbiAgY29uc3QgZGF0YU9mZnNldCA9IHdhc20uX21hbGxvYyhkYXRhTGVuZ3RoKTtcbiAgd2FzbS5zdHJpbmdUb1VURjgoZGF0YSwgZGF0YU9mZnNldCwgZGF0YUxlbmd0aCk7XG4gIGFsbG9jcy5wdXNoKGRhdGFPZmZzZXQpO1xuXG4gIHJldHVybiBkYXRhT2Zmc2V0O1xufTtcblxuaW50ZXJmYWNlIEV4dHJhT3B0aW9uc0hhbmRsZXIge1xuICAobmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGNvbnN0IGl0ZXJhdGVFeHRyYU9wdGlvbnMgPSAoXG4gIG9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBwcmVmaXg6IHN0cmluZyxcbiAgc2VlbjogV2Vha1NldDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sXG4gIGhhbmRsZXI6IEV4dHJhT3B0aW9uc0hhbmRsZXIsXG4pOiB2b2lkID0+IHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09ICdvYmplY3QnICYmIG9wdGlvbnMgIT09IG51bGwpIHtcbiAgICBpZiAoc2Vlbi5oYXMob3B0aW9ucykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2lyY3VsYXIgcmVmZXJlbmNlIGluIG9wdGlvbnMnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2Vlbi5hZGQob3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgT2JqZWN0LmVudHJpZXMob3B0aW9ucykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IHByZWZpeCA/IHByZWZpeCArIGtleSA6IGtleTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgaXRlcmF0ZUV4dHJhT3B0aW9ucyh2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgbmFtZSArICcuJywgc2VlbiwgaGFuZGxlcik7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGhhbmRsZXIobmFtZSwgdmFsdWUudG9TdHJpbmcoKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgaGFuZGxlcihuYW1lLCB2YWx1ZSA/ICcxJyA6ICcwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3QgaGFuZGxlIGV4dHJhIGNvbmZpZyB0eXBlOiAke3R5cGVvZiB2YWx1ZX1gKTtcbiAgICB9XG4gIH0pO1xufTtcblxuLyoqXG4gKiBjaGVjayB3ZWIgYXNzZW1ibHkgQVBJJ3MgbGFzdCBlcnJvciBhbmQgdGhyb3cgZXJyb3IgaWYgYW55IGVycm9yIG9jY3VycmVkLlxuICogQHBhcmFtIG1lc3NhZ2UgYSBtZXNzYWdlIHVzZWQgd2hlbiBhbiBlcnJvciBvY2N1cnJlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IGNoZWNrTGFzdEVycm9yID0gKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQgPT4ge1xuICBjb25zdCB3YXNtID0gZ2V0SW5zdGFuY2UoKTtcblxuICBjb25zdCBzdGFjayA9IHdhc20uc3RhY2tTYXZlKCk7XG4gIHRyeSB7XG4gICAgY29uc3QgcHRyU2l6ZSA9IHdhc20uUFRSX1NJWkU7XG4gICAgY29uc3QgcGFyYW1zT2Zmc2V0ID0gd2FzbS5zdGFja0FsbG9jKDIgKiBwdHJTaXplKTtcbiAgICB3YXNtLl9PcnRHZXRMYXN0RXJyb3IocGFyYW1zT2Zmc2V0LCBwYXJhbXNPZmZzZXQgKyBwdHJTaXplKTtcbiAgICBjb25zdCBlcnJvckNvZGUgPSBOdW1iZXIod2FzbS5nZXRWYWx1ZShwYXJhbXNPZmZzZXQsIHB0clNpemUgPT09IDQgPyAnaTMyJyA6ICdpNjQnKSk7XG4gICAgY29uc3QgZXJyb3JNZXNzYWdlUG9pbnRlciA9IHdhc20uZ2V0VmFsdWUocGFyYW1zT2Zmc2V0ICsgcHRyU2l6ZSwgJyonKTtcbiAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvck1lc3NhZ2VQb2ludGVyID8gd2FzbS5VVEY4VG9TdHJpbmcoZXJyb3JNZXNzYWdlUG9pbnRlcikgOiAnJztcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bWVzc2FnZX0gRVJST1JfQ09ERTogJHtlcnJvckNvZGV9LCBFUlJPUl9NRVNTQUdFOiAke2Vycm9yTWVzc2FnZX1gKTtcbiAgfSBmaW5hbGx5IHtcbiAgICB3YXNtLnN0YWNrUmVzdG9yZShzdGFjayk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEluZmVyZW5jZVNlc3Npb24gfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBnZXRJbnN0YW5jZSB9IGZyb20gJy4vd2FzbS1mYWN0b3J5JztcbmltcG9ydCB7IGFsbG9jV2FzbVN0cmluZywgY2hlY2tMYXN0RXJyb3IsIGl0ZXJhdGVFeHRyYU9wdGlvbnMgfSBmcm9tICcuL3dhc20tdXRpbHMnO1xuXG5leHBvcnQgY29uc3Qgc2V0UnVuT3B0aW9ucyA9IChvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMpOiBbbnVtYmVyLCBudW1iZXJbXV0gPT4ge1xuICBjb25zdCB3YXNtID0gZ2V0SW5zdGFuY2UoKTtcbiAgbGV0IHJ1bk9wdGlvbnNIYW5kbGUgPSAwO1xuICBjb25zdCBhbGxvY3M6IG51bWJlcltdID0gW107XG5cbiAgY29uc3QgcnVuT3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB0cnkge1xuICAgIGlmIChvcHRpb25zPy5sb2dTZXZlcml0eUxldmVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJ1bk9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCA9IDI7IC8vIERlZmF1bHQgdG8gd2FybmluZ1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0eXBlb2Ygb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsICE9PSAnbnVtYmVyJyB8fFxuICAgICAgIU51bWJlci5pc0ludGVnZXIob3B0aW9ucy5sb2dTZXZlcml0eUxldmVsKSB8fFxuICAgICAgb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsIDwgMCB8fFxuICAgICAgb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsID4gNFxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBsb2cgc2VydmVyaXR5IGxldmVsIGlzIG5vdCB2YWxpZDogJHtvcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWx9YCk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnM/LmxvZ1ZlcmJvc2l0eUxldmVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJ1bk9wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWwgPSAwOyAvLyBEZWZhdWx0IHRvIDBcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsICE9PSAnbnVtYmVyJyB8fCAhTnVtYmVyLmlzSW50ZWdlcihvcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBsb2cgdmVyYm9zaXR5IGxldmVsIGlzIG5vdCB2YWxpZDogJHtvcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsfWApO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zPy50ZXJtaW5hdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcnVuT3B0aW9ucy50ZXJtaW5hdGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgdGFnRGF0YU9mZnNldCA9IDA7XG4gICAgaWYgKG9wdGlvbnM/LnRhZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YWdEYXRhT2Zmc2V0ID0gYWxsb2NXYXNtU3RyaW5nKG9wdGlvbnMudGFnLCBhbGxvY3MpO1xuICAgIH1cblxuICAgIHJ1bk9wdGlvbnNIYW5kbGUgPSB3YXNtLl9PcnRDcmVhdGVSdW5PcHRpb25zKFxuICAgICAgcnVuT3B0aW9ucy5sb2dTZXZlcml0eUxldmVsISxcbiAgICAgIHJ1bk9wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWwhLFxuICAgICAgISFydW5PcHRpb25zLnRlcm1pbmF0ZSEsXG4gICAgICB0YWdEYXRhT2Zmc2V0LFxuICAgICk7XG4gICAgaWYgKHJ1bk9wdGlvbnNIYW5kbGUgPT09IDApIHtcbiAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgY3JlYXRlIHJ1biBvcHRpb25zLlwiKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8uZXh0cmEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaXRlcmF0ZUV4dHJhT3B0aW9ucyhvcHRpb25zLmV4dHJhLCAnJywgbmV3IFdlYWtTZXQ8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KCksIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICAgIGNvbnN0IGtleURhdGFPZmZzZXQgPSBhbGxvY1dhc21TdHJpbmcoa2V5LCBhbGxvY3MpO1xuICAgICAgICBjb25zdCB2YWx1ZURhdGFPZmZzZXQgPSBhbGxvY1dhc21TdHJpbmcodmFsdWUsIGFsbG9jcyk7XG5cbiAgICAgICAgaWYgKHdhc20uX09ydEFkZFJ1bkNvbmZpZ0VudHJ5KHJ1bk9wdGlvbnNIYW5kbGUsIGtleURhdGFPZmZzZXQsIHZhbHVlRGF0YU9mZnNldCkgIT09IDApIHtcbiAgICAgICAgICBjaGVja0xhc3RFcnJvcihgQ2FuJ3Qgc2V0IGEgcnVuIGNvbmZpZyBlbnRyeTogJHtrZXl9IC0gJHt2YWx1ZX0uYCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBbcnVuT3B0aW9uc0hhbmRsZSwgYWxsb2NzXTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChydW5PcHRpb25zSGFuZGxlICE9PSAwKSB7XG4gICAgICB3YXNtLl9PcnRSZWxlYXNlUnVuT3B0aW9ucyhydW5PcHRpb25zSGFuZGxlKTtcbiAgICB9XG4gICAgYWxsb2NzLmZvckVhY2goKGFsbG9jKSA9PiB3YXNtLl9mcmVlKGFsbG9jKSk7XG4gICAgdGhyb3cgZTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHR5cGUgeyBJbmZlcmVuY2VTZXNzaW9uIH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgZ2V0SW5zdGFuY2UgfSBmcm9tICcuL3dhc20tZmFjdG9yeSc7XG5pbXBvcnQgeyBhbGxvY1dhc21TdHJpbmcsIGNoZWNrTGFzdEVycm9yLCBpdGVyYXRlRXh0cmFPcHRpb25zIH0gZnJvbSAnLi93YXNtLXV0aWxzJztcblxuY29uc3QgZ2V0R3JhcGhPcHRpbXphdGlvbkxldmVsID0gKGdyYXBoT3B0aW1pemF0aW9uTGV2ZWw6IHN0cmluZyB8IHVua25vd24pOiBudW1iZXIgPT4ge1xuICBzd2l0Y2ggKGdyYXBoT3B0aW1pemF0aW9uTGV2ZWwpIHtcbiAgICBjYXNlICdkaXNhYmxlZCc6XG4gICAgICByZXR1cm4gMDtcbiAgICBjYXNlICdiYXNpYyc6XG4gICAgICByZXR1cm4gMTtcbiAgICBjYXNlICdleHRlbmRlZCc6XG4gICAgICByZXR1cm4gMjtcbiAgICBjYXNlICdhbGwnOlxuICAgICAgcmV0dXJuIDk5O1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGdyYXBoIG9wdGltaXphdGlvbiBsZXZlbDogJHtncmFwaE9wdGltaXphdGlvbkxldmVsfWApO1xuICB9XG59O1xuXG5jb25zdCBnZXRFeGVjdXRpb25Nb2RlID0gKGV4ZWN1dGlvbk1vZGU6ICdzZXF1ZW50aWFsJyB8ICdwYXJhbGxlbCcpOiBudW1iZXIgPT4ge1xuICBzd2l0Y2ggKGV4ZWN1dGlvbk1vZGUpIHtcbiAgICBjYXNlICdzZXF1ZW50aWFsJzpcbiAgICAgIHJldHVybiAwO1xuICAgIGNhc2UgJ3BhcmFsbGVsJzpcbiAgICAgIHJldHVybiAxO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGV4ZWN1dGlvbiBtb2RlOiAke2V4ZWN1dGlvbk1vZGV9YCk7XG4gIH1cbn07XG5cbmNvbnN0IGFwcGVuZERlZmF1bHRPcHRpb25zID0gKG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiB2b2lkID0+IHtcbiAgaWYgKCFvcHRpb25zLmV4dHJhKSB7XG4gICAgb3B0aW9ucy5leHRyYSA9IHt9O1xuICB9XG4gIGlmICghb3B0aW9ucy5leHRyYS5zZXNzaW9uKSB7XG4gICAgb3B0aW9ucy5leHRyYS5zZXNzaW9uID0ge307XG4gIH1cbiAgY29uc3Qgc2Vzc2lvbiA9IG9wdGlvbnMuZXh0cmEuc2Vzc2lvbiBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICBpZiAoIXNlc3Npb24udXNlX29ydF9tb2RlbF9ieXRlc19kaXJlY3RseSkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjYW1lbGNhc2VcbiAgICBzZXNzaW9uLnVzZV9vcnRfbW9kZWxfYnl0ZXNfZGlyZWN0bHkgPSAnMSc7XG4gIH1cblxuICAvLyBpZiB1c2luZyBKU0VQIHdpdGggV2ViR1BVLCBhbHdheXMgZGlzYWJsZSBtZW1vcnkgcGF0dGVyblxuICBpZiAoXG4gICAgb3B0aW9ucy5leGVjdXRpb25Qcm92aWRlcnMgJiZcbiAgICBvcHRpb25zLmV4ZWN1dGlvblByb3ZpZGVycy5zb21lKChlcCkgPT4gKHR5cGVvZiBlcCA9PT0gJ3N0cmluZycgPyBlcCA6IGVwLm5hbWUpID09PSAnd2ViZ3B1JylcbiAgKSB7XG4gICAgb3B0aW9ucy5lbmFibGVNZW1QYXR0ZXJuID0gZmFsc2U7XG4gIH1cbn07XG5cbmNvbnN0IGFwcGVuZFNlc3Npb25Db25maWcgPSAoc2Vzc2lvbk9wdGlvbnNIYW5kbGU6IG51bWJlciwga2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIGFsbG9jczogbnVtYmVyW10pOiB2b2lkID0+IHtcbiAgY29uc3Qga2V5RGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyhrZXksIGFsbG9jcyk7XG4gIGNvbnN0IHZhbHVlRGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyh2YWx1ZSwgYWxsb2NzKTtcbiAgaWYgKGdldEluc3RhbmNlKCkuX09ydEFkZFNlc3Npb25Db25maWdFbnRyeShzZXNzaW9uT3B0aW9uc0hhbmRsZSwga2V5RGF0YU9mZnNldCwgdmFsdWVEYXRhT2Zmc2V0KSAhPT0gMCkge1xuICAgIGNoZWNrTGFzdEVycm9yKGBDYW4ndCBzZXQgYSBzZXNzaW9uIGNvbmZpZyBlbnRyeTogJHtrZXl9IC0gJHt2YWx1ZX0uYCk7XG4gIH1cbn07XG5cbmNvbnN0IGFwcGVuZEVwT3B0aW9uID0gKGVwT3B0aW9uczogQXJyYXk8W251bWJlciwgbnVtYmVyXT4sIGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBhbGxvY3M6IG51bWJlcltdKTogdm9pZCA9PiB7XG4gIGNvbnN0IGtleURhdGFPZmZzZXQgPSBhbGxvY1dhc21TdHJpbmcoa2V5LCBhbGxvY3MpO1xuICBjb25zdCB2YWx1ZURhdGFPZmZzZXQgPSBhbGxvY1dhc21TdHJpbmcodmFsdWUsIGFsbG9jcyk7XG4gIGVwT3B0aW9ucy5wdXNoKFtrZXlEYXRhT2Zmc2V0LCB2YWx1ZURhdGFPZmZzZXRdKTtcbn07XG5cbmNvbnN0IHNldEV4ZWN1dGlvblByb3ZpZGVycyA9IGFzeW5jIChcbiAgc2Vzc2lvbk9wdGlvbnNIYW5kbGU6IG51bWJlcixcbiAgZXhlY3V0aW9uUHJvdmlkZXJzOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLkV4ZWN1dGlvblByb3ZpZGVyQ29uZmlnW10sXG4gIGFsbG9jczogbnVtYmVyW10sXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgZm9yIChjb25zdCBlcCBvZiBleGVjdXRpb25Qcm92aWRlcnMpIHtcbiAgICBsZXQgZXBOYW1lID0gdHlwZW9mIGVwID09PSAnc3RyaW5nJyA/IGVwIDogZXAubmFtZTtcbiAgICBjb25zdCBlcE9wdGlvbnM6IEFycmF5PFtudW1iZXIsIG51bWJlcl0+ID0gW107XG5cbiAgICAvLyBjaGVjayBFUCBuYW1lXG4gICAgc3dpdGNoIChlcE5hbWUpIHtcbiAgICAgIGNhc2UgJ3dlYm5uJzpcbiAgICAgICAgZXBOYW1lID0gJ1dFQk5OJztcbiAgICAgICAgaWYgKHR5cGVvZiBlcCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBjb25zdCB3ZWJubk9wdGlvbnMgPSBlcCBhcyBJbmZlcmVuY2VTZXNzaW9uLldlYk5ORXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgICAgICAgLy8gY29uc3QgY29udGV4dCA9ICh3ZWJubk9wdGlvbnMgYXMgSW5mZXJlbmNlU2Vzc2lvbi5XZWJOTk9wdGlvbnNXaXRoTUxDb250ZXh0KT8uY29udGV4dDtcbiAgICAgICAgICBjb25zdCBkZXZpY2VUeXBlID0gKHdlYm5uT3B0aW9ucyBhcyBJbmZlcmVuY2VTZXNzaW9uLldlYk5OQ29udGV4dE9wdGlvbnMpPy5kZXZpY2VUeXBlO1xuICAgICAgICAgIGlmIChkZXZpY2VUeXBlKSB7XG4gICAgICAgICAgICBhcHBlbmRTZXNzaW9uQ29uZmlnKHNlc3Npb25PcHRpb25zSGFuZGxlLCAnZGV2aWNlVHlwZScsIGRldmljZVR5cGUsIGFsbG9jcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnd2ViZ3B1JzpcbiAgICAgICAgaWYgKEJVSUxEX0RFRlMuVVNFX1dFQkdQVV9FUCkge1xuICAgICAgICAgIGVwTmFtZSA9ICdXZWJHUFUnO1xuICAgICAgICAgIGxldCBjdXN0b21EZXZpY2U6IEdQVURldmljZSB8IHVuZGVmaW5lZDtcblxuICAgICAgICAgIGlmICh0eXBlb2YgZXAgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBjdXN0b21PcHRpb25zID0gZXAgYXMgdW5rbm93biBhcyB7IGRldmljZTogR1BVRGV2aWNlIH07XG4gICAgICAgICAgICBpZiAoY3VzdG9tT3B0aW9ucy5kZXZpY2UpIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBHUFVEZXZpY2UgIT09ICd1bmRlZmluZWQnICYmIGN1c3RvbU9wdGlvbnMuZGV2aWNlIGluc3RhbmNlb2YgR1BVRGV2aWNlKSB7XG4gICAgICAgICAgICAgICAgY3VzdG9tRGV2aWNlID0gY3VzdG9tT3B0aW9ucy5kZXZpY2U7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIEdQVSBkZXZpY2Ugc2V0IGluIFdlYkdQVSBFUCBvcHRpb25zLicpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFRPRE86IGhhbmRsZSBtb3JlIG9wdGlvbnNcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBpbmZvID0gZ2V0SW5zdGFuY2UoKS53ZWJncHVSZWdpc3RlckRldmljZSEoY3VzdG9tRGV2aWNlKTtcbiAgICAgICAgICBpZiAoaW5mbykge1xuICAgICAgICAgICAgY29uc3QgW2RldmljZUlkLCBpbnN0YW5jZUhhbmRsZSwgZGV2aWNlSGFuZGxlXSA9IGluZm87XG4gICAgICAgICAgICBhcHBlbmRFcE9wdGlvbihlcE9wdGlvbnMsICdkZXZpY2VJZCcsIGRldmljZUlkLnRvU3RyaW5nKCksIGFsbG9jcyk7XG4gICAgICAgICAgICBhcHBlbmRFcE9wdGlvbihlcE9wdGlvbnMsICd3ZWJncHVJbnN0YW5jZScsIGluc3RhbmNlSGFuZGxlLnRvU3RyaW5nKCksIGFsbG9jcyk7XG4gICAgICAgICAgICBhcHBlbmRFcE9wdGlvbihlcE9wdGlvbnMsICd3ZWJncHVEZXZpY2UnLCBkZXZpY2VIYW5kbGUudG9TdHJpbmcoKSwgYWxsb2NzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXBOYW1lID0gJ0pTJztcbiAgICAgICAgICBpZiAodHlwZW9mIGVwICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uc3Qgd2ViZ3B1T3B0aW9ucyA9IGVwIGFzIEluZmVyZW5jZVNlc3Npb24uV2ViR3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgICAgICAgICBpZiAod2ViZ3B1T3B0aW9ucz8ucHJlZmVycmVkTGF5b3V0KSB7XG4gICAgICAgICAgICAgIGlmICh3ZWJncHVPcHRpb25zLnByZWZlcnJlZExheW91dCAhPT0gJ05DSFcnICYmIHdlYmdwdU9wdGlvbnMucHJlZmVycmVkTGF5b3V0ICE9PSAnTkhXQycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHByZWZlcnJlZExheW91dCBtdXN0IGJlIGVpdGhlciAnTkNIVycgb3IgJ05IV0MnOiAke3dlYmdwdU9wdGlvbnMucHJlZmVycmVkTGF5b3V0fWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGFwcGVuZFNlc3Npb25Db25maWcoc2Vzc2lvbk9wdGlvbnNIYW5kbGUsICdwcmVmZXJyZWRMYXlvdXQnLCB3ZWJncHVPcHRpb25zLnByZWZlcnJlZExheW91dCwgYWxsb2NzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd3YXNtJzpcbiAgICAgIGNhc2UgJ2NwdSc6XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBub3Qgc3VwcG9ydGVkIGV4ZWN1dGlvbiBwcm92aWRlcjogJHtlcE5hbWV9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgZXBOYW1lRGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyhlcE5hbWUsIGFsbG9jcyk7XG4gICAgY29uc3QgZXBPcHRpb25zQ291bnQgPSBlcE9wdGlvbnMubGVuZ3RoO1xuICAgIGxldCBrZXlzT2Zmc2V0ID0gMDtcbiAgICBsZXQgdmFsdWVzT2Zmc2V0ID0gMDtcbiAgICBpZiAoZXBPcHRpb25zQ291bnQgPiAwKSB7XG4gICAgICBrZXlzT2Zmc2V0ID0gZ2V0SW5zdGFuY2UoKS5fbWFsbG9jKGVwT3B0aW9uc0NvdW50ICogZ2V0SW5zdGFuY2UoKS5QVFJfU0laRSk7XG4gICAgICBhbGxvY3MucHVzaChrZXlzT2Zmc2V0KTtcbiAgICAgIHZhbHVlc09mZnNldCA9IGdldEluc3RhbmNlKCkuX21hbGxvYyhlcE9wdGlvbnNDb3VudCAqIGdldEluc3RhbmNlKCkuUFRSX1NJWkUpO1xuICAgICAgYWxsb2NzLnB1c2godmFsdWVzT2Zmc2V0KTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXBPcHRpb25zQ291bnQ7IGkrKykge1xuICAgICAgICBnZXRJbnN0YW5jZSgpLnNldFZhbHVlKGtleXNPZmZzZXQgKyBpICogZ2V0SW5zdGFuY2UoKS5QVFJfU0laRSwgZXBPcHRpb25zW2ldWzBdLCAnKicpO1xuICAgICAgICBnZXRJbnN0YW5jZSgpLnNldFZhbHVlKHZhbHVlc09mZnNldCArIGkgKiBnZXRJbnN0YW5jZSgpLlBUUl9TSVpFLCBlcE9wdGlvbnNbaV1bMV0sICcqJyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChcbiAgICAgIChhd2FpdCBnZXRJbnN0YW5jZSgpLl9PcnRBcHBlbmRFeGVjdXRpb25Qcm92aWRlcihcbiAgICAgICAgc2Vzc2lvbk9wdGlvbnNIYW5kbGUsXG4gICAgICAgIGVwTmFtZURhdGFPZmZzZXQsXG4gICAgICAgIGtleXNPZmZzZXQsXG4gICAgICAgIHZhbHVlc09mZnNldCxcbiAgICAgICAgZXBPcHRpb25zQ291bnQsXG4gICAgICApKSAhPT0gMFxuICAgICkge1xuICAgICAgY2hlY2tMYXN0RXJyb3IoYENhbid0IGFwcGVuZCBleGVjdXRpb24gcHJvdmlkZXI6ICR7ZXBOYW1lfS5gKTtcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzZXRTZXNzaW9uT3B0aW9ucyA9IGFzeW5jIChvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8W251bWJlciwgbnVtYmVyW11dPiA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBsZXQgc2Vzc2lvbk9wdGlvbnNIYW5kbGUgPSAwO1xuICBjb25zdCBhbGxvY3M6IG51bWJlcltdID0gW107XG5cbiAgY29uc3Qgc2Vzc2lvbk9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBhcHBlbmREZWZhdWx0T3B0aW9ucyhzZXNzaW9uT3B0aW9ucyk7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBncmFwaE9wdGltaXphdGlvbkxldmVsID0gZ2V0R3JhcGhPcHRpbXphdGlvbkxldmVsKHNlc3Npb25PcHRpb25zLmdyYXBoT3B0aW1pemF0aW9uTGV2ZWwgPz8gJ2FsbCcpO1xuICAgIGNvbnN0IGV4ZWN1dGlvbk1vZGUgPSBnZXRFeGVjdXRpb25Nb2RlKHNlc3Npb25PcHRpb25zLmV4ZWN1dGlvbk1vZGUgPz8gJ3NlcXVlbnRpYWwnKTtcbiAgICBjb25zdCBsb2dJZERhdGFPZmZzZXQgPVxuICAgICAgdHlwZW9mIHNlc3Npb25PcHRpb25zLmxvZ0lkID09PSAnc3RyaW5nJyA/IGFsbG9jV2FzbVN0cmluZyhzZXNzaW9uT3B0aW9ucy5sb2dJZCwgYWxsb2NzKSA6IDA7XG5cbiAgICBjb25zdCBsb2dTZXZlcml0eUxldmVsID0gc2Vzc2lvbk9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCA/PyAyOyAvLyBEZWZhdWx0IHRvIDIgLSB3YXJuaW5nXG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGxvZ1NldmVyaXR5TGV2ZWwpIHx8IGxvZ1NldmVyaXR5TGV2ZWwgPCAwIHx8IGxvZ1NldmVyaXR5TGV2ZWwgPiA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGxvZyBzZXJ2ZXJpdHkgbGV2ZWwgaXMgbm90IHZhbGlkOiAke2xvZ1NldmVyaXR5TGV2ZWx9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgbG9nVmVyYm9zaXR5TGV2ZWwgPSBzZXNzaW9uT3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCA/PyAwOyAvLyBEZWZhdWx0IHRvIDAgLSB2ZXJib3NlXG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGxvZ1ZlcmJvc2l0eUxldmVsKSB8fCBsb2dWZXJib3NpdHlMZXZlbCA8IDAgfHwgbG9nVmVyYm9zaXR5TGV2ZWwgPiA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGxvZyB2ZXJib3NpdHkgbGV2ZWwgaXMgbm90IHZhbGlkOiAke2xvZ1ZlcmJvc2l0eUxldmVsfWApO1xuICAgIH1cblxuICAgIGNvbnN0IG9wdGltaXplZE1vZGVsRmlsZVBhdGhPZmZzZXQgPVxuICAgICAgdHlwZW9mIHNlc3Npb25PcHRpb25zLm9wdGltaXplZE1vZGVsRmlsZVBhdGggPT09ICdzdHJpbmcnXG4gICAgICAgID8gYWxsb2NXYXNtU3RyaW5nKHNlc3Npb25PcHRpb25zLm9wdGltaXplZE1vZGVsRmlsZVBhdGgsIGFsbG9jcylcbiAgICAgICAgOiAwO1xuXG4gICAgc2Vzc2lvbk9wdGlvbnNIYW5kbGUgPSB3YXNtLl9PcnRDcmVhdGVTZXNzaW9uT3B0aW9ucyhcbiAgICAgIGdyYXBoT3B0aW1pemF0aW9uTGV2ZWwsXG4gICAgICAhIXNlc3Npb25PcHRpb25zLmVuYWJsZUNwdU1lbUFyZW5hLFxuICAgICAgISFzZXNzaW9uT3B0aW9ucy5lbmFibGVNZW1QYXR0ZXJuLFxuICAgICAgZXhlY3V0aW9uTW9kZSxcbiAgICAgICEhc2Vzc2lvbk9wdGlvbnMuZW5hYmxlUHJvZmlsaW5nLFxuICAgICAgMCxcbiAgICAgIGxvZ0lkRGF0YU9mZnNldCxcbiAgICAgIGxvZ1NldmVyaXR5TGV2ZWwsXG4gICAgICBsb2dWZXJib3NpdHlMZXZlbCxcbiAgICAgIG9wdGltaXplZE1vZGVsRmlsZVBhdGhPZmZzZXQsXG4gICAgKTtcbiAgICBpZiAoc2Vzc2lvbk9wdGlvbnNIYW5kbGUgPT09IDApIHtcbiAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgY3JlYXRlIHNlc3Npb24gb3B0aW9ucy5cIik7XG4gICAgfVxuXG4gICAgaWYgKHNlc3Npb25PcHRpb25zLmV4ZWN1dGlvblByb3ZpZGVycykge1xuICAgICAgYXdhaXQgc2V0RXhlY3V0aW9uUHJvdmlkZXJzKHNlc3Npb25PcHRpb25zSGFuZGxlLCBzZXNzaW9uT3B0aW9ucy5leGVjdXRpb25Qcm92aWRlcnMsIGFsbG9jcyk7XG4gICAgfVxuXG4gICAgaWYgKHNlc3Npb25PcHRpb25zLmVuYWJsZUdyYXBoQ2FwdHVyZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIHNlc3Npb25PcHRpb25zLmVuYWJsZUdyYXBoQ2FwdHVyZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZW5hYmxlR3JhcGhDYXB0dXJlIG11c3QgYmUgYSBib29sZWFuIHZhbHVlOiAke3Nlc3Npb25PcHRpb25zLmVuYWJsZUdyYXBoQ2FwdHVyZX1gKTtcbiAgICAgIH1cbiAgICAgIGFwcGVuZFNlc3Npb25Db25maWcoXG4gICAgICAgIHNlc3Npb25PcHRpb25zSGFuZGxlLFxuICAgICAgICAnZW5hYmxlR3JhcGhDYXB0dXJlJyxcbiAgICAgICAgc2Vzc2lvbk9wdGlvbnMuZW5hYmxlR3JhcGhDYXB0dXJlLnRvU3RyaW5nKCksXG4gICAgICAgIGFsbG9jcyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHNlc3Npb25PcHRpb25zLmZyZWVEaW1lbnNpb25PdmVycmlkZXMpIHtcbiAgICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhzZXNzaW9uT3B0aW9ucy5mcmVlRGltZW5zaW9uT3ZlcnJpZGVzKSkge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmcmVlIGRpbWVuc2lvbiBvdmVycmlkZSBuYW1lIG11c3QgYmUgYSBzdHJpbmc6ICR7bmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCAhTnVtYmVyLmlzSW50ZWdlcih2YWx1ZSkgfHwgdmFsdWUgPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmcmVlIGRpbWVuc2lvbiBvdmVycmlkZSB2YWx1ZSBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXI6ICR7dmFsdWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmFtZU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyhuYW1lLCBhbGxvY3MpO1xuICAgICAgICBpZiAod2FzbS5fT3J0QWRkRnJlZURpbWVuc2lvbk92ZXJyaWRlKHNlc3Npb25PcHRpb25zSGFuZGxlLCBuYW1lT2Zmc2V0LCB2YWx1ZSkgIT09IDApIHtcbiAgICAgICAgICBjaGVja0xhc3RFcnJvcihgQ2FuJ3Qgc2V0IGEgZnJlZSBkaW1lbnNpb24gb3ZlcnJpZGU6ICR7bmFtZX0gLSAke3ZhbHVlfS5gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZXNzaW9uT3B0aW9ucy5leHRyYSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpdGVyYXRlRXh0cmFPcHRpb25zKHNlc3Npb25PcHRpb25zLmV4dHJhLCAnJywgbmV3IFdlYWtTZXQ8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KCksIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICAgIGFwcGVuZFNlc3Npb25Db25maWcoc2Vzc2lvbk9wdGlvbnNIYW5kbGUsIGtleSwgdmFsdWUsIGFsbG9jcyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gW3Nlc3Npb25PcHRpb25zSGFuZGxlLCBhbGxvY3NdO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKHNlc3Npb25PcHRpb25zSGFuZGxlICE9PSAwKSB7XG4gICAgICBpZiAod2FzbS5fT3J0UmVsZWFzZVNlc3Npb25PcHRpb25zKHNlc3Npb25PcHRpb25zSGFuZGxlKSAhPT0gMCkge1xuICAgICAgICBjaGVja0xhc3RFcnJvcihcIkNhbid0IHJlbGVhc2Ugc2Vzc2lvbiBvcHRpb25zLlwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgYWxsb2NzLmZvckVhY2goKGFsbG9jKSA9PiB3YXNtLl9mcmVlKGFsbG9jKSk7XG4gICAgdGhyb3cgZTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yIH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuLy8gYSBkdW1teSB0eXBlIGRlY2xhcmF0aW9uIGZvciBGbG9hdDE2QXJyYXkgaW4gY2FzZSBhbnkgcG9seWZpbGwgaXMgYXZhaWxhYmxlLlxuZGVjbGFyZSBnbG9iYWwge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIGNvbnN0IEZsb2F0MTZBcnJheTogYW55O1xufVxuXG4vLyBUaGlzIGZpbGUgaW5jbHVkZXMgY29tbW9uIGRlZmluaXRpb25zLiBUaGV5IGRvIE5PVCBoYXZlIGRlcGVuZGVuY3kgb24gdGhlIFdlYkFzc2VtYmx5IGluc3RhbmNlLlxuXG4vKipcbiAqIENvcGllZCBmcm9tIE9OTlggZGVmaW5pdGlvbi4gVXNlIHRoaXMgdG8gZHJvcCBkZXBlbmRlbmN5ICdvbm54X3Byb3RvJyB0byBkZWNyZWFzZSBjb21waWxlZCAuanMgZmlsZSBzaXplLlxuICovXG5leHBvcnQgY29uc3QgZW51bSBEYXRhVHlwZSB7XG4gIHVuZGVmaW5lZCA9IDAsXG4gIGZsb2F0ID0gMSxcbiAgdWludDggPSAyLFxuICBpbnQ4ID0gMyxcbiAgdWludDE2ID0gNCxcbiAgaW50MTYgPSA1LFxuICBpbnQzMiA9IDYsXG4gIGludDY0ID0gNyxcbiAgc3RyaW5nID0gOCxcbiAgYm9vbCA9IDksXG4gIGZsb2F0MTYgPSAxMCxcbiAgZG91YmxlID0gMTEsXG4gIHVpbnQzMiA9IDEyLFxuICB1aW50NjQgPSAxMyxcbiAgY29tcGxleDY0ID0gMTQsXG4gIGNvbXBsZXgxMjggPSAxNSxcbiAgYmZsb2F0MTYgPSAxNixcblxuICAvLyA0LWJpdCBkYXRhLXR5cGVzXG4gIHVpbnQ0ID0gMjEsXG4gIGludDQgPSAyMixcbn1cblxuLyoqXG4gKiBNYXAgc3RyaW5nIHRlbnNvciBkYXRhIHRvIGVudW0gdmFsdWVcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtID0gKHR5cGU6IHN0cmluZyk6IERhdGFUeXBlID0+IHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnaW50OCc6XG4gICAgICByZXR1cm4gRGF0YVR5cGUuaW50ODtcbiAgICBjYXNlICd1aW50OCc6XG4gICAgICByZXR1cm4gRGF0YVR5cGUudWludDg7XG4gICAgY2FzZSAnYm9vbCc6XG4gICAgICByZXR1cm4gRGF0YVR5cGUuYm9vbDtcbiAgICBjYXNlICdpbnQxNic6XG4gICAgICByZXR1cm4gRGF0YVR5cGUuaW50MTY7XG4gICAgY2FzZSAndWludDE2JzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS51aW50MTY7XG4gICAgY2FzZSAnaW50MzInOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmludDMyO1xuICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICByZXR1cm4gRGF0YVR5cGUudWludDMyO1xuICAgIGNhc2UgJ2Zsb2F0MTYnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmZsb2F0MTY7XG4gICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICByZXR1cm4gRGF0YVR5cGUuZmxvYXQ7XG4gICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICByZXR1cm4gRGF0YVR5cGUuZG91YmxlO1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICByZXR1cm4gRGF0YVR5cGUuc3RyaW5nO1xuICAgIGNhc2UgJ2ludDY0JzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS5pbnQ2NDtcbiAgICBjYXNlICd1aW50NjQnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLnVpbnQ2NDtcbiAgICBjYXNlICdpbnQ0JzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS5pbnQ0O1xuICAgIGNhc2UgJ3VpbnQ0JzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS51aW50NDtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHt0eXBlfWApO1xuICB9XG59O1xuXG4vKipcbiAqIE1hcCBlbnVtIHZhbHVlIHRvIHN0cmluZyB0ZW5zb3IgZGF0YVxuICovXG5leHBvcnQgY29uc3QgdGVuc29yRGF0YVR5cGVFbnVtVG9TdHJpbmcgPSAodHlwZVByb3RvOiBEYXRhVHlwZSk6IFRlbnNvci5UeXBlID0+IHtcbiAgc3dpdGNoICh0eXBlUHJvdG8pIHtcbiAgICBjYXNlIERhdGFUeXBlLmludDg6XG4gICAgICByZXR1cm4gJ2ludDgnO1xuICAgIGNhc2UgRGF0YVR5cGUudWludDg6XG4gICAgICByZXR1cm4gJ3VpbnQ4JztcbiAgICBjYXNlIERhdGFUeXBlLmJvb2w6XG4gICAgICByZXR1cm4gJ2Jvb2wnO1xuICAgIGNhc2UgRGF0YVR5cGUuaW50MTY6XG4gICAgICByZXR1cm4gJ2ludDE2JztcbiAgICBjYXNlIERhdGFUeXBlLnVpbnQxNjpcbiAgICAgIHJldHVybiAndWludDE2JztcbiAgICBjYXNlIERhdGFUeXBlLmludDMyOlxuICAgICAgcmV0dXJuICdpbnQzMic7XG4gICAgY2FzZSBEYXRhVHlwZS51aW50MzI6XG4gICAgICByZXR1cm4gJ3VpbnQzMic7XG4gICAgY2FzZSBEYXRhVHlwZS5mbG9hdDE2OlxuICAgICAgcmV0dXJuICdmbG9hdDE2JztcbiAgICBjYXNlIERhdGFUeXBlLmZsb2F0OlxuICAgICAgcmV0dXJuICdmbG9hdDMyJztcbiAgICBjYXNlIERhdGFUeXBlLmRvdWJsZTpcbiAgICAgIHJldHVybiAnZmxvYXQ2NCc7XG4gICAgY2FzZSBEYXRhVHlwZS5zdHJpbmc6XG4gICAgICByZXR1cm4gJ3N0cmluZyc7XG4gICAgY2FzZSBEYXRhVHlwZS5pbnQ2NDpcbiAgICAgIHJldHVybiAnaW50NjQnO1xuICAgIGNhc2UgRGF0YVR5cGUudWludDY0OlxuICAgICAgcmV0dXJuICd1aW50NjQnO1xuICAgIGNhc2UgRGF0YVR5cGUuaW50NDpcbiAgICAgIHJldHVybiAnaW50NCc7XG4gICAgY2FzZSBEYXRhVHlwZS51aW50NDpcbiAgICAgIHJldHVybiAndWludDQnO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgZGF0YSB0eXBlOiAke3R5cGVQcm90b31gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBnZXQgdGVuc29yIHNpemUgaW4gYnl0ZXMgYnkgdGhlIGdpdmVuIGRhdGEgdHlwZSBhbmQgZGltZW5zaW9uc1xuICogQHJldHVybnMgc2l6ZSBpbiBpbnRlZ2VyIG9yIHVuZGVmaW5lZCBpZiB0aGUgZGF0YSB0eXBlIGlzIG5vdCBzdXBwb3J0ZWRcbiAqL1xuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZVRlbnNvclNpemVJbkJ5dGVzID0gKFxuICBkYXRlVHlwZTogbnVtYmVyLFxuICBkaW1zT3JTaXplOiByZWFkb25seSBudW1iZXJbXSB8IG51bWJlcixcbik6IG51bWJlciB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IGVsZW1lbnRTaXplID0gW1xuICAgIC0xLCAvLyB1bmRlZmluZWQgPSAwXG4gICAgNCwgLy8gZmxvYXQgPSAxXG4gICAgMSwgLy8gdWludDggPSAyXG4gICAgMSwgLy8gaW50OCA9IDNcbiAgICAyLCAvLyB1aW50MTYgPSA0XG4gICAgMiwgLy8gaW50MTYgPSA1XG4gICAgNCwgLy8gaW50MzIgPSA2XG4gICAgOCwgLy8gaW50NjQgPSA3XG4gICAgLTEsIC8vIHN0cmluZyA9IDhcbiAgICAxLCAvLyBib29sID0gOVxuICAgIDIsIC8vIGZsb2F0MTYgPSAxMFxuICAgIDgsIC8vIGRvdWJsZSA9IDExXG4gICAgNCwgLy8gdWludDMyID0gMTJcbiAgICA4LCAvLyB1aW50NjQgPSAxM1xuICAgIC0xLCAvLyBjb21wbGV4NjQgPSAxNFxuICAgIC0xLCAvLyBjb21wbGV4MTI4ID0gMTVcbiAgICAtMSwgLy8gYmZsb2F0MTYgPSAxNlxuICAgIC0xLCAvLyBGTE9BVDhFNE0zRk4gPSAxN1xuICAgIC0xLCAvLyBGTE9BVDhFNE0zRk5VWiA9IDE4XG4gICAgLTEsIC8vIEZMT0FUOEU1TTIgPSAxOVxuICAgIC0xLCAvLyBGTE9BVDhFNU0yRk5VWiA9IDIwXG4gICAgMC41LCAvLyB1aW50NCA9IDIxXG4gICAgMC41LCAvLyBpbnQ0ID0gMjJcbiAgXVtkYXRlVHlwZV07XG5cbiAgY29uc3Qgc2l6ZSA9IHR5cGVvZiBkaW1zT3JTaXplID09PSAnbnVtYmVyJyA/IGRpbXNPclNpemUgOiBkaW1zT3JTaXplLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIsIDEpO1xuICByZXR1cm4gZWxlbWVudFNpemUgPiAwID8gTWF0aC5jZWlsKHNpemUgKiBlbGVtZW50U2l6ZSkgOiB1bmRlZmluZWQ7XG59O1xuXG4vKipcbiAqIGdldCB0eXBlZCBhcnJheSBjb25zdHJ1Y3RvciBieSB0aGUgZ2l2ZW4gdGVuc29yIHR5cGVcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvclR5cGVUb1R5cGVkQXJyYXlDb25zdHJ1Y3RvciA9IChcbiAgdHlwZTogVGVuc29yLlR5cGUsXG4pOlxuICB8IEZsb2F0MzJBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDhBcnJheUNvbnN0cnVjdG9yXG4gIHwgSW50OEFycmF5Q29uc3RydWN0b3JcbiAgfCBVaW50MTZBcnJheUNvbnN0cnVjdG9yXG4gIHwgSW50MTZBcnJheUNvbnN0cnVjdG9yXG4gIHwgSW50MzJBcnJheUNvbnN0cnVjdG9yXG4gIHwgQmlnSW50NjRBcnJheUNvbnN0cnVjdG9yXG4gIHwgVWludDhBcnJheUNvbnN0cnVjdG9yXG4gIHwgRmxvYXQ2NEFycmF5Q29uc3RydWN0b3JcbiAgfCBVaW50MzJBcnJheUNvbnN0cnVjdG9yXG4gIHwgQmlnVWludDY0QXJyYXlDb25zdHJ1Y3RvciA9PiB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2Zsb2F0MTYnOlxuICAgICAgLy8gYWxsb3cgRmxvYXQxNkFycmF5IHBvbHlmaWxsLlxuICAgICAgcmV0dXJuIHR5cGVvZiBGbG9hdDE2QXJyYXkgIT09ICd1bmRlZmluZWQnICYmIEZsb2F0MTZBcnJheS5mcm9tID8gRmxvYXQxNkFycmF5IDogVWludDE2QXJyYXk7XG4gICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICByZXR1cm4gRmxvYXQzMkFycmF5O1xuICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIHJldHVybiBVaW50OEFycmF5O1xuICAgIGNhc2UgJ2ludDgnOlxuICAgICAgcmV0dXJuIEludDhBcnJheTtcbiAgICBjYXNlICd1aW50MTYnOlxuICAgICAgcmV0dXJuIFVpbnQxNkFycmF5O1xuICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgIHJldHVybiBJbnQxNkFycmF5O1xuICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgIHJldHVybiBJbnQzMkFycmF5O1xuICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXk7XG4gICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICByZXR1cm4gRmxvYXQ2NEFycmF5O1xuICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICByZXR1cm4gVWludDMyQXJyYXk7XG4gICAgY2FzZSAnaW50NjQnOlxuICAgICAgcmV0dXJuIEJpZ0ludDY0QXJyYXk7XG4gICAgY2FzZSAndWludDY0JzpcbiAgICAgIHJldHVybiBCaWdVaW50NjRBcnJheTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCB0eXBlOiAke3R5cGV9YCk7XG4gIH1cbn07XG5cbi8qKlxuICogTWFwIHN0cmluZyBsb2cgbGV2ZWwgdG8gaW50ZWdlciB2YWx1ZVxuICovXG5leHBvcnQgY29uc3QgbG9nTGV2ZWxTdHJpbmdUb0VudW0gPSAobG9nTGV2ZWw/OiAndmVyYm9zZScgfCAnaW5mbycgfCAnd2FybmluZycgfCAnZXJyb3InIHwgJ2ZhdGFsJyk6IG51bWJlciA9PiB7XG4gIHN3aXRjaCAobG9nTGV2ZWwpIHtcbiAgICBjYXNlICd2ZXJib3NlJzpcbiAgICAgIHJldHVybiAwO1xuICAgIGNhc2UgJ2luZm8nOlxuICAgICAgcmV0dXJuIDE7XG4gICAgY2FzZSAnd2FybmluZyc6XG4gICAgICByZXR1cm4gMjtcbiAgICBjYXNlICdlcnJvcic6XG4gICAgICByZXR1cm4gMztcbiAgICBjYXNlICdmYXRhbCc6XG4gICAgICByZXR1cm4gNDtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBsb2dnaW5nIGxldmVsOiAke2xvZ0xldmVsfWApO1xuICB9XG59O1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIHRlbnNvciB0eXBlIGlzIHN1cHBvcnRlZCBieSBHUFUgYnVmZmVyXG4gKi9cbmV4cG9ydCBjb25zdCBpc0dwdUJ1ZmZlclN1cHBvcnRlZFR5cGUgPSAodHlwZTogVGVuc29yLlR5cGUpOiB0eXBlIGlzIFRlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXMgPT5cbiAgdHlwZSA9PT0gJ2Zsb2F0MzInIHx8XG4gIHR5cGUgPT09ICdmbG9hdDE2JyB8fFxuICB0eXBlID09PSAnaW50MzInIHx8XG4gIHR5cGUgPT09ICdpbnQ2NCcgfHxcbiAgdHlwZSA9PT0gJ3VpbnQzMicgfHxcbiAgdHlwZSA9PT0gJ3VpbnQ4JyB8fFxuICB0eXBlID09PSAnYm9vbCcgfHxcbiAgdHlwZSA9PT0gJ3VpbnQ0JyB8fFxuICB0eXBlID09PSAnaW50NCc7XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciB0aGUgZ2l2ZW4gdGVuc29yIHR5cGUgaXMgc3VwcG9ydGVkIGJ5IFdlYk5OIE1MVGVuc29yXG4gKi9cbmV4cG9ydCBjb25zdCBpc01MVGVuc29yU3VwcG9ydGVkVHlwZSA9ICh0eXBlOiBUZW5zb3IuVHlwZSk6IHR5cGUgaXMgVGVuc29yLk1MVGVuc29yRGF0YVR5cGVzID0+XG4gIHR5cGUgPT09ICdmbG9hdDMyJyB8fFxuICB0eXBlID09PSAnZmxvYXQxNicgfHxcbiAgdHlwZSA9PT0gJ2ludDMyJyB8fFxuICB0eXBlID09PSAnaW50NjQnIHx8XG4gIHR5cGUgPT09ICd1aW50MzInIHx8XG4gIHR5cGUgPT09ICd1aW50NjQnIHx8XG4gIHR5cGUgPT09ICdpbnQ4JyB8fFxuICB0eXBlID09PSAndWludDgnIHx8XG4gIHR5cGUgPT09ICdib29sJyB8fFxuICB0eXBlID09PSAndWludDQnIHx8XG4gIHR5cGUgPT09ICdpbnQ0JztcblxuLyoqXG4gKiBNYXAgc3RyaW5nIGRhdGEgbG9jYXRpb24gdG8gaW50ZWdlciB2YWx1ZVxuICovXG5leHBvcnQgY29uc3QgZGF0YUxvY2F0aW9uU3RyaW5nVG9FbnVtID0gKGxvY2F0aW9uOiBUZW5zb3IuRGF0YUxvY2F0aW9uKTogbnVtYmVyID0+IHtcbiAgc3dpdGNoIChsb2NhdGlvbikge1xuICAgIGNhc2UgJ25vbmUnOlxuICAgICAgcmV0dXJuIDA7XG4gICAgY2FzZSAnY3B1JzpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2UgJ2NwdS1waW5uZWQnOlxuICAgICAgcmV0dXJuIDI7XG4gICAgY2FzZSAndGV4dHVyZSc6XG4gICAgICByZXR1cm4gMztcbiAgICBjYXNlICdncHUtYnVmZmVyJzpcbiAgICAgIHJldHVybiA0O1xuICAgIGNhc2UgJ21sLXRlbnNvcic6XG4gICAgICByZXR1cm4gNTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIGxvY2F0aW9uOiAke2xvY2F0aW9ufWApO1xuICB9XG59O1xuXG4vKipcbiAqIE1hcCBpbnRlZ2VyIGRhdGEgbG9jYXRpb24gdG8gc3RyaW5nIHZhbHVlXG4gKi9cbmV4cG9ydCBjb25zdCBkYXRhTG9jYXRpb25FbnVtVG9TdHJpbmcgPSAobG9jYXRpb246IG51bWJlcik6IFRlbnNvci5EYXRhTG9jYXRpb24gfCB1bmRlZmluZWQgPT5cbiAgKFsnbm9uZScsICdjcHUnLCAnY3B1LXBpbm5lZCcsICd0ZXh0dXJlJywgJ2dwdS1idWZmZXInLCAnbWwtdGVuc29yJ10gYXMgY29uc3QpW2xvY2F0aW9uXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgaXNOb2RlIH0gZnJvbSAnLi93YXNtLXV0aWxzLWVudic7XG5cbi8qKlxuICogTG9hZCBhIGZpbGUgaW50byBhIFVpbnQ4QXJyYXkuXG4gKlxuICogQHBhcmFtIGZpbGUgLSB0aGUgZmlsZSB0byBsb2FkLiBDYW4gYmUgYSBVUkwvcGF0aCwgYSBCbG9iLCBhbiBBcnJheUJ1ZmZlciwgb3IgYSBVaW50OEFycmF5LlxuICogQHJldHVybnMgYSBVaW50OEFycmF5IGNvbnRhaW5pbmcgdGhlIGZpbGUgZGF0YS5cbiAqL1xuZXhwb3J0IGNvbnN0IGxvYWRGaWxlID0gYXN5bmMgKGZpbGU6IHN0cmluZyB8IEJsb2IgfCBBcnJheUJ1ZmZlckxpa2UgfCBVaW50OEFycmF5KTogUHJvbWlzZTxVaW50OEFycmF5PiA9PiB7XG4gIGlmICh0eXBlb2YgZmlsZSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoaXNOb2RlKSB7XG4gICAgICAvLyBsb2FkIGZpbGUgaW50byBBcnJheUJ1ZmZlciBpbiBOb2RlLmpzXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IHJlYWRGaWxlIH0gPSByZXF1aXJlKCdub2RlOmZzL3Byb21pc2VzJyk7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShhd2FpdCByZWFkRmlsZShmaWxlKSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChlLmNvZGUgPT09ICdFUlJfRlNfRklMRV9UT09fTEFSR0UnKSB7XG4gICAgICAgICAgLy8gZmlsZSBpcyB0b28gbGFyZ2UsIHVzZSBmcy5jcmVhdGVSZWFkU3RyZWFtIGluc3RlYWRcbiAgICAgICAgICBjb25zdCB7IGNyZWF0ZVJlYWRTdHJlYW0gfSA9IHJlcXVpcmUoJ25vZGU6ZnMnKTtcbiAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjcmVhdGVSZWFkU3RyZWFtKGZpbGUpO1xuICAgICAgICAgIGNvbnN0IGNodW5rczogVWludDhBcnJheVtdID0gW107XG4gICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiBzdHJlYW0pIHtcbiAgICAgICAgICAgIGNodW5rcy5wdXNoKGNodW5rKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KEJ1ZmZlci5jb25jYXQoY2h1bmtzKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbG9hZCBmaWxlIGludG8gQXJyYXlCdWZmZXIgaW4gYnJvd3NlcnNcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goZmlsZSk7XG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZmFpbGVkIHRvIGxvYWQgZXh0ZXJuYWwgZGF0YSBmaWxlOiAke2ZpbGV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjb250ZW50TGVuZ3RoSGVhZGVyID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ0NvbnRlbnQtTGVuZ3RoJyk7XG4gICAgICBjb25zdCBmaWxlU2l6ZSA9IGNvbnRlbnRMZW5ndGhIZWFkZXIgPyBwYXJzZUludChjb250ZW50TGVuZ3RoSGVhZGVyLCAxMCkgOiAwO1xuICAgICAgaWYgKGZpbGVTaXplIDwgMTA3Mzc0MTgyNCAvKiAxR0IgKi8pIHtcbiAgICAgICAgLy8gd2hlbiBDb250ZW50LUxlbmd0aCBoZWFkZXIgaXMgbm90IHNldCwgd2UgY2Fubm90IGRldGVybWluZSB0aGUgZmlsZSBzaXplLiBXZSBhc3N1bWUgaXQgaXMgc21hbGwgZW5vdWdoIHRvXG4gICAgICAgIC8vIGxvYWQgaW50byBtZW1vcnkuXG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGZpbGUgaXMgdG9vIGxhcmdlLCB1c2Ugc3RyZWFtIGluc3RlYWRcbiAgICAgICAgaWYgKCFyZXNwb25zZS5ib2R5KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmYWlsZWQgdG8gbG9hZCBleHRlcm5hbCBkYXRhIGZpbGU6ICR7ZmlsZX0sIG5vIHJlc3BvbnNlIGJvZHkuYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVhZGVyID0gcmVzcG9uc2UuYm9keS5nZXRSZWFkZXIoKTtcblxuICAgICAgICBsZXQgYnVmZmVyO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIHRyeSB0byBjcmVhdGUgQXJyYXlCdWZmZXIgZGlyZWN0bHlcbiAgICAgICAgICBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoZmlsZVNpemUpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBSYW5nZUVycm9yKSB7XG4gICAgICAgICAgICAvLyB1c2UgV2ViQXNzZW1ibHkgTWVtb3J5IHRvIGFsbG9jYXRlIGxhcmdlciBBcnJheUJ1ZmZlclxuICAgICAgICAgICAgY29uc3QgcGFnZXMgPSBNYXRoLmNlaWwoZmlsZVNpemUgLyA2NTUzNik7XG4gICAgICAgICAgICBidWZmZXIgPSBuZXcgV2ViQXNzZW1ibHkuTWVtb3J5KHsgaW5pdGlhbDogcGFnZXMsIG1heGltdW06IHBhZ2VzIH0pLmJ1ZmZlcjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0YW50LWNvbmRpdGlvblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBjaHVua1NpemUgPSB2YWx1ZS5ieXRlTGVuZ3RoO1xuICAgICAgICAgIGNvbnN0IGNodW5rID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyLCBvZmZzZXQsIGNodW5rU2l6ZSk7XG4gICAgICAgICAgY2h1bmsuc2V0KHZhbHVlKTtcbiAgICAgICAgICBvZmZzZXQgKz0gY2h1bmtTaXplO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShidWZmZXIsIDAsIGZpbGVTaXplKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoZmlsZSBpbnN0YW5jZW9mIEJsb2IpIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgZmlsZS5hcnJheUJ1ZmZlcigpKTtcbiAgfSBlbHNlIGlmIChmaWxlIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgIHJldHVybiBmaWxlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShmaWxlKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgbG9nTGV2ZWxTdHJpbmdUb0VudW0gfSBmcm9tICcuLi93YXNtLWNvbW1vbic7XG5cbnR5cGUgTG9nTGV2ZWwgPSBOb25OdWxsYWJsZTxFbnZbJ2xvZ0xldmVsJ10+O1xudHlwZSBNZXNzYWdlU3RyaW5nID0gc3RyaW5nO1xudHlwZSBNZXNzYWdlRnVuY3Rpb24gPSAoKSA9PiBzdHJpbmc7XG50eXBlIE1lc3NhZ2UgPSBNZXNzYWdlU3RyaW5nIHwgTWVzc2FnZUZ1bmN0aW9uO1xuXG5jb25zdCBsb2dMZXZlbFByZWZpeCA9IFsnVicsICdJJywgJ1cnLCAnRScsICdGJ107XG5cbmNvbnN0IGRvTG9nID0gKGxldmVsOiBudW1iZXIsIG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhgWyR7bG9nTGV2ZWxQcmVmaXhbbGV2ZWxdfSwke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX1dJHttZXNzYWdlfWApO1xufTtcblxubGV0IGNvbmZpZ0xvZ0xldmVsOiBMb2dMZXZlbCB8IHVuZGVmaW5lZDtcbmxldCBkZWJ1ZzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuZXhwb3J0IGNvbnN0IGNvbmZpZ3VyZUxvZ2dlciA9ICgkY29uZmlnTG9nTGV2ZWw6IExvZ0xldmVsLCAkZGVidWc6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgY29uZmlnTG9nTGV2ZWwgPSAkY29uZmlnTG9nTGV2ZWw7XG4gIGRlYnVnID0gJGRlYnVnO1xufTtcblxuLyoqXG4gKiBBIHNpbXBsZSBsb2dnaW5nIHV0aWxpdHkgdG8gbG9nIG1lc3NhZ2VzIHRvIHRoZSBjb25zb2xlLlxuICovXG5leHBvcnQgY29uc3QgTE9HID0gKGxvZ0xldmVsOiBMb2dMZXZlbCwgbXNnOiBNZXNzYWdlKTogdm9pZCA9PiB7XG4gIGNvbnN0IG1lc3NhZ2VMZXZlbCA9IGxvZ0xldmVsU3RyaW5nVG9FbnVtKGxvZ0xldmVsKTtcbiAgY29uc3QgY29uZmlnTGV2ZWwgPSBsb2dMZXZlbFN0cmluZ1RvRW51bShjb25maWdMb2dMZXZlbCk7XG4gIGlmIChtZXNzYWdlTGV2ZWwgPj0gY29uZmlnTGV2ZWwpIHtcbiAgICBkb0xvZyhtZXNzYWdlTGV2ZWwsIHR5cGVvZiBtc2cgPT09ICdmdW5jdGlvbicgPyBtc2coKSA6IG1zZyk7XG4gIH1cbn07XG5cbi8qKlxuICogQSBzaW1wbGUgbG9nZ2luZyB1dGlsaXR5IHRvIGxvZyBtZXNzYWdlcyB0byB0aGUgY29uc29sZS4gT25seSBsb2dzIHdoZW4gZGVidWcgaXMgZW5hYmxlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IExPR19ERUJVRzogdHlwZW9mIExPRyA9ICguLi5hcmdzOiBQYXJhbWV0ZXJzPHR5cGVvZiBMT0c+KSA9PiB7XG4gIGlmIChkZWJ1Zykge1xuICAgIExPRyguLi5hcmdzKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLyogZXNsaW50LWRpc2FibGUgbm8tcGFyYW0tcmVhc3NpZ24gKi9cblxuZXhwb3J0IGNsYXNzIE1hdE11bFV0aWwge1xuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZSB3aGVuIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuICAgKiBAcGFyYW0gYSBUaGUgc2hhcGUgb2YgdGVuc29yIEEuIFNob3VsZCBiZSBhIHR1cGxlIG9mIDIgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGIgVGhlIHNoYXBlIG9mIHRlbnNvciBCLiBTaG91bGQgYmUgYSB0dXBsZSBvZiAyIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEByZXR1cm5zIFRoZSBleHBlY3RlZCBzaGFwZSBvZiB0aGUgcmVzdWx0LCBvciB1bmRlZmluZWQgaWYgTi9BXG4gICAqL1xuICBzdGF0aWMgY2FsY01hdE11bFNoYXBlKGE6IFtudW1iZXIsIG51bWJlcl0sIGI6IFtudW1iZXIsIG51bWJlcl0pOiBbbnVtYmVyLCBudW1iZXJdIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gYVsxXSAhPT0gYlswXSA/IHVuZGVmaW5lZCA6IFthWzBdLCBiWzFdXTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQnJvYWRjYXN0VXRpbCB7XG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlIHdoZW4gYnJvYWRjYXN0aW5nIDIgdGVuc29yc1xuICAgKiBAcGFyYW0gYSBUaGUgc2hhcGUgb2YgdGVuc29yIEEuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gYiBUaGUgc2hhcGUgb2YgdGVuc29yIEIuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gaXNNYXRNdWwgV2hldGhlciB0aGUgb3BlcmF0aW9uIGlzIE1hdE11bFxuICAgKiBAcmV0dXJucyBUaGUgZXhwZWN0ZWQgc2hhcGUgb2YgdGhlIHJlc3VsdCwgb3IgdW5kZWZpbmVkIGlmIE4vQVxuICAgKi9cbiAgc3RhdGljIGNhbGNTaGFwZShcbiAgICBhZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgYmRpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGlzTWF0TXVsID0gZmFsc2UsXG4gICk6IHJlYWRvbmx5IG51bWJlcltdIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBhcmFuayA9IGFkaW1zLmxlbmd0aDtcbiAgICBjb25zdCBicmFuayA9IGJkaW1zLmxlbmd0aDtcbiAgICBpZiAoYXJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBiZGltcztcbiAgICB9XG4gICAgaWYgKGJyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gYWRpbXM7XG4gICAgfVxuICAgIGNvbnN0IGNyYW5rID0gTWF0aC5tYXgoYWRpbXMubGVuZ3RoLCBiZGltcy5sZW5ndGgpO1xuICAgIGNvbnN0IGNkaW1zID0gbmV3IEFycmF5PG51bWJlcj4oY3JhbmspO1xuXG4gICAgLy8gY2FsY3VsYXRlIHRoZSBsYXN0IDIgZGltZW5zaW9uIGlmIGl0IGlzIE1hdE11bFxuICAgIGlmIChpc01hdE11bCkge1xuICAgICAgaWYgKGFyYW5rIDwgMiB8fCBicmFuayA8IDIpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNTaGFwZU1hdE11bCA9IE1hdE11bFV0aWwuY2FsY01hdE11bFNoYXBlKFxuICAgICAgICBbYWRpbXNbYXJhbmsgLSAyXSwgYWRpbXNbYXJhbmsgLSAxXV0sXG4gICAgICAgIFtiZGltc1ticmFuayAtIDJdLCBiZGltc1ticmFuayAtIDFdXSxcbiAgICAgICk7XG4gICAgICBpZiAoY1NoYXBlTWF0TXVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIFtjZGltc1tjcmFuayAtIDJdLCBjZGltc1tjcmFuayAtIDFdXSA9IGNTaGFwZU1hdE11bDtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gaXNNYXRNdWwgPyAzIDogMTsgaSA8PSBjcmFuazsgaSsrKSB7XG4gICAgICBjb25zdCBhTGVuID0gYXJhbmsgLSBpIDwgMCA/IDEgOiBhZGltc1thcmFuayAtIGldO1xuICAgICAgY29uc3QgYkxlbiA9IGJyYW5rIC0gaSA8IDAgPyAxIDogYmRpbXNbYnJhbmsgLSBpXTtcblxuICAgICAgaWYgKGFMZW4gIT09IGJMZW4gJiYgYUxlbiA+IDEgJiYgYkxlbiA+IDEpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1heCA9IE1hdGgubWF4KGFMZW4sIGJMZW4pO1xuICAgICAgaWYgKGFMZW4gJiYgYkxlbikge1xuICAgICAgICBjZGltc1tjcmFuayAtIGldID0gTWF0aC5tYXgoYUxlbiwgYkxlbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB3aGVuIGVpdGhlciBhTGVuIG9yIGJMZW4gaXMgMCwgdGhlIG90aGVyIHNob3VsZCBiZSBlaXRoZXIgMCBvciAxLCBvdGhlcndpc2UgaXQgaXMgbm90IGJyb2FkY2FzdGFibGUuXG4gICAgICAgIGlmIChtYXggPiAxKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBjZGltc1tjcmFuayAtIGldID0gMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY2RpbXM7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIGEgc2hhcGUgaXMgdW5pZGlyZWN0aW9uYWwgYnJvYWRjYXN0YWJsZSB0byBhbm90aGVyIHNoYXBlXG4gICAqIEBwYXJhbSBzaGFwZSBUaGUgaW5wdXQgc2hhcGVcbiAgICogQHBhcmFtIGZpbmFsU2hhcGUgVGhlIGRlc2lyZWQgc2hhcGUgYWZ0ZXIgYnJvYWRjYXN0aW5nXG4gICAqL1xuICBzdGF0aWMgaXNWYWxpZEJyb2FkY2FzdChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGZpbmFsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogYm9vbGVhbiB7XG4gICAgLy8gYWxpZ24gc2hhcGUgdG8gdGhlIHJpZ2h0XG4gICAgY29uc3QgaW5wdXRSYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGZpbmFsUmFuayA9IGZpbmFsU2hhcGUubGVuZ3RoO1xuICAgIGlmIChpbnB1dFJhbmsgPiBmaW5hbFJhbmspIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gaW5wdXRSYW5rOyBpKyspIHtcbiAgICAgIGlmIChzaGFwZVtpbnB1dFJhbmsgLSBpXSAhPT0gMSAmJiBzaGFwZVtpbnB1dFJhbmsgLSBpXSAhPT0gZmluYWxTaGFwZVtmaW5hbFJhbmsgLSBpXSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTaGFwZVV0aWwge1xuICAvKipcbiAgICogY2FsY3VsYXRlIHRoZSBzaXplIChudW1iZXIgb2YgZWxlbWVudHMpXG4gICAqL1xuICBzdGF0aWMgc2l6ZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIDAsIGRpbXMubGVuZ3RoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBjb252ZXJ0IGRpbXMgY29ycmVzcG9uZGluZyB0byB0eXBlIGNoYW5nZSB0byBwYWNrLiBleC4gdWludDggZGF0YSB0byB1aW50MzJcbiAgICovXG4gIHN0YXRpYyBjb252ZXJ0U2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHNpemUgPSA0KTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IHJhbmsgPSBkaW1zLmxlbmd0aDtcbiAgICBpZiAocmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBjb25zdCBuZXdEaW1zID0gbmV3IEFycmF5KHJhbmspO1xuICAgIGxldCBpID0gcmFuayAtIDE7XG4gICAgd2hpbGUgKGkgPj0gMCkge1xuICAgICAgaWYgKGRpbXNbaV0gJSBzaXplID09PSAwKSB7XG4gICAgICAgIG5ld0RpbXNbaV0gPSBkaW1zW2ldIC8gc2l6ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoc2l6ZSAlIGRpbXNbaV0gIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgY29udmVydCBzaGFwZScpO1xuICAgICAgfVxuICAgICAgbmV3RGltc1tpXSA9IDE7XG4gICAgICBzaXplIC89IGRpbXNbaV07XG4gICAgICBpLS07XG4gICAgfVxuICAgIGZvciAoaS0tOyBpID49IDA7IGktLSkge1xuICAgICAgbmV3RGltc1tpXSA9IGRpbXNbaV07XG4gICAgfVxuICAgIHJldHVybiBuZXdEaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIGNhbGN1bGF0ZSB0aGUgc2l6ZSAobnVtYmVyIG9mIGVsZW1lbnRzKSBmcm9tIHRoZSBnaXZlbiBheGlzIChpbmNsdXNpdmUpXG4gICAqL1xuICBzdGF0aWMgc2l6ZUZyb21EaW1lbnNpb24oZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAwIHx8IGF4aXMgPiBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGRpbWVuc2lvbiBvZiAke2F4aXN9IGZvciBzaXplRnJvbURpbWVuc2lvbiBhcyBUZW5zb3IgaGFzICR7ZGltcy5sZW5ndGh9IGRpbWVuc2lvbnMuYCk7XG4gICAgfVxuICAgIHJldHVybiBTaGFwZVV0aWwuZ2V0U2l6ZUZyb21EaW1lbnNpb25SYW5nZShkaW1zLCBheGlzLCBkaW1zLmxlbmd0aCk7XG4gIH1cblxuICAvKipcbiAgICogY2FsY3VsYXRlIHRoZSBzaXplIChudW1iZXIgb2YgZWxlbWVudHMpIHRvIHRoZSBnaXZlbiBheGlzIChleGNsdXNpdmUpXG4gICAqL1xuICBzdGF0aWMgc2l6ZVRvRGltZW5zaW9uKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgMCB8fCBheGlzID4gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBkaW1lbnNpb24gb2YgJHtheGlzfSBmb3Igc2l6ZVRvRGltZW5zaW9uIGFzIFRlbnNvciBoYXMgJHtkaW1zLmxlbmd0aH0gZGltZW5zaW9ucy5gKTtcbiAgICB9XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIDAsIGF4aXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIGNhbGN1bGF0ZSB0aGUgc2l6ZSAobnVtYmVyIG9mIGVsZW1lbnRzKSBmcm9tIGFuZCB0byB0aGUgZ2l2ZW4gYXhpcyBbc3RhcnQsIGVuZClcbiAgICovXG4gIHN0YXRpYyBnZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IHNpemUgPSAxO1xuICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAvLyBzYWZldHkgY2hlY2sgYXMgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IG11bHRpcGxlIG90aGVyIG1ldGhvZHMgcmVxdWlyaW5nIHNpemUuXG4gICAgICAvLyBzaXplIGNhbm5vdCBiZSBuZWdhdGl2ZS5cbiAgICAgIGlmIChkaW1zW2ldIDwgMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgICAgICAnY2Fubm90IGdldCB2YWxpZCBzaXplIGZyb20gc3BlY2lmaWVkIGRpbWVuc2lvbiByYW5nZS4gTW9zdCBsaWtlbHkgdGhlIHJhbmdlIGNvbnRhaW5zIG5lZ2F0aXZlIHZhbHVlcyBpbiB0aGVtLicsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBzaXplICo9IE51bWJlcihkaW1zW2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHNpemU7XG4gIH1cblxuICBzdGF0aWMgY29tcHV0ZVN0cmlkZXMoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3QgcmFuayA9IGRpbXMubGVuZ3RoO1xuICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfSBlbHNlIGlmIChyYW5rID09PSAxKSB7XG4gICAgICByZXR1cm4gWzFdO1xuICAgIH1cbiAgICBjb25zdCBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmspO1xuICAgIHN0cmlkZXNbcmFuayAtIDFdID0gMTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IGRpbXNbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIGRpbXNbaSArIDFdO1xuICAgIH1cbiAgICByZXR1cm4gc3RyaWRlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBub3JtYWlsemUgYXhpcyBvZiByYW5nZSBbLXIsIHIpIGludG8gWzAsIHIpLlxuICAgKi9cbiAgc3RhdGljIG5vcm1hbGl6ZUF4aXMoYXhpczogbnVtYmVyLCB0ZW5zb3JSYW5rOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgLXRlbnNvclJhbmsgJiYgYXhpcyA+PSB0ZW5zb3JSYW5rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3VwcG9ydGVkIGF4aXMgZm9yIHRoaXMgb3BlcmF0aW9uLicpO1xuICAgIH1cbiAgICByZXR1cm4gYXhpcyA8IDAgPyBheGlzICsgdGVuc29yUmFuayA6IGF4aXM7XG4gIH1cblxuICBzdGF0aWMgbm9ybWFsaXplQXhlcyhheGVzOiByZWFkb25seSBudW1iZXJbXSwgdGVuc29yUmFuaz86IG51bWJlcik6IG51bWJlcltdIHtcbiAgICByZXR1cm4gYXhlcy5tYXAoKHgpID0+IHRoaXMubm9ybWFsaXplQXhpcyh4LCB0ZW5zb3JSYW5rID8/IGF4ZXMubGVuZ3RoKSk7XG4gIH1cblxuICAvKipcbiAgICogU29ydHMgYSBnaXZlbiBhcnJheSBiYXNlZCBvbiB0aGUgaW5kaWNlcyBpbiB0aGUgUGVybSBhcnJheVxuICAgKiBVc2VkIGluIFRyYW5zcG9zZVxuICAgKiBAcGFyYW0gYSBBcnJheSB0byBiZSBzb3J0ZWQgc3VjaCBhcyBkaW1zIG9yIHN0cmlkZXNcbiAgICogQHBhcmFtIHBlcm0gUGVybSBnaXZlbjsgaWYgbnVsbCBhIHdpbGwgYmUgcmV2ZXJzZWRcbiAgICovXG4gIHN0YXRpYyBzb3J0QmFzZWRPblBlcm0oYTogcmVhZG9ubHkgbnVtYmVyW10sIHBlcm0/OiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAocGVybSkge1xuICAgICAgcmV0dXJuIHBlcm0ubWFwKCh2KSA9PiBhW3ZdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGEuc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhZHMgYSBnaXZlbiBzaGFwZSBhY2NvcmRpbmcgdG8gdGhlIHBhZGRpbmcgdmFsdWVzXG4gICAqIEBwYXJhbSBkaW1zIHNoYXBlIG9mIHRoZSBUZW5zb3IgdG8gYmUgcGFkZGVkXG4gICAqIEBwYXJhbSBwYWQgcGFkIHZhbHVlc1xuICAgKi9cbiAgc3RhdGljIHBhZFNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBwYWQ6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IHJhbmsgPSBkaW1zLmxlbmd0aDtcbiAgICByZXR1cm4gZGltcy5tYXAoKHYsIGkpID0+IHYgKyBwYWRbaV0gKyBwYWRbaSArIHJhbmtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB0d28gc2hhcGVzIGFyZSBpZGVudGljYWxcbiAgICogQHBhcmFtIHNoYXBlMVxuICAgKiBAcGFyYW0gc2hhcGUyXG4gICAqL1xuICBzdGF0aWMgYXJlRXF1YWwoc2hhcGUxOiByZWFkb25seSBudW1iZXJbXSwgc2hhcGUyOiByZWFkb25seSBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChzaGFwZTEubGVuZ3RoICE9PSBzaGFwZTIubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBzaGFwZTEuZXZlcnkoKHYsIGkpID0+IHYgPT09IHNoYXBlMltpXSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBvb2xDb252VXRpbCB7XG4gIC8qKlxuICAgKiBBZGp1c3QgdGhlIGtlcm5lbCwgc3RyaWRlcywgcGFkcyB0byBjb3JyZWN0IHJhbmsuIFNldCB0byBkZWZhdWx0IHZhbHVlIGlmIG5vdCBwcmVzZW50XG4gICAqIEBwYXJhbSBpc0dsb2JhbE9wZXJhdG9yIElmIHRydWUsIHBlcmZvcm0gZ2xvYmFsIHBvb2xpbmcuXG4gICAqIEBwYXJhbSBpbnB1dERpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb24uXG4gICAqIEBwYXJhbSBrZXJuZWxTaGFwZSBUaGUgc2l6ZSBvZiB0aGUga2VybmVsIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIHN0cmlkZXMgU3RyaWRlIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGRpbGF0aW9ucyBEaWxhdGlvbiBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqL1xuICBzdGF0aWMgYWRqdXN0UG9vbEF0dHJpYnV0ZXMoXG4gICAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGtlcm5lbFNoYXBlOiBudW1iZXJbXSxcbiAgICBzdHJpZGVzOiBudW1iZXJbXSxcbiAgICBkaWxhdGlvbnM6IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICApOiB2b2lkIHtcbiAgICBpZiAoIWlzR2xvYmFsT3BlcmF0b3IgJiYga2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dERpbXMubGVuZ3RoIC0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Ygc3BlY2lmaWVkIGtlcm5lbCBzaGFwZXMgc2hvdWxkIGJlIDIgbGVzcyB0aGFuIGxlbmd0aCBvZiBpbnB1dCBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKGlzR2xvYmFsT3BlcmF0b3IpIHtcbiAgICAgIC8vIGFkanVzdCBrZXJuZWwgc2hhcGUgdG8gY292ZXIgdGhlIGlucHV0IGRpbXNcbiAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGlucHV0RGltcy5sZW5ndGggLSAyOyBkaW0rKykge1xuICAgICAgICBpZiAoZGltID49IGtlcm5lbFNoYXBlLmxlbmd0aCkge1xuICAgICAgICAgIGtlcm5lbFNoYXBlLnB1c2goaW5wdXREaW1zW2RpbSArIDJdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBrZXJuZWxTaGFwZVtkaW1dID0gaW5wdXREaW1zW2RpbSArIDJdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRqdXN0IHN0cmlkZXMgbGVuZ3RoIHRvIG1hdGNoIGtlcm5lbCBzaGFwZSBsZW5ndGhcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGg7IGRpbSsrKSB7XG4gICAgICBpZiAoZGltIDwgc3RyaWRlcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHN0cmlkZXNbZGltXSA8IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmlkZXMgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cmlkZXMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGp1c3QgZGlsYXRpb24gdmFsdWVcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGg7IGRpbSsrKSB7XG4gICAgICBpZiAoZGltIDwgZGlsYXRpb25zLmxlbmd0aCkge1xuICAgICAgICBpZiAoZGlsYXRpb25zW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkaWxhdGlvbnMgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpbGF0aW9ucy5wdXNoKDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkanVzdCBwYWRzIGxlbmd0aCB0byBtYXRjaCAyICoga2VybmVsIHNoYXBlIGxlbmd0aFxuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aCAqIDI7IGRpbSsrKSB7XG4gICAgICBpZiAoZGltIDwgcGFkcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHBhZHNbZGltXSA8IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhZCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFkcy5wdXNoKDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNhbml0eSBjaGVja3MgZm9yIHZhbHVlcyBpbiBrZXJuZWwgc2hhcGVzIGFuZCBwYWRzXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGtlcm5lbFNoYXBlW2RpbV0gPD0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2tlcm5lbCBzaGFwZXMgbmVlZCB0byBiZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFkc1tkaW1dID49IGtlcm5lbFNoYXBlW2RpbV0gfHwgcGFkc1tkaW0gKyBrZXJuZWxTaGFwZS5sZW5ndGhdID49IGtlcm5lbFNoYXBlW2RpbV0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYWRzIHNob3VsZCBiZSBzbWFsbGVyIHRoYW4ga2VybmVsJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gYWRqdXN0IHBhZCB2YWx1ZXMgYmFzZWQgb24gJ2F1dG9QYWQnIGF0dHJpYnV0ZVxuICBzdGF0aWMgYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgaXNDaGFubmVsTGFzdDogYm9vbGVhbixcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApOiB2b2lkIHtcbiAgICBpZiAoIWF1dG9QYWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFkcy5sZW5ndGggIT09IDIgKiAoaW5wdXREaW1zLmxlbmd0aCAtIDIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBwYWRzIHNob3VsZCBiZSB0d2ljZSB0aGUgbGVuZ3RoIG9mIGRhdGEgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChzdHJpZGVzLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHN0cmlkZXMgc2hvdWxkIGJlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKGtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIGtlcm5lbCBzaGFwZXMgc2hvdWxkIGJlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICBQb29sQ29udlV0aWwuYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgICAgIGlucHV0RGltc1tkaW0gKyAoaXNDaGFubmVsTGFzdCA/IDEgOiAyKV0sXG4gICAgICAgIHN0cmlkZXNbZGltXSxcbiAgICAgICAgZGlsYXRpb25zW2RpbV0sXG4gICAgICAgIGtlcm5lbFNoYXBlW2RpbV0sXG4gICAgICAgIHBhZHMsXG4gICAgICAgIGRpbSxcbiAgICAgICAgZGltICsgaW5wdXREaW1zLmxlbmd0aCAtIDIsXG4gICAgICAgIGF1dG9QYWQsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIG91dHB1dCBzaGFwZSBmb3IgUG9vbCBvcHMgYmFzZWQgb24gaW5wdXQgYXR0cmlidXRlcy4gKFNob3VsZCBiZSB1c2VkIG9ubHkgZm9yIFBvb2wgb3BzKVxuICAgKiBAcGFyYW0gaXNHbG9iYWxPcGVyYXRvciBJZiB0cnVlLCBwZXJmb3JtIGdsb2JhbCBwb29saW5nLlxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzBdLmRpbXMpXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBkaWxhdGlvbnMgRGlsYXRpb24gYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBhdXRvUGFkIERFUFJFQ0FURUQgYXR0cmlidXRlIHN1cHBvcnRlZCBmb3IgbGVnYWN5IG1vZGVscy4gU3BlY2lmaWVzIGhvdyB0byBpbXBsaWNpdGx5IGNhbGN1bGF0ZSBwYWRzIGluIGVhY2hcbiAgICogICAgIGRpbWVuc2lvbi4gQ2FuIHRha2UgdmFsdWVzIE5PVFNFVCwgU0FNRV9VUFBFUiwgU0FNRV9MT1dFUiwgb3IgVkFMSUQuXG4gICAqL1xuICBzdGF0aWMgY29tcHV0ZVBvb2xPdXRwdXRTaGFwZShcbiAgICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgc3RyaWRlczogbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKTogbnVtYmVyW10ge1xuICAgIGlmIChpbnB1dERpbXMubGVuZ3RoIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hhcGUgbXVzdCBiZSBvZiBzaXplIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJhdGNoIHNpemUgYW5kIG51bWJlciBvZiBjaGFubmVscyBvZiBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW2lucHV0RGltc1swXSwgaW5wdXREaW1zWzFdXTtcblxuICAgIFBvb2xDb252VXRpbC5jb21wdXRlU2hhcGVIZWxwZXIoXG4gICAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICAgICAgaW5wdXREaW1zLFxuICAgICAgb3V0cHV0RGltcyxcbiAgICAgIHN0cmlkZXMsXG4gICAgICBkaWxhdGlvbnMsXG4gICAgICBrZXJuZWxTaGFwZSxcbiAgICAgIHBhZHMsXG4gICAgICBhdXRvUGFkLFxuICAgICk7XG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBvdXRwdXQgc2hhcGUgZm9yIENvbnYgb3AgYmFzZWQgb24gaW5wdXQgYXR0cmlidXRlcy4gKFNob3VsZCBiZSB1c2VkIG9ubHkgZm9yIENvbnYgb3ApXG4gICAqIEBwYXJhbSBpbnB1dERpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb24uIChpbnB1dHNbMF0uZGltcylcbiAgICogQHBhcmFtIGZpbHRlckRpbXMgVGhlIGZpbHRlciB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzFdLmRpbXMpXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBrZXJuZWxTaGFwZSBUaGUgc2l6ZSBvZiB0aGUga2VybmVsIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIHBhZHMgUGFkZGluZyBmb3IgdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGF1dG9QYWQgREVQUkVDQVRFRCBhdHRyaWJ1dGUgc3VwcG9ydGVkIGZvciBsZWdhY3kgbW9kZWxzLiBTcGVjaWZpZXMgaG93IHRvIGltcGxpY2l0bHkgY2FsY3VsYXRlIHBhZHMgaW4gZWFjaFxuICAgKiAgICAgZGltZW5zaW9uLiBDYW4gdGFrZSB2YWx1ZXMgTk9UU0VULCBTQU1FX1VQUEVSLCBTQU1FX0xPV0VSLCBvciBWQUxJRC5cbiAgICovXG4gIHN0YXRpYyBjb21wdXRlQ29udk91dHB1dFNoYXBlKFxuICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgZmlsdGVyRGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgc3RyaWRlczogbnVtYmVyW10sXG4gICAgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sXG4gICAgcGFkczogbnVtYmVyW10sXG4gICAgYXV0b1BhZD86IHN0cmluZyxcbiAgKTogbnVtYmVyW10ge1xuICAgIGlmIChpbnB1dERpbXMubGVuZ3RoIDw9IDAgfHwgZmlsdGVyRGltcy5sZW5ndGggPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciBkaW1zIG9yIGludmFsaWQgZmlsdGVyIHRlbnNvciBkaW1zJyk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJhdGNoIHNpemUgYW5kIG51bWJlciBvZiBjaGFubmVscyBvZiBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW2lucHV0RGltc1swXSwgZmlsdGVyRGltc1swXV07XG5cbiAgICBQb29sQ29udlV0aWwuY29tcHV0ZVNoYXBlSGVscGVyKGZhbHNlLCBpbnB1dERpbXMsIG91dHB1dERpbXMsIHN0cmlkZXMsIGRpbGF0aW9ucywga2VybmVsU2hhcGUsIHBhZHMsIGF1dG9QYWQpO1xuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLy8gd2lsbCBjb21wdXRlIG91dHB1dCBzaGFwZXMgZm9yIGRhdGEgZGltZW5zaW9ucyBPTkxZIChpLmUuKSBubyBiYXRjaCBzaXplIGFuZCBjaGFubmVsc1xuICAvLyBjYWxsZWQgYnkgY29tcHV0ZVBvb2xPdXRwdXRTaGFwZSgpIGFuZCBjb21wdXRlQ29udk91dHB1dFNoYXBlKClcbiAgLy8gYWRqdXN0IHBhZHMgYmFzZWQgb24gJ2F1dG9QYWQnIGF0dHJpYnV0ZSBwcmlvciB0byBzaGFwZSBjb21wdXRhdGlvblxuICBwcml2YXRlIHN0YXRpYyBjb21wdXRlU2hhcGVIZWxwZXIoXG4gICAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbixcbiAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIG91dHB1dERpbXM6IG51bWJlcltdLFxuICAgIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIHBhZHM6IG51bWJlcltdLFxuICAgIGF1dG9QYWQ/OiBzdHJpbmcsXG4gICkge1xuICAgIGlmIChpc0dsb2JhbE9wZXJhdG9yKSB7XG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKDEpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgb3V0cHV0RGltcy5wdXNoKFxuICAgICAgICAgIFBvb2xDb252VXRpbC5hZGp1c3RQYWRBbmRSZXR1cm5TaGFwZShcbiAgICAgICAgICAgIGlucHV0RGltc1tkaW0gKyAyXSxcbiAgICAgICAgICAgIHN0cmlkZXNbZGltXSxcbiAgICAgICAgICAgIGRpbGF0aW9uc1tkaW1dLFxuICAgICAgICAgICAga2VybmVsU2hhcGVbZGltXSxcbiAgICAgICAgICAgIHBhZHMsXG4gICAgICAgICAgICBkaW0sXG4gICAgICAgICAgICBkaW0gKyBpbnB1dERpbXMubGVuZ3RoIC0gMixcbiAgICAgICAgICAgIGF1dG9QYWQsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBoZWxwZXIgZm9yIGNvbXB1dGVTaGFwZUhlbHBlcigpIGFuZCBhZGp1c3RQYWRzQmFzZWRPbkF1dG9QYWQoKVxuICAvLyBhZGp1c3RzIHBhZCB2YWx1ZSBmb3IgZ2l2ZW4gJ2F1dG9QYWQnIHN0cmluZyBhbmQgY29tcHV0ZXMgb3V0cHV0IHNoYXBlIGFsb25nIGEgcGFydGljdWxhciBkaW1lbnNpb25cbiAgcHJpdmF0ZSBzdGF0aWMgYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgaW5TaXplOiBudW1iZXIsXG4gICAgc3RyaWRlOiBudW1iZXIsXG4gICAgZGlsYXRpb246IG51bWJlcixcbiAgICBrZXJuZWw6IG51bWJlcixcbiAgICBwYWRzOiBudW1iZXJbXSxcbiAgICBwYWRIZWFkSW5kZXg6IG51bWJlcixcbiAgICBwYWRUYWlsSW5kZXg6IG51bWJlcixcbiAgICBhdXRvUGFkPzogc3RyaW5nLFxuICApOiBudW1iZXIge1xuICAgIGNvbnN0IGRrZXJuZWwgPSBkaWxhdGlvbiAqIChrZXJuZWwgLSAxKSArIDE7XG4gICAgaWYgKGF1dG9QYWQgJiYgYXV0b1BhZCAhPT0gJ05PVFNFVCcpIHtcbiAgICAgIHN3aXRjaCAoYXV0b1BhZCkge1xuICAgICAgICBjYXNlICdWQUxJRCc6XG4gICAgICAgICAgcGFkc1twYWRIZWFkSW5kZXhdID0gMDtcbiAgICAgICAgICBwYWRzW3BhZFRhaWxJbmRleF0gPSAwO1xuICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKChpblNpemUgLSBka2VybmVsKSAvIHN0cmlkZSArIDEpO1xuICAgICAgICBjYXNlICdTQU1FX0xPV0VSJzpcbiAgICAgICAgY2FzZSAnU0FNRV9VUFBFUic6XG4gICAgICAgICAgaWYgKGRpbGF0aW9uICE9PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbGF0aW9uIG5vdCBzdXBwb3J0ZWQgZm9yIFNBTUVfVVBQRVIgb3IgU0FNRV9MT1dFUicpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBsZWdhY3lUYXJnZXRTaXplID0gKGluU2l6ZSArIHN0cmlkZSAtIDEpIC8gc3RyaWRlO1xuICAgICAgICAgICAgY29uc3QgcGFkTmVlZGVkID0gKGxlZ2FjeVRhcmdldFNpemUgLSAxKSAqIHN0cmlkZSArIGtlcm5lbCAtIGluU2l6ZTtcbiAgICAgICAgICAgIHBhZHNbcGFkSGVhZEluZGV4XSA9IGF1dG9QYWQgPT09ICdTQU1FX0xPV0VSJyA/IE1hdGguZmxvb3IoKHBhZE5lZWRlZCArIDEpIC8gMikgOiBNYXRoLmZsb29yKHBhZE5lZWRlZCAvIDIpO1xuICAgICAgICAgICAgcGFkc1twYWRUYWlsSW5kZXhdID0gcGFkTmVlZGVkIC0gcGFkc1twYWRIZWFkSW5kZXhdO1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKGluU2l6ZSArIHBhZE5lZWRlZCAtIGtlcm5lbCkgLyBzdHJpZGUgKyAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBBdXRvUGFkIHR5cGUnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKGluU2l6ZSArIHBhZHNbcGFkSGVhZEluZGV4XSArIHBhZHNbcGFkVGFpbEluZGV4XSAtIGRrZXJuZWwpIC8gc3RyaWRlICsgMSk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBHZW1tVXRpbCB7XG4gIC8vIHdpbGwgbWFrZSBzdXJlIGlucHV0IHNoYXBlcyBhcmUgY29tcGF0aWJsZSBmb3IgdGhpcyBvcFxuICAvLyBhbmQgcmV0dXJuIGJhY2sgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgaW4gdGhlIGZvcm0gb2YgYSB0dXBsZVxuICAvLyB3aWxsIHRocm93IGV4Y2VwdGlvbiBpZiB0aGUgaW5wdXQgc2hhcGVzIGFyZSBub3QgY29tcGF0aWJsZVxuICBzdGF0aWMgZ2V0U2hhcGVPZkdlbW1SZXN1bHQoXG4gICAgbGVmdFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICB0cmFuc0xlZnQ6IGJvb2xlYW4sXG4gICAgcmlnaHRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgdHJhbnNSaWdodDogYm9vbGVhbixcbiAgICBiaWFzU2hhcGU/OiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChsZWZ0U2hhcGUubGVuZ3RoICE9PSAyIHx8IHJpZ2h0U2hhcGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NoYXBlIG5lZWQgdG8gYmUgb2Ygc2l6ZSAyJyk7XG4gICAgfVxuXG4gICAgbGV0IE06IG51bWJlcjtcbiAgICBsZXQgSzogbnVtYmVyO1xuICAgIGxldCBOOiBudW1iZXI7XG5cbiAgICBpZiAodHJhbnNMZWZ0KSB7XG4gICAgICBNID0gbGVmdFNoYXBlWzFdO1xuICAgICAgSyA9IGxlZnRTaGFwZVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgTSA9IGxlZnRTaGFwZVswXTtcbiAgICAgIEsgPSBsZWZ0U2hhcGVbMV07XG4gICAgfVxuXG4gICAgbGV0IGtEaW0gPSAtMTtcblxuICAgIGlmICh0cmFuc1JpZ2h0KSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVswXTtcbiAgICAgIGtEaW0gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVsxXTtcbiAgICAgIGtEaW0gPSAwO1xuICAgIH1cblxuICAgIGlmIChyaWdodFNoYXBlW2tEaW1dICE9PSBLKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RpbWVuc2lvbiBtaXNtYXRjaCcpO1xuICAgIH1cblxuICAgIGlmIChNIDw9IDAgfHwgTiA8PSAwIHx8IEsgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNoYXBlIHNwZWNpZmllZCcpO1xuICAgIH1cblxuICAgIGlmIChiaWFzU2hhcGUgJiYgIUJyb2FkY2FzdFV0aWwuaXNWYWxpZEJyb2FkY2FzdChiaWFzU2hhcGUsIFtNLCBOXSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ2VtbTogaW52YWxpZCBiaWFzIHNoYXBlIGZvciBicm9hZGNhc3QnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW00sIE4sIEtdO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBNSU5fQ0xJUCA9IC0zLjQwMjgyMzQ2NjM4NTI4ODZlMzg7XG5leHBvcnQgY29uc3QgTUFYX0NMSVAgPSAzLjQwMjgyMzQ2NjM4NTI4ODZlMzg7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvciB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IHRlbnNvclR5cGVUb1R5cGVkQXJyYXlDb25zdHJ1Y3RvciB9IGZyb20gJy4uL3dhc20tY29tbW9uJztcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVZpZXcgPSAoXG4gIGRhdGFCdWZmZXI6IEFycmF5QnVmZmVyLFxuICB0eXBlOiBUZW5zb3IuVHlwZSxcbik6XG4gIHwgSW50MzJBcnJheVxuICB8IFVpbnQzMkFycmF5XG4gIHwgQmlnSW50NjRBcnJheVxuICB8IEJpZ1VpbnQ2NEFycmF5XG4gIHwgVWludDhBcnJheVxuICB8IEZsb2F0MzJBcnJheVxuICB8IEZsb2F0NjRBcnJheVxuICB8IEludDhBcnJheVxuICB8IEludDE2QXJyYXlcbiAgfCBVaW50MTZBcnJheSA9PiBuZXcgKHRlbnNvclR5cGVUb1R5cGVkQXJyYXlDb25zdHJ1Y3Rvcih0eXBlKSkoZGF0YUJ1ZmZlcik7XG5cbi8qKlxuICogYSBUZW5zb3JWaWV3IGRvZXMgbm90IG93biB0aGUgZGF0YS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JWaWV3IHtcbiAgcmVhZG9ubHkgZGF0YTogbnVtYmVyO1xuICByZWFkb25seSBkYXRhVHlwZTogbnVtYmVyO1xuICByZWFkb25seSBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcblxuICAvKipcbiAgICogZ2V0IGEgRmxvYXQxNkFycmF5IGRhdGEgdmlldyBvZiB0aGUgdGVuc29yIGRhdGEuIHRlbnNvciBkYXRhIG11c3QgYmUgb24gQ1BVLlxuICAgKi9cbiAgZ2V0VWludDE2QXJyYXkoKTogVWludDE2QXJyYXk7XG5cbiAgLyoqXG4gICAqIGdldCBhIEZsb2F0MzJBcnJheSBkYXRhIHZpZXcgb2YgdGhlIHRlbnNvciBkYXRhLiB0ZW5zb3IgZGF0YSBtdXN0IGJlIG9uIENQVS5cbiAgICovXG4gIGdldEZsb2F0MzJBcnJheSgpOiBGbG9hdDMyQXJyYXk7XG5cbiAgLyoqXG4gICAqIGdldCBhIEJpZ0ludDY0QXJyYXkgZGF0YSB2aWV3IG9mIHRoZSB0ZW5zb3IgZGF0YS4gdGVuc29yIGRhdGEgbXVzdCBiZSBvbiBDUFUuXG4gICAqL1xuICBnZXRCaWdJbnQ2NEFycmF5KCk6IEJpZ0ludDY0QXJyYXk7XG5cbiAgLyoqXG4gICAqIGdldCBhIEludDMyQXJyYXkgZGF0YSB2aWV3IG9mIHRoZSB0ZW5zb3IgZGF0YS4gdGVuc29yIGRhdGEgbXVzdCBiZSBvbiBDUFUuXG4gICAqL1xuICBnZXRJbnQzMkFycmF5KCk6IEludDMyQXJyYXk7XG5cbiAgLyoqXG4gICAqIGdldCBhIFVpbnQxNkFycmF5IGRhdGEgdmlldyBvZiB0aGUgdGVuc29yIGRhdGEuIHRlbnNvciBkYXRhIG11c3QgYmUgb24gQ1BVLlxuICAgKi9cbiAgZ2V0VWludDE2QXJyYXkoKTogVWludDE2QXJyYXk7XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIG5ldyB0ZW5zb3IgdmlldyB3aXRoIHRoZSBzYW1lIGRhdGEgYnV0IGRpZmZlcmVudCBkaW1lbnNpb25zLlxuICAgKi9cbiAgcmVzaGFwZShuZXdEaW1zOiByZWFkb25seSBudW1iZXJbXSk6IFRlbnNvclZpZXc7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFdlYk5OQmFja2VuZCB9IGZyb20gJy4uL2JhY2tlbmQtd2Vibm4nO1xuaW1wb3J0IHsgdGVuc29yVHlwZVRvVHlwZWRBcnJheUNvbnN0cnVjdG9yIH0gZnJvbSAnLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgTE9HX0RFQlVHIH0gZnJvbSAnLi4vbG9nJztcblxuLy8gV2ViTk4gQVBJIGN1cnJlbnRseSBkb2VzIG5vdCBoYXZlIGEgVHlwZVNjcmlwdCBkZWZpbml0aW9uIGZpbGUuIFRoaXMgZmlsZSBpcyBhIHdvcmthcm91bmQgd2l0aCB0eXBlcyBnZW5lcmF0ZWQgZnJvbVxuLy8gV2ViTk4gQVBJIHNwZWNpZmljYXRpb24uXG4vLyBodHRwczovL2dpdGh1Yi5jb20vd2VibWFjaGluZWxlYXJuaW5nL3dlYm5uL2lzc3Vlcy82Nzdcbi8vLyA8cmVmZXJlbmNlIHBhdGg9XCJ3ZWJubi5kLnRzXCIgLz5cblxuLyoqXG4gKiBNYXAgZnJvbSBNTE9wZXJhbmREYXRhVHlwZSB0byBzaXplIGluIGJpdHMuIFVzaW5nIGJpdHMgaW5zdGVhZCBvZiBieXRlcyB0byBhdm9pZCBwb3NzaWJsZSBwcmVjaXNpb24gbG9zcyBvbiBpbnQ0IGFuZCB1aW50NC5cbiAqL1xuY29uc3Qgd2Vibm5EYXRhVHlwZVRvU2l6ZSA9IG5ldyBNYXA8TUxPcGVyYW5kRGF0YVR5cGUsIG51bWJlcj4oW1xuICBbJ2Zsb2F0MzInLCAzMl0sXG4gIFsnZmxvYXQxNicsIDE2XSxcbiAgWydpbnQzMicsIDMyXSxcbiAgWyd1aW50MzInLCAzMl0sXG4gIFsnaW50NjQnLCA2NF0sXG4gIFsndWludDY0JywgNjRdLFxuICBbJ2ludDgnLCA4XSxcbiAgWyd1aW50OCcsIDhdLFxuICBbJ2ludDQnLCA0XSxcbiAgWyd1aW50NCcsIDRdLFxuXSk7XG5cbi8vIENvbnZlcnQgaW50ZWdlciBkYXRhIHRvIGFuIEludDMyQXJyYXkgYnVmZmVyLlxuLy8gU3VwcG9ydHMgY29udmVyc2lvbiBmcm9tIGludDY0LCB1aW50NjQsIHVpbnQzMiwgaW50OCBhbmQgdWludDggdG8gaW50MzIuXG5leHBvcnQgY29uc3QgY29udmVydERhdGFUb0ludDMyID0gKGRhdGE6IFVpbnQ4QXJyYXksIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSk6IFVpbnQ4QXJyYXkgPT4ge1xuICBpZiAoZGF0YVR5cGUgPT09ICdpbnQzMicpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIGNvbnN0IGRhdGFUeXBlU2l6ZSA9IHdlYm5uRGF0YVR5cGVUb1NpemUuZ2V0KGRhdGFUeXBlKTtcbiAgaWYgKCFkYXRhVHlwZVNpemUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFdlYk5OIGJhY2tlbmQgZG9lcyBub3Qgc3VwcG9ydCBkYXRhIHR5cGU6ICR7ZGF0YVR5cGV9YCk7XG4gIH1cbiAgY29uc3QgYnl0ZXNQZXJFbGVtZW50ID0gZGF0YVR5cGVTaXplIC8gODtcbiAgLy8gTWFrZSBzdXJlIHRoZSBkYXRhIGxlbmd0aCBpcyBhIG11bHRpcGxlIG9mIHRoZSBkYXRhIHR5cGUgc2l6ZS5cbiAgaWYgKGRhdGEuYnl0ZUxlbmd0aCAlIGJ5dGVzUGVyRWxlbWVudCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBVaW50OEFycmF5IGxlbmd0aCAtIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAke2J5dGVzUGVyRWxlbWVudH0uYCk7XG4gIH1cblxuICAvLyBDb252ZXJ0IFVpbnQ4QXJyYXkgdG8gb3JpZ2luYWwgdHlwZWQgYXJyYXkuXG4gIGNvbnN0IG51bUVsZW1lbnRzID0gZGF0YS5ieXRlTGVuZ3RoIC8gYnl0ZXNQZXJFbGVtZW50O1xuICBjb25zdCBvcmlnaW5hbEFycmF5ID0gbmV3ICh0ZW5zb3JUeXBlVG9UeXBlZEFycmF5Q29uc3RydWN0b3IoZGF0YVR5cGUpKShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0LCBudW1FbGVtZW50cyk7XG5cbiAgc3dpdGNoIChkYXRhVHlwZSkge1xuICAgIGNhc2UgJ2ludDY0JzpcbiAgICBjYXNlICd1aW50NjQnOiB7XG4gICAgICAvLyBDb252ZXJ0IG9yaWdpbmFsIHR5cGVkIGFycmF5IHRvIEludDMyQXJyYXkuXG4gICAgICBjb25zdCBpbnQzMkFycmF5ID0gbmV3IEludDMyQXJyYXkobnVtRWxlbWVudHMpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1FbGVtZW50czsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gb3JpZ2luYWxBcnJheVtpXTtcblxuICAgICAgICAvLyBDaGVjayBmb3Igb3ZlcmZsb3cuXG4gICAgICAgIGlmICh2YWx1ZSA+IDIxNDc0ODM2NDduIHx8IHZhbHVlIDwgLTIxNDc0ODM2NDhuKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4gbm90IGNvbnZlcnQgaW50NjQgZGF0YSB0byBpbnQzMiAtIHZhbHVlIG91dCBvZiByYW5nZS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGludDMyQXJyYXlbaV0gPSBOdW1iZXIodmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoaW50MzJBcnJheS5idWZmZXIpO1xuICAgIH1cbiAgICBjYXNlICdpbnQ4JzpcbiAgICBjYXNlICd1aW50OCc6XG4gICAgY2FzZSAndWludDMyJzoge1xuICAgICAgLy8gQ2hlY2sgZm9yIG92ZXJmbG93LlxuICAgICAgaWYgKGRhdGFUeXBlID09PSAndWludDMyJykge1xuICAgICAgICBpZiAob3JpZ2luYWxBcnJheS5zb21lKCh2YWx1ZSkgPT4gdmFsdWUgPiAyMTQ3NDgzNjQ3KSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuIG5vdCBjb252ZXJ0IHVpbnQzMiBkYXRhIHRvIGludDMyIC0gdmFsdWUgb3V0IG9mIHJhbmdlLmApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBDb252ZXJ0IG9yaWdpbmFsIHR5cGVkIGFycmF5IHRvIEludDMyQXJyYXkuXG4gICAgICBjb25zdCBpbnQzMkFycmF5ID0gSW50MzJBcnJheS5mcm9tKG9yaWdpbmFsQXJyYXksIE51bWJlcik7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoaW50MzJBcnJheS5idWZmZXIpO1xuICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIGNvbnZlcnNpb24gZnJvbSAke2RhdGFUeXBlfSB0byAnaW50MzInYCk7XG4gIH1cbn07XG5cbi8vIENvbnZlcnQgSW50MzJBcnJheSBkYXRhIHRvIG9yaWdpbmFsIGludGVnZXIgZGF0YSBidWZmZXIuXG4vLyBTdXBwb3J0cyBjb252ZXJzaW9uIGZyb20gaW50MzIgdG8gaW50NjQsIHVpbnQ2NCwgdWludDMyLCBpbnQ4IGFuZCB1aW50OC5cbmV4cG9ydCBjb25zdCBjb252ZXJ0SW50MzJUb0RhdGEgPSAoZGF0YTogVWludDhBcnJheSwgZGF0YVR5cGU6IE1MT3BlcmFuZERhdGFUeXBlKTogVWludDhBcnJheSA9PiB7XG4gIGlmIChkYXRhVHlwZSA9PT0gJ2ludDMyJykge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIHRoZSBkYXRhIGxlbmd0aCBpcyBhIG11bHRpcGxlIG9mIDQgYnl0ZXMgKEludDMyQXJyYXkpLlxuICBpZiAoZGF0YS5ieXRlTGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBVaW50OEFycmF5IGxlbmd0aCAtIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0IChpbnQzMikuJyk7XG4gIH1cblxuICAvLyBDb252ZXJ0IFVpbnQ4QXJyYXkgdG8gSW50MzJBcnJheS5cbiAgY29uc3QgbnVtRWxlbWVudHMgPSBkYXRhLmJ5dGVMZW5ndGggLyA0O1xuICBjb25zdCBpbnQzMkFycmF5ID0gbmV3IEludDMyQXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgbnVtRWxlbWVudHMpO1xuXG4gIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICBjYXNlICdpbnQ2NCc6IHtcbiAgICAgIGNvbnN0IGJpZ0ludDY0QXJyYXkgPSBCaWdJbnQ2NEFycmF5LmZyb20oaW50MzJBcnJheSwgQmlnSW50KTtcbiAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShiaWdJbnQ2NEFycmF5LmJ1ZmZlcik7XG4gICAgfVxuICAgIGNhc2UgJ3VpbnQ2NCc6IHtcbiAgICAgIGlmIChpbnQzMkFycmF5LnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSA8IDApKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBjb252ZXJ0IGludDMyIGRhdGEgdG8gdWluNjQgLSBuZWdhdGl2ZSB2YWx1ZSBmb3VuZC4nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJpZ1VpbnQ2NEFycmF5ID0gQmlnVWludDY0QXJyYXkuZnJvbShpbnQzMkFycmF5LCBCaWdJbnQpO1xuICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJpZ1VpbnQ2NEFycmF5LmJ1ZmZlcik7XG4gICAgfVxuICAgIGNhc2UgJ2ludDgnOiB7XG4gICAgICBpZiAoaW50MzJBcnJheS5zb21lKCh2YWx1ZSkgPT4gdmFsdWUgPCAtMTI4IHx8IHZhbHVlID4gMTI3KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBub3QgY29udmVydCBpbnQzMiBkYXRhIHRvIGludDggLSB2YWx1ZSBvdXQgb2YgcmFuZ2UuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBpbnQ4QXJyYXkgPSBJbnQ4QXJyYXkuZnJvbShpbnQzMkFycmF5LCBOdW1iZXIpO1xuICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGludDhBcnJheS5idWZmZXIpO1xuICAgIH1cbiAgICBjYXNlICd1aW50OCc6IHtcbiAgICAgIGlmIChpbnQzMkFycmF5LnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSA8IDAgfHwgdmFsdWUgPiAyNTUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBjb252ZXJ0IGludDMyIGRhdGEgdG8gdWludDggLSB2YWx1ZSBvdXQgb2YgcmFuZ2UuJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gVWludDhBcnJheS5mcm9tKGludDMyQXJyYXksIE51bWJlcik7XG4gICAgfVxuICAgIGNhc2UgJ3VpbnQzMic6IHtcbiAgICAgIGlmIChpbnQzMkFycmF5LnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSA8IDApKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBjb252ZXJ0IGludDMyIGRhdGEgdG8gdWludDMyIC0gbmVnYXRpdmUgdmFsdWUgZm91bmQuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCB1aW50MzJBcnJheSA9IFVpbnQzMkFycmF5LmZyb20oaW50MzJBcnJheSwgTnVtYmVyKTtcbiAgICAgIHJldHVybiBuZXcgVWludDhBcnJheSh1aW50MzJBcnJheS5idWZmZXIpO1xuICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIGNvbnZlcnNpb24gZnJvbSAnaW50MzInIHRvICR7ZGF0YVR5cGV9YCk7XG4gIH1cbn07XG5cbmV4cG9ydCB0eXBlIFRlbnNvcklkID0gbnVtYmVyO1xuXG4vKipcbiAqIE1hbmFnZXMgVGVuc29ySWQgdG8gTUxUZW5zb3IgbWFwcGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JNYW5hZ2VyIHtcbiAgLyoqXG4gICAqIFJlc2VydmUgYSBuZXcgVGVuc29ySWQuXG4gICAqL1xuICByZXNlcnZlVGVuc29ySWQoKTogVGVuc29ySWQ7XG4gIC8qKlxuICAgKiBSZWxlYXNlIGEgVGVuc29ySWQuXG4gICAqL1xuICByZWxlYXNlVGVuc29ySWQodGVuc29ySWQ6IFRlbnNvcklkKTogdm9pZDtcbiAgLyoqXG4gICAqIEVuc3VyZSBhIE1MVGVuc29yIGlzIGNyZWF0ZWQgZm9yIHRoZSBUZW5zb3JJZC5cbiAgICovXG4gIGVuc3VyZVRlbnNvcihcbiAgICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgICB0ZW5zb3JJZDogVGVuc29ySWQsXG4gICAgZGF0YVR5cGU6IE1MT3BlcmFuZERhdGFUeXBlLFxuICAgIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBjb3B5T2xkOiBib29sZWFuLFxuICApOiBQcm9taXNlPE1MVGVuc29yPjtcbiAgLyoqXG4gICAqIFVwbG9hZCBkYXRhIHRvIGEgTUxUZW5zb3IuXG4gICAqL1xuICB1cGxvYWQodGVuc29ySWQ6IFRlbnNvcklkLCBkYXRhOiBVaW50OEFycmF5KTogdm9pZDtcbiAgLyoqXG4gICAqIERvd25sb2FkIGRhdGEgZnJvbSBhIE1MVGVuc29yLlxuICAgKi9cbiAgZG93bmxvYWQodGVuc29ySWQ6IFRlbnNvcklkKTogUHJvbWlzZTxBcnJheUJ1ZmZlcj47XG4gIGRvd25sb2FkKHRlbnNvcklkOiBUZW5zb3JJZCwgZHN0VGVuc29yOiBBcnJheUJ1ZmZlclZpZXcgfCBBcnJheUJ1ZmZlcik6IFByb21pc2U8dW5kZWZpbmVkPjtcbiAgLyoqXG4gICAqIFJlbGVhc2UgYWxsIHRlbnNvcnMgZm9yIGEgZ2l2ZW4gc2Vzc2lvbi5cbiAgICovXG4gIHJlbGVhc2VUZW5zb3JzRm9yU2Vzc2lvbihzZXNzaW9uOiBudW1iZXIpOiB2b2lkO1xuICAvKipcbiAgICogUmVnaXN0ZXIgYW4gZXh0ZXJuYWxseSBjcmVhdGVkIE1MVGVuc29yIHdpdGggYSBnaXZlbiBzZXNzaW9uIGlkIGFuZCByZXR1cm4gYSBUZW5zb3JJZC5cbiAgICovXG4gIHJlZ2lzdGVyVGVuc29yKHNlc3Npb25JZDogbnVtYmVyLCBtbFRlbnNvcjogTUxUZW5zb3IsIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSwgc2hhcGU6IG51bWJlcltdKTogVGVuc29ySWQ7XG59XG5cbmxldCB0ZW5zb3JHdWlkID0gMTtcbmNvbnN0IGNyZWF0ZU5ld1RlbnNvcklkID0gKCk6IFRlbnNvcklkID0+IHRlbnNvckd1aWQrKztcblxuLyoqXG4gKiBNYXAgZnJvbSBkYXRhIHR5cGUgdG8gZmFsbGJhY2sgZGF0YSB0eXBlLlxuICogV2hlbiB0aGUgY29udGV4dCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBvcmlnaW5hbCBkYXRhIHR5cGUsIHVzZSBmYWxsYmFjayBkYXRhIHR5cGUgYXMgd29ya2Fyb3VuZC5cbiAqIE5vdGU6IEN1cnJlbnRseSwgd2Ugb25seSBzdXBwb3J0IGZhbGxiYWNrIHRvIGludDMyIGZvciBjZXJ0YWluIGludGVnZXIgZGF0YSB0eXBlcy5cbiAqL1xuY29uc3Qgd2Vibm5EYXRhVHlwZVRvRmFsbGJhY2sgPSBuZXcgTWFwPE1MT3BlcmFuZERhdGFUeXBlLCBNTE9wZXJhbmREYXRhVHlwZT4oW1xuICBbJ2ludDgnLCAnaW50MzInXSxcbiAgWyd1aW50OCcsICdpbnQzMiddLFxuICBbJ3VpbnQzMicsICdpbnQzMiddLFxuICBbJ2ludDY0JywgJ2ludDMyJ10sXG5dKTtcblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIGJ5dGUgbGVuZ3RoIG9mIGEgdGVuc29yIHdpdGggdGhlIGdpdmVuIGRhdGEgdHlwZSBhbmQgc2hhcGUuXG4gKi9cbmNvbnN0IGNhbGN1bGF0ZUJ5dGVMZW5ndGggPSAoZGF0YVR5cGU6IE1MT3BlcmFuZERhdGFUeXBlLCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXIgPT4ge1xuICBjb25zdCBkYXRhVHlwZVNpemUgPSB3ZWJubkRhdGFUeXBlVG9TaXplLmdldChkYXRhVHlwZSk7XG4gIGlmICghZGF0YVR5cGVTaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBXZWJOTiBiYWNrZW5kIGRvZXMgbm90IHN1cHBvcnQgZGF0YSB0eXBlOiAke2RhdGFUeXBlfWApO1xuICB9XG4gIHJldHVybiBzaGFwZS5sZW5ndGggPiAwID8gTWF0aC5jZWlsKChzaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKSAqIGRhdGFUeXBlU2l6ZSkgLyA4KSA6IDA7XG59O1xuXG4vKipcbiAqIFRlbnNvcldyYXBwZXIgd3JhcHMgYW4gTUxUZW5zb3IgYW5kIHByb3ZpZGVzIGEgd2F5IHRvIHRyYWNrIHRoZSBsYXN0IHNlc3Npb24gdGhhdCB1c2VkIGl0LlxuICovXG5jbGFzcyBUZW5zb3JXcmFwcGVyIHtcbiAgLy8gVGhlIGlkIG9mIHRoZSBsYXN0IHNlc3Npb24gdGhhdCB1c2VkIHRoaXMgdGVuc29yLlxuICBwdWJsaWMgc2Vzc2lvbklkOiBudW1iZXI7XG4gIC8vIFRoaXMgZmxhZyBpcyB1c2VkIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIGRhdGEgaGFzIGJlZW4gY29udmVydGVkIHRvIGZhbGxiYWNrIGRhdGEgdHlwZS5cbiAgcHVibGljIGlzRGF0YUNvbnZlcnRlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgbWxDb250ZXh0OiBNTENvbnRleHQ7XG4gIHByaXZhdGUgbWxUZW5zb3I6IE1MVGVuc29yO1xuICBwcml2YXRlIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZTtcbiAgLy8gRmFsbGJhY2sgZGF0YSB0eXBlIHRvIHVzZSB3aGVuIHRoZSBjb250ZXh0IGRvZXMgbm90IHN1cHBvcnQgdGhlIG9yaWdpbmFsIGRhdGEgdHlwZS5cbiAgcHJpdmF0ZSBmYWxsYmFja0RhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSB0ZW5zb3JTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgY29uc3RydWN0b3IoZGVzY3JpcHRvcjoge1xuICAgIHNlc3Npb25JZDogbnVtYmVyO1xuICAgIGNvbnRleHQ6IE1MQ29udGV4dDtcbiAgICB0ZW5zb3I6IE1MVGVuc29yO1xuICAgIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZTtcbiAgICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gICAgZmFsbGJhY2tEYXRhVHlwZT86IE1MT3BlcmFuZERhdGFUeXBlO1xuICB9KSB7XG4gICAgY29uc3QgeyBzZXNzaW9uSWQsIGNvbnRleHQsIHRlbnNvciwgZGF0YVR5cGUsIHNoYXBlLCBmYWxsYmFja0RhdGFUeXBlIH0gPSBkZXNjcmlwdG9yO1xuICAgIHRoaXMuc2Vzc2lvbklkID0gc2Vzc2lvbklkO1xuICAgIHRoaXMubWxDb250ZXh0ID0gY29udGV4dDtcbiAgICB0aGlzLm1sVGVuc29yID0gdGVuc29yO1xuICAgIHRoaXMuZGF0YVR5cGUgPSBkYXRhVHlwZTtcbiAgICB0aGlzLnRlbnNvclNoYXBlID0gc2hhcGU7XG4gICAgdGhpcy5mYWxsYmFja0RhdGFUeXBlID0gZmFsbGJhY2tEYXRhVHlwZTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdGVuc29yKCk6IE1MVGVuc29yIHtcbiAgICByZXR1cm4gdGhpcy5tbFRlbnNvcjtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdHlwZSgpOiBNTE9wZXJhbmREYXRhVHlwZSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVR5cGU7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGZhbGxiYWNrVHlwZSgpOiBNTE9wZXJhbmREYXRhVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmFsbGJhY2tEYXRhVHlwZTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgc2hhcGUoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLnRlbnNvclNoYXBlO1xuICB9XG5cbiAgcHVibGljIGdldCBieXRlTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZUJ5dGVMZW5ndGgodGhpcy5kYXRhVHlwZSwgdGhpcy50ZW5zb3JTaGFwZSk7XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiAnW1dlYk5OXSBUZW5zb3JXcmFwcGVyLmRlc3Ryb3knKTtcbiAgICB0aGlzLm1sVGVuc29yLmRlc3Ryb3koKTtcbiAgfVxuXG4gIHB1YmxpYyB3cml0ZShkYXRhOiBVaW50OEFycmF5KTogdm9pZCB7XG4gICAgdGhpcy5tbENvbnRleHQud3JpdGVUZW5zb3IodGhpcy5tbFRlbnNvciwgZGF0YSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcmVhZCgpOiBQcm9taXNlPEFycmF5QnVmZmVyPjtcbiAgcHVibGljIGFzeW5jIHJlYWQoZHN0QnVmZmVyPzogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpOiBQcm9taXNlPEFycmF5QnVmZmVyIHwgdW5kZWZpbmVkPjtcbiAgcHVibGljIGFzeW5jIHJlYWQoZHN0QnVmZmVyPzogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpOiBQcm9taXNlPEFycmF5QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgaWYgKHRoaXMuZmFsbGJhY2tEYXRhVHlwZSkge1xuICAgICAgLy8gVGhpcyB0ZW5zb3IgaGFzIGJlZW4gZmFsbGJhY2sgdG8gaW50MzIgYXMgd29ya2Fyb3VuZCwgd2UgbmVlZCB0byByZWFkIGl0IGFzIGl0cyBvcmlnaW5hbCBpbnRlZ2VyIGRhdGEgdHlwZS5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLm1sQ29udGV4dC5yZWFkVGVuc29yKHRoaXMubWxUZW5zb3IpO1xuICAgICAgY29uc3Qgb3JpZ2luYWxEYXRhID0gY29udmVydEludDMyVG9EYXRhKG5ldyBVaW50OEFycmF5KGRhdGEpLCB0aGlzLmRhdGFUeXBlKTtcblxuICAgICAgaWYgKGRzdEJ1ZmZlcikge1xuICAgICAgICBjb25zdCB0YXJnZXRCdWZmZXIgPVxuICAgICAgICAgIGRzdEJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyXG4gICAgICAgICAgICA/IG5ldyBVaW50OEFycmF5KGRzdEJ1ZmZlcilcbiAgICAgICAgICAgIDogbmV3IFVpbnQ4QXJyYXkoZHN0QnVmZmVyLmJ1ZmZlciwgZHN0QnVmZmVyLmJ5dGVPZmZzZXQsIGRzdEJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgdGFyZ2V0QnVmZmVyLnNldChvcmlnaW5hbERhdGEpO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsRGF0YS5idWZmZXI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkc3RCdWZmZXIgPyB0aGlzLm1sQ29udGV4dC5yZWFkVGVuc29yKHRoaXMubWxUZW5zb3IsIGRzdEJ1ZmZlcikgOiB0aGlzLm1sQ29udGV4dC5yZWFkVGVuc29yKHRoaXMubWxUZW5zb3IpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjYW5SZXVzZVRlbnNvcihjb250ZXh0OiBNTENvbnRleHQsIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMubWxDb250ZXh0ID09PSBjb250ZXh0ICYmXG4gICAgICB0aGlzLmRhdGFUeXBlID09PSBkYXRhVHlwZSAmJlxuICAgICAgdGhpcy50ZW5zb3JTaGFwZS5sZW5ndGggPT09IHNoYXBlLmxlbmd0aCAmJlxuICAgICAgdGhpcy50ZW5zb3JTaGFwZS5ldmVyeSgodiwgaSkgPT4gdiA9PT0gc2hhcGVbaV0pXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRJc0RhdGFDb252ZXJ0ZWQoaXNDb252ZXJ0ZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmlzRGF0YUNvbnZlcnRlZCA9IGlzQ29udmVydGVkO1xuICB9XG59XG5cbi8qKlxuICogVGVuc29yVHJhY2tlciB0cmFja3MgdGhlIE1MVGVuc29yIGFuZCBwZW5kaW5nIHVwbG9hZCBkYXRhLlxuICpcbiAqIFdlIG5lZWQgdG8gdHJhY2sgdGhlIE1MVGVuc29yIGFuZCBwZW5kaW5nIHVwbG9hZCBkYXRhIGJlY2F1c2Ugd2UgZGVsYXkgdGhlIGNyZWF0aW9uIG9mIE1MVGVuc29yIHVudGlsXG4gKiB3ZSBrbm93IHRoZSBkYXRhIHR5cGUgYW5kIHNoYXBlLiBUaGlzIGlzIGJlY2F1c2UgV2ViTk4gb25seSBzdXBwb3J0IGNyZWF0aW5nIE1MVGVuc29ycyB3aXRoIGRhdGFUeXBlcyBhbmQgc2hhcGUuXG4gKi9cbmNsYXNzIFRlbnNvcklkVHJhY2tlciB7XG4gIHByaXZhdGUgYWN0aXZlVXBsb2FkPzogVWludDhBcnJheTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHRlbnNvck1hbmFnZXI6IFRlbnNvck1hbmFnZXJJbXBsLFxuICAgIHByaXZhdGUgd3JhcHBlcj86IFRlbnNvcldyYXBwZXIsXG4gICkge31cblxuICBwdWJsaWMgZ2V0IHRlbnNvcldyYXBwZXIoKTogVGVuc29yV3JhcHBlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMud3JhcHBlcjtcbiAgfVxuXG4gIHB1YmxpYyByZWxlYXNlVGVuc29yKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRlbnNvcldyYXBwZXIpIHtcbiAgICAgIHRoaXMudGVuc29yTWFuYWdlci5yZWxlYXNlVGVuc29yKHRoaXMudGVuc29yV3JhcHBlcik7XG4gICAgICB0aGlzLndyYXBwZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGVuc3VyZVRlbnNvcihcbiAgICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgICBkYXRhVHlwZTogTUxPcGVyYW5kRGF0YVR5cGUsXG4gICAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGNvcHlPbGQ6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8TUxUZW5zb3I+IHtcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy50ZW5zb3JNYW5hZ2VyLmdldE1MQ29udGV4dChzZXNzaW9uSWQpO1xuICAgIGxldCBmYWxsYmFja0RhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSB8IHVuZGVmaW5lZDtcbiAgICAvLyBDaGVjayBpZiB0aGUgY29udGV4dCBzdXBwb3J0cyB0aGUgZGF0YSB0eXBlLiBJZiBub3QsIHRyeSB0byB1c2UgdGhlIGZhbGxiYWNrIGRhdGEgdHlwZS5cbiAgICBpZiAoIWNvbnRleHQub3BTdXBwb3J0TGltaXRzKCkuaW5wdXQuZGF0YVR5cGVzLmluY2x1ZGVzKGRhdGFUeXBlKSkge1xuICAgICAgZmFsbGJhY2tEYXRhVHlwZSA9IHdlYm5uRGF0YVR5cGVUb0ZhbGxiYWNrLmdldChkYXRhVHlwZSk7XG4gICAgICBpZiAoIWZhbGxiYWNrRGF0YVR5cGUgfHwgIWNvbnRleHQub3BTdXBwb3J0TGltaXRzKCkuaW5wdXQuZGF0YVR5cGVzLmluY2x1ZGVzKGZhbGxiYWNrRGF0YVR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgV2ViTk4gYmFja2VuZCBkb2VzIG5vdCBzdXBwb3J0IGRhdGEgdHlwZTogJHtkYXRhVHlwZX1gKTtcbiAgICAgIH1cbiAgICAgIExPR19ERUJVRyhcbiAgICAgICAgJ3ZlcmJvc2UnLFxuICAgICAgICAoKSA9PiBgW1dlYk5OXSBUZW5zb3JJZFRyYWNrZXIuZW5zdXJlVGVuc29yOiBmYWxsYmFjayBkYXRhVHlwZSBmcm9tICR7ZGF0YVR5cGV9IHRvICR7ZmFsbGJhY2tEYXRhVHlwZX1gLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy53cmFwcGVyKSB7XG4gICAgICBpZiAodGhpcy53cmFwcGVyLmNhblJldXNlVGVuc29yKGNvbnRleHQsIGRhdGFUeXBlLCBzaGFwZSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud3JhcHBlci50ZW5zb3I7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoY29weU9sZCkge1xuICAgICAgICAgIGlmICh0aGlzLndyYXBwZXIuYnl0ZUxlbmd0aCAhPT0gY2FsY3VsYXRlQnl0ZUxlbmd0aChkYXRhVHlwZSwgc2hhcGUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBjb3B5IGRhdGEgdG8gdGVuc29yIHdpdGggZGlmZmVyZW50IHNpemUuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuYWN0aXZlVXBsb2FkID0gbmV3IFVpbnQ4QXJyYXkoYXdhaXQgdGhpcy53cmFwcGVyLnJlYWQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50ZW5zb3JNYW5hZ2VyLnJlbGVhc2VUZW5zb3IodGhpcy53cmFwcGVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZVxuICAgIGNvbnN0IHVzYWdlID0gdHlwZW9mIE1MVGVuc29yVXNhZ2UgPT0gJ3VuZGVmaW5lZCcgPyB1bmRlZmluZWQgOiBNTFRlbnNvclVzYWdlLlJFQUQgfCBNTFRlbnNvclVzYWdlLldSSVRFO1xuICAgIHRoaXMud3JhcHBlciA9IGF3YWl0IHRoaXMudGVuc29yTWFuYWdlci5nZXRDYWNoZWRUZW5zb3IoXG4gICAgICBzZXNzaW9uSWQsXG4gICAgICBkYXRhVHlwZSxcbiAgICAgIHNoYXBlLFxuICAgICAgdXNhZ2UsXG4gICAgICB0cnVlLFxuICAgICAgdHJ1ZSxcbiAgICAgIGZhbGxiYWNrRGF0YVR5cGUsXG4gICAgKTtcblxuICAgIGlmIChjb3B5T2xkICYmIHRoaXMuYWN0aXZlVXBsb2FkKSB7XG4gICAgICAvLyBXZSBkb24ndCBuZWVkIHRvIGNvbnZlcnQgdGhlIG9yaWdpbmFsIGludGVnZXIgZGF0YSB0byBpbnQzMixcbiAgICAgIC8vIGJlY2F1c2UgaXQgaGFzIGJlZW4gY29udmVydGVkIHdoZW4gaXQgd2FzIHVwbG9hZGVkLlxuICAgICAgdGhpcy53cmFwcGVyLndyaXRlKHRoaXMuYWN0aXZlVXBsb2FkKTtcbiAgICAgIHRoaXMuYWN0aXZlVXBsb2FkID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLndyYXBwZXIudGVuc29yO1xuICB9XG5cbiAgcHVibGljIHVwbG9hZChkYXRhOiBVaW50OEFycmF5KTogdm9pZCB7XG4gICAgbGV0IG5ld0RhdGEgPSBkYXRhO1xuICAgIGlmICh0aGlzLndyYXBwZXIpIHtcbiAgICAgIGlmICh0aGlzLndyYXBwZXIuZmFsbGJhY2tUeXBlKSB7XG4gICAgICAgIGlmICh0aGlzLndyYXBwZXIuZmFsbGJhY2tUeXBlID09PSAnaW50MzInKSB7XG4gICAgICAgICAgLy8gQ29udmVydCBvcmlnaW5hbCBpbnRlZ2VyIGRhdGEgdG8gaW50MzIuXG4gICAgICAgICAgbmV3RGF0YSA9IGNvbnZlcnREYXRhVG9JbnQzMihkYXRhLCB0aGlzLndyYXBwZXIudHlwZSk7XG4gICAgICAgICAgdGhpcy53cmFwcGVyLnNldElzRGF0YUNvbnZlcnRlZCh0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGZhbGxiYWNrIGRhdGEgdHlwZTogJHt0aGlzLndyYXBwZXIuZmFsbGJhY2tUeXBlfWApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGlmIHRoZSBkYXRhIHNpemUgbWF0Y2hlcyB0aGUgdGVuc29yIHNpemUuXG4gICAgICBpZiAoZGF0YS5ieXRlTGVuZ3RoID09PSB0aGlzLndyYXBwZXIuYnl0ZUxlbmd0aCkge1xuICAgICAgICAvLyBXcml0ZSB0aGUgbmV3RGF0YSB0byB0aGUgdGVuc29yLlxuICAgICAgICB0aGlzLndyYXBwZXIud3JpdGUobmV3RGF0YSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+ICdEYXRhIHNpemUgZG9lcyBub3QgbWF0Y2ggdGVuc29yIHNpemUuIFJlbGVhc2luZyB0ZW5zb3IuJyk7XG4gICAgICAgIHRoaXMucmVsZWFzZVRlbnNvcigpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmFjdGl2ZVVwbG9hZCkge1xuICAgICAgdGhpcy5hY3RpdmVVcGxvYWQuc2V0KG5ld0RhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFjdGl2ZVVwbG9hZCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkb3dubG9hZChkc3RCdWZmZXI/OiBBcnJheUJ1ZmZlclZpZXcgfCBBcnJheUJ1ZmZlcik6IFByb21pc2U8QXJyYXlCdWZmZXIgfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAodGhpcy5hY3RpdmVVcGxvYWQpIHtcbiAgICAgIC8vIElmIHRoaXMuYWN0aXZlVXBsb2FkIGhhcyBiZWVuIGNvbnZlcnRlZCB0byBpbnQzMiwgd2UgbmVlZCB0byBjb252ZXJ0IGl0IGJhY2sgdG8gb3JpZ2luYWwgaW50ZWdlciBkYXRhIHR5cGUuXG4gICAgICBjb25zdCBkc3REYXRhID0gdGhpcy53cmFwcGVyPy5pc0RhdGFDb252ZXJ0ZWRcbiAgICAgICAgPyBjb252ZXJ0SW50MzJUb0RhdGEodGhpcy5hY3RpdmVVcGxvYWQsIHRoaXMud3JhcHBlcj8udHlwZSlcbiAgICAgICAgOiB0aGlzLmFjdGl2ZVVwbG9hZDtcblxuICAgICAgaWYgKGRzdEJ1ZmZlcikge1xuICAgICAgICBpZiAoZHN0QnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICBuZXcgVWludDhBcnJheShkc3RCdWZmZXIpLnNldChkc3REYXRhKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXcgVWludDhBcnJheShkc3RCdWZmZXIuYnVmZmVyLCBkc3RCdWZmZXIuYnl0ZU9mZnNldCwgZHN0QnVmZmVyLmJ5dGVMZW5ndGgpLnNldChkc3REYXRhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZHN0RGF0YS5idWZmZXI7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghdGhpcy53cmFwcGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbnNvciBoYXMgbm90IGJlZW4gY3JlYXRlZC4nKTtcbiAgICB9XG5cbiAgICBpZiAoIWRzdEJ1ZmZlcikge1xuICAgICAgcmV0dXJuIHRoaXMud3JhcHBlci5yZWFkKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLndyYXBwZXIucmVhZChkc3RCdWZmZXIpO1xuICB9XG59XG5cbmNsYXNzIFRlbnNvck1hbmFnZXJJbXBsIGltcGxlbWVudHMgVGVuc29yTWFuYWdlciB7XG4gIHByaXZhdGUgdGVuc29yVHJhY2tlcnNCeUlkOiBNYXA8VGVuc29ySWQsIFRlbnNvcklkVHJhY2tlcj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgZnJlZVRlbnNvcnM6IFRlbnNvcldyYXBwZXJbXSA9IFtdO1xuICBwcml2YXRlIGV4dGVybmFsVGVuc29yczogU2V0PFRlbnNvcldyYXBwZXI+ID0gbmV3IFNldCgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYmFja2VuZDogV2ViTk5CYWNrZW5kKSB7fVxuXG4gIHB1YmxpYyBnZXRNTENvbnRleHQoc2Vzc2lvbklkOiBudW1iZXIpOiBNTENvbnRleHQge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmJhY2tlbmQuZ2V0TUxDb250ZXh0KHNlc3Npb25JZCk7XG4gICAgaWYgKCFjb250ZXh0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01MQ29udGV4dCBub3QgZm91bmQgZm9yIHNlc3Npb24uJyk7XG4gICAgfVxuICAgIHJldHVybiBjb250ZXh0O1xuICB9XG5cbiAgcHVibGljIHJlc2VydmVUZW5zb3JJZCgpOiBUZW5zb3JJZCB7XG4gICAgY29uc3QgdGVuc29ySWQgPSBjcmVhdGVOZXdUZW5zb3JJZCgpO1xuICAgIHRoaXMudGVuc29yVHJhY2tlcnNCeUlkLnNldCh0ZW5zb3JJZCwgbmV3IFRlbnNvcklkVHJhY2tlcih0aGlzKSk7XG4gICAgcmV0dXJuIHRlbnNvcklkO1xuICB9XG5cbiAgcHVibGljIHJlbGVhc2VUZW5zb3JJZCh0ZW5zb3JJZDogVGVuc29ySWQpOiB2b2lkIHtcbiAgICBjb25zdCB0ZW5zb3JUcmFja2VyID0gdGhpcy50ZW5zb3JUcmFja2Vyc0J5SWQuZ2V0KHRlbnNvcklkKTtcbiAgICBpZiAoIXRlbnNvclRyYWNrZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy50ZW5zb3JUcmFja2Vyc0J5SWQuZGVsZXRlKHRlbnNvcklkKTtcbiAgICBpZiAodGVuc29yVHJhY2tlci50ZW5zb3JXcmFwcGVyKSB7XG4gICAgICB0aGlzLnJlbGVhc2VUZW5zb3IodGVuc29yVHJhY2tlci50ZW5zb3JXcmFwcGVyKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZW5zdXJlVGVuc29yKFxuICAgIHNlc3Npb25JZDogbnVtYmVyLFxuICAgIHRlbnNvcklkOiBUZW5zb3JJZCxcbiAgICBkYXRhVHlwZTogTUxPcGVyYW5kRGF0YVR5cGUsXG4gICAgc2hhcGU6IG51bWJlcltdLFxuICAgIGNvcHlPbGQ6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8TUxUZW5zb3I+IHtcbiAgICBMT0dfREVCVUcoXG4gICAgICAndmVyYm9zZScsXG4gICAgICAoKSA9PlxuICAgICAgICBgW1dlYk5OXSBUZW5zb3JNYW5hZ2VyLmVuc3VyZVRlbnNvciB7dGVuc29ySWQ6ICR7dGVuc29ySWR9LCBkYXRhVHlwZTogJHtcbiAgICAgICAgICBkYXRhVHlwZVxuICAgICAgICB9LCBzaGFwZTogJHtzaGFwZX0sIGNvcHlPbGQ6ICR7Y29weU9sZH19YCxcbiAgICApO1xuICAgIGNvbnN0IHRlbnNvciA9IHRoaXMudGVuc29yVHJhY2tlcnNCeUlkLmdldCh0ZW5zb3JJZCk7XG4gICAgaWYgKCF0ZW5zb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGVuc29yIG5vdCBmb3VuZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRlbnNvci5lbnN1cmVUZW5zb3Ioc2Vzc2lvbklkLCBkYXRhVHlwZSwgc2hhcGUsIGNvcHlPbGQpO1xuICB9XG5cbiAgcHVibGljIHVwbG9hZCh0ZW5zb3JJZDogVGVuc29ySWQsIGRhdGE6IFVpbnQ4QXJyYXkpOiB2b2lkIHtcbiAgICBjb25zdCB0ZW5zb3IgPSB0aGlzLnRlbnNvclRyYWNrZXJzQnlJZC5nZXQodGVuc29ySWQpO1xuICAgIGlmICghdGVuc29yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbnNvciBub3QgZm91bmQuJyk7XG4gICAgfVxuICAgIHRlbnNvci51cGxvYWQoZGF0YSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZG93bmxvYWQodGVuc29ySWQ6IFRlbnNvcklkKTogUHJvbWlzZTxBcnJheUJ1ZmZlcj47XG4gIHB1YmxpYyBhc3luYyBkb3dubG9hZCh0ZW5zb3JJZDogVGVuc29ySWQsIGRzdEJ1ZmZlcjogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpOiBQcm9taXNlPHVuZGVmaW5lZD47XG4gIGFzeW5jIGRvd25sb2FkKHRlbnNvcklkOiBUZW5zb3JJZCwgZHN0QnVmZmVyPzogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpOiBQcm9taXNlPEFycmF5QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgTE9HX0RFQlVHKFxuICAgICAgJ3ZlcmJvc2UnLFxuICAgICAgKCkgPT4gYFtXZWJOTl0gVGVuc29yTWFuYWdlci5kb3dubG9hZCB7dGVuc29ySWQ6ICR7dGVuc29ySWR9LCBkc3RCdWZmZXI6ICR7ZHN0QnVmZmVyPy5ieXRlTGVuZ3RofX1gLFxuICAgICk7XG4gICAgY29uc3QgdGVuc29yVHJhY2tlciA9IHRoaXMudGVuc29yVHJhY2tlcnNCeUlkLmdldCh0ZW5zb3JJZCk7XG4gICAgaWYgKCF0ZW5zb3JUcmFja2VyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbnNvciBub3QgZm91bmQuJyk7XG4gICAgfVxuICAgIHJldHVybiB0ZW5zb3JUcmFja2VyLmRvd25sb2FkKGRzdEJ1ZmZlcik7XG4gIH1cblxuICBwdWJsaWMgcmVsZWFzZVRlbnNvcnNGb3JTZXNzaW9uKHNlc3Npb25JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCB0ZW5zb3Igb2YgdGhpcy5mcmVlVGVuc29ycykge1xuICAgICAgaWYgKHRlbnNvci5zZXNzaW9uSWQgPT09IHNlc3Npb25JZCkge1xuICAgICAgICB0ZW5zb3IuZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmZyZWVUZW5zb3JzID0gdGhpcy5mcmVlVGVuc29ycy5maWx0ZXIoKHRlbnNvcikgPT4gdGVuc29yLnNlc3Npb25JZCAhPT0gc2Vzc2lvbklkKTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3RlclRlbnNvcihcbiAgICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgICBtbFRlbnNvcjogTUxUZW5zb3IsXG4gICAgZGF0YVR5cGU6IE1MT3BlcmFuZERhdGFUeXBlLFxuICAgIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgKTogVGVuc29ySWQge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmdldE1MQ29udGV4dChzZXNzaW9uSWQpO1xuICAgIGNvbnN0IHRlbnNvcklkID0gY3JlYXRlTmV3VGVuc29ySWQoKTtcbiAgICAvLyBEZWZhdWx0aW5nIHRvIFJFQUQgfCBXUklURSBpZiB1c2FnZSBpcyBub3QgcHJvdmlkZWQuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWJpdHdpc2VcbiAgICBjb25zdCB3cmFwcGVyID0gbmV3IFRlbnNvcldyYXBwZXIoe1xuICAgICAgc2Vzc2lvbklkLFxuICAgICAgY29udGV4dCxcbiAgICAgIHRlbnNvcjogbWxUZW5zb3IsXG4gICAgICBkYXRhVHlwZSxcbiAgICAgIHNoYXBlLFxuICAgIH0pO1xuICAgIHRoaXMudGVuc29yVHJhY2tlcnNCeUlkLnNldCh0ZW5zb3JJZCwgbmV3IFRlbnNvcklkVHJhY2tlcih0aGlzLCB3cmFwcGVyKSk7XG4gICAgdGhpcy5leHRlcm5hbFRlbnNvcnMuYWRkKHdyYXBwZXIpO1xuICAgIHJldHVybiB0ZW5zb3JJZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgb3IgY3JlYXRlIGFuIE1MVGVuc29yIHdpdGggdGhlIGdpdmVuIGRhdGEgdHlwZSBhbmQgc2hhcGUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0Q2FjaGVkVGVuc29yKFxuICAgIHNlc3Npb25JZDogbnVtYmVyLFxuICAgIGRhdGFUeXBlOiBNTE9wZXJhbmREYXRhVHlwZSxcbiAgICBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgdXNhZ2U6IE1MVGVuc29yVXNhZ2VGbGFncyB8IHVuZGVmaW5lZCxcbiAgICB3cml0YWJsZTogYm9vbGVhbixcbiAgICByZWFkYWJsZTogYm9vbGVhbixcbiAgICBmYWxsYmFja0RhdGFUeXBlPzogTUxPcGVyYW5kRGF0YVR5cGUsXG4gICk6IFByb21pc2U8VGVuc29yV3JhcHBlcj4ge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmdldE1MQ29udGV4dChzZXNzaW9uSWQpO1xuICAgIGZvciAoY29uc3QgW2luZGV4LCB0ZW5zb3JdIG9mIHRoaXMuZnJlZVRlbnNvcnMuZW50cmllcygpKSB7XG4gICAgICBpZiAodGVuc29yLmNhblJldXNlVGVuc29yKGNvbnRleHQsIGRhdGFUeXBlLCBzaGFwZSkpIHtcbiAgICAgICAgTE9HX0RFQlVHKFxuICAgICAgICAgICd2ZXJib3NlJyxcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgYFtXZWJOTl0gUmV1c2luZyB0ZW5zb3Ige2RhdGFUeXBlOiAke2RhdGFUeXBlfSwgJHtcbiAgICAgICAgICAgICAgZmFsbGJhY2tEYXRhVHlwZSA/IGBmYWxsYmFja0RhdGFUeXBlOiAke2ZhbGxiYWNrRGF0YVR5cGV9LGAgOiAnJ1xuICAgICAgICAgICAgfSBzaGFwZTogJHtzaGFwZX1gLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCB3cmFwcGVyID0gdGhpcy5mcmVlVGVuc29ycy5zcGxpY2UoaW5kZXgsIDEpWzBdO1xuICAgICAgICB3cmFwcGVyLnNlc3Npb25JZCA9IHNlc3Npb25JZDtcbiAgICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgICB9XG4gICAgfVxuICAgIExPR19ERUJVRyhcbiAgICAgICd2ZXJib3NlJyxcbiAgICAgICgpID0+XG4gICAgICAgIGBbV2ViTk5dIE1MQ29udGV4dC5jcmVhdGVUZW5zb3Ige2RhdGFUeXBlOiAke2RhdGFUeXBlfSwgJHtcbiAgICAgICAgICBmYWxsYmFja0RhdGFUeXBlID8gYGZhbGxiYWNrRGF0YVR5cGU6ICR7ZmFsbGJhY2tEYXRhVHlwZX0sYCA6ICcnXG4gICAgICAgIH0gc2hhcGU6ICR7c2hhcGV9fWAsXG4gICAgKTtcbiAgICBjb25zdCB0ZW5zb3IgPSBhd2FpdCBjb250ZXh0LmNyZWF0ZVRlbnNvcih7XG4gICAgICBkYXRhVHlwZTogZmFsbGJhY2tEYXRhVHlwZSA/PyBkYXRhVHlwZSwgLy8gSWYgZmFsbGJhY2sgZGF0YSB0eXBlIGlzIHByb3ZpZGVkLCB1c2UgaXQuXG4gICAgICBzaGFwZSxcbiAgICAgIGRpbWVuc2lvbnM6IHNoYXBlLFxuICAgICAgdXNhZ2UsXG4gICAgICB3cml0YWJsZSxcbiAgICAgIHJlYWRhYmxlLFxuICAgIH0pO1xuICAgIHJldHVybiBuZXcgVGVuc29yV3JhcHBlcih7IHNlc3Npb25JZCwgY29udGV4dCwgdGVuc29yLCBkYXRhVHlwZSwgc2hhcGUsIGZhbGxiYWNrRGF0YVR5cGUgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVsZWFzZSB0ZW5zb3IgZm9yIHJldXNlIHVubGVzcyBleHRlcm5hbC5cbiAgICovXG4gIHB1YmxpYyByZWxlYXNlVGVuc29yKHRlbnNvcldyYXBwZXI6IFRlbnNvcldyYXBwZXIpIHtcbiAgICBpZiAodGhpcy5leHRlcm5hbFRlbnNvcnMuaGFzKHRlbnNvcldyYXBwZXIpKSB7XG4gICAgICB0aGlzLmV4dGVybmFsVGVuc29ycy5kZWxldGUodGVuc29yV3JhcHBlcik7XG4gICAgfVxuICAgIHRoaXMuZnJlZVRlbnNvcnMucHVzaCh0ZW5zb3JXcmFwcGVyKTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgY3JlYXRlVGVuc29yTWFuYWdlciA9ICguLi5hcmdzOiBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIFRlbnNvck1hbmFnZXJJbXBsPik6IFRlbnNvck1hbmFnZXIgPT5cbiAgbmV3IFRlbnNvck1hbmFnZXJJbXBsKC4uLmFyZ3MpO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vLyBXZWJOTiBBUEkgY3VycmVudGx5IGRvZXMgbm90IGhhdmUgYSBUeXBlU2NyaXB0IGRlZmluaXRpb24gZmlsZS4gVGhpcyBmaWxlIGlzIGEgd29ya2Fyb3VuZCB3aXRoIHR5cGVzIGdlbmVyYXRlZCBmcm9tXG4vLyBXZWJOTiBBUEkgc3BlY2lmaWNhdGlvbi5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJtYWNoaW5lbGVhcm5pbmcvd2Vibm4vaXNzdWVzLzY3N1xuLy8vIDxyZWZlcmVuY2UgcGF0aD1cIndlYm5uL3dlYm5uLmQudHNcIiAvPlxuXG5pbXBvcnQgeyBFbnYsIFRlbnNvciB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IERhdGFUeXBlLCB0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bSB9IGZyb20gJy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IGdldEluc3RhbmNlIH0gZnJvbSAnLi4vd2FzbS1mYWN0b3J5JztcblxuaW1wb3J0IHsgY3JlYXRlVmlldyB9IGZyb20gJy4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgVGVuc29ySWQsIGNyZWF0ZVRlbnNvck1hbmFnZXIsIGNvbnZlcnREYXRhVG9JbnQzMiB9IGZyb20gJy4vd2Vibm4vdGVuc29yLW1hbmFnZXInO1xuaW1wb3J0IHsgY29uZmlndXJlTG9nZ2VyLCBMT0dfREVCVUcgfSBmcm9tICcuL2xvZyc7XG5cbi8qXG4gKiBUZW5zb3JQcm90bzo6ZGF0YV90eXBlIHRvIFdlYk5OIE9wZXJhbmRUeXBlIG1hcHBpbmcuXG4gKi9cbmNvbnN0IG9ubnhEYXRhVHlwZVRvV2Vibm5EYXRhVHlwZSA9IG5ldyBNYXA8RGF0YVR5cGUsIE1MT3BlcmFuZERhdGFUeXBlPihbXG4gIFtEYXRhVHlwZS5mbG9hdCwgJ2Zsb2F0MzInXSxcbiAgW0RhdGFUeXBlLmZsb2F0MTYsICdmbG9hdDE2J10sXG4gIFtEYXRhVHlwZS5pbnQzMiwgJ2ludDMyJ10sXG4gIFtEYXRhVHlwZS51aW50MzIsICd1aW50MzInXSxcbiAgW0RhdGFUeXBlLmludDY0LCAnaW50NjQnXSxcbiAgW0RhdGFUeXBlLnVpbnQ2NCwgJ3VpbnQ2NCddLFxuICBbRGF0YVR5cGUuaW50NCwgJ2ludDQnXSxcbiAgW0RhdGFUeXBlLnVpbnQ0LCAndWludDQnXSxcbiAgW0RhdGFUeXBlLmludDgsICdpbnQ4J10sXG4gIFtEYXRhVHlwZS51aW50OCwgJ3VpbnQ4J10sXG4gIFtEYXRhVHlwZS5ib29sLCAndWludDgnXSxcbl0pO1xuXG50eXBlIE1MQ29udGV4dEVudHJ5ID0ge1xuICBncHVEZXZpY2U/OiBHUFVEZXZpY2U7XG4gIG9wdGlvbnM/OiBNTENvbnRleHRPcHRpb25zO1xuICBtbENvbnRleHQ6IE1MQ29udGV4dDtcbn07XG5cbmNvbnN0IGNvbXBhcmVNTENvbnRleHRPcHRpb25zID0gKGE/OiBNTENvbnRleHRPcHRpb25zLCBiPzogTUxDb250ZXh0T3B0aW9ucyk6IGJvb2xlYW4gPT4ge1xuICBpZiAoYSA9PT0gYikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChhID09PSB1bmRlZmluZWQgfHwgYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IGFLZXlzID0gT2JqZWN0LmtleXMoYSkuc29ydCgpIGFzIEFycmF5PGtleW9mIHR5cGVvZiBhPjtcbiAgY29uc3QgYktleXMgPSBPYmplY3Qua2V5cyhiKS5zb3J0KCkgYXMgQXJyYXk8a2V5b2YgdHlwZW9mIGI+O1xuICByZXR1cm4gYUtleXMubGVuZ3RoID09PSBiS2V5cy5sZW5ndGggJiYgYUtleXMuZXZlcnkoKGtleSwgaW5kZXgpID0+IGtleSA9PT0gYktleXNbaW5kZXhdICYmIGFba2V5XSA9PT0gYltrZXldKTtcbn07XG5cbi8qKlxuICogV2ViTk4gYmFja2VuZCBpbXBsZW1lbnRhdGlvbi4gVGhpcyBjbGFzcyBpcyB1c2VkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIE1MVGVuc29ycyBjcmVhdGVkIGJ5IHRoZSBiYWNrZW5kIGFuZCBrZWVwIHRyYWNrXG4gKiBvZiB0aGUgY3VycmVudCBNTENvbnRleHQgYmVpbmcgdXNlZCBieSB0aGUgc2Vzc2lvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJOTkJhY2tlbmQge1xuICAvKipcbiAgICogVGVuc29yIG1hbmFnZXJzIGZvciBlYWNoIHNlc3Npb24uXG4gICAqL1xuICBwcml2YXRlIHRlbnNvck1hbmFnZXIgPSBjcmVhdGVUZW5zb3JNYW5hZ2VyKHRoaXMpO1xuICAvKipcbiAgICogTWFwcyBmcm9tIHNlc3Npb24gaWQgdG8gTUxDb250ZXh0cy5cbiAgICovXG4gIHByaXZhdGUgbWxDb250ZXh0QnlTZXNzaW9uSWQgPSBuZXcgTWFwPG51bWJlciwgTUxDb250ZXh0PigpO1xuICAvKipcbiAgICogTWFwcyBmcm9tIE1MQ29udGV4dCB0byBzZXNzaW9uIGlkcy5cbiAgICovXG4gIHByaXZhdGUgc2Vzc2lvbklkc0J5TUxDb250ZXh0ID0gbmV3IE1hcDxNTENvbnRleHQsIFNldDxudW1iZXI+PigpO1xuICAvKipcbiAgICogQ2FjaGUgb2YgTUxDb250ZXh0cy5cbiAgICovXG4gIHByaXZhdGUgbWxDb250ZXh0Q2FjaGU6IE1MQ29udGV4dEVudHJ5W10gPSBbXTtcbiAgLyoqXG4gICAqIEN1cnJlbnQgc2Vzc2lvbiBpZC5cbiAgICovXG4gIHByaXZhdGUgYWN0aXZlU2Vzc2lvbklkPzogbnVtYmVyO1xuICAvKipcbiAgICogTWFwcyBmcm9tIHNlc3Npb24gaWQgdG8gbGlzdCBvZiBncmFwaCBpbnB1dHMuXG4gICAqL1xuICBwcml2YXRlIHNlc3Npb25HcmFwaElucHV0czogTWFwPG51bWJlciwgc3RyaW5nW10+ID0gbmV3IE1hcCgpO1xuICAvKipcbiAgICogTWFwcyBmcm9tIHNlc3Npb24gaWQgdG8gbGlzdCBvZiBncmFwaCBvdXRwdXRzLlxuICAgKi9cbiAgcHJpdmF0ZSBzZXNzaW9uR3JhcGhPdXRwdXRzOiBNYXA8bnVtYmVyLCBzdHJpbmdbXT4gPSBuZXcgTWFwKCk7XG4gIC8qKlxuICAgKiBUZW1wb3JhcnkgZ3JhcGggaW5wdXRzIGZvciB0aGUgY3VycmVudCBzZXNzaW9uLlxuICAgKiBUaGVzZSBpbnB1dHMgd2lsbCBiZSByZWdpc3RlcmVkIHdoZW4gdGhlIHNlc3Npb24gaXMgY3JlYXRlZC5cbiAgICovXG4gIHByaXZhdGUgdGVtcG9yYXJ5R3JhcGhJbnB1dHM6IHN0cmluZ1tdID0gW107XG4gIC8qKlxuICAgKiBUZW1wb3JhcnkgZ3JhcGggb3V0cHV0cyBmb3IgdGhlIGN1cnJlbnQgc2Vzc2lvbi5cbiAgICogVGhlc2Ugb3V0cHV0cyB3aWxsIGJlIHJlZ2lzdGVyZWQgd2hlbiB0aGUgc2Vzc2lvbiBpcyBjcmVhdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSB0ZW1wb3JhcnlHcmFwaE91dHB1dHM6IHN0cmluZ1tdID0gW107XG4gIC8qKlxuICAgKiBUZW1wb3JhcnkgdGVuc29ycyBmb3IgdGhlIGN1cnJlbnQgc2Vzc2lvbi5cbiAgICovXG4gIHByaXZhdGUgdGVtcG9yYXJ5U2Vzc2lvblRlbnNvcklkczogTWFwPG51bWJlciwgVGVuc29ySWRbXT4gPSBuZXcgTWFwKCk7XG5cbiAgY29uc3RydWN0b3IoZW52OiBFbnYpIHtcbiAgICBjb25maWd1cmVMb2dnZXIoZW52LmxvZ0xldmVsISwgISFlbnYuZGVidWcpO1xuICB9XG5cbiAgcHVibGljIGdldCBjdXJyZW50U2Vzc2lvbklkKCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuYWN0aXZlU2Vzc2lvbklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gYWN0aXZlIHNlc3Npb24nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlU2Vzc2lvbklkO1xuICB9XG5cbiAgcHVibGljIG9uUnVuU3RhcnQoc2Vzc2lvbklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiBgW1dlYk5OXSBvblJ1blN0YXJ0IHtzZXNzaW9uSWQ6ICR7c2Vzc2lvbklkfX1gKTtcbiAgICB0aGlzLmFjdGl2ZVNlc3Npb25JZCA9IHNlc3Npb25JZDtcbiAgfVxuXG4gIHB1YmxpYyBvblJ1bkVuZChzZXNzaW9uSWQ6IG51bWJlcik6IHZvaWQge1xuICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViTk5dIG9uUnVuRW5kIHtzZXNzaW9uSWQ6ICR7c2Vzc2lvbklkfX1gKTtcbiAgICBjb25zdCB0ZW5zb3JJZHMgPSB0aGlzLnRlbXBvcmFyeVNlc3Npb25UZW5zb3JJZHMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKCF0ZW5zb3JJZHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCB0ZW5zb3JJZCBvZiB0ZW5zb3JJZHMpIHtcbiAgICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViTk5dIHJlbGVhc2luZyB0ZW1wb3JhcnkgdGVuc29yIHt0ZW5zb3JJZDogJHt0ZW5zb3JJZH19YCk7XG4gICAgICB0aGlzLnRlbnNvck1hbmFnZXIucmVsZWFzZVRlbnNvcklkKHRlbnNvcklkKTtcbiAgICB9XG4gICAgdGhpcy50ZW1wb3JhcnlTZXNzaW9uVGVuc29ySWRzLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIHRoaXMuYWN0aXZlU2Vzc2lvbklkID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGNyZWF0ZU1MQ29udGV4dChvcHRpb25zT3JEZXZpY2U/OiBNTENvbnRleHRPcHRpb25zIHwgR1BVRGV2aWNlKTogUHJvbWlzZTxNTENvbnRleHQ+IHtcbiAgICBpZiAob3B0aW9uc09yRGV2aWNlIGluc3RhbmNlb2YgR1BVRGV2aWNlKSB7XG4gICAgICBjb25zdCBtbENvbnRleHRJbmRleCA9IHRoaXMubWxDb250ZXh0Q2FjaGUuZmluZEluZGV4KChlbnRyeSkgPT4gZW50cnkuZ3B1RGV2aWNlID09PSBvcHRpb25zT3JEZXZpY2UpO1xuICAgICAgaWYgKG1sQ29udGV4dEluZGV4ICE9PSAtMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tbENvbnRleHRDYWNoZVttbENvbnRleHRJbmRleF0ubWxDb250ZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWxDb250ZXh0ID0gYXdhaXQgbmF2aWdhdG9yLm1sLmNyZWF0ZUNvbnRleHQob3B0aW9uc09yRGV2aWNlKTtcbiAgICAgICAgdGhpcy5tbENvbnRleHRDYWNoZS5wdXNoKHsgZ3B1RGV2aWNlOiBvcHRpb25zT3JEZXZpY2UsIG1sQ29udGV4dCB9KTtcbiAgICAgICAgcmV0dXJuIG1sQ29udGV4dDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9wdGlvbnNPckRldmljZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBtbENvbnRleHRJbmRleCA9IHRoaXMubWxDb250ZXh0Q2FjaGUuZmluZEluZGV4KFxuICAgICAgICAoZW50cnkpID0+IGVudHJ5Lm9wdGlvbnMgPT09IHVuZGVmaW5lZCAmJiBlbnRyeS5ncHVEZXZpY2UgPT09IHVuZGVmaW5lZCxcbiAgICAgICk7XG4gICAgICBpZiAobWxDb250ZXh0SW5kZXggIT09IC0xKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1sQ29udGV4dENhY2hlW21sQ29udGV4dEluZGV4XS5tbENvbnRleHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBtbENvbnRleHQgPSBhd2FpdCBuYXZpZ2F0b3IubWwuY3JlYXRlQ29udGV4dCgpO1xuICAgICAgICB0aGlzLm1sQ29udGV4dENhY2hlLnB1c2goeyBtbENvbnRleHQgfSk7XG4gICAgICAgIHJldHVybiBtbENvbnRleHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbWxDb250ZXh0SW5kZXggPSB0aGlzLm1sQ29udGV4dENhY2hlLmZpbmRJbmRleCgoZW50cnkpID0+XG4gICAgICBjb21wYXJlTUxDb250ZXh0T3B0aW9ucyhlbnRyeS5vcHRpb25zLCBvcHRpb25zT3JEZXZpY2UpLFxuICAgICk7XG4gICAgaWYgKG1sQ29udGV4dEluZGV4ICE9PSAtMSkge1xuICAgICAgcmV0dXJuIHRoaXMubWxDb250ZXh0Q2FjaGVbbWxDb250ZXh0SW5kZXhdLm1sQ29udGV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbWxDb250ZXh0ID0gYXdhaXQgbmF2aWdhdG9yLm1sLmNyZWF0ZUNvbnRleHQob3B0aW9uc09yRGV2aWNlKTtcbiAgICAgIHRoaXMubWxDb250ZXh0Q2FjaGUucHVzaCh7IG9wdGlvbnM6IG9wdGlvbnNPckRldmljZSwgbWxDb250ZXh0IH0pO1xuICAgICAgcmV0dXJuIG1sQ29udGV4dDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXJNTENvbnRleHQoc2Vzc2lvbklkOiBudW1iZXIsIG1sQ29udGV4dDogTUxDb250ZXh0KTogdm9pZCB7XG4gICAgdGhpcy5tbENvbnRleHRCeVNlc3Npb25JZC5zZXQoc2Vzc2lvbklkLCBtbENvbnRleHQpO1xuICAgIGxldCBzZXNzaW9uSWRzID0gdGhpcy5zZXNzaW9uSWRzQnlNTENvbnRleHQuZ2V0KG1sQ29udGV4dCk7XG4gICAgaWYgKCFzZXNzaW9uSWRzKSB7XG4gICAgICBzZXNzaW9uSWRzID0gbmV3IFNldCgpO1xuICAgICAgdGhpcy5zZXNzaW9uSWRzQnlNTENvbnRleHQuc2V0KG1sQ29udGV4dCwgc2Vzc2lvbklkcyk7XG4gICAgfVxuICAgIHNlc3Npb25JZHMuYWRkKHNlc3Npb25JZCk7XG5cbiAgICBpZiAodGhpcy50ZW1wb3JhcnlHcmFwaElucHV0cy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNlc3Npb25HcmFwaElucHV0cy5zZXQoc2Vzc2lvbklkLCB0aGlzLnRlbXBvcmFyeUdyYXBoSW5wdXRzKTtcbiAgICAgIHRoaXMudGVtcG9yYXJ5R3JhcGhJbnB1dHMgPSBbXTtcbiAgICB9XG4gICAgaWYgKHRoaXMudGVtcG9yYXJ5R3JhcGhPdXRwdXRzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2Vzc2lvbkdyYXBoT3V0cHV0cy5zZXQoc2Vzc2lvbklkLCB0aGlzLnRlbXBvcmFyeUdyYXBoT3V0cHV0cyk7XG4gICAgICB0aGlzLnRlbXBvcmFyeUdyYXBoT3V0cHV0cyA9IFtdO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBvblJlbGVhc2VTZXNzaW9uKHNlc3Npb25JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uR3JhcGhJbnB1dHMuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgdGhpcy5zZXNzaW9uR3JhcGhPdXRwdXRzLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIGNvbnN0IG1sQ29udGV4dCA9IHRoaXMubWxDb250ZXh0QnlTZXNzaW9uSWQuZ2V0KHNlc3Npb25JZCkhO1xuICAgIGlmICghbWxDb250ZXh0KSB7XG4gICAgICAvLyBDdXJyZW50IHNlc3Npb24gaXMgbm90IGEgV2ViTk4gc2Vzc2lvbi5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy50ZW5zb3JNYW5hZ2VyLnJlbGVhc2VUZW5zb3JzRm9yU2Vzc2lvbihzZXNzaW9uSWQpO1xuICAgIHRoaXMubWxDb250ZXh0QnlTZXNzaW9uSWQuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgY29uc3Qgc2Vzc2lvbklkcyA9IHRoaXMuc2Vzc2lvbklkc0J5TUxDb250ZXh0LmdldChtbENvbnRleHQpITtcbiAgICBzZXNzaW9uSWRzLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIGlmIChzZXNzaW9uSWRzLnNpemUgPT09IDApIHtcbiAgICAgIHRoaXMuc2Vzc2lvbklkc0J5TUxDb250ZXh0LmRlbGV0ZShtbENvbnRleHQpO1xuICAgICAgY29uc3QgbWxDb250ZXh0SW5kZXggPSB0aGlzLm1sQ29udGV4dENhY2hlLmZpbmRJbmRleCgoZW50cnkpID0+IGVudHJ5Lm1sQ29udGV4dCA9PT0gbWxDb250ZXh0KTtcbiAgICAgIGlmIChtbENvbnRleHRJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgdGhpcy5tbENvbnRleHRDYWNoZS5zcGxpY2UobWxDb250ZXh0SW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRNTENvbnRleHQoc2Vzc2lvbklkOiBudW1iZXIpOiBNTENvbnRleHQgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm1sQ29udGV4dEJ5U2Vzc2lvbklkLmdldChzZXNzaW9uSWQpO1xuICB9XG5cbiAgcHVibGljIHJlc2VydmVUZW5zb3JJZCgpOiBUZW5zb3JJZCB7XG4gICAgcmV0dXJuIHRoaXMudGVuc29yTWFuYWdlci5yZXNlcnZlVGVuc29ySWQoKTtcbiAgfVxuXG4gIHB1YmxpYyByZWxlYXNlVGVuc29ySWQodGVuc29ySWQ6IFRlbnNvcklkKTogdm9pZCB7XG4gICAgTE9HX0RFQlVHKCd2ZXJib3NlJywgKCkgPT4gYFtXZWJOTl0gcmVsZWFzZVRlbnNvcklkIHt0ZW5zb3JJZDogJHt0ZW5zb3JJZH19YCk7XG4gICAgdGhpcy50ZW5zb3JNYW5hZ2VyLnJlbGVhc2VUZW5zb3JJZCh0ZW5zb3JJZCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZW5zdXJlVGVuc29yKFxuICAgIHNlc3Npb25JZDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIHRlbnNvcklkOiBUZW5zb3JJZCxcbiAgICBvbm54RGF0YVR5cGU6IERhdGFUeXBlLFxuICAgIGRpbWVuc2lvbnM6IG51bWJlcltdLFxuICAgIGNvcHlPbGQ6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8TUxUZW5zb3I+IHtcbiAgICBjb25zdCB3ZWJubkRhdGFUeXBlID0gb25ueERhdGFUeXBlVG9XZWJubkRhdGFUeXBlLmdldChvbm54RGF0YVR5cGUpO1xuICAgIGlmICghd2Vibm5EYXRhVHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBPTk5YIGRhdGEgdHlwZTogJHtvbm54RGF0YVR5cGV9YCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRlbnNvck1hbmFnZXIuZW5zdXJlVGVuc29yKFxuICAgICAgc2Vzc2lvbklkID8/IHRoaXMuY3VycmVudFNlc3Npb25JZCxcbiAgICAgIHRlbnNvcklkLFxuICAgICAgd2Vibm5EYXRhVHlwZSxcbiAgICAgIGRpbWVuc2lvbnMsXG4gICAgICBjb3B5T2xkLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgY3JlYXRlVGVtcG9yYXJ5VGVuc29yKFxuICAgIHNlc3Npb25JZDogbnVtYmVyLFxuICAgIG9ubnhEYXRhVHlwZTogRGF0YVR5cGUsXG4gICAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICApOiBQcm9taXNlPFRlbnNvcklkPiB7XG4gICAgTE9HX0RFQlVHKCd2ZXJib3NlJywgKCkgPT4gYFtXZWJOTl0gY3JlYXRlVGVtcG9yYXJ5VGVuc29yIHtvbm54RGF0YVR5cGU6ICR7b25ueERhdGFUeXBlfSwgc2hhcGU6ICR7c2hhcGV9fWApO1xuICAgIGNvbnN0IGRhdGFUeXBlID0gb25ueERhdGFUeXBlVG9XZWJubkRhdGFUeXBlLmdldChvbm54RGF0YVR5cGUpO1xuICAgIGlmICghZGF0YVR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgT05OWCBkYXRhIHR5cGU6ICR7b25ueERhdGFUeXBlfWApO1xuICAgIH1cbiAgICBjb25zdCB0ZW5zb3JJZCA9IHRoaXMudGVuc29yTWFuYWdlci5yZXNlcnZlVGVuc29ySWQoKTtcbiAgICBhd2FpdCB0aGlzLnRlbnNvck1hbmFnZXIuZW5zdXJlVGVuc29yKHNlc3Npb25JZCwgdGVuc29ySWQsIGRhdGFUeXBlLCBzaGFwZSwgZmFsc2UpO1xuICAgIGNvbnN0IHRlbnNvcklkcyA9IHRoaXMudGVtcG9yYXJ5U2Vzc2lvblRlbnNvcklkcy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoIXRlbnNvcklkcykge1xuICAgICAgdGhpcy50ZW1wb3JhcnlTZXNzaW9uVGVuc29ySWRzLnNldChzZXNzaW9uSWQsIFt0ZW5zb3JJZF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0ZW5zb3JJZHMucHVzaCh0ZW5zb3JJZCk7XG4gICAgfVxuICAgIHJldHVybiB0ZW5zb3JJZDtcbiAgfVxuXG4gIHB1YmxpYyB1cGxvYWRUZW5zb3IodGVuc29ySWQ6IFRlbnNvcklkLCBkYXRhOiBVaW50OEFycmF5KTogdm9pZCB7XG4gICAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG4gICAgaWYgKCF3YXNtLnNob3VsZFRyYW5zZmVyVG9NTFRlbnNvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUcnlpbmcgdG8gdXBsb2FkIHRvIGEgTUxUZW5zb3Igd2hpbGUgc2hvdWxkVHJhbnNmZXJUb01MVGVuc29yIGlzIGZhbHNlJyk7XG4gICAgfVxuICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViTk5dIHVwbG9hZFRlbnNvciB7dGVuc29ySWQ6ICR7dGVuc29ySWR9LCBkYXRhOiAke2RhdGEuYnl0ZUxlbmd0aH19YCk7XG4gICAgdGhpcy50ZW5zb3JNYW5hZ2VyLnVwbG9hZCh0ZW5zb3JJZCwgZGF0YSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZG93bmxvYWRUZW5zb3IodGVuc29ySWQ6IFRlbnNvcklkLCBkc3RCdWZmZXI6IEFycmF5QnVmZmVyVmlldyB8IEFycmF5QnVmZmVyKTogUHJvbWlzZTx1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gdGhpcy50ZW5zb3JNYW5hZ2VyLmRvd25sb2FkKHRlbnNvcklkLCBkc3RCdWZmZXIpO1xuICB9XG5cbiAgcHVibGljIGNyZWF0ZU1MVGVuc29yRG93bmxvYWRlcih0ZW5zb3JJZDogVGVuc29ySWQsIHR5cGU6IFRlbnNvci5NTFRlbnNvckRhdGFUeXBlcyk6ICgpID0+IFByb21pc2U8VGVuc29yLkRhdGFUeXBlPiB7XG4gICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLnRlbnNvck1hbmFnZXIuZG93bmxvYWQodGVuc29ySWQpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVZpZXcoZGF0YSwgdHlwZSk7XG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3Rlck1MVGVuc29yKHNlc3Npb25JZDogbnVtYmVyLCB0ZW5zb3I6IE1MVGVuc29yLCBvbm54RGF0YVR5cGU6IERhdGFUeXBlLCBkaW1lbnNpb25zOiBudW1iZXJbXSk6IFRlbnNvcklkIHtcbiAgICBjb25zdCB3ZWJubkRhdGFUeXBlID0gb25ueERhdGFUeXBlVG9XZWJubkRhdGFUeXBlLmdldChvbm54RGF0YVR5cGUpO1xuICAgIGlmICghd2Vibm5EYXRhVHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBPTk5YIGRhdGEgdHlwZTogJHtvbm54RGF0YVR5cGV9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgaWQgPSB0aGlzLnRlbnNvck1hbmFnZXIucmVnaXN0ZXJUZW5zb3Ioc2Vzc2lvbklkLCB0ZW5zb3IsIHdlYm5uRGF0YVR5cGUsIGRpbWVuc2lvbnMpO1xuICAgIExPR19ERUJVRyhcbiAgICAgICd2ZXJib3NlJyxcbiAgICAgICgpID0+XG4gICAgICAgIGBbV2ViTk5dIHJlZ2lzdGVyTUxUZW5zb3Ige3RlbnNvcjogJHt0ZW5zb3J9LCBkYXRhVHlwZTogJHt3ZWJubkRhdGFUeXBlfSwgZGltZW5zaW9uczogJHtcbiAgICAgICAgICBkaW1lbnNpb25zXG4gICAgICAgIH19IC0+IHt0ZW5zb3JJZDogJHtpZH19YCxcbiAgICApO1xuICAgIHJldHVybiBpZDtcbiAgfVxuXG4gIC8vIFJlZ2lzdGVyIGEgV2ViTk4gQ29uc3RhbnQgb3BlcmFuZCBmcm9tIGV4dGVybmFsIGRhdGEuXG4gIHB1YmxpYyByZWdpc3Rlck1MQ29uc3RhbnQoXG4gICAgZXh0ZXJuYWxGaWxlUGF0aDogc3RyaW5nLFxuICAgIGRhdGFPZmZzZXQ6IG51bWJlcixcbiAgICBkYXRhTGVuZ3RoOiBudW1iZXIsXG4gICAgYnVpbGRlcjogTUxHcmFwaEJ1aWxkZXIsXG4gICAgZGVzYzogTUxPcGVyYW5kRGVzY3JpcHRvcixcbiAgICBtb3VudGVkRmlsZXM6IE1hcDxzdHJpbmcsIFVpbnQ4QXJyYXk+IHwgdW5kZWZpbmVkLFxuICAgIHNob3VsZENvbnZlcnRJbnQ2NFRvSW50MzIgPSBmYWxzZSxcbiAgKTogTUxPcGVyYW5kIHtcbiAgICAvLyBJZiBhdmFpbGFibGUsIFwiTW9kdWxlLk1vdW50ZWRGaWxlc1wiIGlzIGEgTWFwIGZvciBhbGwgcHJlbG9hZGVkIGZpbGVzLlxuICAgIGlmICghbW91bnRlZEZpbGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4dGVybmFsIG1vdW50ZWQgZmlsZXMgYXJlIG5vdCBhdmFpbGFibGUuJyk7XG4gICAgfVxuXG4gICAgbGV0IGZpbGVQYXRoID0gZXh0ZXJuYWxGaWxlUGF0aDtcbiAgICBpZiAoZXh0ZXJuYWxGaWxlUGF0aC5zdGFydHNXaXRoKCcuLycpKSB7XG4gICAgICBmaWxlUGF0aCA9IGV4dGVybmFsRmlsZVBhdGguc3Vic3RyaW5nKDIpO1xuICAgIH1cbiAgICBjb25zdCBmaWxlRGF0YSA9IG1vdW50ZWRGaWxlcy5nZXQoZmlsZVBhdGgpO1xuICAgIGlmICghZmlsZURhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmlsZSB3aXRoIG5hbWUgJHtmaWxlUGF0aH0gbm90IGZvdW5kIGluIHByZWxvYWRlZCBmaWxlcy5gKTtcbiAgICB9XG5cbiAgICBpZiAoZGF0YU9mZnNldCArIGRhdGFMZW5ndGggPiBmaWxlRGF0YS5ieXRlTGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ091dCBvZiBib3VuZHM6IGRhdGEgb2Zmc2V0IGFuZCBsZW5ndGggZXhjZWVkIHRoZSBleHRlcm5hbCBmaWxlIGRhdGEgc2l6ZS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBidWZmZXIgPSBmaWxlRGF0YS5zbGljZShkYXRhT2Zmc2V0LCBkYXRhT2Zmc2V0ICsgZGF0YUxlbmd0aCkuYnVmZmVyO1xuICAgIGxldCBidWZmZXJWaWV3OiBBcnJheUJ1ZmZlclZpZXc7XG4gICAgc3dpdGNoIChkZXNjLmRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgYnVmZmVyVmlldyA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdmbG9hdDE2JzpcbiAgICAgICAgYnVmZmVyVmlldyA9XG4gICAgICAgICAgdHlwZW9mIEZsb2F0MTZBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiYgRmxvYXQxNkFycmF5LmZyb20gPyBuZXcgRmxvYXQxNkFycmF5KGJ1ZmZlcikgOiBuZXcgVWludDE2QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICAgIGJ1ZmZlclZpZXcgPSBuZXcgSW50MzJBcnJheShidWZmZXIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICAgIGJ1ZmZlclZpZXcgPSBuZXcgVWludDMyQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbnQ2NCc6XG4gICAgICAgIGlmIChzaG91bGRDb252ZXJ0SW50NjRUb0ludDMyKSB7XG4gICAgICAgICAgLy8gSW50NjQgaXMgbm90IHN1cHBvcnRlZCBieSBjdXJyZW50IGNvbnRleHQsIHVzZSBpbnQzMiBpbnN0ZWFkLlxuICAgICAgICAgIGNvbnN0IGludDMyQnVmZmVyID0gY29udmVydERhdGFUb0ludDMyKG5ldyBVaW50OEFycmF5KGJ1ZmZlciksICdpbnQ2NCcpO1xuICAgICAgICAgIGJ1ZmZlclZpZXcgPSBuZXcgSW50MzJBcnJheShpbnQzMkJ1ZmZlci5idWZmZXIpO1xuICAgICAgICAgIGRlc2MuZGF0YVR5cGUgPSAnaW50MzInO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJ1ZmZlclZpZXcgPSBuZXcgQmlnSW50NjRBcnJheShidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndWludDY0JzpcbiAgICAgICAgYnVmZmVyVmlldyA9IG5ldyBCaWdVaW50NjRBcnJheShidWZmZXIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgICBidWZmZXJWaWV3ID0gbmV3IEludDhBcnJheShidWZmZXIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ludDQnOlxuICAgICAgY2FzZSAndWludDQnOlxuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgICBidWZmZXJWaWV3ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHtkZXNjLmRhdGFUeXBlfSBpbiBjcmVhdGluZyBXZWJOTiBDb25zdGFudCBmcm9tIGV4dGVybmFsIGRhdGEuYCk7XG4gICAgfVxuXG4gICAgTE9HX0RFQlVHKFxuICAgICAgJ3ZlcmJvc2UnLFxuICAgICAgKCkgPT5cbiAgICAgICAgYFtXZWJOTl0gcmVnaXN0ZXJNTENvbnN0YW50IHtkYXRhVHlwZTogJHtkZXNjLmRhdGFUeXBlfSwgc2hhcGU6ICR7ZGVzYy5zaGFwZX19fSAke1xuICAgICAgICAgIHNob3VsZENvbnZlcnRJbnQ2NFRvSW50MzIgPyAnKE5vdGU6IGl0IHdhcyBpbnQ2NCBkYXRhIHR5cGUgYW5kIHJlZ2lzdGVyZWQgdG8gaW50MzIgYXMgd29ya2Fyb3VuZCknIDogJydcbiAgICAgICAgfWAsXG4gICAgKTtcblxuICAgIHJldHVybiBidWlsZGVyLmNvbnN0YW50KGRlc2MsIGJ1ZmZlclZpZXcpO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyR3JhcGhJbnB1dChpbnB1dE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMudGVtcG9yYXJ5R3JhcGhJbnB1dHMucHVzaChpbnB1dE5hbWUpO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyR3JhcGhPdXRwdXQob3V0cHV0TmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy50ZW1wb3JhcnlHcmFwaE91dHB1dHMucHVzaChvdXRwdXROYW1lKTtcbiAgfVxuXG4gIHB1YmxpYyBpc0dyYXBoSW5wdXQoc2Vzc2lvbklkOiBudW1iZXIsIGlucHV0TmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgaW5wdXROYW1lcyA9IHRoaXMuc2Vzc2lvbkdyYXBoSW5wdXRzLmdldChzZXNzaW9uSWQpO1xuICAgIGlmICghaW5wdXROYW1lcykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gaW5wdXROYW1lcy5pbmNsdWRlcyhpbnB1dE5hbWUpO1xuICB9XG5cbiAgcHVibGljIGlzR3JhcGhPdXRwdXQoc2Vzc2lvbklkOiBudW1iZXIsIG91dHB1dE5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG91dHB1dE5hbWVzID0gdGhpcy5zZXNzaW9uR3JhcGhPdXRwdXRzLmdldChzZXNzaW9uSWQpO1xuICAgIGlmICghb3V0cHV0TmFtZXMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dE5hbWVzLmluY2x1ZGVzKG91dHB1dE5hbWUpO1xuICB9XG5cbiAgcHVibGljIGlzR3JhcGhJbnB1dE91dHB1dFR5cGVTdXBwb3J0ZWQoc2Vzc2lvbklkOiBudW1iZXIsIHR5cGU6IFRlbnNvci5UeXBlLCBpc0lucHV0ID0gdHJ1ZSk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLm1sQ29udGV4dEJ5U2Vzc2lvbklkLmdldChzZXNzaW9uSWQpO1xuICAgIGNvbnN0IGRhdGFUeXBlID0gb25ueERhdGFUeXBlVG9XZWJubkRhdGFUeXBlLmdldCh0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bSh0eXBlKSk7XG5cbiAgICBpZiAodHlwZW9mIGRhdGFUeXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChpc0lucHV0KSB7XG4gICAgICByZXR1cm4gISFjb250ZXh0Py5vcFN1cHBvcnRMaW1pdHMoKS5pbnB1dC5kYXRhVHlwZXMuaW5jbHVkZXMoZGF0YVR5cGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gISFjb250ZXh0Py5vcFN1cHBvcnRMaW1pdHMoKS5vdXRwdXQuZGF0YVR5cGVzLmluY2x1ZGVzKGRhdGFUeXBlKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZmx1c2goKTogdm9pZCB7XG4gICAgLy8gVW5saWtlIHRoZSBXZWJHUFUgYmFja2VuZCwgdGhlIFdlYk5OIGJhY2tlbmQgZG9lcyBub3QgbmVlZCB0byBmbHVzaCBhbnkgcGVuZGluZyBvcGVyYXRpb25zLlxuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uL3RlbnNvci12aWV3JztcblxuaW1wb3J0IHsgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9vcHMvY29tbW9uJztcblxuZXhwb3J0IHR5cGUgU2Vzc2lvblN0YXRlID0gJ2RlZmF1bHQnIHwgJ2NhcHR1cmluZycgfCAncmVwbGF5aW5nJztcblxuZXhwb3J0IGVudW0gR3B1RGF0YVR5cGUge1xuICBkZWZhdWx0ID0gMCxcbiAgdXBsb2FkID0gMSxcbiAgcHJvZmlsZSA9IDIsXG59XG5leHBvcnQgdHlwZSBHcHVEYXRhSWQgPSBudW1iZXI7XG5cbmV4cG9ydCB0eXBlIEdwdUFyY2hpdGVjdHVyZSA9ICdhbXBlcmUnIHwgJ2dlbi0xMmxwJztcbmV4cG9ydCB0eXBlIEdwdVZlbmRvciA9ICdhbWQnIHwgJ2ludGVsJyB8ICdudmlkaWEnO1xuZXhwb3J0IGludGVyZmFjZSBBZGFwdGVySW5mbyB7XG4gIGlzQXJjaGl0ZWN0dXJlOiAoYXJjaGl0ZWN0dXJlOiBHcHVBcmNoaXRlY3R1cmUpID0+IGJvb2xlYW47XG4gIGlzVmVuZG9yOiAodmVuZG9yOiBHcHVWZW5kb3IpID0+IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3B1RGF0YSB7XG4gIHR5cGU6IEdwdURhdGFUeXBlO1xuICBpZDogR3B1RGF0YUlkO1xuICBidWZmZXI6IEdQVUJ1ZmZlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JJbmZvIHtcbiAgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIGRhdGFUeXBlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbVVuaWZvcm0ge1xuICB0eXBlOiBEYXRhVHlwZTtcbiAgZGF0YTogbnVtYmVyIHwgcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCB0eXBlIFByb2dyYW1Vbmlmb3JtVmFyaWFibGVJbmZvID0gW3R5cGU6IERhdGFUeXBlLCBsZW5ndGg6IG51bWJlcl07XG5cbi8qKlxuICogUmVwcmVzZW50IHRoZSBkZXBlbmRlbmN5IG9mIGEgcHJvZ3JhbSBvbiBhIHNwZWNpZmljIGlucHV0IHRlbnNvci5cbiAqXG4gKiAtICdub25lJzogdGhlIHNoYWRlci91bmlmb3JtIGRvZXMgbm90IGRlcGVuZCBvbiB0aGlzIGlucHV0J3MgaW5mb1xuICogLSAndHlwZSc6IHRoZSBzaGFkZXIvdW5pZm9ybSBkZXBlbmRzIG9uIGRhdGEgdHlwZSBvZiB0aGlzIGlucHV0XG4gKiAtICdyYW5rJzogdGhlIHNoYWRlci91bmlmb3JtIGRlcGVuZHMgb24gZGF0YSB0eXBlIGFuZCB0aGUgcmFuayBvZiB0aGlzIGlucHV0XG4gKiAtICdkaW1zJzogdGhlIHNoYWRlci91bmlmb3JtIGRlcGVuZHMgb24gZGF0YSB0eXBlIGFuZCB0aGUgZGltcyBvZiB0aGlzIGlucHV0XG4gKiAtICdkYXRhJzogdGhlIHNoYWRlci91bmlmb3JtIGRlcGVuZHMgb24gZGF0YSB0eXBlLCB0aGUgZGltcyBhbmQgdGhlIGRhdGEgb2YgdGhpcyBpbnB1dFxuICovXG5leHBvcnQgdHlwZSBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSA9ICdub25lJyB8ICd0eXBlJyB8ICdyYW5rJyB8ICdkaW1zJyB8ICdkYXRhJztcblxuLyoqXG4gKiBSZXByZXNlbnQgaW5mb3JtYXRpb24gYWJvdXQgYSBwcm9ncmFtJ3MgY2FjaGUgZm9yIHNoYWRlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtU2hhZGVyQ2FjaGVJbmZvIHtcbiAgLyoqXG4gICAqIGFuIG9wdGlvbmFsIHN0cmluZyBhcyBhIGNhY2hlIGhpbnQgaW4gdGhlIGFydGlmYWN0IGNhY2hlLiBJZiB0aGlzIGlzIG5vdCBzcGVjaWZpZWQsIHRoZSBjYWNoZSBoaW50IHdpbGwgYmUgZW1wdHkuXG4gICAqXG4gICAqIFRoaXMgaGludCBzdHJpbmcgc2hvdWxkIG9ubHkgY29udGFpbnMgaW5pdGlhbGl6aW5nLXRpbWUgaW5mb3JtYXRpb24sIHN1Y2ggYXMgdGhlIGF0dHJpYnV0ZXMgb3IgYW55IGluZm9ybWF0aW9uIG9mXG4gICAqIGluaXRpYWxpemVycy4gSXQgc2hvdWxkIE5PVCBjb250YWluIGFueSBydW50aW1lIGluZm9ybWF0aW9uLCBzdWNoIGFzIHRoZSBzaGFwZSBvZiBpbnB1dHMuXG4gICAqL1xuICBoaW50Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBsaXN0IG9mIGRlcGVuZGVuY2llcyBvZiB0aGUgcHJvZ3JhbSBvbiB0aGUgaW5wdXQgdGVuc29ycy4gSWYgdGhpcyBpcyBub3Qgc3BlY2lmaWVkLCB0aGUgcHJvZ3JhbSBkZXBlbmRzXG4gICAqIG9uICdkaW1zJyBvZiBhbGwgaW5wdXRzLlxuICAgKi9cbiAgaW5wdXREZXBlbmRlbmNpZXM/OiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBpbmZvcm1hdGlvbiBhYm91dCBhIHByb2dyYW0ncyBjYWNoZSBmb3IgdW5pZm9ybS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtVW5pZm9ybUNhY2hlSW5mbyB7XG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBzdHJpbmcgYXMgYSBjYWNoZSBoaW50IGluIHRoZSB1bmlmb3JtIGNhY2hlLiBJZiB0aGlzIGlzIG5vdCBzcGVjaWZpZWQsIHRoZSBjYWNoZSBoaW50IHdpbGwgYmUgZW1wdHkuXG4gICAqXG4gICAqIFRoaXMgaGludCBzdHJpbmcgc2hvdWxkIG9ubHkgY29udGFpbnMgcnVudGltZSBpbmZvcm1hdGlvbiwgc3VjaCBhcyB0aGUgc2hhcGUgb2YgaW5wdXRzLlxuICAgKi9cbiAgaGludD86IHN0cmluZztcblxuICAvKipcbiAgICogYW4gb3B0aW9uYWwgbGlzdCBvZiBkZXBlbmRlbmNpZXMgb2YgdGhlIHByb2dyYW0gb24gdGhlIGlucHV0IHRlbnNvcnMuIElmIHRoaXMgaXMgbm90IHNwZWNpZmllZCwgdGhlIHByb2dyYW0gZGVwZW5kc1xuICAgKiBvbiAnbm9uZScgb2YgYWxsIGlucHV0cy5cbiAgICovXG4gIGlucHV0RGVwZW5kZW5jaWVzPzogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXTtcbn1cblxuLyoqXG4gKiBBIHNldCBvZiBkYXRhIHRoYXQgcmVwcmVzZW50IGEgc2hhZGVyIHByb2dyYW1cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtSW5mbyB7XG4gIC8qKlxuICAgKiB0aGUgbmFtZSBvZiB0aGUgcHJvZ3JhbS4gdXNlZCBmb3IgZGVidWdnaW5nIGFuZCBwcm9maWxpbmdcbiAgICovXG4gIG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogYW4gb3B0aW9uYWwgb2JqZWN0IGRlc2NyaWJpbmcgdGhlIGNhY2hlIGluZm9ybWF0aW9uIG9mIHRoZSBwcm9ncmFtIHNoYWRlci5cbiAgICpcbiAgICogSWYgdGhpcyBpcyBub3Qgc3BlY2lmaWVkLCBhc3N1bWUgaGludCBpcyBlbXB0eSBhbmQgaW5wdXREZXBlbmRlbmNpZXMgYXJlIFsnZGltcyddIGZvciBhbGwgaW5wdXRzLlxuICAgKi9cbiAgc2hhZGVyQ2FjaGU/OiBQcm9ncmFtU2hhZGVyQ2FjaGVJbmZvO1xuXG4gIC8qKlxuICAgKiB0aGUgc2hhZGVyJ3MgcHJvY2Vzc2luZyBzb3VyY2UgY29kZS5cbiAgICpcbiAgICogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCB3aGVuIHNoYWRlciBjYWNoZSBtaXNzZWQuXG4gICAqL1xuICBnZXRTaGFkZXJTb3VyY2U6IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIHRvIGdldCBydW4gZGF0YSByZXF1aXJlZCB0byBydW4gdGhlIHByb2dyYW0uXG4gICAqXG4gICAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgZXZlcnkgdGltZSB0aGUgcHJvZ3JhbSBpcyBleGVjdXRlZC4gU2hvdWxkIGtlZXAgdGhpcyBmdW5jdGlvbiBhcyBzaW1wbGUgYXMgcG9zc2libGUuXG4gICAqL1xuICBnZXRSdW5EYXRhOiAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pID0+IHtcbiAgICBvdXRwdXRzOiByZWFkb25seSBUZW5zb3JJbmZvW107XG4gICAgZGlzcGF0Y2hHcm91cDogeyB4OiBudW1iZXI7IHk/OiBudW1iZXI7IHo/OiBudW1iZXIgfTtcbiAgICBwcm9ncmFtVW5pZm9ybXM/OiByZWFkb25seSBQcm9ncmFtVW5pZm9ybVtdO1xuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFydGlmYWN0IHtcbiAgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvO1xuICBjb21wdXRlUGlwZWxpbmU6IEdQVUNvbXB1dGVQaXBlbGluZTtcbiAgdW5pZm9ybVZhcmlhYmxlc0luZm86IHJlYWRvbmx5IFByb2dyYW1Vbmlmb3JtVmFyaWFibGVJbmZvW10gfCB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcHV0ZUNvbnRleHRJbnB1dHNPdXRwdXRzTWFwcGluZyB7XG4gIC8qKlxuICAgKiBzcGVjaWZ5IHRoZSBtYXBwaW5nIHRvIHRoZSBwcm9ncmFtJ3MgaW5wdXRzLiB0aGUgdmFsdWUgY2FuIGJlIGEgbnVtYmVyIG9yIGEgdGVuc29yIHZpZXcuXG4gICAqIC0gaWYgaXQncyBhIG51bWJlciwgaXQncyB0aGUgaW5kZXggb2YgdGhlIGtlcm5lbCdzIGlucHV0XG4gICAqIC0gaWYgaXQncyBhIHRlbnNvciB2aWV3LCBpdCdzIGFuIGV4aXN0aW5nIHRlbnNvciB2aWV3IHRoYXQgd2lsbCBiZSB1c2VkIGFzIHRoZSBpbnB1dFxuICAgKlxuICAgKiBpZiBpbnB1dHMgaXMgbm90IHNwZWNpZmllZCwgdGhlIG1hcHBpbmcgd2lsbCBiZSB0aGUga2VybmVsJ3MgaW5wdXRzIGluIG9yZGVyLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXRzPzogUmVhZG9ubHlBcnJheTxUZW5zb3JWaWV3IHwgbnVtYmVyPjtcbiAgLyoqXG4gICAqIHNwZWNpZnkgdGhlIG1hcHBpbmcgdG8gdGhlIHByb2dyYW0ncyBvdXRwdXRzLiB0aGUgdmFsdWUgbXVzdCBiZSBhIG51bWJlci5cbiAgICogLSBpZiBpdCdzIGEgbm9uLW5lZ2F0aXZlIG51bWJlciwgaXQncyB0aGUgaW5kZXggb2YgdGhlIGtlcm5lbCdzIG91dHB1dFxuICAgKiAtIGlmIGl0J3MgLTEsIGl0J3MgYW4gb3V0cHV0IHRoYXQgd2lsbCBiZSBjcmVhdGVkIGFzIGEgdGVtcG9yYXJ5IHZhbHVlLiB0aGlzIHZhbHVlIHdpbGwgYmUgcmVsZWFzZWQgYWZ0ZXJcbiAgICogdGhlIGtlcm5lbCBpcyBleGVjdXRlZC5cbiAgICogLSBpZiBpdCdzIC0yLCBpdCdzIGFuIG91dHB1dCB0aGF0IHdpbGwgYmUgY3JlYXRlZCBhcyBhIHBlcnNpc3RlbnQgdmFsdWUuIHRoaXMgdmFsdWUgd2lsbCBiZSByZWxlYXNlZCB3aGVuIHRoZVxuICAgKiBrZXJuZWwgaXMgcmVsZWFzZWQuXG4gICAqXG4gICAqIGlmIG91dHB1dHMgaXMgbm90IHNwZWNpZmllZCwgdGhlIG1hcHBpbmcgd2lsbCBiZSB0aGUga2VybmVsJ3Mgb3V0cHV0cyBpbiBvcmRlci5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dHM/OiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBBIENvbXB1dGVDb250ZXh0IGluc3RhbmNlIGNhcnJpZXMgdGhlIHN0YXRlcyB0aGF0IHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBydW5uaW5nIG9mIGEga2VybmVsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXB1dGVDb250ZXh0IHtcbiAgLyoqXG4gICAqIGdwdSBhZGFwdGVyIGluZm9cbiAgICovXG4gIHJlYWRvbmx5IGFkYXB0ZXJJbmZvOiBBZGFwdGVySW5mbztcblxuICAvKipcbiAgICogc3RvcmVzIHRoZSBwb2ludGVyIHRvIE9wS2VybmVsQ29udGV4dFxuICAgKi9cbiAgcmVhZG9ubHkgb3BLZXJuZWxDb250ZXh0OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIGEgbGlzdCBvZiBpbnB1dHMsIGVhY2ggaW5wdXQgaXMgYW4gaW5zdGFuY2Ugb2YgVGVuc29yVmlld1xuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W107XG5cbiAgLyoqXG4gICAqIGEgY3VzdG9tIGRhdGEgb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gc3RvcmUgYW55IGRhdGEgdGhhdCBpcyBuZWVkZWQgYnkgdGhlIGtlcm5lbFxuICAgKi9cbiAgcmVhZG9ubHkga2VybmVsQ3VzdG9tRGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH07XG5cbiAgLyoqXG4gICAqIGEgYnVmZmVyIHRoYXQgY2FuIGJlIHVzZWQgdG8gYWNjZXNzIGN1c3RvbSBkYXRhIGNyZWF0ZWQgZWFjaCB0aW1lIHRoZSBrZXJuZWwgaXMgZXhlY3V0ZWRcbiAgICovXG4gIHJlYWRvbmx5IGN1c3RvbURhdGFCdWZmZXI6IFVpbnQ4QXJyYXk7XG5cbiAgLyoqXG4gICAqIGEgbnVtYmVyIG9mIG91dHB1dHMgZm9yIHRoZSBub2RlXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRDb3VudDogbnVtYmVyO1xuXG4gIGNvbXB1dGUocHJvZ3JhbTogUHJvZ3JhbUluZm8sIGlucHV0c091dHB1dHNNYXBwaW5nPzogQ29tcHV0ZUNvbnRleHRJbnB1dHNPdXRwdXRzTWFwcGluZyk6IFRlbnNvclZpZXdbXTtcbiAgb3V0cHV0KGluZGV4OiBudW1iZXIsIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyO1xufVxuXG5leHBvcnQgdHlwZSBUaW1lc3RhbXBRdWVyeSA9ICdub25lJyB8ICdpbnNpZGUtcGFzc2VzJyB8ICdhdC1wYXNzZXMnO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBXZWJHcHVCYWNrZW5kIH0gZnJvbSAnLi4vYmFja2VuZC13ZWJncHUnO1xuaW1wb3J0IHsgTE9HX0RFQlVHIH0gZnJvbSAnLi4vbG9nJztcblxuaW1wb3J0IHsgR3B1RGF0YSwgR3B1RGF0YUlkLCBHcHVEYXRhVHlwZSB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIG1hbmFnZXMgR3B1RGF0YUlkIC0+IEdwdUJ1ZmZlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdwdURhdGFNYW5hZ2VyIHtcbiAgLyoqXG4gICAqIGNvcHkgZGF0YSBmcm9tIENQVSB0byBHUFUuXG4gICAqL1xuICB1cGxvYWQoaWQ6IEdwdURhdGFJZCwgZGF0YTogVWludDhBcnJheSk6IHZvaWQ7XG4gIC8qKlxuICAgKiBjb3B5IGRhdGEgZnJvbSBHUFUgdG8gR1BVLlxuICAgKi9cbiAgbWVtY3B5KHNvdXJjZUlkOiBHcHVEYXRhSWQsIGRlc3RpbmF0aW9uSWQ6IEdwdURhdGFJZCk6IHZvaWQ7XG4gIC8qKlxuICAgKiBjcmVhdGUgbmV3IGRhdGEgb24gR1BVLlxuICAgKi9cbiAgY3JlYXRlKHNpemU6IG51bWJlciwgdXNhZ2U/OiBudW1iZXIpOiBHcHVEYXRhO1xuICAvKipcbiAgICogZ2V0IEdQVSBkYXRhIGJ5IElELlxuICAgKi9cbiAgZ2V0KGlkOiBHcHVEYXRhSWQpOiBHcHVEYXRhIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogcmVsZWFzZSB0aGUgZGF0YSBvbiBHUFUgYnkgSUQuXG4gICAqXG4gICAqIEByZXR1cm4gc2l6ZSBvZiB0aGUgZGF0YSByZWxlYXNlZFxuICAgKi9cbiAgcmVsZWFzZShpZDogR3B1RGF0YUlkKTogbnVtYmVyO1xuICAvKipcbiAgICogY29weSBkYXRhIGZyb20gR1BVIHRvIENQVS5cbiAgICovXG4gIGRvd25sb2FkKGlkOiBHcHVEYXRhSWQsIGdldFRhcmdldEJ1ZmZlcjogKCkgPT4gVWludDhBcnJheSk6IFByb21pc2U8dm9pZD47XG5cbiAgLyoqXG4gICAqIHJlZnJlc2ggdGhlIGJ1ZmZlcnMgdGhhdCBtYXJrZWQgZm9yIHJlbGVhc2UuXG4gICAqXG4gICAqIHdoZW4gcmVsZWFzZSgpIGlzIGNhbGxlZCwgdGhlIGJ1ZmZlciBpcyBub3QgcmVsZWFzZWQgaW1tZWRpYXRlbHkuIHRoaXMgaXMgYmVjYXVzZSB3ZSBuZWVkIHRvIHdhaXQgZm9yIHRoZSBjb21tYW5kc1xuICAgKiB0byBiZSBzdWJtaXR0ZWQgdG8gdGhlIEdQVS4gdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgdGhlIGNvbW1hbmRzIGFyZSBzdWJtaXR0ZWQgc28gdGhhdCB0aGUgYnVmZmVycyBjYW4gYmVcbiAgICogYWN0dWFsbHkgcmVsZWFzZWQuXG4gICAqL1xuICByZWZyZXNoUGVuZGluZ0J1ZmZlcnMoKTogdm9pZDtcblxuICAvKipcbiAgICogcmVnaXN0ZXIgYW4gZXh0ZXJuYWwgYnVmZmVyIGZvciBJTyBCaW5kaW5nLiBJZiB0aGUgYnVmZmVyIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCwgcmV0dXJuIHRoZSBleGlzdGluZyBHUFUgZGF0YSBJRC5cbiAgICpcbiAgICogR1BVIGRhdGEgbWFuYWdlciBvbmx5IG1hbmFnZXMgYSBtYXBwaW5nIGJldHdlZW4gdGhlIGJ1ZmZlciBhbmQgdGhlIEdQVSBkYXRhIElELiBJdCB3aWxsIG5vdCBtYW5hZ2UgdGhlIGxpZmVjeWNsZSBvZlxuICAgKiB0aGUgZXh0ZXJuYWwgYnVmZmVyLlxuICAgKi9cbiAgcmVnaXN0ZXJFeHRlcm5hbEJ1ZmZlcihidWZmZXI6IEdQVUJ1ZmZlciwgb3JpZ2luYWxTaXplOiBudW1iZXIsIHByZXZpb3VzPzogW0dwdURhdGFJZCwgR1BVQnVmZmVyXSk6IG51bWJlcjtcblxuICAvKipcbiAgICogdW5yZWdpc3RlciBhbiBleHRlcm5hbCBidWZmZXIgZm9yIElPIEJpbmRpbmcuXG4gICAqL1xuICB1bnJlZ2lzdGVyRXh0ZXJuYWxCdWZmZXIoaWQ6IEdwdURhdGFJZCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGRlc3Ryb3kgYWxsIGdwdSBidWZmZXJzLlxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgc2Vzc2lvbiByZWxhdGVkIGRhdGEuXG4gICAqL1xuICBvbkNyZWF0ZVNlc3Npb24oKTogdm9pZDtcblxuICAvKipcbiAgICogcmVsZWFzZSBzZXNzaW9uIHJlbGF0ZWQgZGF0YS5cbiAgICogQHBhcmFtIHNlc3Npb25JZCAtIHNwZWNpZnkgdGhlIHNlc3Npb24gSUQuXG4gICAqL1xuICBvblJlbGVhc2VTZXNzaW9uKHNlc3Npb25JZDogbnVtYmVyKTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIFN0b3JhZ2VDYWNoZVZhbHVlIHtcbiAgZ3B1RGF0YTogR3B1RGF0YTtcbiAgb3JpZ2luYWxTaXplOiBudW1iZXI7XG59XG5cbmNvbnN0IGJ1Y2tldEZyZWVsaXN0OiBNYXA8bnVtYmVyLCBudW1iZXI+ID0gbmV3IE1hcChbXG4gIFs2NCwgMjUwXSxcbiAgWzEyOCwgMjAwXSxcbiAgWzI1NiwgMjAwXSxcbiAgWzUxMiwgMjAwXSxcbiAgWzIwNDgsIDIzMF0sXG4gIFs0MDk2LCAyMDBdLFxuICBbODE5MiwgNTBdLFxuICBbMTYzODQsIDUwXSxcbiAgWzMyNzY4LCA1MF0sXG4gIFs2NTUzNiwgNTBdLFxuICBbMTMxMDcyLCA1MF0sXG4gIFsyNjIxNDQsIDUwXSxcbiAgWzUyNDI4OCwgNTBdLFxuICBbMTA0ODU3NiwgNTBdLFxuICBbMjA5NzE1MiwgMzBdLFxuICBbNDE5NDMwNCwgMjBdLFxuICBbODM4ODYwOCwgMTBdLFxuICBbMTI1ODI5MTIsIDEwXSxcbiAgWzE2Nzc3MjE2LCAxMF0sXG4gIFsyNjIxNDQwMCwgMTVdLFxuICBbMzM1NTQ0MzIsIDIyXSxcbiAgWzQ0MjM2ODAwLCAyXSxcbiAgWzU4OTgyNDAwLCA2XSxcbiAgLy8gd2UgZG9uJ3Qgd2FudCB0byBjYWNoZSB0aGUgYnVja2V0IHNpemVzIGJlbG93IGJ1dCBub3QgY2FjaGluZyB0aGVtXG4gIC8vIHJlc3VsdHMgaW4gc29tZSBtYWpvciBwZXJmb3JtYW5jZSBoaXRzIGZvciBtb2RlbHMgbGlrZSBzZC10dXJiby5cbiAgWzY3MTA4ODY0LCA2XSxcbiAgWzEzNDIxNzcyOCwgNl0sXG4gIFsxNjc3NzIxNjAsIDZdLFxuXSk7XG5cbmNvbnN0IGJ1Y2tldEFycjogbnVtYmVyW10gPSBbXTtcblxuLyoqXG4gKiBub3JtYWxpemUgdGhlIGJ1ZmZlciBzaXplIHNvIHRoYXQgaXQgZml0cyB0aGUgMTI4LWJpdHMgKDE2IGJ5dGVzKSBhbGlnbm1lbnQuXG4gKi9cbmNvbnN0IGNhbGNOb3JtYWxpemVkQnVmZmVyU2l6ZSA9IChzaXplOiBudW1iZXIpID0+IE1hdGguY2VpbChOdW1iZXIoc2l6ZSkgLyAxNikgKiAxNjtcblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIGJ1ZmZlciBzaXplIHNvIHRoYXQgaXQgZml0cyBpbnRvIGJ1Y2tldHMuXG4gKi9cbmNvbnN0IGNhbGNCdWNrZXRCdWZmZXJTaXplID0gKHNpemU6IG51bWJlcikgPT4ge1xuICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCBidWNrZXRBcnIubGVuZ3RoOyBpZHgrKykge1xuICAgIGNvbnN0IHNpemVGb3JCdWNrZXQgPSBidWNrZXRBcnJbaWR4XTtcbiAgICBpZiAoc2l6ZSA8PSBzaXplRm9yQnVja2V0KSB7XG4gICAgICByZXR1cm4gc2l6ZUZvckJ1Y2tldDtcbiAgICB9XG4gIH1cbiAgLy8gbm90IGluIGJ1Y2tldCBsaXN0IC0+IGNhbGxlciB3aWxsIG5vdCBjYWNoZSwgcm91bmQgdXAgdG8gMTYuXG4gIHJldHVybiBNYXRoLmNlaWwoc2l6ZSAvIDE2KSAqIDE2O1xufTtcblxubGV0IGd1aWQgPSAxO1xuY29uc3QgY3JlYXRlTmV3R3B1RGF0YUlkID0gKCkgPT4gZ3VpZCsrO1xuXG4vKipcbiAqIGV4cG9ydGVkIHN0YW5kYXJkIGRvd25sb2FkIGZ1bmN0aW9uLiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgYnkgdGhlIHNlc3Npb24gdG8gZG93bmxvYWQgdGhlIGRhdGEgZnJvbSBHUFUsIGFuZCBhbHNvIGJ5XG4gKiBmYWN0b3J5IHRvIGNyZWF0ZSBHUFUgdGVuc29ycyB3aXRoIHRoZSBjYXBhY2l0eSBvZiBkb3dubG9hZGluZyBkYXRhIGZyb20gR1BVLlxuICpcbiAqIEBwYXJhbSBiYWNrZW5kIC0gdGhlIFdlYkdQVSBiYWNrZW5kXG4gKiBAcGFyYW0gZ3B1QnVmZmVyIC0gdGhlIEdQVSBidWZmZXIgdG8gZG93bmxvYWRcbiAqIEBwYXJhbSBvcmlnaW5hbFNpemUgLSB0aGUgb3JpZ2luYWwgc2l6ZSBvZiB0aGUgZGF0YVxuICogQHBhcmFtIGdldFRhcmdldEJ1ZmZlciAtIG9wdGlvbmFsLiBJZiBwcm92aWRlZCwgdGhlIGRhdGEgd2lsbCBiZSBjb3BpZWQgdG8gdGhlIHRhcmdldCBidWZmZXIuIE90aGVyd2lzZSwgYSBuZXcgYnVmZmVyXG4gKiB3aWxsIGJlIGNyZWF0ZWQgYW5kIHJldHVybmVkLlxuICovXG5leHBvcnQgY29uc3QgZG93bmxvYWRHcHVEYXRhID0gYXN5bmMgKFxuICBiYWNrZW5kOiBXZWJHcHVCYWNrZW5kLFxuICBncHVCdWZmZXI6IEdQVUJ1ZmZlcixcbiAgb3JpZ2luYWxTaXplOiBudW1iZXIsXG4gIGdldFRhcmdldEJ1ZmZlcj86ICgpID0+IFVpbnQ4QXJyYXksXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXk+ID0+IHtcbiAgY29uc3QgYnVmZmVyU2l6ZSA9IGNhbGNOb3JtYWxpemVkQnVmZmVyU2l6ZShvcmlnaW5hbFNpemUpO1xuICBjb25zdCBncHVSZWFkQnVmZmVyID0gYmFja2VuZC5kZXZpY2UuY3JlYXRlQnVmZmVyKFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgeyBzaXplOiBidWZmZXJTaXplLCB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QgfCBHUFVCdWZmZXJVc2FnZS5NQVBfUkVBRCB9LFxuICApO1xuICB0cnkge1xuICAgIGNvbnN0IGNvbW1hbmRFbmNvZGVyID0gYmFja2VuZC5nZXRDb21tYW5kRW5jb2RlcigpO1xuICAgIGJhY2tlbmQuZW5kQ29tcHV0ZVBhc3MoKTtcbiAgICBjb21tYW5kRW5jb2Rlci5jb3B5QnVmZmVyVG9CdWZmZXIoXG4gICAgICBncHVCdWZmZXIgLyogc291cmNlIGJ1ZmZlciAqLyxcbiAgICAgIDAgLyogc291cmNlIG9mZnNldCAqLyxcbiAgICAgIGdwdVJlYWRCdWZmZXIgLyogZGVzdGluYXRpb24gYnVmZmVyICovLFxuICAgICAgMCAvKiBkZXN0aW5hdGlvbiBvZmZzZXQgKi8sXG4gICAgICBidWZmZXJTaXplIC8qIHNpemUgKi8sXG4gICAgKTtcbiAgICBiYWNrZW5kLmZsdXNoKCk7XG5cbiAgICBhd2FpdCBncHVSZWFkQnVmZmVyLm1hcEFzeW5jKEdQVU1hcE1vZGUuUkVBRCk7XG5cbiAgICBjb25zdCBhcnJheUJ1ZmZlciA9IGdwdVJlYWRCdWZmZXIuZ2V0TWFwcGVkUmFuZ2UoKTtcbiAgICBpZiAoZ2V0VGFyZ2V0QnVmZmVyKSB7XG4gICAgICAvLyBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBDUFUgYnVmZmVyIHRvIGFjY2VwdCB0aGUgZGF0YSwgbm8gbmVlZCB0byBjbG9uZSB0aGUgQXJyYXlCdWZmZXIuXG4gICAgICBjb25zdCB0YXJnZXRCdWZmZXIgPSBnZXRUYXJnZXRCdWZmZXIoKTtcbiAgICAgIHRhcmdldEJ1ZmZlci5zZXQobmV3IFVpbnQ4QXJyYXkoYXJyYXlCdWZmZXIsIDAsIG9yaWdpbmFsU2l6ZSkpO1xuICAgICAgcmV0dXJuIHRhcmdldEJ1ZmZlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdGhlIG1hcHBlZCBBcnJheUJ1ZmZlciB3aWxsIGJlIHJlbGVhc2VkIHdoZW4gdGhlIEdQVSBidWZmZXIgaXMgZGVzdHJveWVkLiBOZWVkIHRvIGNsb25lIHRoZVxuICAgICAgLy8gQXJyYXlCdWZmZXIuXG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYXJyYXlCdWZmZXIuc2xpY2UoMCwgb3JpZ2luYWxTaXplKSk7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGdwdVJlYWRCdWZmZXIuZGVzdHJveSgpO1xuICB9XG59O1xuXG5jbGFzcyBHcHVEYXRhTWFuYWdlckltcGwgaW1wbGVtZW50cyBHcHVEYXRhTWFuYWdlciB7XG4gIC8vIEdQVSBEYXRhIElEID0+IEdQVSBEYXRhICggc3RvcmFnZSBidWZmZXIgKVxuICBwcml2YXRlIHN0b3JhZ2VDYWNoZTogTWFwPEdwdURhdGFJZCwgU3RvcmFnZUNhY2hlVmFsdWU+O1xuXG4gIC8vIHBlbmRpbmcgYnVmZmVycyBmb3IgY29tcHV0aW5nXG4gIHByaXZhdGUgYnVmZmVyc1BlbmRpbmc6IEdQVUJ1ZmZlcltdO1xuXG4gIC8vIFRoZSByZXVzYWJsZSBzdG9yYWdlIGJ1ZmZlcnMgZm9yIGNvbXB1dGluZy5cbiAgcHJpdmF0ZSBmcmVlQnVmZmVyczogTWFwPG51bWJlciwgR1BVQnVmZmVyW10+O1xuICAvLyBUaGUgcmV1c2FibGUgdW5pZm9ybSBidWZmZXJzXG4gIHByaXZhdGUgZnJlZVVuaWZvcm1CdWZmZXJzOiBNYXA8bnVtYmVyLCBHUFVCdWZmZXJbXT47XG5cbiAgLy8gVGhlIHBlbmRpbmdCdWZmZXJzIGZvciBjYXB0dXJlIGdyYXBoLlxuICAvLyBhIFNlc3Npb25JRCAtPiBHUFVCdWZmZXJbXSBtYXBwaW5nLlxuICBwcml2YXRlIGNhcHR1cmVkUGVuZGluZ0J1ZmZlcnM6IE1hcDxudW1iZXIsIEdQVUJ1ZmZlcltdPjtcblxuICAvLyBUaGUgc2Vzc2lvbiBjb3VudC5cbiAgcHJpdmF0ZSBzZXNzaW9uQ291bnQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGJhY2tlbmQ6IFdlYkdwdUJhY2tlbmQpIHtcbiAgICB0aGlzLnN0b3JhZ2VDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmZyZWVCdWZmZXJzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuZnJlZVVuaWZvcm1CdWZmZXJzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuYnVmZmVyc1BlbmRpbmcgPSBbXTtcbiAgICB0aGlzLmNhcHR1cmVkUGVuZGluZ0J1ZmZlcnMgPSBuZXcgTWFwKCk7XG5cbiAgICBmb3IgKGNvbnN0IFtrZXldIG9mIGJ1Y2tldEZyZWVsaXN0KSB7XG4gICAgICBidWNrZXRBcnIucHVzaChrZXkpO1xuICAgICAgdGhpcy5mcmVlQnVmZmVycy5zZXQoa2V5LCBbXSk7XG4gICAgICB0aGlzLmZyZWVVbmlmb3JtQnVmZmVycy5zZXQoa2V5LCBbXSk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXNzaW9uQ291bnQgPSAwO1xuICB9XG5cbiAgdXBsb2FkKGlkOiBHcHVEYXRhSWQsIGRhdGE6IFVpbnQ4QXJyYXkpOiB2b2lkIHtcbiAgICBjb25zdCBzcmNBcnJheUJ1ZmZlciA9IGRhdGEuYnVmZmVyO1xuICAgIGNvbnN0IHNyY09mZnNldCA9IGRhdGEuYnl0ZU9mZnNldDtcbiAgICBjb25zdCBzcmNMZW5ndGggPSBkYXRhLmJ5dGVMZW5ndGg7XG4gICAgY29uc3Qgc2l6ZSA9IGNhbGNOb3JtYWxpemVkQnVmZmVyU2l6ZShzcmNMZW5ndGgpO1xuXG4gICAgLy8gZ2V0IGRlc3RpbmF0aW9uIGdwdSBidWZmZXJcbiAgICBjb25zdCBncHVEYXRhQ2FjaGUgPSB0aGlzLnN0b3JhZ2VDYWNoZS5nZXQoaWQpO1xuICAgIGlmICghZ3B1RGF0YUNhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dwdSBkYXRhIGZvciB1cGxvYWRpbmcgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gICAgaWYgKE51bWJlcihncHVEYXRhQ2FjaGUub3JpZ2luYWxTaXplKSAhPT0gc3JjTGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGluY29uc2lzdGVudCBkYXRhIHNpemUuIGdwdSBkYXRhIHNpemU9JHtncHVEYXRhQ2FjaGUub3JpZ2luYWxTaXplfSwgZGF0YSBzaXplPSR7c3JjTGVuZ3RofWApO1xuICAgIH1cblxuICAgIC8vIGNyZWF0ZSBncHUgYnVmZmVyXG4gICAgY29uc3QgZ3B1QnVmZmVyRm9yVXBsb2FkaW5nID0gdGhpcy5iYWNrZW5kLmRldmljZS5jcmVhdGVCdWZmZXIoXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZVxuICAgICAgeyBtYXBwZWRBdENyZWF0aW9uOiB0cnVlLCBzaXplLCB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuTUFQX1dSSVRFIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9TUkMgfSxcbiAgICApO1xuXG4gICAgLy8gY29weSAodXBsb2FkKSBkYXRhXG4gICAgY29uc3QgYXJyYXlCdWZmZXIgPSBncHVCdWZmZXJGb3JVcGxvYWRpbmcuZ2V0TWFwcGVkUmFuZ2UoKTtcbiAgICBuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcikuc2V0KG5ldyBVaW50OEFycmF5KHNyY0FycmF5QnVmZmVyLCBzcmNPZmZzZXQsIHNyY0xlbmd0aCkpO1xuICAgIGdwdUJ1ZmZlckZvclVwbG9hZGluZy51bm1hcCgpO1xuXG4gICAgLy8gR1BVIGNvcHlcbiAgICBjb25zdCBjb21tYW5kRW5jb2RlciA9IHRoaXMuYmFja2VuZC5kZXZpY2UuY3JlYXRlQ29tbWFuZEVuY29kZXIoKTtcbiAgICBjb21tYW5kRW5jb2Rlci5jb3B5QnVmZmVyVG9CdWZmZXIoZ3B1QnVmZmVyRm9yVXBsb2FkaW5nLCAwLCBncHVEYXRhQ2FjaGUuZ3B1RGF0YS5idWZmZXIsIDAsIHNpemUpO1xuICAgIHRoaXMuYmFja2VuZC5kZXZpY2UucXVldWUuc3VibWl0KFtjb21tYW5kRW5jb2Rlci5maW5pc2goKV0pO1xuICAgIGdwdUJ1ZmZlckZvclVwbG9hZGluZy5kZXN0cm95KCk7XG5cbiAgICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiBgW1dlYkdQVV0gR3B1RGF0YU1hbmFnZXIudXBsb2FkKGlkPSR7aWR9KWApO1xuICB9XG5cbiAgbWVtY3B5KHNvdXJjZUlkOiBHcHVEYXRhSWQsIGRlc3RpbmF0aW9uSWQ6IEdwdURhdGFJZCk6IHZvaWQge1xuICAgIC8vIGdldCBzb3VyY2UgZ3B1IGJ1ZmZlclxuICAgIGNvbnN0IHNvdXJjZUdwdURhdGFDYWNoZSA9IHRoaXMuc3RvcmFnZUNhY2hlLmdldChzb3VyY2VJZCk7XG4gICAgaWYgKCFzb3VyY2VHcHVEYXRhQ2FjaGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGdwdSBkYXRhIGZvciBtZW1jcHkgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gICAgLy8gZ2V0IGRlc3RpbmF0aW9uIGdwdSBidWZmZXJcbiAgICBjb25zdCBkZXN0aW5hdGlvbkdwdURhdGFDYWNoZSA9IHRoaXMuc3RvcmFnZUNhY2hlLmdldChkZXN0aW5hdGlvbklkKTtcbiAgICBpZiAoIWRlc3RpbmF0aW9uR3B1RGF0YUNhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Rlc3RpbmF0aW9uIGdwdSBkYXRhIGZvciBtZW1jcHkgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUdwdURhdGFDYWNoZS5vcmlnaW5hbFNpemUgIT09IGRlc3RpbmF0aW9uR3B1RGF0YUNhY2hlLm9yaWdpbmFsU2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbmNvbnNpc3RlbnQgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBncHUgZGF0YSBzaXplJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2l6ZSA9IGNhbGNOb3JtYWxpemVkQnVmZmVyU2l6ZShzb3VyY2VHcHVEYXRhQ2FjaGUub3JpZ2luYWxTaXplKTtcblxuICAgIC8vIEdQVSBjb3B5XG4gICAgY29uc3QgY29tbWFuZEVuY29kZXIgPSB0aGlzLmJhY2tlbmQuZ2V0Q29tbWFuZEVuY29kZXIoKTtcbiAgICB0aGlzLmJhY2tlbmQuZW5kQ29tcHV0ZVBhc3MoKTtcbiAgICBjb21tYW5kRW5jb2Rlci5jb3B5QnVmZmVyVG9CdWZmZXIoXG4gICAgICBzb3VyY2VHcHVEYXRhQ2FjaGUuZ3B1RGF0YS5idWZmZXIsXG4gICAgICAwLFxuICAgICAgZGVzdGluYXRpb25HcHVEYXRhQ2FjaGUuZ3B1RGF0YS5idWZmZXIsXG4gICAgICAwLFxuICAgICAgc2l6ZSxcbiAgICApO1xuICB9XG5cbiAgcmVnaXN0ZXJFeHRlcm5hbEJ1ZmZlcihidWZmZXI6IEdQVUJ1ZmZlciwgb3JpZ2luYWxTaXplOiBudW1iZXIsIHByZXZpb3VzPzogW0dwdURhdGFJZCwgR1BVQnVmZmVyXSk6IG51bWJlciB7XG4gICAgbGV0IGlkOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHByZXZpb3VzKSB7XG4gICAgICBpZCA9IHByZXZpb3VzWzBdO1xuICAgICAgaWYgKGJ1ZmZlciA9PT0gcHJldmlvdXNbMV0pIHtcbiAgICAgICAgTE9HX0RFQlVHKFxuICAgICAgICAgICd2ZXJib3NlJyxcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgYFtXZWJHUFVdIEdwdURhdGFNYW5hZ2VyLnJlZ2lzdGVyRXh0ZXJuYWxCdWZmZXIoc2l6ZT0ke29yaWdpbmFsU2l6ZX0pID0+IGlkPSR7aWR9LCBidWZmZXIgaXMgdGhlIHNhbWUsIHNraXAuYCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGlkO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmJhY2tlbmQuY2FwdHVyZWRDb21tYW5kTGlzdC5oYXModGhpcy5iYWNrZW5kLmN1cnJlbnRTZXNzaW9uSWQhKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlZ2lzdGVyaW5nIGEgZGlmZmVyZW50IGV4dGVybmFsIGJ1ZmZlciB1bmRlciBncmFwaCBjYXB0dXJlIG1vZGUgaXMgbm90IHN1cHBvcnRlZCB5ZXQuXG4gICAgICAgICAgICAgUGxlYXNlIHVzZSB0aGUgcHJldmlvdXMgZXh0ZXJuYWwgYnVmZmVyIWApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZCA9IGNyZWF0ZU5ld0dwdURhdGFJZCgpO1xuICAgIH1cblxuICAgIHRoaXMuc3RvcmFnZUNhY2hlLnNldChpZCwgeyBncHVEYXRhOiB7IGlkLCB0eXBlOiBHcHVEYXRhVHlwZS5kZWZhdWx0LCBidWZmZXIgfSwgb3JpZ2luYWxTaXplIH0pO1xuICAgIExPR19ERUJVRyhcbiAgICAgICd2ZXJib3NlJyxcbiAgICAgICgpID0+IGBbV2ViR1BVXSBHcHVEYXRhTWFuYWdlci5yZWdpc3RlckV4dGVybmFsQnVmZmVyKHNpemU9JHtvcmlnaW5hbFNpemV9KSA9PiBpZD0ke2lkfSwgcmVnaXN0ZXJlZC5gLFxuICAgICk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgdW5yZWdpc3RlckV4dGVybmFsQnVmZmVyKGlkOiBHcHVEYXRhSWQpOiB2b2lkIHtcbiAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zdG9yYWdlQ2FjaGUuZGVsZXRlKGlkKTtcbiAgICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViR1BVXSBHcHVEYXRhTWFuYWdlci51bnJlZ2lzdGVyRXh0ZXJuYWxCdWZmZXIoKSA9PiBpZD0ke2lkfWApO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gIGNyZWF0ZShzaXplOiBudW1iZXIsIHVzYWdlID0gR1BVQnVmZmVyVXNhZ2UuU1RPUkFHRSB8IEdQVUJ1ZmZlclVzYWdlLkNPUFlfU1JDIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QpOiBHcHVEYXRhIHtcbiAgICBjb25zdCBidWZmZXJTaXplID0gY2FsY0J1Y2tldEJ1ZmZlclNpemUoc2l6ZSk7XG5cbiAgICBsZXQgZ3B1QnVmZmVyO1xuICAgIC8vIEN1cnJlbnRseSwgb25seSBzdG9yYWdlIGJ1ZmZlcnMgYXJlIHJldXNlZC5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZVxuICAgIGNvbnN0IGlzU3RvcmFnZSA9ICh1c2FnZSAmIEdQVUJ1ZmZlclVzYWdlLlNUT1JBR0UpID09PSBHUFVCdWZmZXJVc2FnZS5TVE9SQUdFO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgY29uc3QgaXNVbmlmb3JtID0gKHVzYWdlICYgR1BVQnVmZmVyVXNhZ2UuVU5JRk9STSkgPT09IEdQVUJ1ZmZlclVzYWdlLlVOSUZPUk07XG4gICAgaWYgKGlzU3RvcmFnZSB8fCBpc1VuaWZvcm0pIHtcbiAgICAgIGNvbnN0IGZyZWVCdWZmZXJzID0gaXNTdG9yYWdlID8gdGhpcy5mcmVlQnVmZmVycyA6IHRoaXMuZnJlZVVuaWZvcm1CdWZmZXJzO1xuICAgICAgY29uc3QgYnVmZmVycyA9IGZyZWVCdWZmZXJzLmdldChidWZmZXJTaXplKTtcbiAgICAgIGlmICghYnVmZmVycykge1xuICAgICAgICAvLyBubyBzdWNoIGJ1Y2tldC9mcmVlbGlzdCAtIGNyZWF0ZSBncHUgYnVmZmVyXG4gICAgICAgIGdwdUJ1ZmZlciA9IHRoaXMuYmFja2VuZC5kZXZpY2UuY3JlYXRlQnVmZmVyKHsgc2l6ZTogYnVmZmVyU2l6ZSwgdXNhZ2UgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoYnVmZmVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgLy8gaW4gZnJlZWxpc3QsIHVzZSBpdFxuICAgICAgICAgIGdwdUJ1ZmZlciA9IGJ1ZmZlcnMucG9wKCkgYXMgR1BVQnVmZmVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGJ1Y2tldCBlbXB0eSwgY3JlYXRlIGdwdSBidWZmZXJcbiAgICAgICAgICBncHVCdWZmZXIgPSB0aGlzLmJhY2tlbmQuZGV2aWNlLmNyZWF0ZUJ1ZmZlcih7IHNpemU6IGJ1ZmZlclNpemUsIHVzYWdlIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGNyZWF0ZSBncHUgYnVmZmVyXG4gICAgICBncHVCdWZmZXIgPSB0aGlzLmJhY2tlbmQuZGV2aWNlLmNyZWF0ZUJ1ZmZlcih7IHNpemU6IGJ1ZmZlclNpemUsIHVzYWdlIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGdwdURhdGEgPSB7IGlkOiBjcmVhdGVOZXdHcHVEYXRhSWQoKSwgdHlwZTogR3B1RGF0YVR5cGUuZGVmYXVsdCwgYnVmZmVyOiBncHVCdWZmZXIgfTtcbiAgICB0aGlzLnN0b3JhZ2VDYWNoZS5zZXQoZ3B1RGF0YS5pZCwgeyBncHVEYXRhLCBvcmlnaW5hbFNpemU6IE51bWJlcihzaXplKSB9KTtcblxuICAgIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbV2ViR1BVXSBHcHVEYXRhTWFuYWdlci5jcmVhdGUoc2l6ZT0ke3NpemV9KSA9PiBpZD0ke2dwdURhdGEuaWR9YCk7XG4gICAgcmV0dXJuIGdwdURhdGE7XG4gIH1cblxuICBnZXQoaWQ6IEdwdURhdGFJZCk6IEdwdURhdGEgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnN0b3JhZ2VDYWNoZS5nZXQoaWQpPy5ncHVEYXRhO1xuICB9XG5cbiAgcmVsZWFzZShpZElucHV0OiBHcHVEYXRhSWQpOiBudW1iZXIge1xuICAgIGNvbnN0IGlkID0gdHlwZW9mIGlkSW5wdXQgPT09ICdiaWdpbnQnID8gTnVtYmVyKGlkSW5wdXQpIDogaWRJbnB1dDtcbiAgICBjb25zdCBjYWNoZWREYXRhID0gdGhpcy5zdG9yYWdlQ2FjaGUuZ2V0KGlkKTtcbiAgICBpZiAoIWNhY2hlZERhdGEpIHtcbiAgICAgIGlmICh0aGlzLnN0b3JhZ2VDYWNoZS5zaXplID09PSAwKSB7XG4gICAgICAgIC8vIGNhY2hlIHdhcyBwcmV2aW91c2x5IGNsZWFyZWQsIG5vIG5lZWQgdG8gcmVsZWFzZSBhbnl0aGluZy5cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3JlbGVhc2luZyBkYXRhIGRvZXMgbm90IGV4aXN0Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgTE9HX0RFQlVHKCd2ZXJib3NlJywgKCkgPT4gYFtXZWJHUFVdIEdwdURhdGFNYW5hZ2VyLnJlbGVhc2UoaWQ9JHtpZH0pLCBncHVEYXRhSWQ9JHtjYWNoZWREYXRhLmdwdURhdGEuaWR9YCk7XG5cbiAgICB0aGlzLnN0b3JhZ2VDYWNoZS5kZWxldGUoaWQpO1xuICAgIHRoaXMuYnVmZmVyc1BlbmRpbmcucHVzaChjYWNoZWREYXRhLmdwdURhdGEuYnVmZmVyKTtcbiAgICAvLyBjYWNoZWREYXRhLmdwdURhdGEuYnVmZmVyLmRlc3Ryb3koKTtcblxuICAgIHJldHVybiBjYWNoZWREYXRhLm9yaWdpbmFsU2l6ZTtcbiAgfVxuXG4gIGFzeW5jIGRvd25sb2FkKGlkOiBHcHVEYXRhSWQsIGdldFRhcmdldEJ1ZmZlcjogKCkgPT4gVWludDhBcnJheSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNhY2hlZERhdGEgPSB0aGlzLnN0b3JhZ2VDYWNoZS5nZXQoTnVtYmVyKGlkKSk7XG4gICAgaWYgKCFjYWNoZWREYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RhdGEgZG9lcyBub3QgZXhpc3QnKTtcbiAgICB9XG4gICAgYXdhaXQgZG93bmxvYWRHcHVEYXRhKHRoaXMuYmFja2VuZCwgY2FjaGVkRGF0YS5ncHVEYXRhLmJ1ZmZlciwgY2FjaGVkRGF0YS5vcmlnaW5hbFNpemUsIGdldFRhcmdldEJ1ZmZlcik7XG4gIH1cblxuICByZWZyZXNoUGVuZGluZ0J1ZmZlcnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYnVmZmVyc1BlbmRpbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYmFja2VuZC5zZXNzaW9uU3RhdHVzID09PSAnZGVmYXVsdCcpIHtcbiAgICAgIGZvciAoY29uc3QgYnVmZmVyIG9mIHRoaXMuYnVmZmVyc1BlbmRpbmcpIHtcbiAgICAgICAgY29uc3QgbWF4SW5GcmVlTGlzdCA9IGJ1Y2tldEZyZWVsaXN0LmdldChidWZmZXIuc2l6ZSk7XG5cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWJpdHdpc2VcbiAgICAgICAgaWYgKChidWZmZXIudXNhZ2UgJiBHUFVCdWZmZXJVc2FnZS5TVE9SQUdFKSA9PT0gR1BVQnVmZmVyVXNhZ2UuU1RPUkFHRSkge1xuICAgICAgICAgIC8vIFB1dCB0aGUgcGVuZGluZyBidWZmZXIgdG8gZnJlZUJ1ZmZlcnMgbGlzdCBpbnN0ZWFkIG9mIHJlYWxseSBkZXN0cm95aW5nIGl0IGZvciBidWZmZXIgcmV1c2luZy5cbiAgICAgICAgICBjb25zdCBmcmVlbGlzdCA9IHRoaXMuZnJlZUJ1ZmZlcnMuZ2V0KGJ1ZmZlci5zaXplKSB8fCBbXTtcbiAgICAgICAgICBpZiAobWF4SW5GcmVlTGlzdCA9PT0gdW5kZWZpbmVkIHx8IGZyZWVsaXN0Lmxlbmd0aCA+PSBtYXhJbkZyZWVMaXN0KSB7XG4gICAgICAgICAgICBidWZmZXIuZGVzdHJveSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcmVlbGlzdC5wdXNoKGJ1ZmZlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgICAgIH0gZWxzZSBpZiAoKGJ1ZmZlci51c2FnZSAmIEdQVUJ1ZmZlclVzYWdlLlVOSUZPUk0pID09PSBHUFVCdWZmZXJVc2FnZS5VTklGT1JNKSB7XG4gICAgICAgICAgLy8gUHV0IHRoZSBwZW5kaW5nIGJ1ZmZlciB0byBmcmVlVW5pZm9ybUJ1ZmZlcnMgbGlzdCBpbnN0ZWFkIG9mIHJlYWxseSBkZXN0cm95aW5nIGl0IGZvciBidWZmZXIgcmV1c2luZy5cbiAgICAgICAgICBjb25zdCBmcmVlbGlzdCA9IHRoaXMuZnJlZVVuaWZvcm1CdWZmZXJzLmdldChidWZmZXIuc2l6ZSkgfHwgW107XG4gICAgICAgICAgaWYgKG1heEluRnJlZUxpc3QgPT09IHVuZGVmaW5lZCB8fCBmcmVlbGlzdC5sZW5ndGggPj0gbWF4SW5GcmVlTGlzdCkge1xuICAgICAgICAgICAgYnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZnJlZWxpc3QucHVzaChidWZmZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidWZmZXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmJ1ZmZlcnNQZW5kaW5nID0gW107XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERvbid0IHJlbGVhc2UgaW50ZXJtZWRpYXRlIHRlbnNvcnMgaW4gbm9uLWRlZmF1bHQgbW9kZS5cbiAgICAgIC8vIFRPRE86IHJldXNlIHRoZSBzdG9yYWdlIGJ1ZmZlcnMgaW4gbm9uLWRlZmF1bHQgbW9kZS5cbiAgICAgIGxldCBjYXB0dXJlZEJ1ZmZlcnMgPSB0aGlzLmNhcHR1cmVkUGVuZGluZ0J1ZmZlcnMuZ2V0KHRoaXMuYmFja2VuZC5jdXJyZW50U2Vzc2lvbklkISk7XG4gICAgICBpZiAoIWNhcHR1cmVkQnVmZmVycykge1xuICAgICAgICBjYXB0dXJlZEJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgdGhpcy5jYXB0dXJlZFBlbmRpbmdCdWZmZXJzLnNldCh0aGlzLmJhY2tlbmQuY3VycmVudFNlc3Npb25JZCEsIGNhcHR1cmVkQnVmZmVycyk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGJ1ZmZlciBvZiB0aGlzLmJ1ZmZlcnNQZW5kaW5nKSB7XG4gICAgICAgIGNhcHR1cmVkQnVmZmVycy5wdXNoKGJ1ZmZlcik7XG4gICAgICB9XG4gICAgICB0aGlzLmJ1ZmZlcnNQZW5kaW5nID0gW107XG4gICAgfVxuICB9XG5cbiAgZGlzcG9zZSgpIHtcbiAgICB0aGlzLmZyZWVCdWZmZXJzLmZvckVhY2goKGJ1ZmZlcnMpID0+IHtcbiAgICAgIGJ1ZmZlcnMuZm9yRWFjaCgoYnVmZmVyKSA9PiB7XG4gICAgICAgIGJ1ZmZlci5kZXN0cm95KCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICB0aGlzLmZyZWVVbmlmb3JtQnVmZmVycy5mb3JFYWNoKChidWZmZXJzKSA9PiB7XG4gICAgICBidWZmZXJzLmZvckVhY2goKGJ1ZmZlcikgPT4ge1xuICAgICAgICBidWZmZXIuZGVzdHJveSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnN0b3JhZ2VDYWNoZS5mb3JFYWNoKChzdG9yYWdlKSA9PiB7XG4gICAgICBzdG9yYWdlLmdwdURhdGEuYnVmZmVyLmRlc3Ryb3koKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2FwdHVyZWRQZW5kaW5nQnVmZmVycy5mb3JFYWNoKChidWZmZXJzKSA9PiB7XG4gICAgICBidWZmZXJzLmZvckVhY2goKGJ1ZmZlcikgPT4ge1xuICAgICAgICBidWZmZXIuZGVzdHJveSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgdGhpcy5zdG9yYWdlQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5mcmVlQnVmZmVycyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmZyZWVVbmlmb3JtQnVmZmVycyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmNhcHR1cmVkUGVuZGluZ0J1ZmZlcnMgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBvbkNyZWF0ZVNlc3Npb24oKSB7XG4gICAgdGhpcy5zZXNzaW9uQ291bnQgKz0gMTtcbiAgfVxuXG4gIG9uUmVsZWFzZVNlc3Npb24oc2Vzc2lvbklkOiBudW1iZXIpIHtcbiAgICAvLyByZWxlYXNlIHRoZSBjYXB0dXJlZCBwZW5kaW5nIGJ1ZmZlcnMuXG4gICAgY29uc3QgcGVuZGluZ0J1ZmZlcnMgPSB0aGlzLmNhcHR1cmVkUGVuZGluZ0J1ZmZlcnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKHBlbmRpbmdCdWZmZXJzKSB7XG4gICAgICBwZW5kaW5nQnVmZmVycy5mb3JFYWNoKChidWZmZXIpID0+IHtcbiAgICAgICAgYnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5jYXB0dXJlZFBlbmRpbmdCdWZmZXJzLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIH1cblxuICAgIC8vIHJlbGVhc2UgdGhlIHN0b3JhZ2UgY2FjaGUgaWYgbm8gYWN0aXZlIHNlc3Npb25zLlxuICAgIHRoaXMuc2Vzc2lvbkNvdW50IC09IDE7XG4gICAgaWYgKHRoaXMuc2Vzc2lvbkNvdW50ID09PSAwKSB7XG4gICAgICBMT0dfREVCVUcoJ3dhcm5pbmcnLCAoKSA9PiAnW1dlYkdQVV0gQ2xlYXJpbmcgd2ViZ3B1IGJ1ZmZlciBjYWNoZScpO1xuICAgICAgdGhpcy5zdG9yYWdlQ2FjaGUuZm9yRWFjaCgoc3RvcmFnZSkgPT4ge1xuICAgICAgICBzdG9yYWdlLmdwdURhdGEuYnVmZmVyLmRlc3Ryb3koKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zdG9yYWdlQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVHcHVEYXRhTWFuYWdlciA9ICguLi5hcmdzOiBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIEdwdURhdGFNYW5hZ2VySW1wbD4pOiBHcHVEYXRhTWFuYWdlciA9PlxuICBuZXcgR3B1RGF0YU1hbmFnZXJJbXBsKC4uLmFyZ3MpO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5jbGFzcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXlJbXBsIHtcbiAgY29uc3RydWN0b3IoYXR0cmlidXRlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgYXR0cmlidXRlKTtcbiAgfVxuXG4gIHByaXZhdGUga2V5OiBzdHJpbmc7XG4gIHB1YmxpYyBnZXQgY2FjaGVLZXkoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMua2V5KSB7XG4gICAgICB0aGlzLmtleSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMpXG4gICAgICAgIC5zb3J0KClcbiAgICAgICAgLm1hcCgobmFtZSkgPT4gYCR7KHRoaXMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW25hbWVdfWApXG4gICAgICAgIC5qb2luKCc7Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmtleTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGNhY2hlS2V5OiBzdHJpbmc7XG59XG5cbi8qKlxuICogY3JlYXRlIGEgbmV3IG9iamVjdCBmcm9tIHRoZSBnaXZlbiBhdHRyaWJ1dGUsIGFuZCBhZGQgYSBjYWNoZUtleSBwcm9wZXJ0eSB0byBpdFxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5ID0gPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gIGF0dHJpYnV0ZTogVCxcbik6IFQgJiBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgPT4gbmV3IEF0dHJpYnV0ZVdpdGhDYWNoZUtleUltcGwoYXR0cmlidXRlKSBhcyB1bmtub3duIGFzIFQgJiBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBQcm9ncmFtVW5pZm9ybSwgUHJvZ3JhbVVuaWZvcm1WYXJpYWJsZUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbi8qKlxuICogY29uc3RhbnQgdmFsdWUgZm9yIGEgd29ya2dyb3VwIHNpemUuXG4gKlxuICogV2UgZGVmaW5pdGVseSBjYW4gZG8gZnVydGhlciBvcHRpbWl6YXRpb24gaW4gZnV0dXJlLCBidXQgZm9yIG5vdyB3ZSB1c2UgNjQuXG4gKlxuICogcnVsZSBvZiB0aHVtYjogVXNlIFthIHdvcmtncm91cCBzaXplIG9mXSA2NCB1bmxlc3MgeW91IGtub3cgd2hhdCBHUFUgeW91IGFyZSB0YXJnZXRpbmcgb3IgdGhhdCB5b3VyIHdvcmtsb2FkXG4gKiAgICAgICAgICAgICAgICBuZWVkcyBzb21ldGhpbmcgZGlmZmVyZW50LlxuICpcbiAqIGZyb206IGh0dHBzOi8vc3VybWEuZGV2L3RoaW5ncy93ZWJncHUvXG4gKiovXG5leHBvcnQgY29uc3QgV09SS0dST1VQX1NJWkUgPSA2NDtcblxuaW50ZXJmYWNlIEluZGljZXNIZWxwZXJUeXBlcyB7XG4gIC8qKlxuICAgKiBXR1NMIHR5cGUgb2YgaW5kaWNlcyBleHByZXNzaW9uXG4gICAqL1xuICByZWFkb25seSBpbmRpY2VzOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdHU0wgdHlwZSBvZiBhIHZhbHVlXG4gICAqL1xuICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIHR5cGUgb2Ygc3RvcmFnZSB0eXBlIHJlcHJlc2VudGluZyBhIHZhbHVlXG4gICAqXG4gICAqIFRoaXMgaXMgdXN1YWxseSB0aGUgc2FtZSB0byBgdmFsdWVgLCBidXQgZm9yIHNvbWUgdHlwZSAoZWcuIGJvb2wpLCB3ZSBuZWVkIHRvIHVzZSBgdTMyYCBhcyBzdG9yYWdlIHR5cGUgZm9yXG4gICAqIHZhbHVlIHR5cGUgYHZlYzQ8Ym9vbD5gXG4gICAqL1xuICByZWFkb25seSBzdG9yYWdlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIHRlbnNvciB0eXBlIGFzIHJlcHJlc2VudGVkIGluIFRlbnNvclZpZXdcbiAgICovXG4gIHJlYWRvbmx5IHRlbnNvcjogbnVtYmVyO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGNsYXNzIGZvciBnZW5lcmF0aW5nIFdHU0wgY29kZSBmb3IgbWFuaXB1bGF0aW5nIGluZGljZXMgYW5kIGRhdGEgZm9yIGEgc2hhZGVyJ3MgaW5wdXQgb3Igb3V0cHV0LlxuICpcbiAqIFRoaXMgY2xhc3MgaXMgZGVzaWduZWQgdG8gb2ZmZXIgYSB1bmlmaWVkIHdheSB0byBnZW5lcmF0ZSBXR1NMIGNvZGUgZm9yIG1hbmlwdWxhdGluZyBpbmRpY2VzIGFuZCBkYXRhIGZvciBhIHNoYWRlcidzXG4gKiBpbnB1dCBvciBvdXRwdXQuXG4gKlxuICogVGhlIGZvbGxvd2luZyBpcyBhIGxpc3Qgb2YgdGVybWlub2xvZ2llcyB1c2VkIGluIHRoaXMgY2xhc3M6XG4gKiAtIGBvZmZzZXRgOiBhIHVpbnQzMiB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIG9mZnNldCBvZiBhbiBlbGVtZW50IGluIHRoZSBkYXRhIGJ1ZmZlci5cbiAqIC0gYGluZGljZXNgOiBhbiBhYnN0cmFjdGlvbiBvZiBhIG11bHRpLWRpbWVuc2lvbmFsIGFycmF5J3MgaW5kaWNlcyByZXByZXNlbnRpbmcgdGhlIGRhdGEncyBpbmRleCBvbiBlYWNoIGRpbWVuc2lvbi5cbiAqIC0gYHZhbHVlYDogYSB2YWx1ZSBvZiBhIGRhdGEgZWxlbWVudC5cbiAqXG4gKiBVc2VycyBhcmUgZXhwZWN0ZWQgdG8gY3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZm9yIGVhY2ggc2hhZGVyJ3MgaW5wdXQgb3Igb3V0cHV0LCBhbmQgdXNlIHRoZSBpbnN0YW5jZSB0b1xuICogZ2VuZXJhdGUgV0dTTCBjb2RlIGZvciBtYW5pcHVsYXRpbmcgaW5kaWNlcyBhbmQgZGF0YS4gVGhlIGZvbGxvd2luZyAyIGV4cG9ydGVkIGZ1bmN0aW9ucyBhcmUgZm9yIHVzZXJzIHRvIGNhbGwgdG9cbiAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhbiBpbmRpY2VzIGhlbHBlcjpcbiAqIC0gYGlucHV0VmFyaWFibGUoKWA6IGNyZWF0ZSBhbiBpbmRpY2VzIGhlbHBlciBpbnN0YW5jZSBmb3IgYW4gaW5wdXQuXG4gKiAtIGBvdXRwdXRWYXJpYWJsZSgpYDogY3JlYXRlIGFuIGluZGljZXMgaGVscGVyIGluc3RhbmNlIGZvciBhbiBvdXRwdXQuXG4gKiAtIGBpbnRlcm5hbFZhcmlhYmxlKClgOiBjcmVhdGUgYW4gaW5kaWNlcyBoZWxwZXIgaW5zdGFuY2UgZm9yIGFuIGludGVybmFsIHZhcmlhYmxlLlxuICpcbiAqIEFuIGluZGljZXMgaGVscGVyIGluc3RhbmNlIGNvbnRhaW5zIGhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBmb2xsb3dpbmcgb3BlcmF0aW9uczpcbiAqIC0gYWNjZXNzIHJlYWRvbmx5IGJhc2ljIGluZm9ybWF0aW9uLCBpbmNsdWRpbmc6IGBuYW1lYCh0aGUgbmFtZSBvZiB0aGUgaW5wdXQgb3Igb3V0cHV0KSwgYHVzYWdlYCh3aGV0aGVyIGl0J3MgYW5cbiAqIGlucHV0LCBhbiBvdXRwdXQgb3IgYW4gaW50ZXJuYWwgdmFyaWFibGUpIGFuZCBgc2hhcGVgKHRoZSBwYXNzZWQgaW4gc2hhcGUpLlxuICogLSBgdHlwZWA6IGFjY2VzcyByZWFkb25seSB0eXBlIGluZm9ybWF0aW9uLCBpbmNsdWRpbmc6IGBpbmRpY2VzYCh0aGUgdHlwZSBvZiBpbmRpY2VzKSwgYHZhbHVlYCh0aGUgdHlwZSBvZiB2YWx1ZSBhdFxuICogcnVudGltZSksIGBzdG9yYWdlYCh0aGUgdHlwZSBvZiB2YWx1ZSBhdCBzdG9yYWdlKSBhbmQgYHRlbnNvcmAodGhlIHRlbnNvciB0eXBlIGFzIHJlcHJlc2VudGVkIGluIFRlbnNvclZpZXcpLlxuICogLSBnZW5lcmF0ZSBXR1NMIGNvZGUgZm9yIGdldHRpbmcgaW5kaWNlcyBmcm9tIG9mZnNldC4gVXNlIGBvZmZzZXRUb0luZGljZXMoKWAgZm9yIFdHU0wgY29kZSBzbmlwcGV0IHRvIGNhbGN1bGF0ZVxuICogaW5kaWNlcyBmcm9tIG9mZnNldCwgYW5kIHVzZSBgaW5kaWNlc1RvT2Zmc2V0KClgIGZvciBXR1NMIGNvZGUgc25pcHBldCB0byBjYWxjdWxhdGUgb2Zmc2V0IGZyb20gaW5kaWNlcy5cbiAqIC0gdG8gbWFuaXB1bGF0ZSBhbiBpbnN0YW5jZSBvZiBpbmRpY2VzLCB1c2UgYHNldEluZGljZXMoKWAgYW5kIGBnZXRJbmRpY2VzKClgIHRvIHNldCBhbmQgZ2V0IHRoZSBpbmRpY2VzIG9uIGFuXG4gKiBpbmRpY2VzIHZhcmlhYmxlLlxuICogLSB0byBtYW5pcHVsYXRlIGRhdGEsIHVzZSBgc2V0KClgL2BnZXQoKWAgdG8gYWNjZXNzIGRhdGEgYXQgdGhlIGdpdmVuIGluZGljZXMgZnJvbSBwYXJhbWV0ZXIgbGlzdCwgdXNlXG4gKiBgc2V0QnlJbmRpY2VzKClgL2BnZXRCeUluZGljZXMoKWAgdG8gYWNjZXNzIGRhdGEgYXQgdGhlIGdpdmVuIGluZGljZXMgZnJvbSBhbiBpbmRpY2VzIHZhcmlhYmxlLCBhbmQgdXNlXG4gKiBgc2V0QnlPZmZzZXQoKWAvYGdldEJ5T2Zmc2V0KClgIHRvIGFjY2VzcyBkYXRhIGF0IHRoZSBnaXZlbiBvZmZzZXQuXG4gKiAtIGBpbXBsYDogZ2V0IFdHU0wgY29kZSBvZiBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIHV0aWwgZnVuY3Rpb25zIG1lbnRpb25lZCBhYm92ZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmRpY2VzSGVscGVyIHtcbiAgLyoqXG4gICAqIGdldCBXR1NMIGNvZGUgb2YgZnVuY3Rpb24gaW1wbGVtZW50YXRpb24gZm9yIHRoZSB1dGlsIGZ1bmN0aW9ucy5cbiAgICpcbiAgICovXG4gIHJlYWRvbmx5IGltcGw6ICgpID0+IHN0cmluZztcblxuICAvKipcbiAgICogZ2V0IHR5cGUgaW5mb1xuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogSW5kaWNlc0hlbHBlclR5cGVzO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgb2YgYSBleHByZXNzaW9uIGZvciBnZXR0aW5nIGluZGljZXMgZnJvbSBvZmZzZXQuXG4gICAqXG4gICAqIEBwYXJhbSB2YXJPZmZzZXQgLSBhIHUzMiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgb2Zmc2V0LlxuICAgKlxuICAgKiBAcmV0dXJucyBhbiBgdHlwZS5pbmRpY2VzYCBleHByZXNzaW9uXG4gICAqL1xuICByZWFkb25seSBvZmZzZXRUb0luZGljZXM6ICh2YXJPZmZzZXQ6IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgb2YgYW4gYHUzMmAgZXhwcmVzc2lvbiBmb3IgZ2V0dGluZyBvZmZzZXQgZnJvbSBpbmRpY2VzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFySW5kaWNlcyAtIGEgYHR5cGUuaW5kaWNlc2AgZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGluZGljZXMuXG4gICAqXG4gICAqIEByZXR1cm5zIGFuIGB1MzJgIGV4cHJlc3Npb25cbiAgICovXG4gIHJlYWRvbmx5IGluZGljZXNUb09mZnNldDogKHZhckluZGljZXM6IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgb2YgYW4gYHUzMmAgZXhwcmVzc2lvbiBmb3IgZ2V0dGluZyBvcmlnaW5hbCBvZmZzZXQgZnJvbSBicm9hZGNhc3RlZCBpbmRpY2VzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFySW5kaWNlcyAtIGEgYHR5cGUuaW5kaWNlc2AgZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIG91dHB1dCBpbmRpY2VzLlxuICAgKiBAcGFyYW0gb3V0cHV0IC0gb3V0cHV0IEluZGljZXNIZWxwZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIGFuIGB1MzJgIGV4cHJlc3Npb25cbiAgICovXG4gIHJlYWRvbmx5IGJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0OiAodmFySW5kaWNlczogc3RyaW5nLCBvdXRwdXQ6IEluZGljZXNIZWxwZXIpID0+IHN0cmluZztcblxuICAvKipcbiAgICogV0dTTCBjb2RlIG9mIGdlbmVyYXRpbmcgYW4gaW5kaWNlcyBsaXRlcmFsXG4gICAqXG4gICAqIEBwYXJhbSBpbml0IC0gaW5pdGlhbCB2YWx1ZS5cbiAgICovXG4gIHJlYWRvbmx5IGluZGljZXM6ICguLi5pbml0OiBSZWFkb25seUFycmF5PG51bWJlciB8IHN0cmluZz4pID0+IHN0cmluZztcblxuICAvKipcbiAgICogV0dTTCBjb2RlIG9mIGEgc3RhdGVtZW50IGZvciBzZXR0aW5nIGluZGljZXMuXG4gICAqXG4gICAqIEBwYXJhbSB2YXJJbmRpY2VzIC0gYSB2YXJpYWJsZSBuYW1lIGZvciB0aGUgaW5kaWNlcy5cbiAgICogQHBhcmFtIGlkeCAtIHRoZSBpbmRleCBvZiB0aGUgaW5kaWNlcyB0byBzZXQuIGNhbiBiZSBhIG51bWJlciBvciBhIHN0cmluZyAoV0dTTCBgdTMyYCBleHByZXNzaW9uKS5cbiAgICogQHBhcmFtIHZhbHVlIC0gdGhlIHZhbHVlIHRvIHNldC4gY2FuIGJlIGEgbnVtYmVyIG9yIGEgc3RyaW5nIChXR1NMIGB1MzJgIGV4cHJlc3Npb24pLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIFdHU0wgc3RhdGVtZW50XG4gICAqL1xuICByZWFkb25seSBpbmRpY2VzU2V0OiAodmFySW5kaWNlczogc3RyaW5nLCBpZHg6IG51bWJlciB8IHN0cmluZywgdmFsdWU6IG51bWJlciB8IHN0cmluZykgPT4gdm9pZDtcblxuICAvKipcbiAgICogV0dTTCBjb2RlIG9mIGFuIGB1MzJgIGV4cHJlc3Npb24gZm9yIGdldHRpbmcgaW5kaWNlcy5cbiAgICpcbiAgICogQHBhcmFtIHZhckluZGljZXMgLSBhIHZhcmlhYmxlIG5hbWUgZm9yIHRoZSBpbmRpY2VzLlxuICAgKiBAcGFyYW0gaWR4IC0gdGhlIGluZGV4IG9mIHRoZSBpbmRpY2VzIHRvIGdldC4gY2FuIGJlIGEgbnVtYmVyIG9yIGEgc3RyaW5nIChXR1NMIGB1MzJgIGV4cHJlc3Npb24pLlxuICAgKlxuICAgKiBAcmV0dXJucyBhbiBgdTMyYCBleHByZXNzaW9uXG4gICAqL1xuICByZWFkb25seSBpbmRpY2VzR2V0OiAodmFySW5kaWNlczogc3RyaW5nLCBpZHg6IG51bWJlciB8IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgZm9yIGEgc3RhdGVtZW50IGZvciBzZXR0aW5nIGRhdGEgYXQgdGhlIGdpdmVuIGluZGljZXMuXG4gICAqXG4gICAqIEBwYXJhbSBpbmRpY2VzQW5kVmFsdWUgLSBhbiBhcnJheSBvZiBudW1iZXJzIG9yIHN0cmluZ3MgKFdHU0wgYHUzMmAgZXhwcmVzc2lvbikgcmVwcmVzZW50aW5nIHRoZSBpbmRpY2VzLCBmb2xsb3dlZFxuICAgKiAgICAgYnkgdGhlIHZhbHVlIHRvIHNldC4gVGhpcyBhcnJheSBzaG91bGQgaGF2ZSBleGFjdGx5IGBzaGFwZS5sZW5ndGggKyAxYCBlbGVtZW50cy5cbiAgICovXG4gIHJlYWRvbmx5IHNldDogKC4uLmluZGljZXNBbmRWYWx1ZTogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+KSA9PiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdHU0wgY29kZSBmb3IgYSBzdGF0ZW1lbnQgZm9yIHNldHRpbmcgZGF0YSBhdCB0aGUgZ2l2ZW4gaW5kaWNlcyB2YXJpYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHZhckluZGljZXMgLSBhIHZhcmlhYmxlIG5hbWUgZm9yIHRoZSBpbmRpY2VzLlxuICAgKiBAcGFyYW0gdmFsdWUgLSB0aGUgdmFsdWUgdG8gc2V0LiBzaG91bGQgYmUgYSBXR1NMIGV4cHJlc3Npb24uXG4gICAqL1xuICByZWFkb25seSBzZXRCeUluZGljZXM6ICh2YXJJbmRpY2VzOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpID0+IHN0cmluZztcblxuICAvKipcbiAgICogV0dTTCBjb2RlIGZvciBhIHN0YXRlbWVudCBmb3Igc2V0dGluZyBkYXRhIGF0IHRoZSBnaXZlbiBvZmZzZXQuXG4gICAqXG4gICAqIEBwYXJhbSBvZmZzZXQgLSBhIG51bWJlciBvciBhIHN0cmluZyAoV0dTTCBgdTMyYCBleHByZXNzaW9uKSByZXByZXNlbnRpbmcgdGhlIG9mZnNldC5cbiAgICogQHBhcmFtIHZhbHVlIC0gdGhlIHZhbHVlIHRvIHNldC4gc2hvdWxkIGJlIGEgV0dTTCBleHByZXNzaW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgc2V0QnlPZmZzZXQ6IChvZmZzZXQ6IG51bWJlciB8IHN0cmluZywgdmFsdWU6IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXR1NMIGNvZGUgZm9yIGFuIGV4cHJlc3Npb24gZm9yIGdldHRpbmcgZGF0YSBhdCB0aGUgZ2l2ZW4gaW5kaWNlcy5cbiAgICpcbiAgICogQHBhcmFtIGluZGljZXMgLSBhbiBhcnJheSBvZiBudW1iZXJzIG9yIHN0cmluZ3MgKFdHU0wgYHUzMmAgZXhwcmVzc2lvbikgcmVwcmVzZW50aW5nIHRoZSBpbmRpY2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgZ2V0OiAoLi4uaW5kaWNlczogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+KSA9PiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdHU0wgY29kZSBmb3IgYW4gZXhwcmVzc2lvbiBmb3IgZ2V0dGluZyBkYXRhIGF0IHRoZSBnaXZlbiBpbmRpY2VzIHZhcmlhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0gdmFySW5kaWNlcyAtIGEgdmFyaWFibGUgbmFtZSBmb3IgdGhlIGluZGljZXMuXG4gICAqL1xuICByZWFkb25seSBnZXRCeUluZGljZXM6ICh2YXJJbmRpY2VzOiBzdHJpbmcpID0+IHN0cmluZztcblxuICAvKipcbiAgICogV0dTTCBjb2RlIGZvciBhbiBleHByZXNzaW9uIGZvciBnZXR0aW5nIGRhdGEgYXQgdGhlIGdpdmVuIG9mZnNldC5cbiAgICpcbiAgICogQHBhcmFtIG9mZnNldCAtIGEgbnVtYmVyIG9yIGEgc3RyaW5nIChXR1NMIGB1MzJgIGV4cHJlc3Npb24pIHJlcHJlc2VudGluZyB0aGUgb2Zmc2V0LlxuICAgKi9cbiAgcmVhZG9ubHkgZ2V0QnlPZmZzZXQ6IChvZmZzZXQ6IG51bWJlciB8IHN0cmluZykgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBuYW1lIG9mIHRoZSBkYXRhIHZhcmlhYmxlXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIHdoZXRoZXIgdGhlIGhlbHBlciBpcyBmb3IgYW4gaW5wdXQsIGFuIG91dHB1dCBvciBhbiBpbnRlcm5hbCB2YXJpYWJsZS5cbiAgICovXG4gIHJlYWRvbmx5IHVzYWdlOiAnaW5wdXQnIHwgJ291dHB1dCcgfCAnYXRvbWljT3V0cHV0JyB8ICdpbnRlcm5hbCc7XG5cbiAgLyoqXG4gICAqIHRoZSByYW5rIG9mIHRoZSBpbnB1dCBvciBvdXRwdXQuXG4gICAqL1xuICByZWFkb25seSByYW5rOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgdmFyaWFibGUgbmFtZSBmb3IgdGhlIHNoYXBlIG9mIHRoZSBpbnB1dCBvciBvdXRwdXQuXG4gICAqL1xuICByZWFkb25seSBzaGFwZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHZhcmlhYmxlIG5hbWUgZm9yIHRoZSBzdHJpZGVzIG9mIHRoZSBpbnB1dCBvciBvdXRwdXQuXG4gICAqL1xuICByZWFkb25seSBzdHJpZGVzOiBzdHJpbmc7XG59XG5cbmNvbnN0IGdldFdnc2xNYXBwZWRUeXBlID0gKHR5cGU6IG51bWJlciwgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCk6IHN0cmluZyB8IFtzdHJpbmcsIHN0cmluZ10gPT4ge1xuICBpZiAoY29tcG9uZW50cyA9PT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcigndmVjMyBoYXMgc2FtZSBhbGlnbm1lbnQgYXMgdmVjNCwgdXNlIHZlYzQgaW5zdGVhZCcpO1xuICB9XG5cbiAgLy8gcmV0dXJuIHR5cGUgaXMgWyBzdG9yYWdlIHR5cGUsIHJ1bnRpbWUgdHlwZSBdIG9yIGEgc2luZ2xlIHN0cmluZyBmb3IgYm90aFxuICBzd2l0Y2ggKE51bWJlcih0eXBlKSkge1xuICAgIGNhc2UgRGF0YVR5cGUuZmxvYXQxNjpcbiAgICAgIHJldHVybiBjb21wb25lbnRzID4gMSA/IGB2ZWMke2NvbXBvbmVudHN9PGYxNj5gIDogJ2YxNic7XG4gICAgY2FzZSBEYXRhVHlwZS5mbG9hdDpcbiAgICAgIHJldHVybiBjb21wb25lbnRzID4gMSA/IGB2ZWMke2NvbXBvbmVudHN9PGYzMj5gIDogJ2YzMic7XG4gICAgY2FzZSBEYXRhVHlwZS5pbnQzMjpcbiAgICAgIHJldHVybiBjb21wb25lbnRzID4gMSA/IGB2ZWMke2NvbXBvbmVudHN9PGkzMj5gIDogJ2kzMic7XG4gICAgY2FzZSBEYXRhVHlwZS51aW50MzI6XG4gICAgICByZXR1cm4gY29tcG9uZW50cyA+IDEgPyBgdmVjJHtjb21wb25lbnRzfTx1MzI+YCA6ICd1MzInO1xuICAgIGNhc2UgRGF0YVR5cGUuaW50NjQ6XG4gICAgICBpZiAoY29tcG9uZW50cyA+IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgbm90IHN1cHBvcnRlZCB2ZWNYIG9mIHVpbnQ2NCB5ZXQnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbJ3ZlYzI8dTMyPicsICdpMzInXTtcbiAgICBjYXNlIERhdGFUeXBlLnVpbnQ2NDpcbiAgICAgIGlmIChjb21wb25lbnRzID4gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBub3Qgc3VwcG9ydGVkIHZlY1ggb2YgdWludDY0IHlldCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFsndmVjMjx1MzI+JywgJ3UzMiddO1xuICAgIGNhc2UgRGF0YVR5cGUuYm9vbDpcbiAgICAgIGlmIChjb21wb25lbnRzICE9PSA0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYm9vbCBtdXN0IGJlIHZlYzQnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbJ3UzMicsICd2ZWM0PGJvb2w+J107XG4gICAgY2FzZSBEYXRhVHlwZS5pbnQ0OlxuICAgICAgcmV0dXJuICdpMzInO1xuICAgIGNhc2UgRGF0YVR5cGUudWludDQ6XG4gICAgICByZXR1cm4gJ3UzMic7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkYXRhIHR5cGU6ICR7dHlwZX1gKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSA9ICh0eXBlOiBEYXRhVHlwZSwgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCA9IDEpID0+IHtcbiAgY29uc3QgbWFwcGVkVHlwZSA9IGdldFdnc2xNYXBwZWRUeXBlKHR5cGUsIGNvbXBvbmVudHMpO1xuICByZXR1cm4gdHlwZW9mIG1hcHBlZFR5cGUgPT09ICdzdHJpbmcnID8gbWFwcGVkVHlwZSA6IG1hcHBlZFR5cGVbMF07XG59O1xuXG5leHBvcnQgY29uc3QgdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZSA9ICh0eXBlOiBEYXRhVHlwZSwgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCA9IDEpID0+IHtcbiAgY29uc3QgbWFwcGVkVHlwZSA9IGdldFdnc2xNYXBwZWRUeXBlKHR5cGUsIGNvbXBvbmVudHMpO1xuICByZXR1cm4gdHlwZW9mIG1hcHBlZFR5cGUgPT09ICdzdHJpbmcnID8gbWFwcGVkVHlwZSA6IG1hcHBlZFR5cGVbMV07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMgPSAoLi4uZGltczogUmVhZG9ubHlBcnJheTxyZWFkb25seSBudW1iZXJbXT4pOiBQcm9ncmFtVW5pZm9ybVtdID0+IHtcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW107XG4gIGRpbXMuZm9yRWFjaCgoZGltKSA9PiB7XG4gICAgaWYgKGRpbS5sZW5ndGggIT09IDApIHtcbiAgICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKFxuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZGltIH0sXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoZGltKSB9LFxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcHJvZ3JhbVVuaWZvcm1zO1xufTtcblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0byBnZXQgbWF4aW11bSB2ZWN0b3Igc2l6ZSBmb3Igc3BlY2lmaWVkIGRhdGEgbGVuZ3RoXG4gKiBAcGFyYW0gc2l6ZVxuICovXG5leHBvcnQgY29uc3QgZ2V0TWF4Q29tcG9uZW50cyA9IChzaXplOiBudW1iZXIpID0+IHtcbiAgLy8gd2UgY2Fubm90IHVzZSB2ZWMzIHR5cGUgc2luY2UgaXQgaGFzIGFsaWdubWVudCBvZiAxNiBieXRlc1xuICBpZiAoc2l6ZSAlIDQgPT09IDApIHtcbiAgICByZXR1cm4gNDtcbiAgfSBlbHNlIGlmIChzaXplICUgMiA9PT0gMCkge1xuICAgIHJldHVybiAyO1xuICB9XG5cbiAgcmV0dXJuIDE7XG59O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgaW5pdGlhbGl6ZXMgdmFyaWFibGUgYXMgYSBzY2FsYXIgb3IgdmVjdG9yLiBlLmcuIGYzMigwKSBvciB2ZWM0ZigwLDAsMCwwKVxuICogQHBhcmFtIGRhdGFUeXBlXG4gKiBAcGFyYW0gY29tcG9uZW50c1xuICogQHBhcmFtIHZhbHVlXG4gKi9cbmV4cG9ydCBjb25zdCBmaWxsVmVjdG9yID0gKGRhdGFUeXBlID0gJ2YzMicsIGNvbXBvbmVudHM/OiBudW1iZXIsIHZhbHVlID0gJzAnKSA9PiB7XG4gIGlmICghY29tcG9uZW50cyB8fCBjb21wb25lbnRzID09PSAxKSB7XG4gICAgcmV0dXJuIGAke2RhdGFUeXBlfSgke3ZhbHVlfSlgO1xuICB9XG5cbiAgcmV0dXJuIGB2ZWMke2NvbXBvbmVudHN9PCR7ZGF0YVR5cGV9Pigke3ZhbHVlfSlgO1xufTtcblxuLyoqXG4gKiBBIGhlbHBlciBmdW5jdGlvbiB0aGF0IGNhc3RzIHZhbHVlIG9yIHZlY3RvciB0byBmMzJcbiAqIEBwYXJhbSBkYXRhVHlwZVxuICogQHBhcmFtIGNvbXBvbmVudHNcbiAqIEBwYXJhbSB2YWx1ZVxuICovXG5leHBvcnQgY29uc3QgY2FzdFRvRjMyID0gKGRhdGFUeXBlOiBzdHJpbmcsIGNvbXBvbmVudHM6IG51bWJlciwgdmFsdWU6IHN0cmluZykgPT4ge1xuICBpZiAoZGF0YVR5cGUgPT09ICdmMzInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChjb21wb25lbnRzID09PSAxKSB7XG4gICAgcmV0dXJuIGBmMzIoJHt2YWx1ZX0pYDtcbiAgfVxuXG4gIHJldHVybiBgdmVjJHtjb21wb25lbnRzfTxmMzI+KCR7dmFsdWV9KWA7XG59O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBzY2FsYXIgb3Igc3VtcyBhbGwgY29tcG9uZW50cyBvZiBhIHZlY3RvclxuICogQHBhcmFtIG5hbWVcbiAqIEBwYXJhbSBjb21wb25lbnRzXG4gKi9cbmV4cG9ydCBjb25zdCBzdW1WZWN0b3IgPSAobmFtZTogc3RyaW5nLCBjb21wb25lbnRzOiBudW1iZXIpID0+IHtcbiAgaWYgKGNvbXBvbmVudHMgPT09IDQpIHtcbiAgICByZXR1cm4gYCgke25hbWV9LnggKyAke25hbWV9LnkgKyAke25hbWV9LnogKyAke25hbWV9LncpYDtcbiAgfSBlbHNlIGlmIChjb21wb25lbnRzID09PSAyKSB7XG4gICAgcmV0dXJuIGAoJHtuYW1lfS54ICsgJHtuYW1lfS55KWA7XG4gIH0gZWxzZSBpZiAoY29tcG9uZW50cyA9PT0gMykge1xuICAgIHJldHVybiBgKCR7bmFtZX0ueCArICR7bmFtZX0ueSArICR7bmFtZX0ueilgO1xuICB9XG5cbiAgcmV0dXJuIG5hbWU7XG59O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB2YXJpYWJsZSBlbGVtZW50IGF0IGluZGV4LlxuICogQHBhcmFtIG5hbWUgLSB0aGUgbmFtZSBvZiB2YXJpYWJsZS5cbiAqIEBwYXJhbSBpbmRleCAtIHRoZSBpbmRleCBvZiB2YXJpYWJsZSBlbGVtZW50LlxuICogQHBhcmFtIGxlbmd0aCAtIHRoZSBsZW5ndGggb2YgdmFyaWFibGUuXG4gKiBAcGFyYW0gdHlwZSAtIHRoZSB0eXBlIG9mIHZhcmlhYmxlLCBvcHRpb25hbC5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldEVsZW1lbnRBdCA9IChcbiAgbmFtZTogc3RyaW5nLFxuICBpbmRleDogbnVtYmVyIHwgc3RyaW5nLFxuICBsZW5ndGg6IG51bWJlcixcbiAgdHlwZT86IFVuaWZvcm1EYXRhRWxlbWVudFR5cGUsXG4pOiBzdHJpbmcgPT4ge1xuICBpZiAobmFtZS5zdGFydHNXaXRoKCd1bmlmb3Jtcy4nKSAmJiBsZW5ndGggPiA0KSB7XG4gICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmICh0eXBlID09PSAnZjE2Jykge1xuICAgICAgICByZXR1cm4gYCR7bmFtZX1bKCR7aW5kZXh9KSAvIDhdWygke2luZGV4fSkgJSA4IC8gNF1bKCR7aW5kZXh9KSAlIDggJSA0XWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gYCR7bmFtZX1bKCR7aW5kZXh9KSAvIDRdWygke2luZGV4fSkgJSA0XWA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlID09PSAnZjE2Jykge1xuICAgICAgICByZXR1cm4gYCR7bmFtZX1bJHtNYXRoLmZsb29yKGluZGV4IC8gOCl9XVske01hdGguZmxvb3IoKGluZGV4ICUgOCkgLyA0KX1dWyR7KGluZGV4ICUgOCkgJSA0fV1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGAke25hbWV9WyR7TWF0aC5mbG9vcihpbmRleCAvIDQpfV1bJHtpbmRleCAlIDR9XWA7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBsZW5ndGggPiAxID8gYCR7bmFtZX1bJHtpbmRleH1dYCA6IG5hbWU7XG4gIH1cbn07XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IGEgSW5kaWNlc0hlbHBlciBmb3IgYSBnaXZlbiBpbnB1dCBvciBvdXRwdXQuXG4gKlxuICogQHBhcmFtIG5hbWUgLSB0aGUgbmFtZSBvZiB0aGUgaW5wdXQgb3Igb3V0cHV0LlxuICogQHBhcmFtIHRlbnNvclR5cGUgLSB0aGUgdGVuc29yIHR5cGUgb2YgdGhlIGlucHV0IG9yIG91dHB1dC5cbiAqIEBwYXJhbSBzaGFwZU9yUmFuayAtIHRoZSB0ZW5zb3Igc2hhcGUgb3IgdGhlIHJhbmsgb2YgdGhlIGlucHV0IG9yIG91dHB1dC5cbiAqIEBwYXJhbSB1c2FnZSAtIHRoZSB1c2FnZSBvZiB0aGUgaW5kaWNlcyBoZWxwZXIuXG4gKiBAcGFyYW0gY29tcG9uZW50cyAtIGluZGljYXRlcyB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgb2YgZWFjaCBlbGVtZW50LiAxIGZvciBzY2FsYXIsIDIgZm9yIHZlYzIsIDMgZm9yIHZlYzMsIDQgZm9yXG4gKiAgICB2ZWM0LlxuICovXG5jb25zdCBjcmVhdGVJbmRpY2VzSGVscGVyID0gKFxuICBuYW1lOiBzdHJpbmcsXG4gIHRlbnNvclR5cGU6IG51bWJlcixcbiAgc2hhcGVPclJhbms6IG51bWJlciB8IHJlYWRvbmx5IG51bWJlcltdLFxuICB1c2FnZTogSW5kaWNlc0hlbHBlclsndXNhZ2UnXSxcbiAgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCxcbik6IEluZGljZXNIZWxwZXIgPT4ge1xuICBjb25zdCB1c2VVbmlmb3JtID0gdHlwZW9mIHNoYXBlT3JSYW5rID09PSAnbnVtYmVyJztcbiAgY29uc3QgcmFuayA9IHVzZVVuaWZvcm0gPyBzaGFwZU9yUmFuayA6IHNoYXBlT3JSYW5rLmxlbmd0aDtcbiAgY29uc3QgcmFua0lkZW50aXR5ID0gWy4uLm5ldyBBcnJheShyYW5rKS5rZXlzKCldO1xuICBjb25zdCBpbmRpY2VzVHlwZSA9IHJhbmsgPCAyID8gJ3UzMicgOiByYW5rIDw9IDQgPyBgdmVjJHtyYW5rfTx1MzI+YCA6IGBhcnJheTx1MzIsICR7cmFua30+YDtcbiAgY29uc3QgbWFwcGVkVHlwZSA9IGdldFdnc2xNYXBwZWRUeXBlKHRlbnNvclR5cGUsIGNvbXBvbmVudHMpO1xuICBjb25zdCB2YWx1ZVR5cGUgPSB0eXBlb2YgbWFwcGVkVHlwZSA9PT0gJ3N0cmluZycgPyBtYXBwZWRUeXBlIDogbWFwcGVkVHlwZVsxXTtcbiAgY29uc3Qgc3RvcmFnZVR5cGUgPSB0eXBlb2YgbWFwcGVkVHlwZSA9PT0gJ3N0cmluZycgPyBtYXBwZWRUeXBlIDogbWFwcGVkVHlwZVswXTtcbiAgY29uc3QgdHlwZSA9IHsgaW5kaWNlczogaW5kaWNlc1R5cGUsIHZhbHVlOiB2YWx1ZVR5cGUsIHN0b3JhZ2U6IHN0b3JhZ2VUeXBlLCB0ZW5zb3I6IHRlbnNvclR5cGUgfTtcblxuICBjb25zdCBub3JtYWxpemVEaW0gPSAoZGltOiBudW1iZXIgfCBzdHJpbmcpOiBzdHJpbmcgPT4gKHR5cGVvZiBkaW0gPT09ICdzdHJpbmcnID8gZGltIDogYCR7ZGltfXVgKTtcblxuICBjb25zdCBpbXBsZW1lbnRhdGlvblVzZWQgPSB7XG4gICAgb2Zmc2V0VG9JbmRpY2VzOiBmYWxzZSxcbiAgICBpbmRpY2VzVG9PZmZzZXQ6IGZhbHNlLFxuICAgIGJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0OiBmYWxzZSxcbiAgICBzZXQ6IGZhbHNlLFxuICAgIHNldEJ5SW5kaWNlczogZmFsc2UsXG4gICAgZ2V0OiBmYWxzZSxcbiAgICBnZXRCeUluZGljZXM6IGZhbHNlLFxuICB9O1xuXG4gIGNvbnN0IHVuaWZvcm1QcmVmaXggPSB1c2VVbmlmb3JtID8gJ3VuaWZvcm1zLicgOiAnJztcbiAgY29uc3Qgc2hhcGUgPSBgJHt1bmlmb3JtUHJlZml4fSR7bmFtZX1fc2hhcGVgO1xuICBjb25zdCBzdHJpZGVzID0gYCR7dW5pZm9ybVByZWZpeH0ke25hbWV9X3N0cmlkZXNgO1xuXG4gIGxldCBvMmlTbmlwcGV0ID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDE7IGkrKykge1xuICAgIG8yaVNuaXBwZXQgKz0gYFxuICAgIGxldCBkaW0ke2l9ID0gY3VycmVudCAvICR7Z2V0RWxlbWVudEF0KHN0cmlkZXMsIGksIHJhbmspfTtcbiAgICBsZXQgcmVzdCR7aX0gPSBjdXJyZW50ICUgJHtnZXRFbGVtZW50QXQoc3RyaWRlcywgaSwgcmFuayl9O1xuICAgIGluZGljZXNbJHtpfV0gPSBkaW0ke2l9O1xuICAgIGN1cnJlbnQgPSByZXN0JHtpfTtcbiAgICBgO1xuICB9XG4gIG8yaVNuaXBwZXQgKz0gYGluZGljZXNbJHtyYW5rIC0gMX1dID0gY3VycmVudDtgO1xuXG4gIGNvbnN0IG9mZnNldFRvSW5kaWNlc0ltcGxlbWVudGF0aW9uID1cbiAgICByYW5rIDwgMlxuICAgICAgPyAnJ1xuICAgICAgOiBgXG4gIGZuIG8yaV8ke25hbWV9KG9mZnNldDogdTMyKSAtPiAke3R5cGUuaW5kaWNlc30ge1xuICAgIHZhciBpbmRpY2VzOiAke3R5cGUuaW5kaWNlc307XG4gICAgdmFyIGN1cnJlbnQgPSBvZmZzZXQ7XG4gICAgJHtvMmlTbmlwcGV0fVxuICAgIHJldHVybiBpbmRpY2VzO1xuICB9YDtcblxuICBjb25zdCBvZmZzZXRUb0luZGljZXMgPSAodmFyT2Zmc2V0OiBzdHJpbmcpID0+IHtcbiAgICBpbXBsZW1lbnRhdGlvblVzZWQub2Zmc2V0VG9JbmRpY2VzID0gdHJ1ZTtcbiAgICByZXR1cm4gcmFuayA8IDIgPyB2YXJPZmZzZXQgOiBgbzJpXyR7bmFtZX0oJHt2YXJPZmZzZXR9KWA7XG4gIH07XG5cbiAgY29uc3Qgb2Zmc2V0czogc3RyaW5nW10gPSBbXTtcbiAgaWYgKHJhbmsgPj0gMikge1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIG9mZnNldHMucHVzaChgJHtnZXRFbGVtZW50QXQoc3RyaWRlcywgaSwgcmFuayl9ICogKGluZGljZXNbJHtpfV0pYCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgaW5kaWNlc1RvT2Zmc2V0SW1wbGVtZW50YXRpb24gPVxuICAgIHJhbmsgPCAyXG4gICAgICA/ICcnXG4gICAgICA6IGBcbiAgZm4gaTJvXyR7bmFtZX0oaW5kaWNlczogJHt0eXBlLmluZGljZXN9KSAtPiB1MzIge1xuICAgIHJldHVybiAke29mZnNldHMuam9pbignKycpfTtcbiAgfWA7XG5cbiAgY29uc3QgaW5kaWNlc1RvT2Zmc2V0ID0gKHZhckluZGljZXM6IHN0cmluZykgPT4ge1xuICAgIGltcGxlbWVudGF0aW9uVXNlZC5pbmRpY2VzVG9PZmZzZXQgPSB0cnVlO1xuICAgIHJldHVybiByYW5rIDwgMiA/IHZhckluZGljZXMgOiBgaTJvXyR7bmFtZX0oJHt2YXJJbmRpY2VzfSlgO1xuICB9O1xuXG4gIGNvbnN0IGluZGljZXMgPSAoLi4uaW5pdDogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+KSA9PlxuICAgIHJhbmsgPT09IDAgPyAnMHUnIDogYCR7dHlwZS5pbmRpY2VzfSgke2luaXQubWFwKG5vcm1hbGl6ZURpbSkuam9pbignLCcpfSlgO1xuXG4gIGNvbnN0IGluZGljZXNHZXQgPSAodmFySW5kaWNlczogc3RyaW5nLCBpZHg6IG51bWJlciB8IHN0cmluZykgPT4ge1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgcmV0dXJuIGAke3ZhckluZGljZXN9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGAke2dldEVsZW1lbnRBdCh2YXJJbmRpY2VzLCBpZHgsIHJhbmspfWA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGluZGljZXNTZXQgPSAodmFySW5kaWNlczogc3RyaW5nLCBpZHg6IG51bWJlciB8IHN0cmluZywgdmFsdWU6IHN0cmluZykgPT4ge1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgcmV0dXJuIGAke3ZhckluZGljZXN9PSR7dmFsdWV9O2A7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBgJHtnZXRFbGVtZW50QXQodmFySW5kaWNlcywgaWR4LCByYW5rKX09JHt2YWx1ZX07YDtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXRJbXBsZW1lbnRhdGlvbjogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICBjb25zdCBicm9hZGNhc3RlZEluZGljZXNUb09mZnNldCA9ICh2YXJJbmRpY2VzOiBzdHJpbmcsIG91dHB1dDogSW5kaWNlc0hlbHBlcikgPT4ge1xuICAgIGltcGxlbWVudGF0aW9uVXNlZC5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldCA9IHRydWU7XG4gICAgY29uc3QgaW1wbEtleSA9IGAke291dHB1dC5uYW1lfWJyb2FkY2FzdGVkSW5kaWNlc1RvJHtuYW1lfU9mZnNldGA7XG4gICAgaWYgKGltcGxLZXkgaW4gYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXRJbXBsZW1lbnRhdGlvbikge1xuICAgICAgcmV0dXJuIGAke2ltcGxLZXl9KCR7dmFySW5kaWNlc30pYDtcbiAgICB9XG4gICAgY29uc3Qgb2Zmc2V0cyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IGlkeCA9IG91dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRJbmRpY2VzJywgaSArIG91dHB1dC5yYW5rIC0gcmFuayk7XG4gICAgICBvZmZzZXRzLnB1c2goYCR7aW5kaWNlc0dldChzdHJpZGVzLCBpKX0gKiAoJHtpZHh9ICUgJHtpbmRpY2VzR2V0KHNoYXBlLCBpKX0pYCk7XG4gICAgfVxuICAgIGJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0SW1wbGVtZW50YXRpb25baW1wbEtleV0gPSBgZm4gJHtpbXBsS2V5fShvdXRwdXRJbmRpY2VzOiAke291dHB1dC50eXBlLmluZGljZXN9KSAtPiB1MzIge1xuICAgICAgICAgICAgIHJldHVybiAke29mZnNldHMubGVuZ3RoID4gMCA/IG9mZnNldHMuam9pbignKycpIDogJzB1J307XG4gICAgICAgICAgIH1gO1xuXG4gICAgcmV0dXJuIGAke2ltcGxLZXl9KCR7dmFySW5kaWNlc30pYDtcbiAgfTtcblxuICBjb25zdCBzZXRCeU9mZnNldCA9IChvZmZzZXQ6IG51bWJlciB8IHN0cmluZywgdmFsdWU6IHN0cmluZykgPT5cbiAgICAoKCkgPT4ge1xuICAgICAgaWYgKHR5cGUuc3RvcmFnZSA9PT0gdHlwZS52YWx1ZSkge1xuICAgICAgICByZXR1cm4gYCR7bmFtZX1bJHtvZmZzZXR9XT0ke3ZhbHVlfTtgO1xuICAgICAgfSBlbHNlIGlmICh0eXBlLnN0b3JhZ2UgPT09ICd2ZWMyPHUzMj4nICYmIHR5cGUudmFsdWUgPT09ICdpMzInKSB7XG4gICAgICAgIC8vIGludDY0LCBjb21wb25lbnRzID09PSAxXG4gICAgICAgIHJldHVybiBgJHtuYW1lfVske29mZnNldH1dPXZlYzI8dTMyPih1MzIoJHt2YWx1ZX0pLCBzZWxlY3QoMHUsIDB4RkZGRkZGRkZ1LCAke3ZhbHVlfSA8IDApKTtgO1xuICAgICAgfSBlbHNlIGlmICh0eXBlLnN0b3JhZ2UgPT09ICd2ZWMyPHUzMj4nICYmIHR5cGUudmFsdWUgPT09ICd1MzInKSB7XG4gICAgICAgIC8vIHVpbnQ2NCwgY29tcG9uZW50cyA9PT0gMVxuICAgICAgICByZXR1cm4gYCR7bmFtZX1bJHtvZmZzZXR9XT12ZWMyPHUzMj4odTMyKCR7dmFsdWV9KSwgMHUpO2A7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUuc3RvcmFnZSA9PT0gJ3UzMicgJiYgdHlwZS52YWx1ZSA9PT0gJ3ZlYzQ8Ym9vbD4nKSB7XG4gICAgICAgIC8vIGJvb2wsIGNvbXBvbmVudHMgPT09IDRcbiAgICAgICAgcmV0dXJuIGAke25hbWV9WyR7b2Zmc2V0fV09ZG90KHZlYzQ8dTMyPigweDEsIDB4MTAwLCAweDEwMDAwLCAweDEwMDAwMDApLCB2ZWM0PHUzMj4oJHt2YWx1ZX0pKTtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBub3Qgc3VwcG9ydGVkIGNvbWJpbmF0aW9uIG9mIHN0b3JhZ2UgdHlwZSAke3R5cGUuc3RvcmFnZX0gYW5kIHZhbHVlIHR5cGUgJHt0eXBlLnZhbHVlfSB5ZXRgKTtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gIGNvbnN0IGdldEJ5T2Zmc2V0ID0gKG9mZnNldDogbnVtYmVyIHwgc3RyaW5nKSA9PlxuICAgICgoKSA9PiB7XG4gICAgICBpZiAodHlwZS5zdG9yYWdlID09PSB0eXBlLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiBgJHtuYW1lfVske29mZnNldH1dYDtcbiAgICAgIH0gZWxzZSBpZiAodHlwZS5zdG9yYWdlID09PSAndmVjMjx1MzI+JyAmJiB0eXBlLnZhbHVlID09PSAnaTMyJykge1xuICAgICAgICAvLyBpbnQ2NCwgY29tcG9uZW50cyA9PT0gMVxuICAgICAgICByZXR1cm4gYGkzMigke25hbWV9WyR7b2Zmc2V0fV0ueClgO1xuICAgICAgfSBlbHNlIGlmICh0eXBlLnN0b3JhZ2UgPT09ICd2ZWMyPHUzMj4nICYmIHR5cGUudmFsdWUgPT09ICd1MzInKSB7XG4gICAgICAgIC8vIHVpbnQ2NCwgY29tcG9uZW50cyA9PT0gMVxuICAgICAgICByZXR1cm4gYHUzMigke25hbWV9WyR7b2Zmc2V0fV0ueClgO1xuICAgICAgfSBlbHNlIGlmICh0eXBlLnN0b3JhZ2UgPT09ICd1MzInICYmIHR5cGUudmFsdWUgPT09ICd2ZWM0PGJvb2w+Jykge1xuICAgICAgICAvLyBib29sLCBjb21wb25lbnRzID09PSA0XG4gICAgICAgIHJldHVybiBgdmVjNDxib29sPihib29sKCR7bmFtZX1bJHtvZmZzZXR9XSAmIDB4RkZ1KSwgYm9vbCgke25hbWV9WyR7b2Zmc2V0fV0gJiAweEZGMDB1KSwgYm9vbCgke25hbWV9WyR7XG4gICAgICAgICAgb2Zmc2V0XG4gICAgICAgIH1dICYgMHhGRjAwMDB1KSwgYm9vbCgke25hbWV9WyR7b2Zmc2V0fV0gJiAweEZGMDAwMDAwdSkpYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbm90IHN1cHBvcnRlZCBjb21iaW5hdGlvbiBvZiBzdG9yYWdlIHR5cGUgJHt0eXBlLnN0b3JhZ2V9IGFuZCB2YWx1ZSB0eXBlICR7dHlwZS52YWx1ZX0geWV0YCk7XG4gICAgICB9XG4gICAgfSkoKTtcblxuICBjb25zdCBnZXRCeUluZGljZXNJbXBsZW1lbnRhdGlvbiA9XG4gICAgcmFuayA8IDJcbiAgICAgID8gJydcbiAgICAgIDogYFxuICBmbiBnZXRfJHtuYW1lfUJ5SW5kaWNlcyhpbmRpY2VzOiAke3R5cGUuaW5kaWNlc30pIC0+ICR7dmFsdWVUeXBlfSB7XG4gICAgcmV0dXJuICR7Z2V0QnlPZmZzZXQoYGkyb18ke25hbWV9KGluZGljZXMpYCl9O1xuICB9YDtcblxuICBjb25zdCBnZXRJbXBsZW1lbnRhdGlvbiA9XG4gICAgcmFuayA8IDJcbiAgICAgID8gJydcbiAgICAgIDogKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBmdW5jdGlvblBhcmFtcyA9IHJhbmtJZGVudGl0eS5tYXAoKGkpID0+IGBkJHtpfTogdTMyYCkuam9pbignLCAnKTtcbiAgICAgICAgICBjb25zdCBkaW1zUGFyYW1zID0gcmFua0lkZW50aXR5Lm1hcCgoaSkgPT4gYGQke2l9YCkuam9pbignLCAnKTtcbiAgICAgICAgICByZXR1cm4gYFxuICBmbiBnZXRfJHtuYW1lfSgke2Z1bmN0aW9uUGFyYW1zfSkgLT4gJHt2YWx1ZVR5cGV9IHtcbiAgICByZXR1cm4gZ2V0XyR7bmFtZX1CeUluZGljZXMoJHtpbmRpY2VzKGRpbXNQYXJhbXMpfSk7XG4gIH1gO1xuICAgICAgICB9KSgpO1xuXG4gIGNvbnN0IGdldCA9ICguLi5pbmRpY2VzOiBSZWFkb25seUFycmF5PG51bWJlciB8IHN0cmluZz4pID0+IHtcbiAgICBpZiAoaW5kaWNlcy5sZW5ndGggIT09IHJhbmspIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW5kaWNlcyBsZW5ndGggbXVzdCBiZSAke3Jhbmt9YCk7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZEluZGljZXMgPSBpbmRpY2VzLm1hcChub3JtYWxpemVEaW0pLmpvaW4oJywnKTtcblxuICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gZ2V0QnlPZmZzZXQoJzB1Jyk7XG4gICAgfSBlbHNlIGlmIChyYW5rID09PSAxKSB7XG4gICAgICByZXR1cm4gZ2V0QnlPZmZzZXQobm9ybWFsaXplZEluZGljZXNbMF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbXBsZW1lbnRhdGlvblVzZWQuZ2V0ID0gdHJ1ZTtcbiAgICAgIGltcGxlbWVudGF0aW9uVXNlZC5nZXRCeUluZGljZXMgPSB0cnVlO1xuICAgICAgaW1wbGVtZW50YXRpb25Vc2VkLmluZGljZXNUb09mZnNldCA9IHRydWU7XG4gICAgICByZXR1cm4gYGdldF8ke25hbWV9KCR7bm9ybWFsaXplZEluZGljZXN9KWA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGdldEJ5SW5kaWNlcyA9ICh2YXJJbmRpY2VzOiBzdHJpbmcpID0+IHtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHJldHVybiBnZXRCeU9mZnNldCh2YXJJbmRpY2VzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW1wbGVtZW50YXRpb25Vc2VkLmdldEJ5SW5kaWNlcyA9IHRydWU7XG4gICAgICBpbXBsZW1lbnRhdGlvblVzZWQuaW5kaWNlc1RvT2Zmc2V0ID0gdHJ1ZTtcbiAgICAgIHJldHVybiBgZ2V0XyR7bmFtZX1CeUluZGljZXMoJHt2YXJJbmRpY2VzfSlgO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBzZXRCeUluZGljZXNJbXBsZW1lbnRhdGlvbiA9XG4gICAgcmFuayA8IDJcbiAgICAgID8gJydcbiAgICAgIDogYFxuICBmbiBzZXRfJHtuYW1lfUJ5SW5kaWNlcyhpbmRpY2VzOiAke3R5cGUuaW5kaWNlc30sIHZhbHVlOiAke3ZhbHVlVHlwZX0pIHtcbiAgICAke3NldEJ5T2Zmc2V0KGBpMm9fJHtuYW1lfShpbmRpY2VzKWAsICd2YWx1ZScpfVxuICB9YDtcblxuICBjb25zdCBzZXRJbXBsZW1lbnRhdGlvbiA9XG4gICAgcmFuayA8IDJcbiAgICAgID8gJydcbiAgICAgIDogKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBmdW5jdGlvblBhcmFtcyA9IHJhbmtJZGVudGl0eS5tYXAoKGkpID0+IGBkJHtpfTogdTMyYCkuam9pbignLCAnKTtcbiAgICAgICAgICBjb25zdCBkaW1zUGFyYW1zID0gcmFua0lkZW50aXR5Lm1hcCgoaSkgPT4gYGQke2l9YCkuam9pbignLCAnKTtcbiAgICAgICAgICByZXR1cm4gYFxuICBmbiBzZXRfJHtuYW1lfSgke2Z1bmN0aW9uUGFyYW1zfSwgdmFsdWU6ICR7dmFsdWVUeXBlfSkge1xuICAgIHNldF8ke25hbWV9QnlJbmRpY2VzKCR7aW5kaWNlcyhkaW1zUGFyYW1zKX0sIHZhbHVlKTtcbiAgfWA7XG4gICAgICAgIH0pKCk7XG5cbiAgY29uc3Qgc2V0ID0gKC4uLmluZGljZXNBbmRWYWx1ZTogUmVhZG9ubHlBcnJheTxudW1iZXIgfCBzdHJpbmc+KSA9PiB7XG4gICAgaWYgKGluZGljZXNBbmRWYWx1ZS5sZW5ndGggIT09IHJhbmsgKyAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGluZGljZXMgbGVuZ3RoIG11c3QgYmUgJHtyYW5rfWApO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZSA9IGluZGljZXNBbmRWYWx1ZVtyYW5rXTtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd2YWx1ZSBtdXN0IGJlIHN0cmluZycpO1xuICAgIH1cblxuICAgIGNvbnN0IG5vcm1hbGl6ZWRJbmRpY2VzID0gaW5kaWNlc0FuZFZhbHVlLnNsaWNlKDAsIHJhbmspLm1hcChub3JtYWxpemVEaW0pLmpvaW4oJywnKTtcblxuICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gc2V0QnlPZmZzZXQoJzB1JywgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAocmFuayA9PT0gMSkge1xuICAgICAgcmV0dXJuIHNldEJ5T2Zmc2V0KG5vcm1hbGl6ZWRJbmRpY2VzWzBdLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGltcGxlbWVudGF0aW9uVXNlZC5zZXQgPSB0cnVlO1xuICAgICAgaW1wbGVtZW50YXRpb25Vc2VkLnNldEJ5SW5kaWNlcyA9IHRydWU7XG4gICAgICBpbXBsZW1lbnRhdGlvblVzZWQuaW5kaWNlc1RvT2Zmc2V0ID0gdHJ1ZTtcbiAgICAgIHJldHVybiBgc2V0XyR7bmFtZX0oJHtub3JtYWxpemVkSW5kaWNlc30sICR7dmFsdWV9KWA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHNldEJ5SW5kaWNlcyA9ICh2YXJJbmRpY2VzOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHJldHVybiBzZXRCeU9mZnNldCh2YXJJbmRpY2VzLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGltcGxlbWVudGF0aW9uVXNlZC5zZXRCeUluZGljZXMgPSB0cnVlO1xuICAgICAgaW1wbGVtZW50YXRpb25Vc2VkLmluZGljZXNUb09mZnNldCA9IHRydWU7XG4gICAgICByZXR1cm4gYHNldF8ke25hbWV9QnlJbmRpY2VzKCR7dmFySW5kaWNlc30sICR7dmFsdWV9KTtgO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBpbXBsID0gKCkgPT4ge1xuICAgIGNvbnN0IGltcGxzID0gW107XG4gICAgbGV0IG5lZWRTaGFwZVN0cmlkZXMgPSBmYWxzZTtcbiAgICBpZiAoaW1wbGVtZW50YXRpb25Vc2VkLm9mZnNldFRvSW5kaWNlcykge1xuICAgICAgaW1wbHMucHVzaChvZmZzZXRUb0luZGljZXNJbXBsZW1lbnRhdGlvbik7XG4gICAgICBuZWVkU2hhcGVTdHJpZGVzID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGltcGxlbWVudGF0aW9uVXNlZC5pbmRpY2VzVG9PZmZzZXQpIHtcbiAgICAgIGltcGxzLnB1c2goaW5kaWNlc1RvT2Zmc2V0SW1wbGVtZW50YXRpb24pO1xuICAgICAgbmVlZFNoYXBlU3RyaWRlcyA9IHRydWU7XG4gICAgfVxuICAgIGlmIChpbXBsZW1lbnRhdGlvblVzZWQuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQpIHtcbiAgICAgIE9iamVjdC52YWx1ZXMoYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXRJbXBsZW1lbnRhdGlvbikuZm9yRWFjaCgoaW1wbCkgPT4gaW1wbHMucHVzaChpbXBsKSk7XG4gICAgICBuZWVkU2hhcGVTdHJpZGVzID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGltcGxlbWVudGF0aW9uVXNlZC5zZXQpIHtcbiAgICAgIGltcGxzLnB1c2goc2V0SW1wbGVtZW50YXRpb24pO1xuICAgICAgbmVlZFNoYXBlU3RyaWRlcyA9IHRydWU7XG4gICAgfVxuICAgIGlmIChpbXBsZW1lbnRhdGlvblVzZWQuc2V0QnlJbmRpY2VzKSB7XG4gICAgICBpbXBscy5wdXNoKHNldEJ5SW5kaWNlc0ltcGxlbWVudGF0aW9uKTtcbiAgICAgIG5lZWRTaGFwZVN0cmlkZXMgPSB0cnVlO1xuICAgIH1cbiAgICBpZiAoaW1wbGVtZW50YXRpb25Vc2VkLmdldCkge1xuICAgICAgaW1wbHMucHVzaChnZXRJbXBsZW1lbnRhdGlvbik7XG4gICAgICBuZWVkU2hhcGVTdHJpZGVzID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGltcGxlbWVudGF0aW9uVXNlZC5nZXRCeUluZGljZXMpIHtcbiAgICAgIGltcGxzLnB1c2goZ2V0QnlJbmRpY2VzSW1wbGVtZW50YXRpb24pO1xuICAgICAgbmVlZFNoYXBlU3RyaWRlcyA9IHRydWU7XG4gICAgfVxuICAgIGlmICghdXNlVW5pZm9ybSAmJiBuZWVkU2hhcGVTdHJpZGVzKSB7XG4gICAgICBpbXBscy51bnNoaWZ0KFxuICAgICAgICBgY29uc3QgJHtzaGFwZX0gPSAke3R5cGUuaW5kaWNlc30oJHtzaGFwZU9yUmFuay5qb2luKCcsJyl9KTtgLFxuICAgICAgICBgY29uc3QgJHtzdHJpZGVzfSA9ICR7dHlwZS5pbmRpY2VzfSgke1NoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhzaGFwZU9yUmFuaykuam9pbignLCcpfSk7YCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBpbXBscy5qb2luKCdcXG4nKTtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIGltcGwsXG4gICAgdHlwZSxcbiAgICBvZmZzZXRUb0luZGljZXMsXG4gICAgaW5kaWNlc1RvT2Zmc2V0LFxuICAgIGJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0LFxuICAgIGluZGljZXMsXG4gICAgaW5kaWNlc0dldCxcbiAgICBpbmRpY2VzU2V0LFxuICAgIHNldCxcbiAgICBzZXRCeU9mZnNldCxcbiAgICBzZXRCeUluZGljZXMsXG4gICAgZ2V0LFxuICAgIGdldEJ5T2Zmc2V0LFxuICAgIGdldEJ5SW5kaWNlcyxcbiAgICAvLyBpc1ZlYzQsXG4gICAgdXNhZ2UsXG4gICAgbmFtZSxcbiAgICBzdHJpZGVzLFxuICAgIHNoYXBlLFxuICAgIHJhbmssXG4gIH07XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIEluZGljZXNIZWxwZXIgZm9yIGFuIGlucHV0LlxuICpcbiAqIEBwYXJhbSBuYW1lIC0gdGhlIG5hbWUgb2YgdGhlIGlucHV0LlxuICogQHBhcmFtIHR5cGUgLSB0aGUgdGVuc29yIHR5cGUgb2YgdGhlIGlucHV0LlxuICogQHBhcmFtIHNoYXBlT3JSYW5rIC0gdGhlIHRlbnNvciBzaGFwZSBvciB0aGUgcmFuayBvZiB0aGUgaW5wdXQuXG4gKiBAcGFyYW0gY29tcG9uZW50cyAtIHRoZSBudW1iZXIgb2YgY29tcG9uZW50cyBvZiB0aGUgaW5wdXQuIGF2YWlsYWJsZSB2YWx1ZXMgYXJlIDEsIDIsIDMsIDQuIGRlZmF1bHQgaXMgMS5cbiAqIEByZXR1cm5zIGFuIEluZGljZXNIZWxwZXIgZm9yIHRoZSBpbnB1dC5cbiAqL1xuZXhwb3J0IGNvbnN0IGlucHV0VmFyaWFibGUgPSAoXG4gIG5hbWU6IHN0cmluZyxcbiAgdHlwZTogbnVtYmVyLFxuICBzaGFwZU9yUmFuazogbnVtYmVyIHwgcmVhZG9ubHkgbnVtYmVyW10sXG4gIGNvbXBvbmVudHM6IDEgfCAyIHwgMyB8IDQgPSAxLFxuKTogSW5kaWNlc0hlbHBlciA9PiBjcmVhdGVJbmRpY2VzSGVscGVyKG5hbWUsIHR5cGUsIHNoYXBlT3JSYW5rLCAnaW5wdXQnLCBjb21wb25lbnRzKTtcblxuLyoqXG4gKiBDcmVhdGUgYSBJbmRpY2VzSGVscGVyIGZvciBhbiBvdXRwdXQuXG4gKlxuICogQHBhcmFtIG5hbWUgLSB0aGUgbmFtZSBvZiB0aGUgb3V0cHV0LlxuICogQHBhcmFtIHR5cGUgLSB0aGUgdGVuc29yIHR5cGUgb2YgdGhlIG91dHB1dC5cbiAqIEBwYXJhbSBzaGFwZU9yUmFuayAtIHRoZSB0ZW5zb3Igc2hhcGUgb3IgdGhlIHJhbmsgb2YgdGhlIG91dHB1dC5cbiAqIEBwYXJhbSBjb21wb25lbnRzIC0gdGhlIG51bWJlciBvZiBjb21wb25lbnRzIG9mIHRoZSBvdXRwdXQuIGF2YWlsYWJsZSB2YWx1ZXMgYXJlIDEsIDIsIDMsIDQuIGRlZmF1bHQgaXMgMS5cbiAqIEByZXR1cm5zIGFuIEluZGljZXNIZWxwZXIgZm9yIHRoZSBvdXRwdXQuXG4gKi9cbmV4cG9ydCBjb25zdCBvdXRwdXRWYXJpYWJsZSA9IChcbiAgbmFtZTogc3RyaW5nLFxuICB0eXBlOiBudW1iZXIsXG4gIHNoYXBlT3JSYW5rOiBudW1iZXIgfCByZWFkb25seSBudW1iZXJbXSxcbiAgY29tcG9uZW50czogMSB8IDIgfCAzIHwgNCA9IDEsXG4pOiBJbmRpY2VzSGVscGVyID0+IGNyZWF0ZUluZGljZXNIZWxwZXIobmFtZSwgdHlwZSwgc2hhcGVPclJhbmssICdvdXRwdXQnLCBjb21wb25lbnRzKTtcblxuLyoqXG4gKiBDcmVhdGUgYSBJbmRpY2VzSGVscGVyIGZvciBhbiBhdG9taWMgb3V0cHV0LlxuICpcbiAqIEBwYXJhbSBuYW1lIC0gdGhlIG5hbWUgb2YgdGhlIG91dHB1dC5cbiAqIEBwYXJhbSB0eXBlIC0gdGhlIHRlbnNvciB0eXBlIG9mIHRoZSBvdXRwdXQuXG4gKiBAcGFyYW0gc2hhcGVPclJhbmsgLSB0aGUgdGVuc29yIHNoYXBlIG9yIHRoZSByYW5rIG9mIHRoZSBvdXRwdXQuXG4gKiBAcmV0dXJucyBhbiBJbmRpY2VzSGVscGVyIGZvciB0aGUgb3V0cHV0LlxuICovXG5leHBvcnQgY29uc3QgYXRvbWljT3V0cHV0VmFyaWFibGUgPSAoXG4gIG5hbWU6IHN0cmluZyxcbiAgdHlwZTogbnVtYmVyLFxuICBzaGFwZU9yUmFuazogbnVtYmVyIHwgcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBJbmRpY2VzSGVscGVyID0+IGNyZWF0ZUluZGljZXNIZWxwZXIobmFtZSwgdHlwZSwgc2hhcGVPclJhbmssICdhdG9taWNPdXRwdXQnLCAxKTtcblxuLyoqXG4gKiBDcmVhdGUgYSBJbmRpY2VzSGVscGVyIGZvciBhbiBpbnRlcm5hbCB2YXJpYWJsZS5cbiAqXG4gKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZS5cbiAqIEBwYXJhbSB0eXBlIC0gdGhlIHRlbnNvciB0eXBlIG9mIHRoZSB2YXJpYWJsZS5cbiAqIEBwYXJhbSBzaGFwZU9yUmFuayAtIHRoZSB0ZW5zb3Igc2hhcGUgb3IgdGhlIHJhbmsgb2YgdGhlIHZhcmlhYmxlLlxuICogQHBhcmFtIGNvbXBvbmVudHMgLSB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgb2YgdGhlIHZhcmlhYmxlLiBhdmFpbGFibGUgdmFsdWVzIGFyZSAxLCAyLCAzLCA0LiBkZWZhdWx0IGlzIDEuXG4gKiBAcmV0dXJucyBhbiBJbmRpY2VzSGVscGVyIGZvciB0aGUgdmFyaWFibGUuXG4gKi9cbmV4cG9ydCBjb25zdCBpbnRlcm5hbFZhcmlhYmxlID0gKFxuICBuYW1lOiBzdHJpbmcsXG4gIHR5cGU6IG51bWJlcixcbiAgc2hhcGVPclJhbms6IG51bWJlciB8IHJlYWRvbmx5IG51bWJlcltdLFxuICBjb21wb25lbnRzOiAxIHwgMiB8IDMgfCA0ID0gMSxcbik6IEluZGljZXNIZWxwZXIgPT4gY3JlYXRlSW5kaWNlc0hlbHBlcihuYW1lLCB0eXBlLCBzaGFwZU9yUmFuaywgJ2ludGVybmFsJywgY29tcG9uZW50cyk7XG5cbmV4cG9ydCB0eXBlIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUgPSAndTMyJyB8ICdmMTYnIHwgJ2YzMicgfCAnaTMyJztcbmV4cG9ydCB0eXBlIFVuaWZvcm1zQXJyYXlUeXBlID0gQXJyYXk8eyBuYW1lOiBzdHJpbmc7IHR5cGU6IFVuaWZvcm1EYXRhRWxlbWVudFR5cGU7IGxlbmd0aD86IG51bWJlciB9PjtcblxuLyoqXG4gKiBBIFNoYWRlckhlbHBlciBpcyBhIGhlbHBlciBjbGFzcyBmb3IgZ2VuZXJhdGluZyBXR1NMIGNvZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2hhZGVySGVscGVyIHtcbiAgLyoqXG4gICAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGdlbmVyYXRlIHRoZSBzdGFydCBvZiBtYWluIGZ1bmN0aW9uIGluIFdHU0wgc291cmNlIGNvZGUuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICAgKiAgLi4uXG4gICAqXG4gICAqICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICogICAgLy8geW91ciBjb2RlIGhlcmUgaW5zaWRlIG1haW4oKSBmdW5jdGlvblxuICAgKiAgICAuLi5cbiAgICogIH1cbiAgICogYDtcbiAgICpcbiAgICogQHBhcmFtIHdvcmtncm91cFNpemUgLSBhbiBvcHRpb25hbCB3b3JrZ3JvdXAgc2l6ZS4gZGVmYXVsdCBpcyBXT1JLR1JPVVBfU0laRS5cbiAgICovXG4gIG1haW5TdGFydCh3b3JrZ3JvdXBTaXplPzogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIGhlbHBlciBmdW5jdGlvbiB0byBnZW5lcmF0ZSB0aGUgY29kZSBzbmlwcGV0IGZvciBndWFyZGluZyBhZ2FpbnN0IG91dC1vZi1ib3VuZHMgc2l6ZS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICAqICAuLi5cbiAgICpcbiAgICogICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgKiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKG91dHB1dFNpemUpfVxuICAgKlxuICAgKiAgICAvLyB5b3VyIGNvZGUgaGVyZSBpbnNpZGUgbWFpbigpIGZ1bmN0aW9uXG4gICAqICAgIC4uLlxuICAgKiAgfVxuICAgKiBgO1xuICAgKlxuICAgKiBAcGFyYW0gc2l6ZSAtIHRoZSBzaXplIG9mIHRoZSBkYXRhIHRvIGd1YXJkIGFnYWluc3QuIGNhbiBiZSBhIG51bWJlciBvciBhIHN0cmluZyAoV0dTTCBgdTMyYCBleHByZXNzaW9uKS5cbiAgICovXG4gIGd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoc2l6ZTogdW5rbm93bik6IHN0cmluZztcblxuICAvKipcbiAgICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgdGhlIGNvZGUgc25pcHBldCBmb3IgZGVjbGFyaW5nIG11bHRpcGxlIGlucHV0cyBvciBvdXRwdXRzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFyaWFibGVzIC0gYW4gYXJyYXkgb2YgSW5kaWNlc0hlbHBlciBmb3IgdGhlIHZhcmlhYmxlcy5cbiAgICovXG4gIGRlY2xhcmVWYXJpYWJsZXMoLi4udmFyaWFibGVzOiBJbmRpY2VzSGVscGVyW10pOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIG9uZSB1bmlmb3JtLiBDYW4gYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzIHRvIHJlZ2lzdGVyIG11bHRpcGxlIHVuaWZvcm1zLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIG9mIHRoZSB1bmlmb3JtLlxuICAgKiBAcGFyYW0gdHlwZSAtIHRoZSB0eXBlIG9mIHRoZSB1bmlmb3JtLlxuICAgKiBAcGFyYW0gbGVuZ3RoIC0gdGhlIGxlbmd0aCBvZiB0aGUgdW5pZm9ybSwgZGVmYXVsdCB0byAxIHdoZW4gaXQgaXMgbm90IHByb3ZpZGVkLlxuICAgKi9cbiAgcmVnaXN0ZXJVbmlmb3JtKG5hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nLCBsZW5ndGg/OiBudW1iZXIpOiBTaGFkZXJIZWxwZXI7XG5cbiAgLyoqXG4gICAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIG11bHRpcGxlIHVuaWZvcm1zLiBDYW4gYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzIHRvIHJlZ2lzdGVyIG11bHRpcGxlIHVuaWZvcm1zLlxuICAgKlxuICAgKiBAcGFyYW0gdW5pZm9ybXMgLSBhbiBhcnJheSBvZiB1bmlmb3Jtcy4gRWFjaCBlbGVtZW50IG9mIHRoZSBhcnJheSBpcyBhbiBvYmplY3Qgd2l0aCAyIHByb3BlcnRpZXM6IGBuYW1lYCBhbmRcbiAgICogICAgIGB0eXBlYC5cbiAgICovXG4gIHJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlKTogU2hhZGVySGVscGVyO1xuXG4gIC8qKlxuICAgKiBBIGhlbHBlciBmdW5jdGlvbiB0byByZWdpc3RlciBtdWx0aXBsZSBpbnRlcm5hbCB2YXJpYWJsZXMuIENhbiBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMgdG8gcmVnaXN0ZXIgbXVsdGlwbGVcbiAgICogaW50ZXJuYWwgdmFyaWFibGVzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFyaWFibGVzIC0gYW4gYXJyYXkgb2YgSW5kaWNlc0hlbHBlciBmb3IgdGhlIHZhcmlhYmxlcy5cbiAgICovXG4gIHJlZ2lzdGVySW50ZXJuYWxWYXJpYWJsZXMoLi4udmFyaWFibGVzOiBJbmRpY2VzSGVscGVyW10pOiBTaGFkZXJIZWxwZXI7XG59XG5cbmNsYXNzIFNoYWRlckhlbHBlckltcGwgaW1wbGVtZW50cyBTaGFkZXJIZWxwZXIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgcHJpdmF0ZSBsaW1pdHM6IEdQVVN1cHBvcnRlZExpbWl0cyxcbiAgKSB7fVxuXG4gIGd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoc2l6ZTogbnVtYmVyIHwgc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyBHdWFyZCBhZ2FpbnN0IG91dC1vZi1ib3VuZHMgd29yayBncm91cCBzaXplc1xuICAgIGNvbnN0IHNpemVJbkNvZGUgPSB0eXBlb2Ygc2l6ZSA9PT0gJ251bWJlcicgPyBgJHtzaXplfXVgIDogc2l6ZTtcbiAgICByZXR1cm4gYGlmIChnbG9iYWxfaWR4ID49ICR7c2l6ZUluQ29kZX0pIHsgcmV0dXJuOyB9YDtcbiAgfVxuXG4gIG1haW5TdGFydCh3b3JrZ3JvdXBTaXplOiBudW1iZXIgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBXT1JLR1JPVVBfU0laRSkge1xuICAgIGNvbnN0IHdvcmtncm91cFNpemVYID0gdHlwZW9mIHdvcmtncm91cFNpemUgPT09ICdudW1iZXInID8gd29ya2dyb3VwU2l6ZSA6IHdvcmtncm91cFNpemVbMF07XG4gICAgY29uc3Qgd29ya2dyb3VwU2l6ZVkgPSB0eXBlb2Ygd29ya2dyb3VwU2l6ZSA9PT0gJ251bWJlcicgPyAxIDogd29ya2dyb3VwU2l6ZVsxXTtcbiAgICBjb25zdCB3b3JrZ3JvdXBTaXplWiA9IHR5cGVvZiB3b3JrZ3JvdXBTaXplID09PSAnbnVtYmVyJyA/IDEgOiB3b3JrZ3JvdXBTaXplWzJdO1xuXG4gICAgaWYgKFxuICAgICAgd29ya2dyb3VwU2l6ZVggPiB0aGlzLmxpbWl0cy5tYXhDb21wdXRlV29ya2dyb3VwU2l6ZVggfHxcbiAgICAgIHdvcmtncm91cFNpemVZID4gdGhpcy5saW1pdHMubWF4Q29tcHV0ZVdvcmtncm91cFNpemVZIHx8XG4gICAgICB3b3JrZ3JvdXBTaXplWiA+IHRoaXMubGltaXRzLm1heENvbXB1dGVXb3JrZ3JvdXBTaXplWlxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgd29ya2dyb3VwIHNpemUgWyR7d29ya2dyb3VwU2l6ZVh9LCAke3dvcmtncm91cFNpemVZfSwgJHtcbiAgICAgICAgICB3b3JrZ3JvdXBTaXplWlxuICAgICAgICB9XSBleGNlZWRzIHRoZSBtYXhpbXVtIHdvcmtncm91cCBzaXplIFske3RoaXMubGltaXRzLm1heENvbXB1dGVXb3JrZ3JvdXBTaXplWH0sICR7XG4gICAgICAgICAgdGhpcy5saW1pdHMubWF4Q29tcHV0ZVdvcmtncm91cFNpemVZXG4gICAgICAgIH0sICR7dGhpcy5saW1pdHMubWF4Q29tcHV0ZVdvcmtncm91cFNpemVafV0uYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHdvcmtncm91cFNpemVYICogd29ya2dyb3VwU2l6ZVkgKiB3b3JrZ3JvdXBTaXplWiA+IHRoaXMubGltaXRzLm1heENvbXB1dGVJbnZvY2F0aW9uc1Blcldvcmtncm91cCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgd29ya2dyb3VwIHNpemUgWyR7d29ya2dyb3VwU2l6ZVh9LCAke3dvcmtncm91cFNpemVZfSwgJHtcbiAgICAgICAgICB3b3JrZ3JvdXBTaXplWlxuICAgICAgICB9XSBleGNlZWRzIHRoZSBtYXhpbXVtIHdvcmtncm91cCBpbnZvY2F0aW9ucyAke3RoaXMubGltaXRzLm1heENvbXB1dGVJbnZvY2F0aW9uc1Blcldvcmtncm91cH0uYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgaXMxRGltZW5zaW9uRGlzcGF0Y2ggPSB0aGlzLm5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwWzFdID09PSAxICYmIHRoaXMubm9ybWFsaXplZERpc3BhdGNoR3JvdXBbMl0gPT09IDE7XG4gICAgY29uc3QgcGFyYW1MaXN0ID0gaXMxRGltZW5zaW9uRGlzcGF0Y2hcbiAgICAgID8gYEBidWlsdGluKGdsb2JhbF9pbnZvY2F0aW9uX2lkKSBnbG9iYWxfaWQgOiB2ZWMzPHUzMj4sXG4gICAgQGJ1aWx0aW4od29ya2dyb3VwX2lkKSB3b3JrZ3JvdXBfaWQgOiB2ZWMzPHUzMj4sXG4gICAgQGJ1aWx0aW4obG9jYWxfaW52b2NhdGlvbl9pbmRleCkgbG9jYWxfaWR4IDogdTMyLFxuICAgIEBidWlsdGluKGxvY2FsX2ludm9jYXRpb25faWQpIGxvY2FsX2lkIDogdmVjMzx1MzI+YFxuICAgICAgOiBgQGJ1aWx0aW4oZ2xvYmFsX2ludm9jYXRpb25faWQpIGdsb2JhbF9pZCA6IHZlYzM8dTMyPixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBidWlsdGluKGxvY2FsX2ludm9jYXRpb25faWQpIGxvY2FsX2lkIDogdmVjMzx1MzI+LFxuICAgIEBidWlsdGluKGxvY2FsX2ludm9jYXRpb25faW5kZXgpIGxvY2FsX2lkeCA6IHUzMixcbiAgICBAYnVpbHRpbih3b3JrZ3JvdXBfaWQpIHdvcmtncm91cF9pZCA6IHZlYzM8dTMyPixcbiAgICBAYnVpbHRpbihudW1fd29ya2dyb3VwcykgbnVtX3dvcmtncm91cHMgOiB2ZWMzPHUzMj5gO1xuICAgIGNvbnN0IGdsb2JhbElkeERlZmluaXRpb24gPSBpczFEaW1lbnNpb25EaXNwYXRjaFxuICAgICAgPyBgbGV0IGdsb2JhbF9pZHggPSBnbG9iYWxfaWQueDtcbiAgICAgICAgIGxldCB3b3JrZ3JvdXBfaW5kZXggPSB3b3JrZ3JvdXBfaWQueDtgXG4gICAgICA6IGBsZXQgd29ya2dyb3VwX2luZGV4ID0gd29ya2dyb3VwX2lkLnogKiBudW1fd29ya2dyb3Vwc1swXSAqIG51bV93b3JrZ3JvdXBzWzFdICtcbiAgICAgICAgICAgICB3b3JrZ3JvdXBfaWQueSAqIG51bV93b3JrZ3JvdXBzWzBdICsgd29ya2dyb3VwX2lkLng7XG4gICAgICAgICBsZXQgZ2xvYmFsX2lkeCA9IHdvcmtncm91cF9pbmRleCAqICR7d29ya2dyb3VwU2l6ZVggKiB3b3JrZ3JvdXBTaXplWSAqIHdvcmtncm91cFNpemVafXUgKyBsb2NhbF9pZHg7YDtcblxuICAgIHJldHVybiBgQGNvbXB1dGUgQHdvcmtncm91cF9zaXplKCR7d29ya2dyb3VwU2l6ZVh9LCAke3dvcmtncm91cFNpemVZfSwgJHt3b3JrZ3JvdXBTaXplWn0pXG4gIGZuIG1haW4oJHtwYXJhbUxpc3R9KSB7XG4gICAgJHtnbG9iYWxJZHhEZWZpbml0aW9ufVxuICBgO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBlbmRWYXJpYWJsZVVuaWZvcm1zKHZhcmlhYmxlOiBJbmRpY2VzSGVscGVyKTogdm9pZCB7XG4gICAgaWYgKHZhcmlhYmxlLnJhbmsgIT09IDApIHtcbiAgICAgIGlmICh2YXJpYWJsZS5zaGFwZS5zdGFydHNXaXRoKCd1bmlmb3Jtcy4nKSkge1xuICAgICAgICB0aGlzLnVuaWZvcm1zLnB1c2goeyBuYW1lOiB2YXJpYWJsZS5zaGFwZS5yZXBsYWNlKCd1bmlmb3Jtcy4nLCAnJyksIHR5cGU6ICd1MzInLCBsZW5ndGg6IHZhcmlhYmxlLnJhbmsgfSk7XG4gICAgICB9XG4gICAgICBpZiAodmFyaWFibGUuc3RyaWRlcy5zdGFydHNXaXRoKCd1bmlmb3Jtcy4nKSkge1xuICAgICAgICB0aGlzLnVuaWZvcm1zLnB1c2goeyBuYW1lOiB2YXJpYWJsZS5zdHJpZGVzLnJlcGxhY2UoJ3VuaWZvcm1zLicsICcnKSwgdHlwZTogJ3UzMicsIGxlbmd0aDogdmFyaWFibGUucmFuayB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRlY2xhcmVWYXJpYWJsZSh2YXJpYWJsZTogSW5kaWNlc0hlbHBlciwgYmluZGluZ0luZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGlmICh2YXJpYWJsZS51c2FnZSA9PT0gJ2ludGVybmFsJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgdXNlIGludGVybmFsIHZhcmlhYmxlIHdpdGggZGVjbGFyZVZhcmlhYmxlKCkuIHVzZSByZWdpc3RlckludGVybmFsVmFyaWFibGVzKCkgaW5zdGVhZC4nKTtcbiAgICB9XG4gICAgdGhpcy52YXJpYWJsZXMucHVzaCh2YXJpYWJsZSk7XG4gICAgdGhpcy5hcHBlbmRWYXJpYWJsZVVuaWZvcm1zKHZhcmlhYmxlKTtcbiAgICBjb25zdCBhY2Nlc3MgPSB2YXJpYWJsZS51c2FnZSA9PT0gJ2lucHV0JyA/ICdyZWFkJyA6ICdyZWFkX3dyaXRlJztcbiAgICBjb25zdCBzdG9yYWdlVHlwZSA9IHZhcmlhYmxlLnVzYWdlID09PSAnYXRvbWljT3V0cHV0JyA/IGBhdG9taWM8aTMyPmAgOiB2YXJpYWJsZS50eXBlLnN0b3JhZ2U7XG4gICAgcmV0dXJuIGBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtiaW5kaW5nSW5kZXh9KSB2YXI8c3RvcmFnZSwgJHthY2Nlc3N9PiAke3ZhcmlhYmxlLm5hbWV9OiBhcnJheTwke3N0b3JhZ2VUeXBlfT47YDtcbiAgfVxuXG4gIGRlY2xhcmVWYXJpYWJsZXMoLi4udmFyaWFibGVzOiBJbmRpY2VzSGVscGVyW10pOiBzdHJpbmcge1xuICAgIHJldHVybiB2YXJpYWJsZXMubWFwKCh2KSA9PiB0aGlzLmRlY2xhcmVWYXJpYWJsZSh2LCB0aGlzLnZhcmlhYmxlSW5kZXgrKykpLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlckludGVybmFsVmFyaWFibGUodmFyaWFibGU6IEluZGljZXNIZWxwZXIpOiB2b2lkIHtcbiAgICBpZiAodmFyaWFibGUudXNhZ2UgIT09ICdpbnRlcm5hbCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ2Nhbm5vdCB1c2UgaW5wdXQgb3Igb3V0cHV0IHZhcmlhYmxlIHdpdGggcmVnaXN0ZXJJbnRlcm5hbFZhcmlhYmxlKCkuIHVzZSBkZWNsYXJlVmFyaWFibGVzKCkgaW5zdGVhZC4nLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmludGVybmFsVmFyaWFibGVzLnB1c2godmFyaWFibGUpO1xuICAgIHRoaXMuYXBwZW5kVmFyaWFibGVVbmlmb3Jtcyh2YXJpYWJsZSk7XG4gIH1cblxuICByZWdpc3RlckludGVybmFsVmFyaWFibGVzKC4uLnZhcmlhYmxlczogSW5kaWNlc0hlbHBlcltdKTogU2hhZGVySGVscGVyIHtcbiAgICB2YXJpYWJsZXMuZm9yRWFjaCgodikgPT4gdGhpcy5yZWdpc3RlckludGVybmFsVmFyaWFibGUodikpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmVnaXN0ZXJVbmlmb3JtKG5hbWU6IHN0cmluZywgdHlwZTogVW5pZm9ybURhdGFFbGVtZW50VHlwZSwgbGVuZ3RoID0gMSk6IFNoYWRlckhlbHBlciB7XG4gICAgdGhpcy51bmlmb3Jtcy5wdXNoKHsgbmFtZSwgdHlwZSwgbGVuZ3RoIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmVnaXN0ZXJVbmlmb3JtcyhhZGRpdGlvbmFsVW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlKTogU2hhZGVySGVscGVyIHtcbiAgICB0aGlzLnVuaWZvcm1zID0gdGhpcy51bmlmb3Jtcy5jb25jYXQoYWRkaXRpb25hbFVuaWZvcm1zKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHByaXZhdGUgaW50ZXJuYWxWYXJpYWJsZXM6IEluZGljZXNIZWxwZXJbXSA9IFtdO1xuICBwcml2YXRlIHZhcmlhYmxlczogSW5kaWNlc0hlbHBlcltdID0gW107XG4gIHByaXZhdGUgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW107XG4gIHByaXZhdGUgdW5pZm9ybURlY2xhcmF0aW9uKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMudW5pZm9ybXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgY29uc3QgdW5pZm9ybVNuaXBwZXRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgeyBuYW1lLCB0eXBlLCBsZW5ndGggfSBvZiB0aGlzLnVuaWZvcm1zKSB7XG4gICAgICBpZiAobGVuZ3RoICYmIGxlbmd0aCA+IDQpIHtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdmMTYnKSB7XG4gICAgICAgICAgdW5pZm9ybVNuaXBwZXRzLnB1c2goYEBhbGlnbigxNikgJHtuYW1lfTphcnJheTxtYXQyeDQ8JHt0eXBlfT4sICR7TWF0aC5jZWlsKGxlbmd0aCAvIDgpfT5gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB1bmlmb3JtU25pcHBldHMucHVzaChgJHtuYW1lfTphcnJheTx2ZWM0PCR7dHlwZX0+LCAke01hdGguY2VpbChsZW5ndGggLyA0KX0+YCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHR5cGVUZW1wID0gbGVuZ3RoID09IG51bGwgfHwgbGVuZ3RoID09PSAxID8gdHlwZSA6IGB2ZWMke2xlbmd0aH08JHt0eXBlfT5gO1xuICAgICAgICB1bmlmb3JtU25pcHBldHMucHVzaChgJHtuYW1lfToke3R5cGVUZW1wfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBgXG4gICAgICBzdHJ1Y3QgVW5pZm9ybXMgeyAke3VuaWZvcm1TbmlwcGV0cy5qb2luKCcsICcpfSB9O1xuICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7dGhpcy52YXJpYWJsZUluZGV4fSkgdmFyPHVuaWZvcm0+IHVuaWZvcm1zOiBVbmlmb3JtcztgO1xuICB9XG4gIHByaXZhdGUgdmFyaWFibGVJbmRleCA9IDA7XG5cbiAgLyoqXG4gICAqIEdldCBhZGRpdGlvbmFsIGltcGxlbWVudGF0aW9uIHRoYXQgbmVlZHMgdG8gYmUgYWRkZWQgdG8gdGhlIHNoYWRlciBzb3VyY2UuXG4gICAqL1xuICBnZXQgYWRkaXRpb25hbEltcGxlbWVudGF0aW9ucygpOiBzdHJpbmcge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLnVuaWZvcm1EZWNsYXJhdGlvbigpICtcbiAgICAgIHRoaXMudmFyaWFibGVzLm1hcCgoaSkgPT4gaS5pbXBsKCkpLmpvaW4oJ1xcbicpICtcbiAgICAgIHRoaXMuaW50ZXJuYWxWYXJpYWJsZXMubWFwKChpKSA9PiBpLmltcGwoKSkuam9pbignXFxuJylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgdmFyaWFibGUgaW5mbyBvZiB0aGUgc2hhZGVyIHByb2dyYW0uXG4gICAqL1xuICBnZXQgdmFyaWFibGVzSW5mbygpOiBQcm9ncmFtVW5pZm9ybVZhcmlhYmxlSW5mb1tdIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy51bmlmb3Jtcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgdW5pZm9ybVdnc2xUeXBlVG9EYXRhVHlwZSA9ICh0eXBlOiBVbmlmb3JtRGF0YUVsZW1lbnRUeXBlKSA9PlxuICAgICAgW0RhdGFUeXBlLnVpbnQzMiwgRGF0YVR5cGUuZmxvYXQxNiwgRGF0YVR5cGUuZmxvYXQsIERhdGFUeXBlLmludDMyXVtbJ3UzMicsICdmMTYnLCAnZjMyJywgJ2kzMiddLmluZGV4T2YodHlwZSldO1xuICAgIHJldHVybiB0aGlzLnVuaWZvcm1zLm1hcCgodSkgPT4gW3VuaWZvcm1XZ3NsVHlwZVRvRGF0YVR5cGUodS50eXBlKSwgdS5sZW5ndGggPz8gMV0pO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVTaGFkZXJIZWxwZXIgPSAoZGlzcGF0Y2hHcm91cDogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCBsaW1pdHM6IEdQVVN1cHBvcnRlZExpbWl0cykgPT5cbiAgbmV3IFNoYWRlckhlbHBlckltcGwoZGlzcGF0Y2hHcm91cCwgbGltaXRzKTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBJbmRpY2VzSGVscGVyLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zcG9zZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBwZXJtOiBudW1iZXJbXTtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIHBlcm06IHJlYWRvbmx5IG51bWJlcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9zZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKHBlcm0ubGVuZ3RoICE9PSAwICYmIHBlcm0ubGVuZ3RoICE9PSBpbnB1dHNbMF0uZGltcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBlcm0gc2l6ZSAke3Blcm0ubGVuZ3RofSBkb2VzIG5vdCBtYXRjaCBpbnB1dCByYW5rICR7aW5wdXRzWzBdLmRpbXMubGVuZ3RofWApO1xuICB9XG59O1xuXG5jb25zdCBnZXRBZGp1c3RlZFBlcm0gPSAoaW5wdXRSYW5rOiBudW1iZXIsIHBlcm06IG51bWJlcltdKTogbnVtYmVyW10gPT5cbiAgcGVybS5sZW5ndGggIT09IDAgPyBwZXJtIDogWy4uLm5ldyBBcnJheShpbnB1dFJhbmspLmtleXMoKV0ucmV2ZXJzZSgpO1xuXG5jb25zdCBnZXRPdXRwdXRTaGFwZSA9IChpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcGVybTogbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSA9PlxuICBTaGFwZVV0aWwuc29ydEJhc2VkT25QZXJtKGlucHV0U2hhcGUsIGdldEFkanVzdGVkUGVybShpbnB1dFNoYXBlLmxlbmd0aCwgcGVybSkpO1xuXG5jb25zdCBwZXJtRnVuY3Rpb25Cb2R5ID0gKHBlcm06IG51bWJlcltdLCByYW5rOiBudW1iZXIsIGlucHV0OiBJbmRpY2VzSGVscGVyLCBvdXRwdXQ6IEluZGljZXNIZWxwZXIpOiBzdHJpbmcgPT4ge1xuICBsZXQgcmV2ZXJzZUZ1bmMgPSBgZm4gcGVybShpOiAke291dHB1dC50eXBlLmluZGljZXN9KSAtPiAke2lucHV0LnR5cGUuaW5kaWNlc30ge1xuICAgIHZhciBhOiAke2lucHV0LnR5cGUuaW5kaWNlc307YDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAvLyBpbnB1dCBpbmRpY2VzIGFuZCBvdXRwdXQgaW5kaWNlcyBzaG91bGQgYWx3YXlzIGJlIGxhcmdlciBvciBlcXVhbCB0byAyLFxuICAgIC8vIHNvIGluZGV4ZXIgaXMgYWx3YXlzIHZhbGlkIHRvIGJlIHVzZWQgb24gYGFgIGFuZCBgaWAuXG4gICAgcmV2ZXJzZUZ1bmMgKz0gYGFbJHtwZXJtW2ldfV09aVske2l9XTtgO1xuICB9XG4gIHJldHVybiAocmV2ZXJzZUZ1bmMgKz0gJ3JldHVybiBhO30nKTtcbn07XG5cbmNvbnN0IHNxdWVlemVTaGFwZSA9IChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGFkanVzdGVkUGVybTogbnVtYmVyW10pOiB7IG5ld1NoYXBlOiBudW1iZXJbXTsgbmV3UGVybTogbnVtYmVyW10gfSA9PiB7XG4gIGNvbnN0IG5ld1NoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBuZXdQZXJtOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoYXBlLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKHNoYXBlW2ldICE9PSAxKSB7XG4gICAgICBuZXdTaGFwZS5wdXNoKHNoYXBlW2ldKTtcbiAgICB9XG4gICAgaWYgKHNoYXBlW2FkanVzdGVkUGVybVtpXV0gIT09IDEpIHtcbiAgICAgIG5ld1Blcm0ucHVzaChhZGp1c3RlZFBlcm1baV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4geyBuZXdTaGFwZSwgbmV3UGVybSB9O1xufTtcblxuY29uc3QgaXNUcmFuc3Bvc2VSZXNoYXBlID0gKHBlcm06IG51bWJlcltdLCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pID0+IHtcbiAgLy8gQXMgbG9uZyBhcyB0aGUgZGltcyB3aXRoIHZhbHVlcyA+IDEgc3RheSBpbiB0aGUgc2FtZSBvcmRlciwgaXQncyBhIHJlc2hhcGUuXG4gIC8vIEV4YW1wbGU6IFNoYXBlPSgxLDEsMTAyNCw0MDk2KSAtPiBwZXJtPSgyLDAsMywxKS5cbiAgbGV0IGxhc3RQZXJtdXRlZEF4aXMgPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHBlcm0ubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoc2hhcGVbcGVybVtpXV0gPT09IDEpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAocGVybVtpXSA8IGxhc3RQZXJtdXRlZEF4aXMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgbGFzdFBlcm11dGVkQXhpcyA9IHBlcm1baV07XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8gPSAoaW5wdXRUZW5zb3I6IFRlbnNvclZpZXcsIHBlcm1BdHRyOiBudW1iZXJbXSk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXREYXRhVHlwZSA9IGlucHV0VGVuc29yLmRhdGFUeXBlO1xuICBjb25zdCBpbnB1dFJhbmsgPSBpbnB1dFRlbnNvci5kaW1zLmxlbmd0aDtcbiAgY29uc3QgcGVybSA9IGdldEFkanVzdGVkUGVybShpbnB1dFJhbmssIHBlcm1BdHRyKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBnZXRPdXRwdXRTaGFwZShpbnB1dFRlbnNvci5kaW1zLCBwZXJtKTtcbiAgbGV0IG5ld0lucHV0U2hhcGUgPSBpbnB1dFRlbnNvci5kaW1zO1xuICBsZXQgbmV3T3V0cHV0U2hhcGUgPSBvdXRwdXRTaGFwZTtcbiAgY29uc3QgdHJhbnNwb3NlQXNSZXNoYXBlID0gaW5wdXRSYW5rIDwgMiB8fCBpc1RyYW5zcG9zZVJlc2hhcGUocGVybSwgaW5wdXRUZW5zb3IuZGltcyk7XG4gIGxldCBnZXRTaGFkZXJTb3VyY2U7XG4gIGlmICh0cmFuc3Bvc2VBc1Jlc2hhcGUpIHtcbiAgICBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBpbnB1dERhdGFUeXBlLCBuZXdJbnB1dFNoYXBlLCA0KTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dERhdGFUeXBlLCBuZXdPdXRwdXRTaGFwZSwgNCk7XG4gICAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgb3V0cHV0W2dsb2JhbF9pZHhdID0gaW5wdXRbZ2xvYmFsX2lkeF07XG4gIH1gO1xuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogJ1RyYW5zcG9zZUNvcHknLFxuICAgICAgc2hhZGVyQ2FjaGU6IHsgaW5wdXREZXBlbmRlbmNpZXM6IFsndHlwZSddIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dFRlbnNvci5kYXRhVHlwZSB9XSxcbiAgICAgICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8gLyA0IC8qIGNvbXBvbmVudHMgKi8pIH0sXG4gICAgICAgICAgcHJvZ3JhbVVuaWZvcm1zOiBbeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNCkgfV0sXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIH07XG4gIH1cbiAgY29uc3QgeyBuZXdTaGFwZSwgbmV3UGVybSB9ID0gc3F1ZWV6ZVNoYXBlKGlucHV0VGVuc29yLmRpbXMsIHBlcm0pO1xuICBjb25zdCBjaGFubmVsc0xhc3QgPSBTaGFwZVV0aWwuYXJlRXF1YWwobmV3UGVybSwgWzIsIDMsIDFdKTtcbiAgY29uc3QgY2hhbm5lbHNGaXJzdCA9IFNoYXBlVXRpbC5hcmVFcXVhbChuZXdQZXJtLCBbMywgMSwgMl0pO1xuICBjb25zdCB1c2VTaGFyZWQgPSBuZXdTaGFwZS5sZW5ndGggPT09IDIgfHwgY2hhbm5lbHNMYXN0IHx8IGNoYW5uZWxzRmlyc3Q7XG4gIGlmICh1c2VTaGFyZWQpIHtcbiAgICBuZXdJbnB1dFNoYXBlID0gY2hhbm5lbHNMYXN0XG4gICAgICA/IFtuZXdTaGFwZVswXSwgbmV3U2hhcGVbMV0gKiBuZXdTaGFwZVsyXV1cbiAgICAgIDogY2hhbm5lbHNGaXJzdFxuICAgICAgICA/IFtuZXdTaGFwZVswXSAqIG5ld1NoYXBlWzFdLCBuZXdTaGFwZVsyXV1cbiAgICAgICAgOiBuZXdTaGFwZTtcbiAgICBuZXdPdXRwdXRTaGFwZSA9IFtuZXdJbnB1dFNoYXBlWzFdLCBuZXdJbnB1dFNoYXBlWzBdXTtcbiAgICBjb25zdCB0aWxlU2l6ZSA9IDE2O1xuICAgIGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgICAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdhJywgaW5wdXREYXRhVHlwZSwgbmV3SW5wdXRTaGFwZS5sZW5ndGgpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0RGF0YVR5cGUsIG5ld091dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG4gIHZhcjx3b3JrZ3JvdXA+IHRpbGUgOiBhcnJheTxhcnJheTwke291dHB1dC50eXBlLnZhbHVlfSwgJHt0aWxlU2l6ZSArIDF9PiwgJHt0aWxlU2l6ZX0+O1xuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoW3RpbGVTaXplLCB0aWxlU2l6ZSwgMV0pfVxuICAgIGxldCBzdHJpZGUgPSAodW5pZm9ybXMub3V0cHV0X3NoYXBlWzFdIC0gMSkgLyAke3RpbGVTaXplfSArIDE7XG4gICAgbGV0IHdvcmtncm91cF9pZF94ID0gd29ya2dyb3VwX2luZGV4ICUgc3RyaWRlO1xuICAgIGxldCB3b3JrZ3JvdXBfaWRfeSA9IHdvcmtncm91cF9pbmRleCAvIHN0cmlkZTtcbiAgICBsZXQgaW5wdXRfY29sID0gd29ya2dyb3VwX2lkX3kgKiAke3RpbGVTaXplfXUgKyBsb2NhbF9pZC54O1xuICAgIGxldCBpbnB1dF9yb3cgPSB3b3JrZ3JvdXBfaWRfeCAqICR7dGlsZVNpemV9dSArIGxvY2FsX2lkLnk7XG4gICAgaWYgKGlucHV0X3JvdyA8IHVuaWZvcm1zLmFfc2hhcGVbMF0gJiYgaW5wdXRfY29sIDwgdW5pZm9ybXMuYV9zaGFwZVsxXSkge1xuICAgICAgdGlsZVtsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKGAke2lucHV0LnR5cGUuaW5kaWNlc30oaW5wdXRfcm93LCBpbnB1dF9jb2wpYCl9O1xuICAgIH1cbiAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICBsZXQgb3V0cHV0X2NvbCA9IHdvcmtncm91cF9pZF94ICogJHt0aWxlU2l6ZX11ICsgbG9jYWxfaWQueDtcbiAgICBsZXQgb3V0cHV0X3JvdyA9IHdvcmtncm91cF9pZF95ICogJHt0aWxlU2l6ZX11ICsgbG9jYWxfaWQueTtcbiAgICBpZiAob3V0cHV0X3JvdyA8IHVuaWZvcm1zLm91dHB1dF9zaGFwZVswXSAmJiBvdXRwdXRfY29sIDwgdW5pZm9ybXMub3V0cHV0X3NoYXBlWzFdKSB7XG4gICAgICAke291dHB1dC5zZXRCeUluZGljZXMoYCR7b3V0cHV0LnR5cGUuaW5kaWNlc30ob3V0cHV0X3Jvdywgb3V0cHV0X2NvbClgLCAndGlsZVtsb2NhbF9pZC54XVtsb2NhbF9pZC55XScpfVxuICAgIH1cbiAgfWA7XG4gICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogJ1RyYW5zcG9zZVNoYXJlZCcsXG4gICAgICBzaGFkZXJDYWNoZTogeyBpbnB1dERlcGVuZGVuY2llczogWyd0eXBlJ10gfSxcbiAgICAgIGdldFJ1bkRhdGE6ICgpID0+IHtcbiAgICAgICAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0VGVuc29yLmRhdGFUeXBlIH1dLFxuICAgICAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG5ld091dHB1dFNoYXBlWzFdIC8gdGlsZVNpemUpLCB5OiBNYXRoLmNlaWwobmV3T3V0cHV0U2hhcGVbMF0gLyB0aWxlU2l6ZSkgfSxcbiAgICAgICAgICBwcm9ncmFtVW5pZm9ybXM6IFtcbiAgICAgICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgICAgICAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhuZXdJbnB1dFNoYXBlLCBuZXdPdXRwdXRTaGFwZSksXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBnZXRTaGFkZXJTb3VyY2UsXG4gICAgfTtcbiAgfVxuXG4gIGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnYScsIGlucHV0RGF0YVR5cGUsIG5ld0lucHV0U2hhcGUubGVuZ3RoKTtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXREYXRhVHlwZSwgbmV3T3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG5cbiAgJHtwZXJtRnVuY3Rpb25Cb2R5KHBlcm0sIGlucHV0UmFuaywgaW5wdXQsIG91dHB1dCl9XG5cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cblxuICAgIGxldCBpbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgIGxldCBhSW5kaWNlcyA9IHBlcm0oaW5kaWNlcyk7XG5cbiAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIGlucHV0LmdldEJ5SW5kaWNlcygnYUluZGljZXMnKSl9XG4gIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdUcmFuc3Bvc2UnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke3Blcm1BdHRyfWAsIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+IHtcbiAgICAgIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0VGVuc29yLmRhdGFUeXBlIH1dLFxuICAgICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgICAgICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMobmV3SW5wdXRTaGFwZSwgbmV3T3V0cHV0U2hhcGUpLFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCB0cmFuc3Bvc2UgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFRyYW5zcG9zZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMucGVybSk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgYXR0cmlidXRlcy5wZXJtKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogVHJhbnNwb3NlQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBwZXJtOiBhdHRyaWJ1dGVzLnBlcm0gYXMgbnVtYmVyW10gfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0IHsgY3JlYXRlUmVkdWNlQXR0cmlidXRlc0Zyb21JbnB1dHMsIFJlZHVjZUF0dHJpYnV0ZXMgfSBmcm9tICcuL3JlZHVjZSc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuY29uc3QgcmVkdWNlT3BzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICBtYXg6ICdzZWxlY3QoYmVzdFZhbHVlLCBjYW5kaWRhdGUsIGNhbmRpZGF0ZSA+IGJlc3RWYWx1ZSknLFxuICBtaW46ICdzZWxlY3QoYmVzdFZhbHVlLCBjYW5kaWRhdGUsIGNhbmRpZGF0ZSA8IGJlc3RWYWx1ZSknLFxuICBtZWFuOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbiAgc3VtOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbiAgcHJvZDogJ2Jlc3RWYWx1ZSAqIGNhbmRpZGF0ZScsXG4gIHN1bVNxdWFyZTogJ2Jlc3RWYWx1ZSArIGNhbmRpZGF0ZSAqIGNhbmRpZGF0ZScsXG4gIGxvZ1N1bUV4cDogJ2Jlc3RWYWx1ZSArIGV4cChjYW5kaWRhdGUpJyxcbiAgbDE6ICdiZXN0VmFsdWUgKyBhYnMoY2FuZGlkYXRlKScsXG4gIGwyOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlICogY2FuZGlkYXRlJyxcbiAgbG9nU3VtOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbn07XG5cbmNvbnN0IHJlZHVjZVNoYXJlZE9wczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgbWF4OiAnc2VsZWN0KGJlc3RWYWx1ZSwgY2FuZGlkYXRlLCBjYW5kaWRhdGUgPiBiZXN0VmFsdWUpJyxcbiAgbWluOiAnc2VsZWN0KGJlc3RWYWx1ZSwgY2FuZGlkYXRlLCBjYW5kaWRhdGUgPCBiZXN0VmFsdWUpJyxcbiAgbWVhbjogJ2Jlc3RWYWx1ZSArIGNhbmRpZGF0ZScsXG4gIHN1bTogJ2Jlc3RWYWx1ZSArIGNhbmRpZGF0ZScsXG4gIHByb2Q6ICdiZXN0VmFsdWUgKiBjYW5kaWRhdGUnLFxuICBzdW1TcXVhcmU6ICdiZXN0VmFsdWUgKyBjYW5kaWRhdGUnLFxuICBsb2dTdW1FeHA6ICdiZXN0VmFsdWUgKyBjYW5kaWRhdGUnLFxuICBsMTogJ2Jlc3RWYWx1ZSArIGNhbmRpZGF0ZScsXG4gIGwyOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbiAgbG9nU3VtOiAnYmVzdFZhbHVlICsgY2FuZGlkYXRlJyxcbn07XG5cbmNvbnN0IHJlZHVjZUluaXRWYWx1ZXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gIG1heDogJ19BW29mZnNldF0nLFxuICBtaW46ICdfQVtvZmZzZXRdJyxcbiAgbWVhbjogJzAnLFxuICBzdW06ICcwJyxcbiAgcHJvZDogJzEnLFxuICBzdW1TcXVhcmU6ICcwJyxcbiAgbG9nU3VtRXhwOiAnMCcsXG4gIGwxOiAnMCcsXG4gIGwyOiAnMCcsXG4gIGxvZ1N1bTogJzAnLFxufTtcblxuY29uc3QgcmVkdWNlT3V0cHV0VmFsdWVzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICBtYXg6ICdiZXN0VmFsdWUnLFxuICBtaW46ICdiZXN0VmFsdWUnLFxuICBzdW06ICdiZXN0VmFsdWUnLFxuICBwcm9kOiAnYmVzdFZhbHVlJyxcbiAgc3VtU3F1YXJlOiAnYmVzdFZhbHVlJyxcbiAgbG9nU3VtRXhwOiAnbG9nKGJlc3RWYWx1ZSknLFxuICBsMTogJ2Jlc3RWYWx1ZScsXG4gIGwyOiAnc3FydChiZXN0VmFsdWUpJyxcbiAgbG9nU3VtOiAnbG9nKGJlc3RWYWx1ZSknLFxufTtcblxuY29uc3QgZ2V0SW5uZXJNb3N0QXhlcyA9IChudW1Jbm5lckF4ZXM6IG51bWJlciwgcmFuazogbnVtYmVyKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCByZXMgPSBbXTtcbiAgZm9yIChsZXQgaSA9IHJhbmsgLSBudW1Jbm5lckF4ZXM7IGkgPCByYW5rOyArK2kpIHtcbiAgICByZXMucHVzaChpKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblxuY29uc3QgY29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyA9IChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdKTogW251bWJlcltdLCBudW1iZXJbXV0gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFtdO1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCByYW5rOyBkaW0rKykge1xuICAgIGlmIChheGVzLmluZGV4T2YoZGltKSA9PT0gLTEpIHtcbiAgICAgIG91dHB1dFNoYXBlLnB1c2goc2hhcGVbZGltXSk7XG4gICAgfVxuICB9XG4gIGNvbnN0IHJlZHVjZVNoYXBlID0gYXhlcy5tYXAoKGRpbSkgPT4gc2hhcGVbZGltXSk7XG4gIHJldHVybiBbb3V0cHV0U2hhcGUsIHJlZHVjZVNoYXBlXTtcbn07XG5cbmNvbnN0IGV4cGFuZFNoYXBlVG9LZWVwRGltID0gKHNoYXBlOiBudW1iZXJbXSwgYXhlczogbnVtYmVyW10pOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGggKyBheGVzLmxlbmd0aDtcbiAgY29uc3QgZXhwYW5kU2hhcGUgPSBbXTtcbiAgbGV0IHNoYXBlSWR4ID0gMDtcbiAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgcmFuazsgZGltKyspIHtcbiAgICBpZiAoYXhlcy5pbmRleE9mKGRpbSkgPT09IC0xKSB7XG4gICAgICBleHBhbmRTaGFwZS5wdXNoKHNoYXBlW3NoYXBlSWR4KytdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhwYW5kU2hhcGUucHVzaCgxKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGV4cGFuZFNoYXBlO1xufTtcblxuY29uc3QgYXJlQXhlc0lubmVyTW9zdERpbXMgPSAoYXhlczogbnVtYmVyW10sIHJhbms6IG51bWJlcik6IGJvb2xlYW4gPT4ge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGF4ZXMubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoYXhlc1theGVzLmxlbmd0aCAtIGkgLSAxXSAhPT0gcmFuayAtIDEgLSBpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuY29uc3QgZ2V0QXhlc1Blcm11dGF0aW9uID0gKGF4ZXM6IG51bWJlcltdLCByYW5rOiBudW1iZXIpOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IHJlcyA9IFtdO1xuICBpZiAoIWFyZUF4ZXNJbm5lck1vc3REaW1zKGF4ZXMsIHJhbmspKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaSkgPT09IC0xKSB7XG4gICAgICAgIHJlcy5wdXNoKGkpO1xuICAgICAgfVxuICAgIH1cbiAgICBheGVzLmZvckVhY2goKGF4aXMpID0+IHJlcy5wdXNoKGF4aXMpKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVJlZHVjZVNoYXJlZFByb2dyYW1JbmZvID0gKFxuICBuYW1lOiBzdHJpbmcsXG4gIGNhY2hlS2V5OiBzdHJpbmcsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICByZWR1Y2VUeXBlOiBzdHJpbmcsXG4gIG91dHB1dERhdGFUeXBlOiBEYXRhVHlwZSxcbiAgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuICByZWR1Y2VTaGFwZTogbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcblxuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCByZWR1Y2VTaXplID0gU2hhcGVVdGlsLnNpemUocmVkdWNlU2hhcGUpO1xuXG4gIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnX0EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0U2hhcGUpO1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0Jywgb3V0cHV0RGF0YVR5cGUsIG91dHB1dFNoYXBlKTtcblxuICBsZXQgd29ya2dyb3VwU2l6ZSA9IDY0O1xuICAvLyBJZiBvbmx5IG9uZSB3b3JrZ3JvdXAgaXMgZGlzcGF0Y2hlZCwgaW5jcmVhc2Ugd29ya2dyb3VwU2l6ZSB0byBpbXByb3ZlIHBhcmFsbGVsaXNtLlxuICBpZiAob3V0cHV0U2l6ZSA9PT0gMSkge1xuICAgIHdvcmtncm91cFNpemUgPSAyNTY7XG4gIH1cblxuICBjb25zdCBzaGFyZWRNZW1vcnlTbmlwcGV0ID0gYFxuICAgICAgICAgIHZhcjx3b3JrZ3JvdXA+IGFCZXN0VmFsdWVzIDogYXJyYXk8ZjMyLCAke3dvcmtncm91cFNpemV9PjtcbiAgICAgICBgO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICAgICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ3JlZHVjZVNpemUnLCAndTMyJykuZGVjbGFyZVZhcmlhYmxlcyhpbnB1dCwgb3V0cHV0KX1cbiAgICAgICAgJHtzaGFyZWRNZW1vcnlTbmlwcGV0fVxuICAgICAgICBmbiBESVZfQ0VJTChhIDogdTMyLCBiIDogdTMyKSAtPiB1MzIge1xuICAgICAgICAgIHJldHVybiAoKGEgLSAxdSkgLyBiICsgMXUpO1xuICAgICAgICAgfVxuICAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KHdvcmtncm91cFNpemUpfVxuXG4gICAgICAgICAgbGV0IG91dHB1dEluZGV4ID0gZ2xvYmFsX2lkeCAvICR7d29ya2dyb3VwU2l6ZX07XG4gICAgICAgICAgbGV0IG9mZnNldCA9IG91dHB1dEluZGV4ICogdW5pZm9ybXMucmVkdWNlU2l6ZTtcblxuICAgICAgICAgIHZhciBiZXN0VmFsdWUgPSBmMzIoJHtyZWR1Y2VJbml0VmFsdWVzW3JlZHVjZVR5cGVdfSk7XG4gICAgICAgICAgbGV0IExlbmd0aCA9IHVuaWZvcm1zLnJlZHVjZVNpemU7XG4gICAgICAgICAgZm9yICh2YXIgayA9IGxvY2FsX2lkeDsgayA8IExlbmd0aDsgayA9IGsgKyAke3dvcmtncm91cFNpemV9KSB7XG4gICAgICAgICAgIGxldCBjYW5kaWRhdGUgPSBmMzIoJHtpbnB1dC5nZXRCeU9mZnNldCgnb2Zmc2V0ICsgaycpfSk7XG4gICAgICAgICAgIGJlc3RWYWx1ZSA9ICR7cmVkdWNlT3BzW3JlZHVjZVR5cGVdfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYUJlc3RWYWx1ZXNbbG9jYWxfaWR4XSA9IGJlc3RWYWx1ZTtcbiAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgICAgIHZhciByZWR1Y2VTaXplID0gbWluKExlbmd0aCwgJHt3b3JrZ3JvdXBTaXplfXUpO1xuICAgICAgICAgZm9yICh2YXIgY3VycmVudFNpemUgPSByZWR1Y2VTaXplIC8gMnU7IHJlZHVjZVNpemUgPiAxdTtcbiAgICAgICAgICAgICBjdXJyZW50U2l6ZSA9IHJlZHVjZVNpemUgLyAydSkge1xuICAgICAgICAgICBsZXQgaW50ZXJ2YWwgPSBESVZfQ0VJTChyZWR1Y2VTaXplLCAydSk7XG4gICAgICAgICAgIGlmIChsb2NhbF9pZHggPCBjdXJyZW50U2l6ZSkge1xuICAgICAgICAgICAgbGV0IGNhbmRpZGF0ZSA9IGFCZXN0VmFsdWVzW2xvY2FsX2lkeCArIGludGVydmFsXTtcbiAgICAgICAgICAgIGJlc3RWYWx1ZSA9ICR7cmVkdWNlU2hhcmVkT3BzW3JlZHVjZVR5cGVdfTtcbiAgICAgICAgICAgIGFCZXN0VmFsdWVzW2xvY2FsX2lkeF0gPSBiZXN0VmFsdWU7XG4gICAgICAgICAgIH1cbiAgICAgICAgICAgcmVkdWNlU2l6ZSA9IGludGVydmFsO1xuICAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgICAgICB9XG5cbiAgICAgICAgIGlmIChsb2NhbF9pZHggPT0gMHUpIHtcbiAgICAgICAgICAke291dHB1dC5zZXRCeU9mZnNldChcbiAgICAgICAgICAgICdvdXRwdXRJbmRleCcsXG4gICAgICAgICAgICBgJHtcbiAgICAgICAgICAgICAgcmVkdWNlVHlwZSA9PT0gJ21lYW4nXG4gICAgICAgICAgICAgICAgPyBgJHtvdXRwdXQudHlwZS5zdG9yYWdlfShiZXN0VmFsdWUgLyBmMzIodW5pZm9ybXMucmVkdWNlU2l6ZSkpYFxuICAgICAgICAgICAgICAgIDogYCR7b3V0cHV0LnR5cGUuc3RvcmFnZX0oJHtyZWR1Y2VPdXRwdXRWYWx1ZXNbcmVkdWNlVHlwZV19KWBcbiAgICAgICAgICAgIH1gLFxuICAgICAgICAgICl9O1xuICAgICAgICAgfVxuICAgICAgICB9YDtcblxuICAvLyBPbmUgd29yayBncm91cCBpcyByZXNwb25zaWJsZSBmb3Igb25seSBvbmUgZWxlbWVudCBvZiBvdXRwdXQuXG4gIHJldHVybiB7XG4gICAgbmFtZSxcbiAgICAvLyBOb3RlIHRoYXQgaW4gSlNFUCwgV0cgc2l6ZSBpcyBub3QgaW5jbHVkZWQgaW4gY2FjaGUgYnkgZGVmYXVsdCwgYnV0IFdlYkdQVSBFUCBpdCBpcy5cbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtjYWNoZUtleX07JHt3b3JrZ3JvdXBTaXplfWAsIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3R5cGUnXSB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBvdXRwdXREYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogb3V0cHV0U2l6ZSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zOiBbeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHJlZHVjZVNpemUgfV0sXG4gICAgfSksXG4gIH07XG59O1xuXG5jb25zdCByZWR1Y2VDb21tb24gPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBuYW1lOiBzdHJpbmcsXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4gIHJlZHVjZVR5cGU6ICdzdW0nIHwgJ3N1bVNxdWFyZScgfCAncHJvZCcgfCAnbWluJyB8ICdtYXgnIHwgJ21lYW4nIHwgJ2xvZ1N1bUV4cCcgfCAnbDEnIHwgJ2wyJyB8ICdsb2dTdW0nLFxuKTogdm9pZCA9PiB7XG4gIGNvbnN0IHVwZGF0ZWRBdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzID1cbiAgICBjb250ZXh0LmlucHV0cy5sZW5ndGggPT09IDEgPyBhdHRyaWJ1dGVzIDogY3JlYXRlUmVkdWNlQXR0cmlidXRlc0Zyb21JbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuXG4gIGxldCB1cGRhdGVkQXhlcyA9IHVwZGF0ZWRBdHRyaWJ1dGVzLmF4ZXM7XG4gIGlmICh1cGRhdGVkQXhlcy5sZW5ndGggPT09IDAgJiYgIXVwZGF0ZWRBdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzKSB7XG4gICAgdXBkYXRlZEF4ZXMgPSBjb250ZXh0LmlucHV0c1swXS5kaW1zLm1hcCgoX2RpbSwgaSkgPT4gaSk7XG4gIH1cbiAgY29uc3Qgbm9ybWFsaXplQXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKHVwZGF0ZWRBeGVzLCBjb250ZXh0LmlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG5cbiAgbGV0IGF4ZXMgPSBub3JtYWxpemVBeGVzO1xuICBsZXQgaW5wdXQgPSBjb250ZXh0LmlucHV0c1swXTtcbiAgY29uc3QgcGVybXV0ZWRBeGVzID0gZ2V0QXhlc1Blcm11dGF0aW9uKGF4ZXMsIGNvbnRleHQuaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgaWYgKHBlcm11dGVkQXhlcy5sZW5ndGggPiAwKSB7XG4gICAgaW5wdXQgPSBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sIHBlcm11dGVkQXhlcyksIHtcbiAgICAgIGlucHV0czogWzBdLFxuICAgICAgb3V0cHV0czogWy0xXSxcbiAgICB9KVswXTtcbiAgICBheGVzID0gZ2V0SW5uZXJNb3N0QXhlcyhheGVzLmxlbmd0aCwgaW5wdXQuZGltcy5sZW5ndGgpO1xuICB9XG5cbiAgY29uc3QgW291dHB1dFNoYXBlLCByZWR1Y2VTaGFwZV0gPSBjb21wdXRlT3V0QW5kUmVkdWNlU2hhcGVzKGlucHV0LmRpbXMsIGF4ZXMpO1xuICBsZXQgZmluYWxPdXRwdXRTaGFwZSA9IG91dHB1dFNoYXBlO1xuICBpZiAodXBkYXRlZEF0dHJpYnV0ZXMua2VlcERpbXMpIHtcbiAgICBmaW5hbE91dHB1dFNoYXBlID0gZXhwYW5kU2hhcGVUb0tlZXBEaW0ob3V0cHV0U2hhcGUsIG5vcm1hbGl6ZUF4ZXMpO1xuICB9XG5cbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZVJlZHVjZVNoYXJlZFByb2dyYW1JbmZvKFxuICAgICAgbmFtZSxcbiAgICAgIHVwZGF0ZWRBdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgW2lucHV0XSxcbiAgICAgIHJlZHVjZVR5cGUsXG4gICAgICBjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSxcbiAgICAgIGZpbmFsT3V0cHV0U2hhcGUsXG4gICAgICByZWR1Y2VTaGFwZSxcbiAgICApLFxuICAgIHsgaW5wdXRzOiBbaW5wdXRdIH0sXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWVhblNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZU1lYW5TaGFyZWQnLCBhdHRyaWJ1dGVzLCAnbWVhbicpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZUwxU2hhcmVkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHJlZHVjZUNvbW1vbihjb250ZXh0LCAnUmVkdWNlTDFTaGFyZWQnLCBhdHRyaWJ1dGVzLCAnbDEnKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VMMlNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZUwyU2hhcmVkJywgYXR0cmlidXRlcywgJ2wyJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtRXhwU2hhcmVkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHJlZHVjZUNvbW1vbihjb250ZXh0LCAnUmVkdWNlTG9nU3VtRXhwU2hhcmVkJywgYXR0cmlidXRlcywgJ2xvZ1N1bUV4cCcpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZU1heFNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZU1heFNoYXJlZCcsIGF0dHJpYnV0ZXMsICdtYXgnKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNaW5TaGFyZWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgcmVkdWNlQ29tbW9uKGNvbnRleHQsICdSZWR1Y2VNaW5TaGFyZWQnLCBhdHRyaWJ1dGVzLCAnbWluJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlUHJvZFNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZVByb2RTaGFyZWQnLCBhdHRyaWJ1dGVzLCAncHJvZCcpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZVN1bVNoYXJlZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICByZWR1Y2VDb21tb24oY29udGV4dCwgJ1JlZHVjZVN1bVNoYXJlZCcsIGF0dHJpYnV0ZXMsICdzdW0nKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VTdW1TcXVhcmVTaGFyZWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgcmVkdWNlQ29tbW9uKGNvbnRleHQsICdSZWR1Y2VTdW1TcXVhcmVTaGFyZWQnLCBhdHRyaWJ1dGVzLCAnc3VtU3F1YXJlJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtU2hhcmVkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHJlZHVjZUNvbW1vbihjb250ZXh0LCAnUmVkdWNlTG9nU3VtU2hhcmVkJywgYXR0cmlidXRlcywgJ2xvZ1N1bScpO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1TaGFkZXJDYWNoZUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBJbmRpY2VzSGVscGVyLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0IHtcbiAgcmVkdWNlTDFTaGFyZWQsXG4gIHJlZHVjZUwyU2hhcmVkLFxuICByZWR1Y2VMb2dTdW1FeHBTaGFyZWQsXG4gIHJlZHVjZUxvZ1N1bVNoYXJlZCxcbiAgcmVkdWNlTWF4U2hhcmVkLFxuICByZWR1Y2VNZWFuU2hhcmVkLFxuICByZWR1Y2VNaW5TaGFyZWQsXG4gIHJlZHVjZVByb2RTaGFyZWQsXG4gIHJlZHVjZVN1bVNoYXJlZCxcbiAgcmVkdWNlU3VtU3F1YXJlU2hhcmVkLFxufSBmcm9tICcuL3JlZHVjZS1zaGFyZWQnO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoID09PSAwIHx8IGlucHV0cy5sZW5ndGggPiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWR1Y2Ugb3AgcmVxdWlyZXMgMSBvciAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAyICYmIGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBheGVzIGlucHV0IGRpbXMuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVkdWNlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGtlZXBEaW1zOiBib29sZWFuO1xuICBub29wV2l0aEVtcHR5QXhlczogYm9vbGVhbjtcbiAgYXhlczogbnVtYmVyW107XG59XG5cbmV4cG9ydCB0eXBlIFJlZHVjZU9wID0gKFxuICBpbnB1dDogSW5kaWNlc0hlbHBlcixcbiAgb3V0cHV0OiBJbmRpY2VzSGVscGVyLFxuICBheGVzOiByZWFkb25seSBudW1iZXJbXSxcbikgPT4gW3N0cmluZywgc3RyaW5nLCBzdHJpbmcsIHN0cmluZywgLi4uc3RyaW5nW11dO1xuXG5jb25zdCBub09wOiBSZWR1Y2VPcCA9IChpbnB1dCkgPT4gWycnLCAnJywgYHZhciB2YWx1ZSA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9O2AsICcnXTtcbmV4cG9ydCBjb25zdCBjcmVhdGVSZWR1Y2VQcm9ncmFtSW5mbyA9IChcbiAgbmFtZTogc3RyaW5nLFxuICBzaGFkZXJDYWNoZTogUHJvZ3JhbVNoYWRlckNhY2hlSW5mbyxcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIHJlZHVjZU9wOiBSZWR1Y2VPcCxcbiAgYXhlc0lucHV0OiBudW1iZXJbXSxcbiAgb3V0cHV0RGF0YVR5cGU6IERhdGFUeXBlLFxuICBrZWVwRGltcyA9IGZhbHNlLFxuICBub29wV2l0aEVtcHR5QXhlcyA9IGZhbHNlLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbnB1dFJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF4ZXNJbnB1dCwgaW5wdXRSYW5rKTtcbiAgY29uc3QgcmVkdWNlT25BbGxBeGVzID0gIW5vb3BXaXRoRW1wdHlBeGVzICYmIGF4ZXMubGVuZ3RoID09PSAwO1xuICBpbnB1dFNoYXBlLmZvckVhY2goKGQsIGkpID0+IHtcbiAgICBpZiAocmVkdWNlT25BbGxBeGVzIHx8IGF4ZXMuaW5kZXhPZihpKSA+PSAwKSB7XG4gICAgICBpZiAoa2VlcERpbXMpIHtcbiAgICAgICAgb3V0cHV0U2hhcGUucHVzaCgxKTtcbiAgICAgIH0gLy8gZWxzZSB7IC8vIHNraXAgdGhpcyBheGlzfVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXRTaGFwZS5wdXNoKGQpO1xuICAgIH1cbiAgfSk7XG4gIGNvbnN0IG91dHB1dFJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGlkeENvcHk6IHN0cmluZ1tdID0gW107IC8vIGNvcHkgb3V0cHV0IGluZGV4ZXMgdG8gaW5wdXQgaW5kZXhlc1xuXG4gICAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdfQScsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRSYW5rKTtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0Jywgb3V0cHV0RGF0YVR5cGUsIG91dHB1dFJhbmspO1xuICAgIGNvbnN0IG9wcyA9IHJlZHVjZU9wKGlucHV0LCBvdXRwdXQsIGF4ZXMpO1xuICAgIGxldCByZWR1Y2VPcHMgPSBvcHNbMl07XG5cbiAgICBmb3IgKGxldCBrID0gMCwgbCA9IDA7IGsgPCBpbnB1dFJhbms7IGsrKykge1xuICAgICAgLy8gaWYgdGhpcyBheGlzIGlzIHJlZHVjZWRcbiAgICAgIGlmIChyZWR1Y2VPbkFsbEF4ZXMgfHwgYXhlcy5pbmRleE9mKGspID49IDApIHtcbiAgICAgICAgaWYgKGtlZXBEaW1zKSB7XG4gICAgICAgICAgbCsrO1xuICAgICAgICB9XG4gICAgICAgIC8vIGxvb3Agb3ZlciB0aGUgZC10aCBheGlzXG4gICAgICAgIHJlZHVjZU9wcyA9IGBmb3IodmFyIGoke2t9OiB1MzIgPSAwOyBqJHtrfSA8ICR7aW5wdXRTaGFwZVtrXX07IGoke2t9KyspIHtcbiAgICAgICAgICAgICAgICAgICR7b3BzWzJdLmluY2x1ZGVzKCdsYXN0X2luZGV4JykgPyBgbGV0IGxhc3RfaW5kZXggPSBqJHtrfTtgIDogJyd9XG4gICAgICAgICAgICAgICAgICAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0X2luZGljZXMnLCBrLCBgaiR7a31gKX1cbiAgICAgICAgICAgICAgICAgICR7cmVkdWNlT3BzfVxuICAgICAgICAgICAgICAgIH1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWR4Q29weS5wdXNoKGAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0X2luZGljZXMnLCBrLCBvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCBsKSl9O2ApO1xuICAgICAgICBsKys7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBgXG5cbiAgICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3JtKCdvdXRwdXRfc2l6ZScsICd1MzInKS5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBvdXRwdXQpfVxuXG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgICAgICAgdmFyIGlucHV0X2luZGljZXM6ICR7aW5wdXQudHlwZS5pbmRpY2VzfTtcbiAgICAgICAgICBsZXQgb3V0cHV0X2luZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG5cbiAgICAgICAgICAke2lkeENvcHkuam9pbignXFxuJyl9XG4gICAgICAgICAgJHtvcHNbMF19ICAgICAgIC8vIGluaXQgb3BzIGZvciByZWR1Y2UgbWF4L21pblxuICAgICAgICAgICR7b3BzWzFdfVxuICAgICAgICAgICR7cmVkdWNlT3BzfVxuICAgICAgICAgICR7b3BzWzNdfVxuICAgICAgICAgICR7b3BzLmxlbmd0aCA9PT0gNCA/IG91dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICd2YWx1ZScpIDogb3BzLnNsaWNlKDQpLmpvaW4oJ1xcbicpfVxuICAgICAgICB9YDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5hbWUsXG4gICAgc2hhZGVyQ2FjaGUsXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IG91dHB1dERhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zOiBbXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0U2hhcGUsIG91dHB1dFNoYXBlKSxcbiAgICAgIF0sXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUmVkdWNlQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLFxuKTogUmVkdWNlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF4ZXM6IG51bWJlcltdID0gW107XG4gIGlmIChpbnB1dHNbMV0uZGltc1swXSA+IDApIHtcbiAgICBpbnB1dHNbMV0uZ2V0QmlnSW50NjRBcnJheSgpLmZvckVhY2goKHYpID0+IGF4ZXMucHVzaChOdW1iZXIodikpKTtcbiAgfVxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBheGVzLFxuICAgIGtlZXBEaW1zOiBhdHRyaWJ1dGVzLmtlZXBEaW1zLFxuICAgIG5vb3BXaXRoRW1wdHlBeGVzOiBhdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzLFxuICB9KTtcbn07XG5cbmNvbnN0IHJ1blJlZHVjZVByb2dyYW0gPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBuYW1lOiBzdHJpbmcsXG4gIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsXG4gIHJlZHVjZU9wOiBSZWR1Y2VPcCxcbik6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgY29uc3QgdXBkYXRlZEF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMgPVxuICAgIGlucHV0cy5sZW5ndGggPT09IDEgPyBhdHRyaWJ1dGVzIDogY3JlYXRlUmVkdWNlQXR0cmlidXRlc0Zyb21JbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcblxuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8oXG4gICAgICBuYW1lLFxuICAgICAgeyBoaW50OiB1cGRhdGVkQXR0cmlidXRlcy5jYWNoZUtleSwgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuayddIH0sXG4gICAgICBbaW5wdXRzWzBdXSxcbiAgICAgIHVwZGF0ZWRBdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzICYmIHVwZGF0ZWRBdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID09PSAwID8gbm9PcCA6IHJlZHVjZU9wLFxuICAgICAgdXBkYXRlZEF0dHJpYnV0ZXMuYXhlcyxcbiAgICAgIGlucHV0c1swXS5kYXRhVHlwZSxcbiAgICAgIHVwZGF0ZWRBdHRyaWJ1dGVzLmtlZXBEaW1zLFxuICAgICAgdXBkYXRlZEF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMsXG4gICAgKSxcbiAgICB7IGlucHV0czogWzBdIH0sXG4gICk7XG59O1xuXG5jb25zdCByZWR1Y2VMb2dTdW1OYWl2ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dCwgb3V0cHV0KSA9PiBbXG4gICAgYHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUuc3RvcmFnZX0oMCk7YCxcbiAgICAnJyxcbiAgICBgdmFsdWUgKz0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07YCxcbiAgICAndmFsdWUgPSBsb2codmFsdWUpOycsXG4gIF07XG4gIHJ1blJlZHVjZVByb2dyYW0oY29udGV4dCwgJ1JlZHVjZUxvZ1N1bScsIGF0dHJpYnV0ZXMsIHJlZHVjZU9wKTtcbn07XG5cbmNvbnN0IHJlZHVjZUwxTmFpdmUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXQsIG91dHB1dCkgPT4gW1xuICAgIGB2YXIgdmFsdWUgPSAke291dHB1dC50eXBlLnN0b3JhZ2V9KDApO2AsXG4gICAgJycsXG4gICAgYHZhbHVlICs9IGFicygke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfSk7YCxcbiAgICAnJyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlTDEnLCBhdHRyaWJ1dGVzLCByZWR1Y2VPcCk7XG59O1xuXG5jb25zdCByZWR1Y2VMMk5haXZlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQpID0+IFtcbiAgICBgdmFyIHQgPSAke291dHB1dC50eXBlLnZhbHVlfSgwKTsgdmFyIHZhbHVlID0gJHtvdXRwdXQudHlwZS52YWx1ZX0oMCk7YCxcbiAgICAnJyxcbiAgICBgdCA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9OyB2YWx1ZSArPSAodCAqIHQpO2AsXG4gICAgJ3ZhbHVlID0gc3FydCh2YWx1ZSk7JyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlTDInLCBhdHRyaWJ1dGVzLCByZWR1Y2VPcCk7XG59O1xuXG5jb25zdCByZWR1Y2VMb2dTdW1FeHBOYWl2ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dCwgb3V0cHV0KSA9PiBbXG4gICAgYHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUuc3RvcmFnZX0oMCk7YCxcbiAgICAnJyxcbiAgICBgdmFsdWUgKz0gZXhwKCR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9KTtgLFxuICAgICd2YWx1ZSA9IGxvZyh2YWx1ZSk7JyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlTG9nU3VtRXhwJywgYXR0cmlidXRlcywgcmVkdWNlT3ApO1xufTtcblxuY29uc3QgcmVkdWNlTWF4TmFpdmUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXQsIF9vdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dC5yYW5rOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goaW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIGssIDApKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gW1xuICAgICAgYCR7aWR4WmVyby5qb2luKCdcXG4nKX1gLFxuICAgICAgYHZhciB2YWx1ZSA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9O2AsXG4gICAgICBgdmFsdWUgPSBtYXgodmFsdWUsICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9KTtgLFxuICAgICAgJycsXG4gICAgXTtcbiAgfTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlTWF4JywgYXR0cmlidXRlcywgcmVkdWNlT3ApO1xufTtcblxuY29uc3QgcmVkdWNlTWVhbk5haXZlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBsZXQgc2l6ZSA9IDEuMDtcbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0LnJhbms7IGsrKykge1xuICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIC8vIFRPRE86IHRoaXMgZGVwZW5kcyBvbiB0aGUgaW5wdXQgZGltcy4gSWYgd2Ugd2FudCB0byB1c2UgdW5pZm9ybSwgdGhpcyBuZWVkIHRvIGJlIHVwZGF0ZWQuXG4gICAgICAgIHNpemUgKj0gY29udGV4dC5pbnB1dHNbMF0uZGltc1trXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gW1xuICAgICAgJ3ZhciBzdW0gPSBmMzIoMCk7JyxcbiAgICAgICcnLFxuICAgICAgYHN1bSArPSBmMzIoJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX0pO2AsXG4gICAgICBgbGV0IHZhbHVlID0gJHtvdXRwdXQudHlwZS52YWx1ZX0oc3VtIC8gJHtzaXplfSk7YCxcbiAgICBdO1xuICB9O1xuICBydW5SZWR1Y2VQcm9ncmFtKGNvbnRleHQsICdSZWR1Y2VNZWFuJywgYXR0cmlidXRlcywgcmVkdWNlT3ApO1xufTtcblxuY29uc3QgcmVkdWNlTWluTmFpdmUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXQsIF9vdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dC5yYW5rOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0X2luZGljZXNbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtcbiAgICAgIGAke2lkeFplcm8uam9pbignXFxuJyl9YCxcbiAgICAgIGB2YXIgdmFsdWUgPSAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfTtgLFxuICAgICAgYHZhbHVlID0gbWluKHZhbHVlLCAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfSk7YCxcbiAgICAgICcnLFxuICAgIF07XG4gIH07XG4gIHJ1blJlZHVjZVByb2dyYW0oY29udGV4dCwgJ1JlZHVjZU1pbicsIGF0dHJpYnV0ZXMsIHJlZHVjZU9wKTtcbn07XG5cbmNvbnN0IHJlZHVjZVByb2ROYWl2ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dCwgb3V0cHV0KSA9PiBbXG4gICAgYHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUuc3RvcmFnZX0oMSk7YCxcbiAgICAnJyxcbiAgICBgdmFsdWUgKj0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07YCxcbiAgICAnJyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlUHJvZCcsIGF0dHJpYnV0ZXMsIHJlZHVjZU9wKTtcbn07XG5cbmNvbnN0IHJlZHVjZVN1bU5haXZlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQpID0+IFtcbiAgICBgdmFyIHZhbHVlID0gJHtvdXRwdXQudHlwZS5zdG9yYWdlfSgwKTtgLFxuICAgICcnLFxuICAgIGB2YWx1ZSArPSAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfTtgLFxuICAgICcnLFxuICBdO1xuICBydW5SZWR1Y2VQcm9ncmFtKGNvbnRleHQsICdSZWR1Y2VTdW0nLCBhdHRyaWJ1dGVzLCByZWR1Y2VPcCk7XG59O1xuXG5jb25zdCByZWR1Y2VTdW1TcXVhcmVOYWl2ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dCwgb3V0cHV0KSA9PiBbXG4gICAgYHZhciB0ID0gJHtvdXRwdXQudHlwZS52YWx1ZX0oMCk7IHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUudmFsdWV9KDApO2AsXG4gICAgJycsXG4gICAgYHQgPSAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfTsgdmFsdWUgKz0gdCAqIHQ7YCxcbiAgICAnJyxcbiAgXTtcbiAgcnVuUmVkdWNlUHJvZ3JhbShjb250ZXh0LCAnUmVkdWNlU3VtU3F1YXJlJywgYXR0cmlidXRlcywgcmVkdWNlT3ApO1xufTtcblxuY29uc3QgdXNlTmFpdmVSZWR1Y2VNZXRob2QgPSAoXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXhlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG5vb3BXaXRoRW1wdHlBeGVzOiBib29sZWFuLFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmIChheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBub29wV2l0aEVtcHR5QXhlcztcbiAgfVxuXG4gIGxldCBvdXRwdXRTaXplID0gMTtcbiAgbGV0IHJlZHVjZVNpemUgPSAxO1xuICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBheGVzLmxlbmd0aDsgZGltKyspIHtcbiAgICBpZiAoYXhlcy5pbmRleE9mKGRpbSkgPT09IC0xKSB7XG4gICAgICBvdXRwdXRTaXplICo9IHNoYXBlW2RpbV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZHVjZVNpemUgKj0gc2hhcGVbZGltXTtcbiAgICB9XG4gIH1cblxuICAvLyBUaGUgY29uZGl0aW9uIGRhdGEgaXMgdmVyeSByb3VnaCwgYWx0aG91Z2ggY29uc2lkZXJpbmcgdGhlIGNvdW50IG9mIEV4ZWN1dGlvbiBVbml0IChFVSksIHRoZSBwb3RlbnRpYWxcbiAgLy8gd29yayBncm91cHMgaW4gYSBFVSBhbmQgdGhlIGNvdW50cyBvZiBsb29wcyBpbiB0aGUgbmFpdmUgYW5kIHNoYXJlZCBtZXRob2RzLCBhbHNvIGRvaW5nIGV4cGVyaW1lbnRzXG4gIC8vIG9uIHNvbWUgbWFjaGluZXMuXG4gIHJldHVybiByZWR1Y2VTaXplIDwgMzIgJiYgb3V0cHV0U2l6ZSA+IDEwMjQ7XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWVhbiA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAodXNlTmFpdmVSZWR1Y2VNZXRob2QoY29udGV4dC5pbnB1dHNbMF0uZGltcywgYXR0cmlidXRlcy5heGVzLCBhdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzKSkge1xuICAgIHJlZHVjZU1lYW5OYWl2ZShjb250ZXh0LCBhdHRyaWJ1dGVzKTtcbiAgfSBlbHNlIHtcbiAgICByZWR1Y2VNZWFuU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTDEgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgaWYgKHVzZU5haXZlUmVkdWNlTWV0aG9kKGNvbnRleHQuaW5wdXRzWzBdLmRpbXMsIGF0dHJpYnV0ZXMuYXhlcywgYXR0cmlidXRlcy5ub29wV2l0aEVtcHR5QXhlcykpIHtcbiAgICByZWR1Y2VMMU5haXZlKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9IGVsc2Uge1xuICAgIHJlZHVjZUwxU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTDIgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgaWYgKHVzZU5haXZlUmVkdWNlTWV0aG9kKGNvbnRleHQuaW5wdXRzWzBdLmRpbXMsIGF0dHJpYnV0ZXMuYXhlcywgYXR0cmlidXRlcy5ub29wV2l0aEVtcHR5QXhlcykpIHtcbiAgICByZWR1Y2VMMk5haXZlKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9IGVsc2Uge1xuICAgIHJlZHVjZUwyU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtRXhwID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlTG9nU3VtRXhwTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlTG9nU3VtRXhwU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWF4ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlTWF4TmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlTWF4U2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWluID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlTWluTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlTWluU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlUHJvZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAodXNlTmFpdmVSZWR1Y2VNZXRob2QoY29udGV4dC5pbnB1dHNbMF0uZGltcywgYXR0cmlidXRlcy5heGVzLCBhdHRyaWJ1dGVzLm5vb3BXaXRoRW1wdHlBeGVzKSkge1xuICAgIHJlZHVjZVByb2ROYWl2ZShjb250ZXh0LCBhdHRyaWJ1dGVzKTtcbiAgfSBlbHNlIHtcbiAgICByZWR1Y2VQcm9kU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlU3VtID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlU3VtTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlU3VtU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlU3VtU3F1YXJlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlU3VtU3F1YXJlTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlU3VtU3F1YXJlU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICh1c2VOYWl2ZVJlZHVjZU1ldGhvZChjb250ZXh0LmlucHV0c1swXS5kaW1zLCBhdHRyaWJ1dGVzLmF4ZXMsIGF0dHJpYnV0ZXMubm9vcFdpdGhFbXB0eUF4ZXMpKSB7XG4gICAgcmVkdWNlTG9nU3VtTmFpdmUoY29udGV4dCwgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVkdWNlTG9nU3VtU2hhcmVkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vLyBUT0RPOiB0aGlzIGlzIHRoZSBzYW1lIG5haXZlIGltcGxlbWVudGF0aW9uIHdlIHVzZSBmb3IgcmVkdWNlIHRoYXQgaGFzXG4vLyBwZXJmb3JtYW5jZSBsaW1pdGF0aW9ucyB3aGVuIHRoZSByZWR1Y2VkIGF4aXMgaXMgbG9uZy4gTmVlZCB0byBhZGRcbi8vIGEgb3B0aW1pemVkIGNvZGVwYXRoIGZvciB0aGlzLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8sIFJlZHVjZU9wIH0gZnJvbSAnLi9yZWR1Y2UnO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoID09PSAwIHx8IGlucHV0cy5sZW5ndGggPiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBcmdNaW5NYXhPcCBvcCByZXF1aXJlcyAxIG9yIDIgaW5wdXRzLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0uZGF0YVR5cGUgIT09IERhdGFUeXBlLmZsb2F0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXJnTWluTWF4QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGtlZXBEaW1zOiBib29sZWFuO1xuICBheGlzOiBudW1iZXI7XG4gIHNlbGVjdExhc3RJbmRleDogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgYXJnTWluID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBcmdNaW5NYXhBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgYXJnTWluTWF4T3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dC5yYW5rOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0X2luZGljZXNbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBbXG4gICAgICBgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfWAsXG4gICAgICBgdmFyIHZhbHVlID0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07XFxudmFyIGJlc3RfaW5kZXggOiBpMzIgPSAwO2AsXG4gICAgICBgaWYgKCR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9ICR7YXR0cmlidXRlcy5zZWxlY3RMYXN0SW5kZXggPiAwID8gJzw9JyA6ICc8J30gdmFsdWUpIHtcbiAgICAgICAgIHZhbHVlID0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07XG4gICAgICAgICBiZXN0X2luZGV4ID0gaTMyKGxhc3RfaW5kZXgpO1xuICAgICAgIH1gLFxuICAgICAgJycsXG4gICAgICBvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAnYmVzdF9pbmRleCcpLFxuICAgIF07XG4gIH07XG5cbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvKFxuICAgICAgJ0FyZ01pbicsXG4gICAgICB7IGhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgICAgW2NvbnRleHQuaW5wdXRzWzBdXSxcbiAgICAgIGFyZ01pbk1heE9wLFxuICAgICAgW2F0dHJpYnV0ZXMuYXhpc10sXG4gICAgICBEYXRhVHlwZS5pbnQ2NCxcbiAgICAgIGF0dHJpYnV0ZXMua2VlcERpbXMsXG4gICAgKSxcbiAgICB7IGlucHV0czogWzBdIH0sXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgYXJnTWF4ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBcmdNaW5NYXhBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgYXJnTWluTWF4T3A6IFJlZHVjZU9wID0gKGlucHV0LCBvdXRwdXQsIGF4ZXMpID0+IHtcbiAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dC5yYW5rOyBrKyspIHtcbiAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0X2luZGljZXNbJHtrfV0gPSAwO2ApOyAvLyBmaXJzdCBlbGVtZW50XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBbXG4gICAgICBgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfWAsXG4gICAgICBgdmFyIHZhbHVlID0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07XFxudmFyIGJlc3RfaW5kZXggOiBpMzIgPSAwO2AsXG4gICAgICBgaWYgKCR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9ICR7YXR0cmlidXRlcy5zZWxlY3RMYXN0SW5kZXggPiAwID8gJz49JyA6ICc+J30gdmFsdWUpIHtcbiAgICAgICAgIHZhbHVlID0gJHtpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXMnKX07XG4gICAgICAgICBiZXN0X2luZGV4ID0gaTMyKGxhc3RfaW5kZXgpO1xuICAgICAgIH1gLFxuICAgICAgJycsXG4gICAgICBvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAnYmVzdF9pbmRleCcpLFxuICAgIF07XG4gIH07XG5cbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvKFxuICAgICAgJ2FyZ01heCcsXG4gICAgICB7IGhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgICAgW2NvbnRleHQuaW5wdXRzWzBdXSxcbiAgICAgIGFyZ01pbk1heE9wLFxuICAgICAgW2F0dHJpYnV0ZXMuYXhpc10sXG4gICAgICBEYXRhVHlwZS5pbnQ2NCxcbiAgICAgIGF0dHJpYnV0ZXMua2VlcERpbXMsXG4gICAgKSxcbiAgICB7IGlucHV0czogWzBdIH0sXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VBcmdNaW5NYXhBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogQXJnTWluTWF4QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoYXR0cmlidXRlcyBhcyBPbWl0PEFyZ01pbk1heEF0dHJpYnV0ZXMsIGtleW9mIEF0dHJpYnV0ZVdpdGhDYWNoZUtleT4pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBHcHVEYXRhVHlwZSwgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge1xuICBnZXRNYXhDb21wb25lbnRzLFxuICBJbmRpY2VzSGVscGVyLFxuICBpbnB1dFZhcmlhYmxlLFxuICBvdXRwdXRWYXJpYWJsZSxcbiAgU2hhZGVySGVscGVyLFxuICB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUsXG4gIHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUsXG4gIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBjb25zdCBlbnVtIEF0dGVudGlvblFrdkZvcm1hdCB7XG4gIHVua25vd24sIC8vIGVudW0gdmFsdWUgbm90IHNldCwgb3IgZGVwZW5kcyBvbiBxa3YgcHJvamVjdGlvbiBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzXG4gIHFrdkJOU0gsIC8vIGZvciBub24tcGFja2VkIHFrdiwgcGVybXV0ZWRcbiAgcWt2QlNOSCwgLy8gZm9yIG5vbi1wYWNrZWQgcWt2LCBub3QgcGVybXV0ZWQsIHVzZWQgYnkgbWVtb3J5IGVmZmljaWVudCBhdHRlbnRpb24gb3IgTXVsdGlIZWFkQXR0ZW50aW9uXG4gIHFrdkJTTjNILCAvLyBmb3IgVFJUIGZ1c2VkIGF0dGVudGlvbiwgcWt2IGFyZSBwYWNrZWRcbiAgcWt2Qk5TSHFrdkJTM05ILCAvLyBmb3IgVFJUIGZ1c2VkIGNhdXNhbCBhdHRlbnRpb24sIGRhdGEgaGFzIHR3byBmb3JtYXRzIChxa3YgaXMgM0JOU0gsIGdlbW1fYnVmZmVyIGlzIEJTM05IKVxuICBxS3ZCU05IeEJTTjJILCAvLyBmb3IgVFJUIGZ1c2VkIGNyb3NzIGF0dGVudGlvbiwga3YgYXJlIHBhY2tlZFxuICBxa3ZUTkgsIC8vIGZvciBtZW1vcnkgZWZmaWNpZW50IGF0dGVudGlvbiwgcWt2IGFyZSBub3QgcGFja2VkLCBhbmQgcGFkZGluZ3MgYXJlIHJlbW92ZWQuXG4gIHFrdlROM0gsIC8vIGZvciBUUlQgZnVzZWQgYXR0ZW50aW9uLCBxa3YgYXJlIHBhY2tlZCBhbmQgcGFkZGluZ3MgYXJlIHJlbW92ZWRcbn1cblxuZXhwb3J0IGNvbnN0IGVudW0gQXR0ZW50aW9uTWFza1R5cGUge1xuICBub25lLCAvLyBObyBtYXNrXG4gIG1hc2sxZEtleVNlcUxlbiwgLy8gW2JhdGNoX3NpemVdLCBrZXkgc2VxdWVuY2UgbGVuZ3RoXG4gIG1hc2sxZEVuZFN0YXJ0LCAvLyBbMiAqIGJhdGNoX3NpemVdIHdpdGggZW5kIHBvc2l0aW9ucyBhbmQgc3RhcnQgcG9zaXRpb25zXG4gIG1hc2sxREtleVNlcUxlblN0YXJ0LCAvLyBbMyAqIGJhdGNoX3NpemUgKyAyXSB3aXRoIFtrZXlfbGVuWzBdLCAuLi4sIGtleV9sZW5bYmF0Y2hfc2l6ZSAtIDFdLCBxdWVyeV9zdGFydFswXSxcbiAgLy8gLi4uLCBxdWVyeV9zdGFydFtiYXRjaF9zaXplIC0gMV0sIHF1ZXJ5X2VuZFtiYXRjaF9zaXplIC0gMV0sIGtleV9zdGFydFswXSwgLi4uLFxuICAvLyBrZXlfc3RhcnRbYmF0Y2hfc2l6ZSAtIDFdLCBrZXlfZW5kW2JhdGNoX3NpemUgLSAxXV1cbiAgbWFzazJkRHVtbXksIC8vIGR1bW15IG1hc2sgd2l0aCBzaGFwZSBbMSwgMV0gb3IgW2JhdGNoX3NpemUsIDFdLiBJdCBoYXMgc2FtZSBlZmZlY3QgYXMgbm8gbWFzay5cbiAgbWFzazJkS2V5UGFkZGluZywgLy8gW2JhdGNoX3NpemUsIHRvdGFsX3NlcXVlbmNlX2xlbmd0aF1cbiAgbWFzazNkQXR0ZW50aW9uLCAvLyBbYmF0Y2hfc2l6ZSwgc2VxdWVuY2VfbGVuZ3RoLCB0b3RhbF9zZXF1ZW5jZV9sZW5ndGhdXG4gIG1hc2s0ZE1lZ2F0cm9uLCAvLyBNZWdhdHJvbiBjYXVzYWwgbWFzayB3aXRoIHNoYXBlIFtiYXRjaF9zaXplLCAxLCBtYXhfc2VxdWVuY2VfbGVuZ3RoLCBtYXhfc2VxdWVuY2VfbGVuZ3RoXVxuICBtYXNrVW5rbm93bixcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBdHRlbnRpb25QYXJhbWV0ZXJzIHtcbiAgYmF0Y2hTaXplOiBudW1iZXI7XG4gIHNlcXVlbmNlTGVuZ3RoOiBudW1iZXI7XG4gIHBhc3RTZXF1ZW5jZUxlbmd0aDogbnVtYmVyO1xuICBrdlNlcXVlbmNlTGVuZ3RoOiBudW1iZXI7XG4gIHRvdGFsU2VxdWVuY2VMZW5ndGg6IG51bWJlcjtcbiAgbWF4U2VxdWVuY2VMZW5ndGg6IG51bWJlcjtcbiAgaW5wdXRIaWRkZW5TaXplOiBudW1iZXI7XG4gIGhpZGRlblNpemU6IG51bWJlcjtcbiAgdkhpZGRlblNpemU6IG51bWJlcjtcbiAgaGVhZFNpemU6IG51bWJlcjtcbiAgdkhlYWRTaXplOiBudW1iZXI7XG4gIG51bUhlYWRzOiBudW1iZXI7XG4gIGt2TnVtSGVhZHM/OiBudW1iZXI7XG4gIG5SZXBzPzogbnVtYmVyO1xuICBpc1VuaWRpcmVjdGlvbmFsPzogYm9vbGVhbjtcbiAgcGFzdFByZXNlbnRTaGFyZUJ1ZmZlcjogYm9vbGVhbjtcbiAgbWFza0ZpbHRlclZhbHVlPzogbnVtYmVyO1xuICBtYXNrVHlwZTogQXR0ZW50aW9uTWFza1R5cGU7XG4gIHNjYWxlOiBudW1iZXI7XG4gIGJyb2FkY2FzdFJlc1Bvc0JpYXM6IGJvb2xlYW47XG4gIHBhc3NQYXN0SW5LdjogYm9vbGVhbjtcbiAgcWt2Rm9ybWF0OiBBdHRlbnRpb25Ra3ZGb3JtYXQ7XG4gIHNvZnRjYXA/OiBudW1iZXI7XG4gIGRvUm90YXJ5PzogbnVtYmVyO1xuICByb3RhcnlJbnRlckxlYXZlZD86IG51bWJlcjtcbiAgc29tbW9vdGhTb2Z0bWF4PzogbnVtYmVyO1xuICBsb2NhbFdpbmRvd3NTaXplPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0dGVudGlvbkF0dHJzIHtcbiAgbnVtSGVhZHM6IG51bWJlcjtcbiAgaXNVbmlkaXJlY3Rpb25hbDogbnVtYmVyO1xuICBtYXNrRmlsdGVyVmFsdWU6IG51bWJlcjtcbiAgc2NhbGU6IG51bWJlcjtcbiAgZG9Sb3Rhcnk6IG51bWJlcjtcbiAgcWt2SGlkZGVuU2l6ZXM6IG51bWJlcltdO1xuICBwYXN0UHJlc2VudFNoYXJlQnVmZmVyOiBib29sZWFuO1xufVxuXG5jb25zdCB2YWxpZGF0ZUF0dGVudGlvbklucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogQXR0ZW50aW9uQXR0cnMpOiBBdHRlbnRpb25QYXJhbWV0ZXJzID0+IHtcbiAgLy8gQWJicmV2aWF0aW9uIGFuZCBNZWFuaW5nczpcbiAgLy8gICBCOiAgICBiYXRjaF9zaXplXG4gIC8vICAgUzogICAgc2VxdWVuY2VfbGVuZ3RoIChpbnB1dCBzZXF1ZW5jZSBsZW5ndGggb2YgcXVlcnkpXG4gIC8vICAgUDogICAgcGFzdF9zZXF1ZW5jZV9sZW5ndGggKHBhc3Qgc2VxdWVuY2UgbGVuZ3RoIG9mIGtleSBvciB2YWx1ZSlcbiAgLy8gICBMOiAgICBrdl9zZXF1ZW5jZV9sZW5ndGggKGlucHV0IHNlcXVlbmNlIGxlbmd0aCBvZiBrZXkgb3IgdmFsdWUpXG4gIC8vICAgTTogICAgbWF4X3NlcXVlbmNlX2xlbmd0aFxuICAvLyAgIFQ6ICAgIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCA9IHBhc3Rfc2VxdWVuY2VfbGVuZ3RoICsga3Zfc2VxdWVuY2VfbGVuZ3RoXG4gIC8vICAgTjogICAgbnVtX2hlYWRzXG4gIC8vICAgSDogICAgaGVhZCBzaXplIGZvciBRIGFuZCBLLCBha2EgcV9oZWFkX3NpemUgb3Iga19oZWFkX3NpemUgb3IgcWtfaGVhZF9zaXplXG4gIC8vICAgSF92OiAgdl9oZWFkX3NpemVcbiAgLy8gICBEX2k6ICBpbnB1dCBoaWRkZW4gc2l6ZVxuICAvLyAgIEQ6ICAgIGhpZGRlbiBzaXplIGZvciBRIGFuZCBLIChEID0gTiAqIEgpLCBha2EgcV9oaWRkZW5fc2l6ZSBvciBrX2hpZGRlbl9zaXplIG9yIHFrX2hpZGRlbl9zaXplXG4gIC8vICAgRF92OiAgdl9oaWRkZW5fc2l6ZSA9IG51bV9oZWFkcyAqIHZfaGVhZF9zaXplXG5cbiAgLy8gV2hlbiBwYXN0IHN0YXRlIGlzIHVzZWQsIFEsIEsgYW5kIFYgc2hvdWxkIGhhdmUgc2FtZSBoaWRkZW4gc2l6ZSAodW5sZXNzIHdlIHNwbGl0IGl0IGludG8gcGFzdF9rZXkgYW5kIHBhc3RfdmFsdWUpLlxuXG4gIC8vIElucHV0IHNoYXBlczpcbiAgLy8gICBpbnB1dCAgICAgICAgKFEvSy9WKSAgICA6IChCLCBTLCBEX2kpXG4gIC8vICAgd2VpZ2h0cyAgICAgIChRL0svVikgICAgOiAoRF9pLCBEICsgRCArIERfdilcbiAgLy8gICBiaWFzICAgICAgICAgKFEvSy9WKSAgICA6IChEICsgRCArIERfdilcbiAgLy8gICBtYXNrX2luZGV4ICAgICAgICAgICAgICA6IHNlZSBiZWxvd1xuICAvLyAgIHBhc3QgICAgICAgICAoSy9WKSAgICAgIDogKDIsIEIsIE4sIFAsIEgpIG9yIE5VTExcbiAgLy8gICBhdHRlbnRpb25fYmlhcyAgICAgICAgICA6IChCLCBOLCBTLCBUKSBvciBOVUxMXG5cbiAgLy8gRm9yIG1hc2tfaW5kZXgsIHRoZSBmb2xsb3dpbmcgc2hhcGVzIGFyZSBzdXBwb3J0ZWQ6XG4gIC8vICAgICBOVUxMLCAoQiwgMSksICgxLCAxKVxuICAvLyAgICAgKEIpLCAoMiAqIEIpLCAoMyAqIEIgKyAyKVxuICAvLyAgICAgKEIsIFQpXG4gIC8vICAgICAoQiwgUywgVClcbiAgLy8gICAgIChCLCAxLCBNLCBNKVxuICAvL1xuICAvLyBXaGVuIGEgbW9kZWwgaXMgcHJ1bmVkIChsaWtlIHNvbWUgYXR0ZW50aW9uIGhlYWRzIGFyZSByZW1vdmVkIGluIFEvSy9WKSwgaW5wdXRfaGlkZGVuX3NpemUgY291bGQgYmUgbGFyZ2VyXG4gIC8vIHRoYW4gaGlkZGVuIGRpbWVuc2lvbiBvZiBRLCBLIGFuZCBWLlxuXG4gIGNvbnN0IGlucHV0ID0gaW5wdXRzWzBdO1xuICBjb25zdCB3ZWlnaHRzID0gaW5wdXRzWzFdO1xuICBjb25zdCBiaWFzID0gaW5wdXRzWzJdO1xuICBjb25zdCBtYXNrSW5kZXggPSBpbnB1dHNbM107XG4gIGNvbnN0IHBhc3QgPSBpbnB1dHNbNF07XG4gIGNvbnN0IGF0dGVudGlvbkJpYXMgPSBpbnB1dHNbNV07XG5cbiAgaWYgKHBhc3QgJiYgYXR0ZW50aW9uQmlhcykge1xuICAgIHRocm93IG5ldyBFcnJvcignQXR0ZW50aW9uIGNhbm5vdCBoYXZlIGJvdGggcGFzdCBhbmQgYXR0ZW50aW9uX2JpYXMnKTtcbiAgfVxuXG4gIGlmIChpbnB1dC5kaW1zLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJpbnB1dFwiIG11c3QgaGF2ZSAzIGRpbWVuc2lvbnMnKTtcbiAgfVxuXG4gIGNvbnN0IGJhdGNoU2l6ZSA9IGlucHV0LmRpbXNbMF07XG4gIGNvbnN0IHNlcXVlbmNlTGVuZ3RoID0gaW5wdXQuZGltc1sxXTtcbiAgY29uc3QgaW5wdXRIaWRkZW5TaXplID0gaW5wdXQuZGltc1syXTtcblxuICBpZiAoYmlhcy5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJiaWFzXCIgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAxIGRpbWVuc2lvbnMnKTtcbiAgfVxuXG4gIGlmICh3ZWlnaHRzLmRpbXMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcIndlaWdodHNcIiBpcyBleHBlY3RlZCB0byBoYXZlIDIgZGltZW5zaW9ucycpO1xuICB9XG5cbiAgaWYgKHdlaWdodHMuZGltc1swXSAhPT0gaW5wdXRIaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCAxIGRpbWVuc2lvbiAwIHNob3VsZCBoYXZlIHNhbWUgbGVuZ3RoIGFzIGRpbWVuc2lvbiAyIG9mIGlucHV0IDAnKTtcbiAgfVxuXG4gIGlmIChiaWFzLmRpbXNbMF0gIT09IHdlaWdodHMuZGltc1sxXSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJiaWFzXCIgZGltZW5zaW9uIDAgc2hvdWxkIGhhdmUgc2FtZSBsZW5ndGggYXMgZGltZW5zaW9uIDEgb2YgaW5wdXQgXCJ3ZWlnaHRzXCInKTtcbiAgfVxuXG4gIGxldCBxSGlkZGVuU2l6ZSA9IGJpYXMuZGltc1swXSAvIDM7XG4gIGxldCBrSGlkZGVuU2l6ZSA9IHFIaWRkZW5TaXplO1xuICBsZXQgdkhpZGRlblNpemUgPSBrSGlkZGVuU2l6ZTtcbiAgaWYgKGF0dHJpYnV0ZXMucWt2SGlkZGVuU2l6ZXMubGVuZ3RoID4gMCkge1xuICAgIGlmIChhdHRyaWJ1dGVzLnFrdkhpZGRlblNpemVzLmxlbmd0aCAhPT0gMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdxa3ZfaGlkZGVuX3NpemVzIGF0dHJpYnV0ZSBzaG91bGQgaGF2ZSAzIGVsZW1lbnRzJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc3ogb2YgYXR0cmlidXRlcy5xa3ZIaWRkZW5TaXplcykge1xuICAgICAgaWYgKHN6ICUgYXR0cmlidXRlcy5udW1IZWFkcyAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Frdl9oaWRkZW5fc2l6ZXMgc2hvdWxkIGJlIGRpdmlzaWJsZSBieSBudW1faGVhZHMnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBxSGlkZGVuU2l6ZSA9IGF0dHJpYnV0ZXMucWt2SGlkZGVuU2l6ZXNbMF07XG4gICAga0hpZGRlblNpemUgPSBhdHRyaWJ1dGVzLnFrdkhpZGRlblNpemVzWzFdO1xuICAgIHZIaWRkZW5TaXplID0gYXR0cmlidXRlcy5xa3ZIaWRkZW5TaXplc1syXTtcbiAgfVxuXG4gIGNvbnN0IGt2U2VxdWVuY2VMZW5ndGggPSBzZXF1ZW5jZUxlbmd0aDtcblxuICBpZiAocUhpZGRlblNpemUgIT09IGtIaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdxa3ZfaGlkZGVuX3NpemVzIGZpcnN0IGVsZW1lbnQgc2hvdWxkIGJlIHNhbWUgYXMgdGhlIHNlY29uZCcpO1xuICB9XG5cbiAgaWYgKGJpYXMuZGltc1swXSAhPT0gcUhpZGRlblNpemUgKyBrSGlkZGVuU2l6ZSArIHZIaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcImJpYXNcIiBkaW1lbnNpb24gMCBzaG91bGQgaGF2ZSBzYW1lIGxlbmd0aCBhcyBzdW0gb2YgUS9LL1YgaGlkZGVuIHNpemVzJyk7XG4gIH1cblxuICBsZXQgcGFzdFNlcXVlbmNlTGVuZ3RoID0gMDtcbiAgaWYgKHBhc3QpIHtcbiAgICBpZiAoa0hpZGRlblNpemUgIT09IHZIaWRkZW5TaXplKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdFwiIGV4cGVjdCBrX2hpZGRlbl9zaXplID09IHZfaGlkZGVuX3NpemUnKTtcbiAgICB9XG4gICAgaWYgKHBhc3QuZGltcy5sZW5ndGggIT09IDUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0XCIgbXVzdCBoYXZlIDUgZGltZW5zaW9ucycpO1xuICAgIH1cbiAgICBpZiAocGFzdC5kaW1zWzBdICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdFwiIGZpcnN0IGRpbWVuc2lvbiBtdXN0IGJlIDInKTtcbiAgICB9XG4gICAgaWYgKHBhc3QuZGltc1sxXSAhPT0gYmF0Y2hTaXplKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdFwiIHNlY29uZCBkaW1lbnNpb24gbXVzdCBiZSBiYXRjaF9zaXplJyk7XG4gICAgfVxuICAgIGlmIChwYXN0LmRpbXNbMl0gIT09IGF0dHJpYnV0ZXMubnVtSGVhZHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0XCIgdGhpcmQgZGltZW5zaW9uIG11c3QgYmUgbnVtX2hlYWRzJyk7XG4gICAgfVxuICAgIGlmIChwYXN0LmRpbXNbNF0gIT09IGtIaWRkZW5TaXplIC8gYXR0cmlidXRlcy5udW1IZWFkcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInBhc3RcIiBmaWZ0aCBkaW1lbnNpb24gbXVzdCBiZSBrX2hpZGRlbl9zaXplIC8gbnVtX2hlYWRzJyk7XG4gICAgfVxuXG4gICAgaWYgKCFhdHRyaWJ1dGVzLnBhc3RQcmVzZW50U2hhcmVCdWZmZXIpIHtcbiAgICAgIHBhc3RTZXF1ZW5jZUxlbmd0aCA9IHBhc3QuZGltc1szXTtcbiAgICB9XG4gICAgLy8gVE9ETzogaGFuZGxlIHBhc3Rfc2VxX2xlblxuICB9XG5cbiAgY29uc3QgdG90YWxTZXF1ZW5jZUxlbmd0aCA9IGt2U2VxdWVuY2VMZW5ndGggKyBwYXN0U2VxdWVuY2VMZW5ndGg7XG4gIGNvbnN0IG1heFNlcXVlbmNlTGVuZ3RoID0gLTE7XG5cbiAgY29uc3QgbWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5ub25lO1xuICBpZiAobWFza0luZGV4KSB7XG4gICAgLy8gbWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5NQVNLX1VOS05PV047XG4gICAgLy8gVE9ETzogaGFuZGxlIG1hc2tcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01hc2sgbm90IHN1cHBvcnRlZCcpO1xuICB9XG5cbiAgaWYgKHBhc3QpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Bhc3QgaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG5cbiAgaWYgKGF0dGVudGlvbkJpYXMpIHtcbiAgICBpZiAoYXR0ZW50aW9uQmlhcy5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcImF0dGVudGlvbl9iaWFzXCIgbXVzdCBoYXZlIDQgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIC8vIFRPRE86IHN1cHBvcnQgYnJvYWRjYXN0aW5nIHRoZSBmaXJzdCBhbmQgc2Vjb25kIGRpbWVuc2lvbnMgb2YgYXR0ZW50aW9uX2JpYXNcbiAgICBpZiAoXG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbMF0gIT09IGJhdGNoU2l6ZSB8fFxuICAgICAgYXR0ZW50aW9uQmlhcy5kaW1zWzFdICE9PSBhdHRyaWJ1dGVzLm51bUhlYWRzIHx8XG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbMl0gIT09IHNlcXVlbmNlTGVuZ3RoIHx8XG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbM10gIT09IHRvdGFsU2VxdWVuY2VMZW5ndGhcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0IFwiYXR0ZW50aW9uX2JpYXNcIiBzaGFwZSAoYmF0Y2hfc2l6ZSwgbnVtX2hlYWRzLCBzZXF1ZW5jZV9sZW5ndGgsIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhdGNoU2l6ZSxcbiAgICBzZXF1ZW5jZUxlbmd0aCxcbiAgICBwYXN0U2VxdWVuY2VMZW5ndGgsXG4gICAga3ZTZXF1ZW5jZUxlbmd0aCxcbiAgICB0b3RhbFNlcXVlbmNlTGVuZ3RoLFxuICAgIG1heFNlcXVlbmNlTGVuZ3RoLFxuICAgIGlucHV0SGlkZGVuU2l6ZSxcbiAgICBoaWRkZW5TaXplOiBxSGlkZGVuU2l6ZSxcbiAgICB2SGlkZGVuU2l6ZSxcbiAgICBoZWFkU2l6ZTogTWF0aC5mbG9vcihxSGlkZGVuU2l6ZSAvIGF0dHJpYnV0ZXMubnVtSGVhZHMpLFxuICAgIHZIZWFkU2l6ZTogTWF0aC5mbG9vcih2SGlkZGVuU2l6ZSAvIGF0dHJpYnV0ZXMubnVtSGVhZHMpLFxuICAgIG51bUhlYWRzOiBhdHRyaWJ1dGVzLm51bUhlYWRzLFxuICAgIGlzVW5pZGlyZWN0aW9uYWw6IGZhbHNlLFxuICAgIHBhc3RQcmVzZW50U2hhcmVCdWZmZXI6IGZhbHNlLFxuICAgIG1hc2tGaWx0ZXJWYWx1ZTogYXR0cmlidXRlcy5tYXNrRmlsdGVyVmFsdWUsXG4gICAgbWFza1R5cGUsXG4gICAgc2NhbGU6IGF0dHJpYnV0ZXMuc2NhbGUsXG4gICAgYnJvYWRjYXN0UmVzUG9zQmlhczogZmFsc2UsXG4gICAgcGFzc1Bhc3RJbkt2OiBmYWxzZSxcbiAgICBxa3ZGb3JtYXQ6IEF0dGVudGlvblFrdkZvcm1hdC5xa3ZCTlNILFxuICB9O1xufTtcblxuY29uc3QgaW5pdFZhclN0dWIgPSAoXG4gIHNlcUxlbnNJbnB1dDogSW5kaWNlc0hlbHBlciB8IHVuZGVmaW5lZCxcbiAgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0OiBJbmRpY2VzSGVscGVyIHwgdW5kZWZpbmVkLFxuICBpbml0UGFzdFNlcXVlbmNlTGVuZ3RoOiBib29sZWFuLFxuKSA9PiB7XG4gIC8vIEluIHRoZSBjYXNlIG9mIEdRQSwgcmVkZWZpbmUgdG90YWxfc2VxdWVuY2VfbGVuZ3RoLCBwcmVzZW50X3NlcXVlbmNlX2xlbmd0aCBhbmQgcGFzdF9zZXF1ZW5jZV9sZW5ndGggYmFzZWQgb24gc2VxbGVuX2sgaW5wdXRcbiAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCAmJiBzZXFMZW5zSW5wdXQpIHtcbiAgICByZXR1cm4gYFxuICAgICAgbGV0IHRvdGFsX3NlcXVlbmNlX2xlbmd0aF9pbnB1dCA9IHUzMigke3RvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dC5nZXRCeU9mZnNldCgnMCcpfSk7XG4gICAgICBsZXQgcHJlc2VudF9zZXF1ZW5jZV9sZW5ndGggPSBtYXgodG90YWxfc2VxdWVuY2VfbGVuZ3RoX2lucHV0LCB1bmlmb3Jtcy5wYXN0X3NlcXVlbmNlX2xlbmd0aCk7XG4gICAgICBsZXQgaXNfc3Vic2VxdWVudF9wcm9tcHQ6IGJvb2wgPSBzZXF1ZW5jZV9sZW5ndGggPiAxICYmIHNlcXVlbmNlX2xlbmd0aCAhPSB0b3RhbF9zZXF1ZW5jZV9sZW5ndGhfaW5wdXQ7XG4gICAgICBsZXQgaXNfZmlyc3RfcHJvbXB0OiBib29sID0gaXNfc3Vic2VxdWVudF9wcm9tcHQgPT0gZmFsc2UgJiYgc2VxdWVuY2VfbGVuZ3RoID09IHRvdGFsX3NlcXVlbmNlX2xlbmd0aF9pbnB1dDtcbiAgICAgIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCA9IHUzMigke3NlcUxlbnNJbnB1dD8uZ2V0QnlPZmZzZXQoJ2JhdGNoSWR4Jyl9KSArIDE7XG4gICAgICB2YXIgcGFzdF9zZXF1ZW5jZV9sZW5ndGg6IHUzMiA9IDA7XG4gICAgICBpZiAoaXNfZmlyc3RfcHJvbXB0ID09IGZhbHNlKSB7XG4gICAgICAgIHBhc3Rfc2VxdWVuY2VfbGVuZ3RoID0gdG90YWxfc2VxdWVuY2VfbGVuZ3RoIC0gc2VxdWVuY2VfbGVuZ3RoO1xuICAgICAgfVxuICAgICAgIGA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGBcbiAgICAke2luaXRQYXN0U2VxdWVuY2VMZW5ndGggPyAnbGV0IHBhc3Rfc2VxdWVuY2VfbGVuZ3RoID0gdW5pZm9ybXMucGFzdF9zZXF1ZW5jZV9sZW5ndGgnIDogJyd9O1xuICAgIGxldCBwcmVzZW50X3NlcXVlbmNlX2xlbmd0aCA9IHRvdGFsX3NlcXVlbmNlX2xlbmd0aDtcbiAgICBgO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVJblBsYWNlU29mdG1heFByb2dyYW1JbmZvID0gKFxuICBpbnB1dDogVGVuc29yVmlldyxcbiAgYmF0Y2hTaXplOiBudW1iZXIsXG4gIG51bUhlYWRzOiBudW1iZXIsXG4gIHBhc3RTZXF1ZW5jZUxlbmd0aDogbnVtYmVyLFxuICBzZXF1ZW5jZUxlbmd0aDogbnVtYmVyLFxuICB0b3RhbFNlcXVlbmNlTGVuZ3RoOiBudW1iZXIsXG4gIHNlcUxlbnM6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQsXG4gIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dDogVGVuc29yVmlldyB8IHVuZGVmaW5lZCxcbikgPT4ge1xuICAvLyBTZXQgY29tcG9uZW50cyB0byAxIGlmIHNlcUxlbnMgaXMgc3BlY2lmaWVkLCBpLmUuIEdyb3VwUXVlcnlBdHRlbnRpb24uXG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKHNlcUxlbnMgPyAxIDogdG90YWxTZXF1ZW5jZUxlbmd0aCk7XG4gIGxldCBXRyA9IDY0O1xuICBjb25zdCB0b3RhbFNlcXVlbmNlTGVuZ3RoQ29tcCA9IHRvdGFsU2VxdWVuY2VMZW5ndGggLyBjb21wb25lbnRzO1xuICBpZiAodG90YWxTZXF1ZW5jZUxlbmd0aENvbXAgPCBXRykge1xuICAgIFdHID0gMzI7XG4gIH1cbiAgY29uc3QgZWxlbWVudHNQZXJUaHJlYWQgPSBNYXRoLmNlaWwodG90YWxTZXF1ZW5jZUxlbmd0aCAvIGNvbXBvbmVudHMgLyBXRyk7XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYmF0Y2hTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG51bUhlYWRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHBhc3RTZXF1ZW5jZUxlbmd0aCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBzZXF1ZW5jZUxlbmd0aCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiB0b3RhbFNlcXVlbmNlTGVuZ3RoQ29tcCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBlbGVtZW50c1BlclRocmVhZCB9LFxuICBdO1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShpbnB1dC5kYXRhVHlwZSwgY29tcG9uZW50cyk7XG4gIGNvbnN0IGYzMlR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlKERhdGFUeXBlLmZsb2F0LCBjb21wb25lbnRzKTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3R5cGUnXTtcbiAgaWYgKHNlcUxlbnMpIHtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCd0eXBlJyk7XG4gIH1cbiAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCkge1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3R5cGUnKTtcbiAgfVxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBpbnB1dEhlbHBlciA9IG91dHB1dFZhcmlhYmxlKCd4JywgaW5wdXQuZGF0YVR5cGUsIGlucHV0LmRpbXMsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGlucHV0SGVscGVycyA9IFtpbnB1dEhlbHBlcl07XG4gICAgY29uc3Qgc2VxTGVuc0lucHV0SGVscGVyID0gc2VxTGVucyA/IGlucHV0VmFyaWFibGUoJ3NlcV9sZW5zJywgc2VxTGVucy5kYXRhVHlwZSwgc2VxTGVucy5kaW1zKSA6IHVuZGVmaW5lZDtcbiAgICBpZiAoc2VxTGVuc0lucHV0SGVscGVyKSB7XG4gICAgICBpbnB1dEhlbHBlcnMucHVzaChzZXFMZW5zSW5wdXRIZWxwZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dEhlbHBlciA9IHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dFxuICAgICAgPyBpbnB1dFZhcmlhYmxlKCd0b3RhbF9zZXF1ZW5jZV9sZW5ndGhfaW5wdXQnLCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQuZGF0YVR5cGUsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dC5kaW1zKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dEhlbHBlcikge1xuICAgICAgaW5wdXRIZWxwZXJzLnB1c2godG90YWxTZXF1ZW5jZUxlbmd0aElucHV0SGVscGVyKTtcbiAgICB9XG4gICAgY29uc3QgZWxlbVZhbHVlVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoaW5wdXQuZGF0YVR5cGUpO1xuICAgIGNvbnN0IHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSA9IFtcbiAgICAgIHsgbmFtZTogJ2JhdGNoX3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnbnVtX2hlYWRzJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3Bhc3Rfc2VxdWVuY2VfbGVuZ3RoJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3NlcXVlbmNlX2xlbmd0aCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICd0b3RhbF9zZXF1ZW5jZV9sZW5ndGgnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnZWxlbWVudHNfcGVyX3RocmVhZCcsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcblxuICAgIHJldHVybiBgXG4gIHZhcjx3b3JrZ3JvdXA+IHRocmVhZF9tYXg6IGFycmF5PGYzMiwgJHtXR30+O1xuICB2YXI8d29ya2dyb3VwPiB0aHJlYWRfc3VtOiBhcnJheTxmMzIsICR7V0d9PjtcbiAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dEhlbHBlcnMpfVxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoW1dHLCAxLCAxXSl9XG4gICAgbGV0IGJhdGNoSWR4ID0gd29ya2dyb3VwX2lkLnogLyB1bmlmb3Jtcy5udW1faGVhZHM7XG4gICAgbGV0IGhlYWRJZHggPSB3b3JrZ3JvdXBfaWQueiAlIHVuaWZvcm1zLm51bV9oZWFkcztcbiAgICBsZXQgc2VxdWVuY2VfbGVuZ3RoID0gdW5pZm9ybXMuc2VxdWVuY2VfbGVuZ3RoO1xuICAgIHZhciB0b3RhbF9zZXF1ZW5jZV9sZW5ndGggPSB1bmlmb3Jtcy50b3RhbF9zZXF1ZW5jZV9sZW5ndGg7XG4gICAgJHtpbml0VmFyU3R1YihzZXFMZW5zSW5wdXRIZWxwZXIsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dEhlbHBlciwgZmFsc2UpfVxuICAgIGxldCBsb2NhbF9vZmZzZXQgPSBsb2NhbF9pZHggKiB1bmlmb3Jtcy5lbGVtZW50c19wZXJfdGhyZWFkO1xuICAgIGxldCBvZmZzZXQgPSAoZ2xvYmFsX2lkeCAvICR7V0d9KSAqIHVuaWZvcm1zLnRvdGFsX3NlcXVlbmNlX2xlbmd0aCArIGxvY2FsX29mZnNldDtcbiAgICBsZXQgc2VxX2NhdXNhbF9sZW5ndGggPSAke3NlcUxlbnMgPyAndTMyKHBhc3Rfc2VxdWVuY2VfbGVuZ3RoICsgd29ya2dyb3VwX2lkLnkgKyAxKScgOiAndG90YWxfc2VxdWVuY2VfbGVuZ3RoJ307XG4gICAgdmFyIHRocmVhZF9tYXhfdmVjdG9yID0gJHtmMzJUeXBlfSgtMy40MDI4MjNlKzM4Zik7XG4gICAgZm9yICh2YXIgaTogdTMyID0gMDsgaSA8IHVuaWZvcm1zLmVsZW1lbnRzX3Blcl90aHJlYWQgJiYgaSArIGxvY2FsX29mZnNldCA8IHNlcV9jYXVzYWxfbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRocmVhZF9tYXhfdmVjdG9yID0gbWF4KCR7ZjMyVHlwZX0oeFtvZmZzZXQgKyBpXSksIHRocmVhZF9tYXhfdmVjdG9yKTtcbiAgICB9XG4gICAgdGhyZWFkX21heFtsb2NhbF9pZHhdID0gJHsoKCkgPT4ge1xuICAgICAgc3dpdGNoIChjb21wb25lbnRzKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICByZXR1cm4gJ3RocmVhZF9tYXhfdmVjdG9yJztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHJldHVybiAnbWF4KHRocmVhZF9tYXhfdmVjdG9yLngsIHRocmVhZF9tYXhfdmVjdG9yLnkpJztcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHJldHVybiAnbWF4KG1heCh0aHJlYWRfbWF4X3ZlY3Rvci54LCB0aHJlYWRfbWF4X3ZlY3Rvci55KSwgbWF4KHRocmVhZF9tYXhfdmVjdG9yLnosIHRocmVhZF9tYXhfdmVjdG9yLncpKSc7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBjb21wb25lbnRzOiAke2NvbXBvbmVudHN9YCk7XG4gICAgICB9XG4gICAgfSkoKX07XG4gICAgd29ya2dyb3VwQmFycmllcigpO1xuXG4gICAgdmFyIG1heF92YWx1ZSA9ICBmMzIoLTMuNDAyODIzZSszOGYpO1xuICAgIGZvciAodmFyIGkgPSAwdTsgaSA8ICR7V0d9OyBpKyspIHtcbiAgICAgIG1heF92YWx1ZSA9IG1heCh0aHJlYWRfbWF4W2ldLCBtYXhfdmFsdWUpO1xuICAgIH1cblxuICAgIHZhciBzdW1fdmVjdG9yID0gJHtmMzJUeXBlfSgwKTtcbiAgICBmb3IgKHZhciBpOiB1MzIgPSAwOyBpIDwgdW5pZm9ybXMuZWxlbWVudHNfcGVyX3RocmVhZCAmJiBpICsgbG9jYWxfb2Zmc2V0IDwgc2VxX2NhdXNhbF9sZW5ndGg7IGkrKykge1xuICAgICAgc3VtX3ZlY3RvciArPSBleHAoJHtmMzJUeXBlfSh4W29mZnNldCArIGldKSAtIG1heF92YWx1ZSk7XG4gICAgfVxuICAgIHRocmVhZF9zdW1bbG9jYWxfaWR4XSA9ICR7KCgpID0+IHtcbiAgICAgIHN3aXRjaCAoY29tcG9uZW50cykge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgcmV0dXJuICdzdW1fdmVjdG9yJztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHJldHVybiAnc3VtX3ZlY3Rvci54ICsgc3VtX3ZlY3Rvci55JztcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHJldHVybiAnc3VtX3ZlY3Rvci54ICsgc3VtX3ZlY3Rvci55ICsgc3VtX3ZlY3Rvci56ICsgc3VtX3ZlY3Rvci53JztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGNvbXBvbmVudHM6ICR7Y29tcG9uZW50c31gKTtcbiAgICAgIH1cbiAgICB9KSgpfTtcbiAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICB2YXIgc3VtOiBmMzIgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwdTsgaSA8ICR7V0d9OyBpKyspIHtcbiAgICAgIHN1bSArPSB0aHJlYWRfc3VtW2ldO1xuICAgIH1cblxuICAgIGlmIChzdW0gPT0gMCkge1xuICAgICAgZm9yICh2YXIgaTogdTMyID0gMDsgaSA8IHVuaWZvcm1zLmVsZW1lbnRzX3Blcl90aHJlYWQgJiYgaSArIGxvY2FsX29mZnNldCA8IHNlcV9jYXVzYWxfbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgeFtvZmZzZXQgKyBpXSA9ICR7aW5wdXRIZWxwZXIudHlwZS52YWx1ZX0oJHtlbGVtVmFsdWVUeXBlfSgxLjApIC8gJHtlbGVtVmFsdWVUeXBlfShzZXFfY2F1c2FsX2xlbmd0aCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBpOiB1MzIgPSAwOyBpIDwgdW5pZm9ybXMuZWxlbWVudHNfcGVyX3RocmVhZCAmJiBpICsgbG9jYWxfb2Zmc2V0IDwgc2VxX2NhdXNhbF9sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZjMyaW5wdXQgPSAke2YzMlR5cGV9KHhbb2Zmc2V0ICsgaV0pO1xuICAgICAgICB4W29mZnNldCArIGldID0gJHtpbnB1dEhlbHBlci50eXBlLnZhbHVlfShleHAoZjMyaW5wdXQgLSBtYXhfdmFsdWUpIC8gc3VtKTtcbiAgICAgIH1cbiAgICB9XG4gICAgICAke1xuICAgICAgICBzZXFMZW5zXG4gICAgICAgICAgPyBgXG4gICAgICAgIGZvciAodmFyIHRvdGFsX3NlcV9pZDogdTMyID0gc2VxX2NhdXNhbF9sZW5ndGg7IHRvdGFsX3NlcV9pZCArIGxvY2FsX29mZnNldCA8IHVuaWZvcm1zLnRvdGFsX3NlcXVlbmNlX2xlbmd0aDsgdG90YWxfc2VxX2lkKyspIHtcbiAgICAgICAgICB4W29mZnNldCArIHRvdGFsX3NlcV9pZF0gPSAke2lucHV0SGVscGVyLnR5cGUudmFsdWV9KCR7ZWxlbVZhbHVlVHlwZX0oMCkpO1xuICAgICAgICB9YFxuICAgICAgICAgIDogJydcbiAgICAgIH07XG4gIH1gO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0F0dGVudGlvblByb2JzU29mdG1heCcsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7V0d9OyR7ZGF0YVR5cGV9OyR7Y29tcG9uZW50c31gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW10sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IDEsIHk6IHNlcXVlbmNlTGVuZ3RoLCB6OiBiYXRjaFNpemUgKiBudW1IZWFkcyB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlQXR0ZW50aW9uUHJvYnNQcm9ncmFtSW5mbyA9IChcbiAgb3V0cHV0Q291bnQ6IG51bWJlcixcbiAgcTogVGVuc29yVmlldyxcbiAga2V5OiBUZW5zb3JWaWV3LFxuICBwYXN0S2V5OiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkLFxuICBhdHRlbnRpb25CaWFzOiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkLFxuICBwYXJhbWV0ZXJzOiBBdHRlbnRpb25QYXJhbWV0ZXJzLFxuICBwYXN0U2VxdWVuY2VMZW5ndGg6IG51bWJlcixcbiAgc2VxTGVuczogVGVuc29yVmlldyB8IHVuZGVmaW5lZCxcbiAgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0OiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkLFxuKSA9PiB7XG4gIGNvbnN0IHRvdGFsU2VxdWVuY2VMZW5ndGggPSBwYXN0U2VxdWVuY2VMZW5ndGggKyBwYXJhbWV0ZXJzLmt2U2VxdWVuY2VMZW5ndGg7XG4gIGNvbnN0IHByb2JzU2hhcGUgPSBbcGFyYW1ldGVycy5iYXRjaFNpemUsIHBhcmFtZXRlcnMubnVtSGVhZHMsIHBhcmFtZXRlcnMuc2VxdWVuY2VMZW5ndGgsIHRvdGFsU2VxdWVuY2VMZW5ndGhdO1xuICBjb25zdCBwcmVzZW50S2V5ID0gb3V0cHV0Q291bnQgPiAxICYmIHBhc3RLZXk7XG4gIGNvbnN0IGt2TnVtSGVhZHMgPSBwYXJhbWV0ZXJzLmt2TnVtSGVhZHMgPyBwYXJhbWV0ZXJzLmt2TnVtSGVhZHMgOiBwYXJhbWV0ZXJzLm51bUhlYWRzO1xuICBjb25zdCBwcmVzZW50S2V5U2hhcGUgPSBwcmVzZW50S2V5XG4gICAgPyBbcGFyYW1ldGVycy5iYXRjaFNpemUsIGt2TnVtSGVhZHMsIHRvdGFsU2VxdWVuY2VMZW5ndGgsIHBhcmFtZXRlcnMuaGVhZFNpemVdXG4gICAgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IG5SZXBzID0gcGFyYW1ldGVycy5uUmVwcyA/IHBhcmFtZXRlcnMublJlcHMgOiAxO1xuICAvLyBUT0RPOiBoYW5kbGUgbWFza1xuXG4gIGNvbnN0IGFscGhhID0gcGFyYW1ldGVycy5zY2FsZSA9PT0gMCA/IDEuMCAvIE1hdGguc3FydChwYXJhbWV0ZXJzLmhlYWRTaXplKSA6IHBhcmFtZXRlcnMuc2NhbGU7XG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKHBhcmFtZXRlcnMuaGVhZFNpemUpO1xuICBjb25zdCB2ZWN0b3JpemVkSGVhZFNpemUgPSBwYXJhbWV0ZXJzLmhlYWRTaXplIC8gY29tcG9uZW50cztcbiAgY29uc3QgVElMRV9TSVpFID0gMTI7XG4gIGNvbnN0IGRpc3BhdGNoID0ge1xuICAgIHg6IE1hdGguY2VpbCh0b3RhbFNlcXVlbmNlTGVuZ3RoIC8gVElMRV9TSVpFKSxcbiAgICB5OiBNYXRoLmNlaWwocGFyYW1ldGVycy5zZXF1ZW5jZUxlbmd0aCAvIFRJTEVfU0laRSksXG4gICAgejogcGFyYW1ldGVycy5iYXRjaFNpemUgKiBwYXJhbWV0ZXJzLm51bUhlYWRzLFxuICB9O1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHBhcmFtZXRlcnMuc2VxdWVuY2VMZW5ndGggfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogdmVjdG9yaXplZEhlYWRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHRvdGFsU2VxdWVuY2VMZW5ndGggfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1ldGVycy5udW1IZWFkcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXJhbWV0ZXJzLmhlYWRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogYWxwaGEgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFzdFNlcXVlbmNlTGVuZ3RoIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHBhcmFtZXRlcnMua3ZTZXF1ZW5jZUxlbmd0aCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBuUmVwcyB9LFxuICBdO1xuICAvLyBGZWVkIHBhc3RLZXkgdG8gdGhlIHNoYWRlci1jb2RlIG9ubHkgaWYgaXQgaXMgbm9uLXplcm8gYW5kIHByZXNlbnRLZXkgaXMgYmVpbmcgcHJvZHVjZWRcbiAgY29uc3QgZmVlZFBhc3RLZXkgPSBwcmVzZW50S2V5ICYmIHBhc3RLZXkgJiYgU2hhcGVVdGlsLnNpemUocGFzdEtleS5kaW1zKSA+IDA7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWyd0eXBlJywgJ3R5cGUnXTtcbiAgaWYgKGZlZWRQYXN0S2V5KSB7XG4gICAgaW5wdXREZXBlbmRlbmNpZXMucHVzaCgndHlwZScpO1xuICB9XG4gIGlmIChhdHRlbnRpb25CaWFzKSB7XG4gICAgaW5wdXREZXBlbmRlbmNpZXMucHVzaCgndHlwZScpO1xuICB9XG4gIGlmIChzZXFMZW5zKSB7XG4gICAgaW5wdXREZXBlbmRlbmNpZXMucHVzaCgndHlwZScpO1xuICB9XG4gIGlmICh0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQpIHtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCd0eXBlJyk7XG4gIH1cbiAgY29uc3Qgb3V0cHV0cyA9IFt7IGRpbXM6IHByb2JzU2hhcGUsIGRhdGFUeXBlOiBxLmRhdGFUeXBlLCBncHVEYXRhVHlwZTogR3B1RGF0YVR5cGUuZGVmYXVsdCB9XTtcbiAgaWYgKHByZXNlbnRLZXkpIHtcbiAgICBvdXRwdXRzLnB1c2goeyBkaW1zOiBwcmVzZW50S2V5U2hhcGUhLCBkYXRhVHlwZTogcS5kYXRhVHlwZSwgZ3B1RGF0YVR5cGU6IEdwdURhdGFUeXBlLmRlZmF1bHQgfSk7XG4gIH1cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgcUlucHV0ID0gaW5wdXRWYXJpYWJsZSgncScsIHEuZGF0YVR5cGUsIHEuZGltcywgY29tcG9uZW50cyk7XG4gICAgY29uc3Qga0lucHV0ID0gaW5wdXRWYXJpYWJsZSgna2V5Jywga2V5LmRhdGFUeXBlLCBrZXkuZGltcywgY29tcG9uZW50cyk7XG4gICAgY29uc3QgaW5wdXRWYXJzID0gW3FJbnB1dCwga0lucHV0XTtcbiAgICBpZiAoZmVlZFBhc3RLZXkpIHtcbiAgICAgIGNvbnN0IHBhc3RLZXlJbnB1dCA9IGlucHV0VmFyaWFibGUoJ3Bhc3Rfa2V5JywgcGFzdEtleS5kYXRhVHlwZSwgcGFzdEtleS5kaW1zLCBjb21wb25lbnRzKTtcbiAgICAgIGlucHV0VmFycy5wdXNoKHBhc3RLZXlJbnB1dCk7XG4gICAgfVxuICAgIGlmIChhdHRlbnRpb25CaWFzKSB7XG4gICAgICBpbnB1dFZhcnMucHVzaChpbnB1dFZhcmlhYmxlKCdhdHRlbnRpb25fYmlhcycsIGF0dGVudGlvbkJpYXMuZGF0YVR5cGUsIGF0dGVudGlvbkJpYXMuZGltcykpO1xuICAgIH1cbiAgICBjb25zdCBzZXFMZW5zSW5wdXRWYXJpYWJsZSA9IHNlcUxlbnMgPyBpbnB1dFZhcmlhYmxlKCdzZXFfbGVucycsIHNlcUxlbnMuZGF0YVR5cGUsIHNlcUxlbnMuZGltcykgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHNlcUxlbnNJbnB1dFZhcmlhYmxlKSB7XG4gICAgICBpbnB1dFZhcnMucHVzaChzZXFMZW5zSW5wdXRWYXJpYWJsZSk7XG4gICAgfVxuICAgIGNvbnN0IHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dFZhcmlhYmxlID0gdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0XG4gICAgICA/IGlucHV0VmFyaWFibGUoJ3RvdGFsX3NlcXVlbmNlX2xlbmd0aF9pbnB1dCcsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dC5kYXRhVHlwZSwgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0LmRpbXMpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICBpZiAodG90YWxTZXF1ZW5jZUxlbmd0aElucHV0VmFyaWFibGUpIHtcbiAgICAgIGlucHV0VmFycy5wdXNoKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dFZhcmlhYmxlKTtcbiAgICB9XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIHEuZGF0YVR5cGUsIHByb2JzU2hhcGUpO1xuICAgIGNvbnN0IG91dHB1dFZhcnMgPSBbb3V0cHV0XTtcbiAgICBpZiAocHJlc2VudEtleSkge1xuICAgICAgb3V0cHV0VmFycy5wdXNoKG91dHB1dFZhcmlhYmxlKCdwcmVzZW50X2tleScsIHEuZGF0YVR5cGUsIHByZXNlbnRLZXlTaGFwZSEsIGNvbXBvbmVudHMpKTtcbiAgICB9XG4gICAgY29uc3QgZjMyVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoRGF0YVR5cGUuZmxvYXQsIGNvbXBvbmVudHMpO1xuXG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnTScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdLJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ04nLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnbnVtX2hlYWRzJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2hlYWRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdhbHBoYScsIHR5cGU6ICdmMzInIGFzIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUgfSxcbiAgICAgIHsgbmFtZTogJ3Bhc3Rfc2VxdWVuY2VfbGVuZ3RoJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2t2X3NlcXVlbmNlX2xlbmd0aCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICduX3JlcHMnLCB0eXBlOiAndTMyJyB9LFxuICAgIF07XG4gICAgcmV0dXJuIGBcbiAgY29uc3QgVElMRV9TSVpFID0gJHtUSUxFX1NJWkV9dTtcblxuICB2YXI8d29ya2dyb3VwPiB0aWxlUTogYXJyYXk8JHtxSW5wdXQudHlwZS5zdG9yYWdlfSwgJHtUSUxFX1NJWkUgKiBUSUxFX1NJWkV9PjtcbiAgdmFyPHdvcmtncm91cD4gdGlsZUs6IGFycmF5PCR7cUlucHV0LnR5cGUuc3RvcmFnZX0sICR7VElMRV9TSVpFICogVElMRV9TSVpFfT47XG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJzLCAuLi5vdXRwdXRWYXJzKX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KFtUSUxFX1NJWkUsIFRJTEVfU0laRSwgMV0pfVxuICAgIC8vIHggaG9sZHMgdGhlIE4gYW5kIHkgaG9sZHMgdGhlIE1cbiAgICBsZXQgaGVhZElkeCA9IHdvcmtncm91cF9pZC56ICUgdW5pZm9ybXMubnVtX2hlYWRzO1xuICAgIGxldCBrdkhlYWRJZHggPSAke25SZXBzID09PSAxID8gJ2hlYWRJZHgnIDogJ2hlYWRJZHggLyB1bmlmb3Jtcy5uX3JlcHMnfTtcbiAgICBsZXQga3ZfbnVtX2hlYWRzID0gJHtuUmVwcyA9PT0gMSA/ICd1bmlmb3Jtcy5udW1faGVhZHMnIDogJ3VuaWZvcm1zLm51bV9oZWFkcyAvIHVuaWZvcm1zLm5fcmVwcyd9O1xuICAgIGxldCBiYXRjaElkeCA9IHdvcmtncm91cF9pZC56IC8gdW5pZm9ybXMubnVtX2hlYWRzO1xuICAgIGxldCBtID0gd29ya2dyb3VwX2lkLnkgKiBUSUxFX1NJWkU7XG4gICAgbGV0IG4gPSB3b3JrZ3JvdXBfaWQueCAqIFRJTEVfU0laRTtcbiAgICBsZXQgc2VxdWVuY2VfbGVuZ3RoID0gdW5pZm9ybXMuTTtcbiAgICB2YXIgdG90YWxfc2VxdWVuY2VfbGVuZ3RoID0gdW5pZm9ybXMuTjtcbiAgICAke2luaXRWYXJTdHViKHNlcUxlbnNJbnB1dFZhcmlhYmxlLCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXRWYXJpYWJsZSwgdHJ1ZSl9XG4gICAgbGV0IGFic0t2SGVhZElkeCA9IGJhdGNoSWR4ICoga3ZfbnVtX2hlYWRzICsga3ZIZWFkSWR4O1xuICAgIGxldCBxT2Zmc2V0ID0gd29ya2dyb3VwX2lkLnogKiB1bmlmb3Jtcy5NICogdW5pZm9ybXMuSyArIG0gKiB1bmlmb3Jtcy5LO1xuICAgICR7ZmVlZFBhc3RLZXkgJiYgcHJlc2VudEtleSA/ICdsZXQgcGFzdEtleU9mZnNldCA9IGFic0t2SGVhZElkeCAqIHVuaWZvcm1zLnBhc3Rfc2VxdWVuY2VfbGVuZ3RoICogdW5pZm9ybXMuSzsnIDogJyd9O1xuICAgIGxldCBrT2Zmc2V0ID0gYWJzS3ZIZWFkSWR4ICogdW5pZm9ybXMua3Zfc2VxdWVuY2VfbGVuZ3RoICogdW5pZm9ybXMuSztcbiAgICAke3ByZXNlbnRLZXkgPyAnbGV0IHByZXNlbnRLZXlPZmZzZXQgPSBhYnNLdkhlYWRJZHggKiB1bmlmb3Jtcy5OICogdW5pZm9ybXMuSzsnIDogJyd9XG4gICAgdmFyIHZhbHVlID0gJHtmMzJUeXBlfSgwKTtcbiAgICBmb3IgKHZhciB3OiB1MzIgPSAwdTsgdyA8IHVuaWZvcm1zLks7IHcgKz0gVElMRV9TSVpFKSB7XG4gICAgICBpZiAoZ2xvYmFsX2lkLnkgPCB1bmlmb3Jtcy5NICYmIHcgKyBsb2NhbF9pZC54IDwgdW5pZm9ybXMuSykge1xuICAgICAgICB0aWxlUVtUSUxFX1NJWkUgKiBsb2NhbF9pZC55ICsgbG9jYWxfaWQueF0gPSBxW3FPZmZzZXQgKyBsb2NhbF9pZC55ICogdW5pZm9ybXMuSyArIHcgKyBsb2NhbF9pZC54XTtcbiAgICAgIH1cbiAgICAgIGlmIChuICsgbG9jYWxfaWQueSA8IHVuaWZvcm1zLk4gJiYgdyArIGxvY2FsX2lkLnggPCB1bmlmb3Jtcy5LKSB7XG4gICAgICAgIHZhciBpZHggPSBUSUxFX1NJWkUgKiBsb2NhbF9pZC55ICsgbG9jYWxfaWQueDtcbiAgICAgICR7KCgpID0+IHtcbiAgICAgICAgaWYgKGZlZWRQYXN0S2V5ICYmIHByZXNlbnRLZXkpIHtcbiAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICBpZiAobiArIGxvY2FsX2lkLnkgPCBwYXN0X3NlcXVlbmNlX2xlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRpbGVLW2lkeF0gPSBwYXN0X2tleVtwYXN0S2V5T2Zmc2V0ICsgKG4gKyBsb2NhbF9pZC55KSAqIHVuaWZvcm1zLksgKyB3ICsgbG9jYWxfaWQueF07XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAobiArIGxvY2FsX2lkLnkgLSBwYXN0X3NlcXVlbmNlX2xlbmd0aCA8IHVuaWZvcm1zLmt2X3NlcXVlbmNlX2xlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRpbGVLW2lkeF0gPSBrZXlba09mZnNldCArIChuICsgbG9jYWxfaWQueSAtIHBhc3Rfc2VxdWVuY2VfbGVuZ3RoKSAqIHVuaWZvcm1zLksgKyB3ICsgbG9jYWxfaWQueF07XG4gICAgICAgICAgICAgIH1gO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgaWYgKG4gKyBsb2NhbF9pZC55IDwgdW5pZm9ybXMua3Zfc2VxdWVuY2VfbGVuZ3RoKSB7XG4gICAgICAgICAgICB0aWxlS1tpZHhdID0ga2V5W2tPZmZzZXQgKyAobiArIGxvY2FsX2lkLnkpICogdW5pZm9ybXMuSyArIHcgKyBsb2NhbF9pZC54XTtcbiAgICAgICAgICB9YDtcbiAgICAgICAgfVxuICAgICAgfSkoKX1cbiAgICAgICR7XG4gICAgICAgIHByZXNlbnRLZXlcbiAgICAgICAgICA/IGBpZiAobiArIGxvY2FsX2lkLnkgPCBwcmVzZW50X3NlcXVlbmNlX2xlbmd0aCkge1xuICAgICAgICBwcmVzZW50X2tleVtwcmVzZW50S2V5T2Zmc2V0ICsgKG4gKyBsb2NhbF9pZC55KSAqIHVuaWZvcm1zLksgKyB3ICsgbG9jYWxfaWQueF0gPSB0aWxlS1tpZHhdO1xuICAgICAgfWBcbiAgICAgICAgICA6ICcnXG4gICAgICB9XG4gICAgICB9XG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgIGZvciAodmFyIGs6IHUzMiA9IDB1OyBrIDwgVElMRV9TSVpFICYmIHcrayA8IHVuaWZvcm1zLks7IGsrKykge1xuICAgICAgICAgIHZhbHVlICs9ICR7ZjMyVHlwZX0odGlsZVFbVElMRV9TSVpFICogbG9jYWxfaWQueSArIGtdICogdGlsZUtbVElMRV9TSVpFICogbG9jYWxfaWQueCArIGtdKTtcbiAgICAgIH1cblxuICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuICAgIH1cblxuICAgIGlmIChnbG9iYWxfaWQueSA8IHVuaWZvcm1zLk0gJiYgZ2xvYmFsX2lkLnggPCB0b3RhbF9zZXF1ZW5jZV9sZW5ndGgpIHtcbiAgICAgIGxldCBoZWFkT2Zmc2V0ID0gd29ya2dyb3VwX2lkLnogKiB1bmlmb3Jtcy5NICogdW5pZm9ybXMuTjtcbiAgICAgIGxldCBvdXRwdXRJZHggPSBoZWFkT2Zmc2V0ICsgZ2xvYmFsX2lkLnkgKiB1bmlmb3Jtcy5OICsgZ2xvYmFsX2lkLng7XG4gICAgICB2YXIgc3VtOiBmMzIgPSAkeygoKSA9PiB7XG4gICAgICAgIHN3aXRjaCAoY29tcG9uZW50cykge1xuICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIHJldHVybiAndmFsdWUnO1xuICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIHJldHVybiAndmFsdWUueCArIHZhbHVlLnknO1xuICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgIHJldHVybiAndmFsdWUueCArIHZhbHVlLnkgKyB2YWx1ZS56ICsgdmFsdWUudyc7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgY29tcG9uZW50czogJHtjb21wb25lbnRzfWApO1xuICAgICAgICB9XG4gICAgICB9KSgpfTtcbiAgICAgICAgb3V0cHV0W291dHB1dElkeF0gPSAke291dHB1dC50eXBlLnZhbHVlfSAoc3VtICogdW5pZm9ybXMuYWxwaGEpICsgJHtcbiAgICAgICAgICBhdHRlbnRpb25CaWFzID8gJ2F0dGVudGlvbl9iaWFzW291dHB1dElkeF0nIDogJzAuMCdcbiAgICAgICAgfTtcbiAgICB9XG4gIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdBdHRlbnRpb25Qcm9icycsXG4gICAgc2hhZGVyQ2FjaGU6IHtcbiAgICAgIGhpbnQ6IGAke2NvbXBvbmVudHN9OyR7YXR0ZW50aW9uQmlhcyAhPT0gdW5kZWZpbmVkfTske3Bhc3RLZXkgIT09IHVuZGVmaW5lZH07JHtvdXRwdXRDb3VudH1gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXMsXG4gICAgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoeyBvdXRwdXRzLCBkaXNwYXRjaEdyb3VwOiBkaXNwYXRjaCwgcHJvZ3JhbVVuaWZvcm1zIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZVZ4QXR0ZW50aW9uU2NvcmVQcm9ncmFtSW5mbyA9IChcbiAgb3V0cHV0Q291bnQ6IG51bWJlcixcbiAgcHJvYnM6IFRlbnNvclZpZXcsXG4gIHY6IFRlbnNvclZpZXcsXG4gIHBhc3RWYWx1ZTogVGVuc29yVmlldyB8IHVuZGVmaW5lZCxcbiAgcGFyYW1zOiBBdHRlbnRpb25QYXJhbWV0ZXJzLFxuICBwYXN0U2VxdWVuY2VMZW5ndGg6IG51bWJlcixcbiAgc2VxTGVuczogVGVuc29yVmlldyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZCxcbiAgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0OiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLFxuKSA9PiB7XG4gIGNvbnN0IHRvdGFsU2VxdWVuY2VMZW5ndGggPSBwYXN0U2VxdWVuY2VMZW5ndGggKyBwYXJhbXMua3ZTZXF1ZW5jZUxlbmd0aDtcbiAgY29uc3QgblJlcHMgPSBwYXJhbXMublJlcHMgPyBwYXJhbXMublJlcHMgOiAxO1xuICBjb25zdCByZXBlYXRlZFZIaWRkZW5TaXplID0gcGFyYW1zLnZIaWRkZW5TaXplICogblJlcHM7XG4gIGNvbnN0IHByZXNlbnRWYWx1ZSA9IG91dHB1dENvdW50ID4gMSAmJiBwYXN0VmFsdWU7XG4gIGNvbnN0IGt2TnVtSGVhZHMgPSBwYXJhbXMua3ZOdW1IZWFkcyA/IHBhcmFtcy5rdk51bUhlYWRzIDogcGFyYW1zLm51bUhlYWRzO1xuICBjb25zdCBwcmVzZW50VmFsdWVTaGFwZSA9IHByZXNlbnRWYWx1ZVxuICAgID8gW3BhcmFtcy5iYXRjaFNpemUsIGt2TnVtSGVhZHMsIHRvdGFsU2VxdWVuY2VMZW5ndGgsIHBhcmFtcy5oZWFkU2l6ZV1cbiAgICA6IHVuZGVmaW5lZDtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbcGFyYW1zLmJhdGNoU2l6ZSwgcGFyYW1zLnNlcXVlbmNlTGVuZ3RoLCByZXBlYXRlZFZIaWRkZW5TaXplXTtcbiAgY29uc3QgVElMRV9TSVpFID0gMTI7XG4gIGNvbnN0IGRpc3BhdGNoID0ge1xuICAgIHg6IE1hdGguY2VpbChwYXJhbXMudkhlYWRTaXplIC8gVElMRV9TSVpFKSxcbiAgICB5OiBNYXRoLmNlaWwocGFyYW1zLnNlcXVlbmNlTGVuZ3RoIC8gVElMRV9TSVpFKSxcbiAgICB6OiBwYXJhbXMuYmF0Y2hTaXplICogcGFyYW1zLm51bUhlYWRzLFxuICB9O1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1zLnNlcXVlbmNlTGVuZ3RoIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHRvdGFsU2VxdWVuY2VMZW5ndGggfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1zLnZIZWFkU2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXJhbXMubnVtSGVhZHMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1zLmhlYWRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHJlcGVhdGVkVkhpZGRlblNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFzdFNlcXVlbmNlTGVuZ3RoIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHBhcmFtcy5rdlNlcXVlbmNlTGVuZ3RoIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG5SZXBzIH0sXG4gIF07XG4gIC8vIEZlZWQgcGFzdFZhbHVlIHRvIHRoZSBzaGFkZXItY29kZSBvbmx5IGlmIGl0IGlzIG5vbi1lbXB0eSBhbmQgcHJlc2VudFZhbHVlIGlzIGJlaW5nIHByb2R1Y2VkXG4gIGNvbnN0IGZlZWRQYXN0VmFsdWUgPSBwcmVzZW50VmFsdWUgJiYgcGFzdFZhbHVlICYmIFNoYXBlVXRpbC5zaXplKHBhc3RWYWx1ZS5kaW1zKSA+IDA7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWyd0eXBlJywgJ3R5cGUnXTtcbiAgaWYgKGZlZWRQYXN0VmFsdWUpIHtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCd0eXBlJyk7XG4gIH1cbiAgaWYgKHNlcUxlbnMpIHtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCd0eXBlJyk7XG4gIH1cbiAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCkge1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3R5cGUnKTtcbiAgfVxuICBjb25zdCBvdXRwdXRzID0gW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBwcm9icy5kYXRhVHlwZSwgZ3B1RGF0YVR5cGU6IEdwdURhdGFUeXBlLmRlZmF1bHQgfV07XG4gIGlmIChwcmVzZW50VmFsdWUpIHtcbiAgICBvdXRwdXRzLnB1c2goeyBkaW1zOiBwcmVzZW50VmFsdWVTaGFwZSEsIGRhdGFUeXBlOiBwcm9icy5kYXRhVHlwZSwgZ3B1RGF0YVR5cGU6IEdwdURhdGFUeXBlLmRlZmF1bHQgfSk7XG4gIH1cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgcHJvYnNIZWxwZXIgPSBpbnB1dFZhcmlhYmxlKCdwcm9icycsIHByb2JzLmRhdGFUeXBlLCBwcm9icy5kaW1zKTtcbiAgICBjb25zdCB2SGVscGVyID0gaW5wdXRWYXJpYWJsZSgndicsIHYuZGF0YVR5cGUsIHYuZGltcyk7XG4gICAgY29uc3QgaW5wdXRWYXJzID0gW3Byb2JzSGVscGVyLCB2SGVscGVyXTtcbiAgICBpZiAoZmVlZFBhc3RWYWx1ZSkge1xuICAgICAgaW5wdXRWYXJzLnB1c2goaW5wdXRWYXJpYWJsZSgncGFzdF92YWx1ZScsIHBhc3RWYWx1ZS5kYXRhVHlwZSwgcGFzdFZhbHVlLmRpbXMpKTtcbiAgICB9XG4gICAgY29uc3Qgc2VxTGVuc0lucHV0VmFyaWFibGUgPSBzZXFMZW5zID8gaW5wdXRWYXJpYWJsZSgnc2VxX2xlbnMnLCBzZXFMZW5zLmRhdGFUeXBlLCBzZXFMZW5zLmRpbXMpIDogdW5kZWZpbmVkO1xuICAgIGlmIChzZXFMZW5zKSB7XG4gICAgICBpbnB1dFZhcnMucHVzaChzZXFMZW5zSW5wdXRWYXJpYWJsZSEpO1xuICAgIH1cbiAgICBjb25zdCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXRWYXJpYWJsZSA9IHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dFxuICAgICAgPyBpbnB1dFZhcmlhYmxlKCd0b3RhbF9zZXF1ZW5jZV9sZW5ndGhfaW5wdXQnLCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQuZGF0YVR5cGUsIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dC5kaW1zKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCkge1xuICAgICAgaW5wdXRWYXJzLnB1c2godG90YWxTZXF1ZW5jZUxlbmd0aElucHV0VmFyaWFibGUhKTtcbiAgICB9XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIHByb2JzLmRhdGFUeXBlLCBvdXRwdXRTaGFwZSk7XG4gICAgY29uc3Qgb3V0cHV0VmFycyA9IFtvdXRwdXRdO1xuICAgIGlmIChwcmVzZW50VmFsdWUpIHtcbiAgICAgIG91dHB1dFZhcnMucHVzaChvdXRwdXRWYXJpYWJsZSgncHJlc2VudF92YWx1ZScsIHByb2JzLmRhdGFUeXBlLCBwcmVzZW50VmFsdWVTaGFwZSEpKTtcbiAgICB9XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnTScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdLJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ04nLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnbnVtX2hlYWRzJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2hlYWRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICd2X2hpZGRlbl9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3Bhc3Rfc2VxdWVuY2VfbGVuZ3RoJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2t2X3NlcXVlbmNlX2xlbmd0aCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICduX3JlcHMnLCB0eXBlOiAndTMyJyB9LFxuICAgIF07XG4gICAgcmV0dXJuIGBcbiAgY29uc3QgVElMRV9TSVpFID0gJHtUSUxFX1NJWkV9dTtcbiAgdmFyPHdvcmtncm91cD4gdGlsZVE6IGFycmF5PCR7cHJvYnNIZWxwZXIudHlwZS52YWx1ZX0sICR7VElMRV9TSVpFICogVElMRV9TSVpFfT47XG4gIHZhcjx3b3JrZ3JvdXA+IHRpbGVWOiBhcnJheTwke3Byb2JzSGVscGVyLnR5cGUudmFsdWV9LCAke1RJTEVfU0laRSAqIFRJTEVfU0laRX0+O1xuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKC4uLmlucHV0VmFycywgLi4ub3V0cHV0VmFycyl9XG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydChbVElMRV9TSVpFLCBUSUxFX1NJWkUsIDFdKX1cbiAgIGxldCBoZWFkSWR4ID0gd29ya2dyb3VwX2lkLnogJSB1bmlmb3Jtcy5udW1faGVhZHM7XG4gICBsZXQgYmF0Y2hJZHggPSB3b3JrZ3JvdXBfaWQueiAvIHVuaWZvcm1zLm51bV9oZWFkcztcbiAgIGxldCBrdkhlYWRJZHggPSAke25SZXBzID09PSAxID8gJ2hlYWRJZHgnIDogJ2hlYWRJZHggLyB1bmlmb3Jtcy5uX3JlcHMnfTtcbiAgIGxldCBrdl9udW1faGVhZHMgPSAke25SZXBzID09PSAxID8gJ3VuaWZvcm1zLm51bV9oZWFkcycgOiAndW5pZm9ybXMubnVtX2hlYWRzIC8gdW5pZm9ybXMubl9yZXBzJ307XG4gICBsZXQgbSA9IGdsb2JhbF9pZC55O1xuICAgbGV0IG4gPSBnbG9iYWxfaWQueDtcbiAgIGxldCBzZXF1ZW5jZV9sZW5ndGggPSB1bmlmb3Jtcy5NO1xuICAgdmFyIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCA9IHVuaWZvcm1zLks7XG4gICAke2luaXRWYXJTdHViKHNlcUxlbnNJbnB1dFZhcmlhYmxlLCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXRWYXJpYWJsZSwgdHJ1ZSl9XG4gICBsZXQgb2Zmc2V0QSA9IHdvcmtncm91cF9pZC56ICogdW5pZm9ybXMuTSAqIHVuaWZvcm1zLksgKyBtICogdW5pZm9ybXMuSztcbiAgIGxldCBhYnNLdkhlYWRJZHggPSBiYXRjaElkeCAqIGt2X251bV9oZWFkcyArIGt2SGVhZElkeDsgLy8ga3ZIZWFkSWR4IGlzIHJlbGF0aXZlIHRvIHRoZSBiYXRjaFxuICAgJHtmZWVkUGFzdFZhbHVlICYmIHByZXNlbnRWYWx1ZSA/ICdsZXQgcGFzdFZhbHVlT2Zmc2V0ID0gYWJzS3ZIZWFkSWR4ICogdW5pZm9ybXMuTiAqIHVuaWZvcm1zLnBhc3Rfc2VxdWVuY2VfbGVuZ3RoICsgbjsnIDogJyd9O1xuICAgbGV0IHZPZmZzZXQgPSBhYnNLdkhlYWRJZHggKiB1bmlmb3Jtcy5OICogdW5pZm9ybXMua3Zfc2VxdWVuY2VfbGVuZ3RoICsgbjtcbiAgICR7cHJlc2VudFZhbHVlID8gJ2xldCBwcmVzZW50VmFsdWVPZmZzZXQgPSBhYnNLdkhlYWRJZHggKiB1bmlmb3Jtcy5OICogdW5pZm9ybXMuSyArIG47JyA6ICcnfVxuICAgdmFyIHZhbHVlID0gJHtwcm9ic0hlbHBlci50eXBlLnN0b3JhZ2V9KDApO1xuICAgZm9yICh2YXIgdzogdTMyID0gMHU7IHcgPCB1bmlmb3Jtcy5LOyB3ICs9IFRJTEVfU0laRSkge1xuICAgICAgaWYgKG0gPCB1bmlmb3Jtcy5NICYmIHcgKyBsb2NhbF9pZC54IDwgdW5pZm9ybXMuSykge1xuICAgICAgICB0aWxlUVtUSUxFX1NJWkUgKiBsb2NhbF9pZC55ICsgbG9jYWxfaWQueF0gPSBwcm9ic1tvZmZzZXRBICsgdyArIGxvY2FsX2lkLnhdO1xuICAgICAgfVxuICAgICAgaWYgKG4gPCB1bmlmb3Jtcy5OICYmIHcgKyBsb2NhbF9pZC55IDwgdW5pZm9ybXMuSykge1xuICAgICAgICB2YXIgaWR4ID0gVElMRV9TSVpFICogbG9jYWxfaWQueSArIGxvY2FsX2lkLng7XG4gICAgICAgICR7KCgpID0+IHtcbiAgICAgICAgICBpZiAoZmVlZFBhc3RWYWx1ZSAmJiBwcmVzZW50VmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgIGlmICh3ICsgbG9jYWxfaWQueSA8IHBhc3Rfc2VxdWVuY2VfbGVuZ3RoKSB7XG4gICAgICAgICAgdGlsZVZbaWR4XSA9IHBhc3RfdmFsdWVbcGFzdFZhbHVlT2Zmc2V0ICsgKHcgKyBsb2NhbF9pZC55KSAqIHVuaWZvcm1zLk5dO1xuICAgICAgICB9IGVsc2UgaWYgKHcgKyBsb2NhbF9pZC55IC0gcGFzdF9zZXF1ZW5jZV9sZW5ndGggPCB1bmlmb3Jtcy5rdl9zZXF1ZW5jZV9sZW5ndGgpIHtcbiAgICAgICAgICB0aWxlVltpZHhdID0gdlt2T2Zmc2V0ICsgKHcgKyBsb2NhbF9pZC55IC0gcGFzdF9zZXF1ZW5jZV9sZW5ndGgpICogdW5pZm9ybXMuTl07XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICBpZiAodyArIGxvY2FsX2lkLnkgPCB1bmlmb3Jtcy5rdl9zZXF1ZW5jZV9sZW5ndGgpIHtcbiAgICAgICAgICAgICAgdGlsZVZbaWR4XSA9IHZbdk9mZnNldCArICh3ICsgbG9jYWxfaWQueSkgKiB1bmlmb3Jtcy5OXTtcbiAgICAgICAgICAgIH1gO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKX1cbiAgICAgICAgJHtcbiAgICAgICAgICBwcmVzZW50VmFsdWVcbiAgICAgICAgICAgID8gYFxuICAgICAgICAgICAgaWYgKHcgKyBsb2NhbF9pZC55IDwgcHJlc2VudF9zZXF1ZW5jZV9sZW5ndGgpIHtcbiAgICAgICAgICBwcmVzZW50X3ZhbHVlW3ByZXNlbnRWYWx1ZU9mZnNldCArICh3ICsgbG9jYWxfaWQueSkgKiB1bmlmb3Jtcy5OXSA9IHRpbGVWW2lkeF07XG4gICAgICAgIH1gXG4gICAgICAgICAgICA6ICcnXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgd29ya2dyb3VwQmFycmllcigpO1xuICAgICBmb3IgKHZhciBrOiB1MzIgPSAwdTsgayA8IFRJTEVfU0laRSAmJiB3K2sgPCB0b3RhbF9zZXF1ZW5jZV9sZW5ndGg7IGsrKykge1xuICAgICAgIHZhbHVlICs9IHRpbGVRW1RJTEVfU0laRSAqIGxvY2FsX2lkLnkgKyBrXSAqIHRpbGVWW1RJTEVfU0laRSAqIGsgKyBsb2NhbF9pZC54XTtcbiAgICAgfVxuICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICB9XG5cbiAgIC8vIHdlIG5lZWQgdG8gdHJhbnNwb3NlIG91dHB1dCBmcm9tIEJOU0hfdiB0byBCU05EX3ZcbiAgIGlmIChtIDwgdW5pZm9ybXMuTSAmJiBuIDwgdW5pZm9ybXMuTikge1xuICAgICBsZXQgb3V0cHV0SWR4ID0gYmF0Y2hJZHggKiB1bmlmb3Jtcy5NICogdW5pZm9ybXMudl9oaWRkZW5fc2l6ZSArIG0gKiB1bmlmb3Jtcy52X2hpZGRlbl9zaXplXG4gICAgICAgKyBoZWFkSWR4ICogdW5pZm9ybXMuTiArIG47XG4gICAgIG91dHB1dFtvdXRwdXRJZHhdID0gdmFsdWU7XG4gICB9XG4gIH1gO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0F0dGVudGlvblNjb3JlJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtwYXN0VmFsdWUgIT09IHVuZGVmaW5lZH07JHtvdXRwdXRDb3VudH1gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7IG91dHB1dHMsIGRpc3BhdGNoR3JvdXA6IGRpc3BhdGNoLCBwcm9ncmFtVW5pZm9ybXMgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFwcGx5QXR0ZW50aW9uID0gKFxuICBjb250ZXh0OiBDb21wdXRlQ29udGV4dCxcbiAgcTogVGVuc29yVmlldyxcbiAgazogVGVuc29yVmlldyxcbiAgdjogVGVuc29yVmlldyxcbiAgX21hc2tJbmRleDogVGVuc29yVmlldyB8IHVuZGVmaW5lZCxcbiAgX3Bhc3Q6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQsXG4gIHBhc3RLZXk6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQsXG4gIHBhc3RWYWx1ZTogVGVuc29yVmlldyB8IHVuZGVmaW5lZCxcbiAgYXR0ZW50aW9uQmlhc0lucHV0OiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkLFxuICBwYXJhbWV0ZXJzOiBBdHRlbnRpb25QYXJhbWV0ZXJzLFxuICBzZXFMZW5zOiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLFxuICB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQ6IFRlbnNvclZpZXcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4pID0+IHtcbiAgLy8gQXNzdW1wdGlvbiBpcyB0aGF0IHByZXNlbnRLZXkvcHJlc2VudFZhbHVlIGV4aXN0cyBvbmx5IGlmIHBhc3RLZXkvcGFzdFZhbHVlIGV4aXN0cy5cbiAgY29uc3Qgb3V0cHV0Q291bnQgPSBNYXRoLm1pbihjb250ZXh0Lm91dHB1dENvdW50LCAxICsgKHBhc3RLZXkgPyAxIDogMCkgKyAocGFzdFZhbHVlID8gMSA6IDApKTtcbiAgY29uc3QgcGFzdFNlcXVlbmNlTGVuZ3RoID0gb3V0cHV0Q291bnQgPiAxID8gcGFyYW1ldGVycy5wYXN0U2VxdWVuY2VMZW5ndGggOiAwO1xuICBjb25zdCB0b3RhbFNlcXVlbmNlTGVuZ3RoID0gcGFzdFNlcXVlbmNlTGVuZ3RoICsgcGFyYW1ldGVycy5rdlNlcXVlbmNlTGVuZ3RoO1xuICBjb25zdCBhdHRlbnRpb25CaWFzID1cbiAgICBhdHRlbnRpb25CaWFzSW5wdXQgJiYgU2hhcGVVdGlsLnNpemUoYXR0ZW50aW9uQmlhc0lucHV0LmRpbXMpID4gMCA/IGF0dGVudGlvbkJpYXNJbnB1dCA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBpbnB1dHNLID0gW3EsIGtdO1xuICBpZiAob3V0cHV0Q291bnQgPiAxICYmIHBhc3RLZXkgJiYgU2hhcGVVdGlsLnNpemUocGFzdEtleS5kaW1zKSA+IDApIHtcbiAgICBpbnB1dHNLLnB1c2gocGFzdEtleSk7XG4gIH1cbiAgaWYgKGF0dGVudGlvbkJpYXMpIHtcbiAgICBpbnB1dHNLLnB1c2goYXR0ZW50aW9uQmlhcyk7XG4gIH1cbiAgaWYgKHNlcUxlbnMpIHtcbiAgICBpbnB1dHNLLnB1c2goc2VxTGVucyk7XG4gIH1cbiAgaWYgKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCkge1xuICAgIGlucHV0c0sucHVzaCh0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQpO1xuICB9XG4gIC8vIFJ1biBBdHRlbnRpb25Qcm9ic1xuICBjb25zdCBwcm9icyA9IGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVBdHRlbnRpb25Qcm9ic1Byb2dyYW1JbmZvKFxuICAgICAgb3V0cHV0Q291bnQsXG4gICAgICBxLFxuICAgICAgayxcbiAgICAgIHBhc3RLZXksXG4gICAgICBhdHRlbnRpb25CaWFzLFxuICAgICAgcGFyYW1ldGVycyxcbiAgICAgIHBhc3RTZXF1ZW5jZUxlbmd0aCxcbiAgICAgIHNlcUxlbnMsXG4gICAgICB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQsXG4gICAgKSxcbiAgICB7IGlucHV0czogaW5wdXRzSywgb3V0cHV0czogb3V0cHV0Q291bnQgPiAxID8gWy0xLCAxXSA6IFstMV0gfSxcbiAgKVswXTtcblxuICAvLyBSdW4gU29mdG1heFxuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlSW5QbGFjZVNvZnRtYXhQcm9ncmFtSW5mbyhcbiAgICAgIHByb2JzLFxuICAgICAgcGFyYW1ldGVycy5iYXRjaFNpemUsXG4gICAgICBwYXJhbWV0ZXJzLm51bUhlYWRzLFxuICAgICAgcGFzdFNlcXVlbmNlTGVuZ3RoLFxuICAgICAgcGFyYW1ldGVycy5zZXF1ZW5jZUxlbmd0aCxcbiAgICAgIHRvdGFsU2VxdWVuY2VMZW5ndGgsXG4gICAgICBzZXFMZW5zLFxuICAgICAgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0LFxuICAgICksXG4gICAgeyBpbnB1dHM6IHNlcUxlbnMgJiYgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0ID8gW3Byb2JzLCBzZXFMZW5zLCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXRdIDogW3Byb2JzXSwgb3V0cHV0czogW10gfSxcbiAgKTtcblxuICAvLyBSdW4gQXR0ZW50aW9uU2NvcmVcbiAgY29uc3QgaW5wdXRzViA9IFtwcm9icywgdl07XG4gIGlmIChvdXRwdXRDb3VudCA+IDEgJiYgcGFzdFZhbHVlICYmIFNoYXBlVXRpbC5zaXplKHBhc3RWYWx1ZS5kaW1zKSA+IDApIHtcbiAgICBpbnB1dHNWLnB1c2gocGFzdFZhbHVlKTtcbiAgfVxuICBpZiAoc2VxTGVucykge1xuICAgIGlucHV0c1YucHVzaChzZXFMZW5zKTtcbiAgfVxuICBpZiAodG90YWxTZXF1ZW5jZUxlbmd0aElucHV0KSB7XG4gICAgaW5wdXRzVi5wdXNoKHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCk7XG4gIH1cbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZVZ4QXR0ZW50aW9uU2NvcmVQcm9ncmFtSW5mbyhcbiAgICAgIG91dHB1dENvdW50LFxuICAgICAgcHJvYnMsXG4gICAgICB2LFxuICAgICAgcGFzdFZhbHVlLFxuICAgICAgcGFyYW1ldGVycyxcbiAgICAgIHBhc3RTZXF1ZW5jZUxlbmd0aCxcbiAgICAgIHNlcUxlbnMsXG4gICAgICB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQsXG4gICAgKSxcbiAgICB7XG4gICAgICBpbnB1dHM6IGlucHV0c1YsXG4gICAgICBvdXRwdXRzOiBvdXRwdXRDb3VudCA+IDEgPyBbMCwgMl0gOiBbMF0sXG4gICAgfSxcbiAgKTtcbn07XG5cbmNvbnN0IHByZXBhcmUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIHBhcmFtZXRlcnM6IEF0dGVudGlvblBhcmFtZXRlcnMpID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbcGFyYW1ldGVycy5iYXRjaFNpemUsIHBhcmFtZXRlcnMubnVtSGVhZHMsIHBhcmFtZXRlcnMuc2VxdWVuY2VMZW5ndGgsIHBhcmFtZXRlcnMuaGVhZFNpemVdO1xuICBjb25zdCBNID0gcGFyYW1ldGVycy5zZXF1ZW5jZUxlbmd0aDtcbiAgY29uc3QgSyA9IHBhcmFtZXRlcnMuaW5wdXRIaWRkZW5TaXplO1xuICBjb25zdCBOID0gcGFyYW1ldGVycy5oZWFkU2l6ZTtcbiAgY29uc3QgVElMRV9TSVpFID0gMTI7XG4gIGNvbnN0IGRpc3BhdGNoID0ge1xuICAgIHg6IE1hdGguY2VpbChwYXJhbWV0ZXJzLmhlYWRTaXplIC8gVElMRV9TSVpFKSxcbiAgICB5OiBNYXRoLmNlaWwocGFyYW1ldGVycy5zZXF1ZW5jZUxlbmd0aCAvIFRJTEVfU0laRSksXG4gICAgejogcGFyYW1ldGVycy5iYXRjaFNpemUgKiBwYXJhbWV0ZXJzLm51bUhlYWRzLFxuICB9O1xuICBjb25zdCBpbnB1dHMgPSBbY29udGV4dC5pbnB1dHNbMF0sIGNvbnRleHQuaW5wdXRzWzFdLCBjb250ZXh0LmlucHV0c1syXV07XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogTSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBLIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IE4gfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcGFyYW1ldGVycy5udW1IZWFkcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXJhbWV0ZXJzLmhlYWRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHBhcmFtZXRlcnMuaGlkZGVuU2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYXJhbWV0ZXJzLmhpZGRlblNpemUgKyBwYXJhbWV0ZXJzLmhpZGRlblNpemUgKyBwYXJhbWV0ZXJzLnZIaWRkZW5TaXplIH0sXG4gIF07XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3Qgb3V0cHV0USA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXRfcScsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUpO1xuICAgIGNvbnN0IG91dHB1dEsgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0X2snLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlKTtcbiAgICBjb25zdCBvdXRwdXRWID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dF92JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZSk7XG4gICAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMpO1xuICAgIGNvbnN0IHdlaWdodCA9IGlucHV0VmFyaWFibGUoJ3dlaWdodCcsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMpO1xuICAgIGNvbnN0IGJpYXMgPSBpbnB1dFZhcmlhYmxlKCdiaWFzJywgaW5wdXRzWzJdLmRhdGFUeXBlLCBpbnB1dHNbMl0uZGltcyk7XG4gICAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dC50eXBlLnN0b3JhZ2U7XG5cbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdNJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ0snLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnTicsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdudW1faGVhZHMnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnaGVhZF9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2hpZGRlbl9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2xkYicsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICBjb25zdCBUSUxFX1NJWkUgPSAke1RJTEVfU0laRX11O1xuICB2YXI8d29ya2dyb3VwPiB0aWxlSW5wdXQ6IGFycmF5PCR7ZGF0YVR5cGV9LCAke1RJTEVfU0laRSAqIFRJTEVfU0laRX0+O1xuICB2YXI8d29ya2dyb3VwPiB0aWxlV2VpZ2h0UTogYXJyYXk8JHtkYXRhVHlwZX0sICR7VElMRV9TSVpFICogVElMRV9TSVpFfT47XG4gIHZhcjx3b3JrZ3JvdXA+IHRpbGVXZWlnaHRLOiBhcnJheTwke2RhdGFUeXBlfSwgJHtUSUxFX1NJWkUgKiBUSUxFX1NJWkV9PjtcbiAgdmFyPHdvcmtncm91cD4gdGlsZVdlaWdodFY6IGFycmF5PCR7ZGF0YVR5cGV9LCAke1RJTEVfU0laRSAqIFRJTEVfU0laRX0+O1xuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCB3ZWlnaHQsIGJpYXMsIG91dHB1dFEsIG91dHB1dEssIG91dHB1dFYpfVxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoW1RJTEVfU0laRSwgVElMRV9TSVpFLCAxXSl9XG4gICAgbGV0IGJhdGNoSW5kZXggPSB3b3JrZ3JvdXBfaWQueiAvIHVuaWZvcm1zLm51bV9oZWFkcztcbiAgICBsZXQgaGVhZE51bWJlciA9IHdvcmtncm91cF9pZC56ICUgdW5pZm9ybXMubnVtX2hlYWRzO1xuICAgIGxldCBtID0gZ2xvYmFsX2lkLnk7XG4gICAgbGV0IG4gPSBnbG9iYWxfaWQueDtcblxuICAgIGxldCBpbnB1dE9mZnNldCA9IGJhdGNoSW5kZXggKiAodW5pZm9ybXMuTSAqIHVuaWZvcm1zLkspICsgbSAqIHVuaWZvcm1zLks7XG4gICAgbGV0IGJpYXNPZmZzZXRRID0gaGVhZE51bWJlciAqIHVuaWZvcm1zLmhlYWRfc2l6ZTtcbiAgICBsZXQgYmlhc09mZnNldEsgPSB1bmlmb3Jtcy5oaWRkZW5fc2l6ZSArIGJpYXNPZmZzZXRRO1xuICAgIGxldCBiaWFzT2Zmc2V0ViA9IHVuaWZvcm1zLmhpZGRlbl9zaXplICsgYmlhc09mZnNldEs7XG5cbiAgICB2YXIgdmFsdWVRID0gJHtkYXRhVHlwZX0oMCk7XG4gICAgdmFyIHZhbHVlSyA9ICR7ZGF0YVR5cGV9KDApO1xuICAgIHZhciB2YWx1ZVYgPSAke2RhdGFUeXBlfSgwKTtcbiAgICBmb3IgKHZhciB3OiB1MzIgPSAwdTsgdyA8IHVuaWZvcm1zLks7IHcgKz0gVElMRV9TSVpFKSB7XG4gICAgICBpZiAobSA8IHVuaWZvcm1zLk0gJiYgdyArIGxvY2FsX2lkLnggPCB1bmlmb3Jtcy5LKSB7XG4gICAgICAgIHRpbGVJbnB1dFtUSUxFX1NJWkUgKiBsb2NhbF9pZC55ICsgbG9jYWxfaWQueF0gPSBpbnB1dFtpbnB1dE9mZnNldCArIHcgKyBsb2NhbF9pZC54XTtcbiAgICAgIH1cbiAgICAgIGlmIChuIDwgdW5pZm9ybXMuTiAmJiB3ICsgbG9jYWxfaWQueSA8IHVuaWZvcm1zLkspIHtcbiAgICAgICAgbGV0IG9mZnNldCA9IG4gKyAodyArIGxvY2FsX2lkLnkpICogdW5pZm9ybXMubGRiO1xuICAgICAgICB0aWxlV2VpZ2h0UVtUSUxFX1NJWkUgKiBsb2NhbF9pZC55ICsgbG9jYWxfaWQueF0gPSB3ZWlnaHRbYmlhc09mZnNldFEgKyBvZmZzZXRdO1xuICAgICAgICB0aWxlV2VpZ2h0S1tUSUxFX1NJWkUgKiBsb2NhbF9pZC55ICsgbG9jYWxfaWQueF0gPSB3ZWlnaHRbYmlhc09mZnNldEsgKyBvZmZzZXRdO1xuICAgICAgICB0aWxlV2VpZ2h0VltUSUxFX1NJWkUgKiBsb2NhbF9pZC55ICsgbG9jYWxfaWQueF0gPSB3ZWlnaHRbYmlhc09mZnNldFYgKyBvZmZzZXRdO1xuICAgICAgfVxuICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuICAgICAgZm9yICh2YXIgazogdTMyID0gMHU7IGs8VElMRV9TSVpFICYmIHcrayA8IHVuaWZvcm1zLks7IGsrKykge1xuICAgICAgICBsZXQgaW5wdXRUaWxlT2Zmc2V0ID0gVElMRV9TSVpFICogbG9jYWxfaWQueSArIGs7XG4gICAgICAgIGxldCB3ZWlnaHRUaWxlT2Zmc2V0ID0gVElMRV9TSVpFICogayArIGxvY2FsX2lkLng7XG4gICAgICAgIHZhbHVlUSArPSB0aWxlSW5wdXRbaW5wdXRUaWxlT2Zmc2V0XSAqIHRpbGVXZWlnaHRRW3dlaWdodFRpbGVPZmZzZXRdO1xuICAgICAgICB2YWx1ZUsgKz0gdGlsZUlucHV0W2lucHV0VGlsZU9mZnNldF0gKiB0aWxlV2VpZ2h0S1t3ZWlnaHRUaWxlT2Zmc2V0XTtcbiAgICAgICAgdmFsdWVWICs9IHRpbGVJbnB1dFtpbnB1dFRpbGVPZmZzZXRdICogdGlsZVdlaWdodFZbd2VpZ2h0VGlsZU9mZnNldF07XG4gICAgICB9XG5cbiAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcbiAgICB9XG5cbiAgICBsZXQgaGVhZE9mZnNldCA9IChtICogdW5pZm9ybXMuTiArIG4pICUgdW5pZm9ybXMuaGVhZF9zaXplO1xuICAgIHZhbHVlUSArPSBiaWFzW2hlYWRPZmZzZXQgKyBiaWFzT2Zmc2V0UV07XG4gICAgdmFsdWVLICs9IGJpYXNbaGVhZE9mZnNldCArIGJpYXNPZmZzZXRLXTtcbiAgICB2YWx1ZVYgKz0gYmlhc1toZWFkT2Zmc2V0ICsgYmlhc09mZnNldFZdO1xuXG4gICAgbGV0IG9mZnNldCA9IHdvcmtncm91cF9pZC56ICogdW5pZm9ybXMuTSAqIHVuaWZvcm1zLk47XG4gICAgaWYgKG0gPCB1bmlmb3Jtcy5NICYmIG4gPCB1bmlmb3Jtcy5OKSB7XG4gICAgICBsZXQgb3V0cHV0SWR4ID0gb2Zmc2V0ICsgbSAqIHVuaWZvcm1zLk4gKyBuO1xuICAgICAgb3V0cHV0X3Fbb3V0cHV0SWR4XSA9IHZhbHVlUTtcbiAgICAgIG91dHB1dF9rW291dHB1dElkeF0gPSB2YWx1ZUs7XG4gICAgICBvdXRwdXRfdltvdXRwdXRJZHhdID0gdmFsdWVWO1xuICAgIH1cbiAgfWA7XG4gIH07XG5cbiAgcmV0dXJuIGNvbnRleHQuY29tcHV0ZShcbiAgICB7XG4gICAgICBuYW1lOiAnQXR0ZW50aW9uUHJlcGFyZScsXG4gICAgICBzaGFkZXJDYWNoZTogeyBpbnB1dERlcGVuZGVuY2llczogWyd0eXBlJywgJ3R5cGUnLCAndHlwZSddIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlLCBncHVEYXRhVHlwZTogR3B1RGF0YVR5cGUuZGVmYXVsdCB9LFxuICAgICAgICAgIHsgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSwgZ3B1RGF0YVR5cGU6IEdwdURhdGFUeXBlLmRlZmF1bHQgfSxcbiAgICAgICAgICB7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUsIGdwdURhdGFUeXBlOiBHcHVEYXRhVHlwZS5kZWZhdWx0IH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRpc3BhdGNoR3JvdXA6IGRpc3BhdGNoLFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgICB9KSxcbiAgICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICB9LFxuICAgIHsgaW5wdXRzLCBvdXRwdXRzOiBbLTEsIC0xLCAtMV0gfSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBhdHRlbnRpb24gPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEF0dGVudGlvbkF0dHJzKTogdm9pZCA9PiB7XG4gIGNvbnN0IHBhcmFtcyA9IHZhbGlkYXRlQXR0ZW50aW9uSW5wdXRzKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKTtcblxuICBjb25zdCBbcSwgaywgdl0gPSBwcmVwYXJlKGNvbnRleHQsIHBhcmFtcyk7XG5cbiAgcmV0dXJuIGFwcGx5QXR0ZW50aW9uKFxuICAgIGNvbnRleHQsXG4gICAgcSxcbiAgICBrLFxuICAgIHYsXG4gICAgY29udGV4dC5pbnB1dHNbNF0sXG4gICAgdW5kZWZpbmVkLFxuICAgIHVuZGVmaW5lZCxcbiAgICB1bmRlZmluZWQsXG4gICAgY29udGV4dC5pbnB1dHNbNV0sXG4gICAgcGFyYW1zLFxuICApO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBnZXRNYXhDb21wb25lbnRzLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhdGNoTm9ybUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBlcHNpbG9uOiBudW1iZXI7XG4gIHJlYWRvbmx5IG1vbWVudHVtOiBudW1iZXI7XG4gIHJlYWRvbmx5IHNwYXRpYWw6IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRyYWluaW5nTW9kZTogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZm9ybWF0OiAnTkhXQycgfCAnTkNIVyc7XG4gIHJlYWRvbmx5IG91dHB1dENvdW50OiBudW1iZXI7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLCBhdHRyaWJ1dGVzOiBCYXRjaE5vcm1BdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0JhdGNoTm9ybWFsaXphdGlvbiByZXF1aXJlcyA1IGlucHV0cycpO1xuICB9XG5cbiAgY29uc3QgY2hlY2tTaGFwZUVxdWFsID0gKGFjdHVhbDogcmVhZG9ubHkgbnVtYmVyW10sIGV4cGVjdGVkOiByZWFkb25seSBudW1iZXJbXSwgbWVzc2FnZTogc3RyaW5nKSA9PiB7XG4gICAgY29uc3QgciA9IGV4cGVjdGVkLmxlbmd0aDtcbiAgICBpZiAociAhPT0gYWN0dWFsLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21lc3NhZ2V9OiBudW0gZGltZW5zaW9ucyAhPSAke3J9YCk7XG4gICAgfVxuICAgIGV4cGVjdGVkLmZvckVhY2goKHYsIGkpID0+IHtcbiAgICAgIGlmICh2ICE9PSBhY3R1YWxbaV0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21lc3NhZ2V9OiBkaW1bJHtpfV0gZG8gbm90IG1hdGNoYCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCA+IDEpIHtcbiAgICBjb25zdCBzaGFwZSA9XG4gICAgICBhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnXG4gICAgICAgID8gYXR0cmlidXRlcy5zcGF0aWFsXG4gICAgICAgICAgPyBpbnB1dHNbMF0uZGltcy5zbGljZSgtMSlcbiAgICAgICAgICA6IGlucHV0c1swXS5kaW1zLnNsaWNlKC0xKS5jb25jYXQoaW5wdXRzWzBdLmRpbXMuc2xpY2UoMSwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMSkpXG4gICAgICAgIDogaW5wdXRzWzBdLmRpbXMuc2xpY2UoMSwgYXR0cmlidXRlcy5zcGF0aWFsID8gMiA6IHVuZGVmaW5lZCk7XG4gICAgY2hlY2tTaGFwZUVxdWFsKGlucHV0c1sxXS5kaW1zLCBzaGFwZSwgJ0ludmFsaWQgaW5wdXQgc2NhbGUnKTtcbiAgICBjaGVja1NoYXBlRXF1YWwoaW5wdXRzWzJdLmRpbXMsIHNoYXBlLCAnSW52YWxpZCBpbnB1dCBCJyk7XG4gICAgY2hlY2tTaGFwZUVxdWFsKGlucHV0c1szXS5kaW1zLCBzaGFwZSwgJ0ludmFsaWQgaW5wdXQgbWVhbicpO1xuICAgIGNoZWNrU2hhcGVFcXVhbChpbnB1dHNbNF0uZGltcywgc2hhcGUsICdJbnZhbGlkIGlucHV0IHZhcicpO1xuICB9IGVsc2Uge1xuICAgIGNoZWNrU2hhcGVFcXVhbChpbnB1dHNbMV0uZGltcywgWzFdLCAnSW52YWxpZCBpbnB1dCBzY2FsZScpO1xuICAgIGNoZWNrU2hhcGVFcXVhbChpbnB1dHNbMl0uZGltcywgWzFdLCAnSW52YWxpZCBpbnB1dCBCJyk7XG4gICAgY2hlY2tTaGFwZUVxdWFsKGlucHV0c1szXS5kaW1zLCBbMV0sICdJbnZhbGlkIGlucHV0IG1lYW4nKTtcbiAgICBjaGVja1NoYXBlRXF1YWwoaW5wdXRzWzRdLmRpbXMsIFsxXSwgJ0ludmFsaWQgaW5wdXQgdmFyJyk7XG4gIH1cbn07XG5cbmNvbnN0IGNyZWF0ZUJhdGNoTm9ybUluZmVyZW5jZVByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogQmF0Y2hOb3JtQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeyBlcHNpbG9uLCBzcGF0aWFsLCBmb3JtYXQgfSA9IGF0dHJpYnV0ZXM7XG4gIGNvbnN0IHlTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBjb21wb25lbnRzID0gc3BhdGlhbCA/IGdldE1heENvbXBvbmVudHMoeVNoYXBlW3lTaGFwZS5sZW5ndGggLSAxXSkgOiAxO1xuICBjb25zdCBjQ29tcG9uZW50cyA9IGZvcm1hdCA9PT0gJ05IV0MnICYmIHlTaGFwZS5sZW5ndGggPiAxID8gY29tcG9uZW50cyA6IDE7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZSh5U2hhcGUpIC8gY29tcG9uZW50cztcbiAgLy8gT25seSBzdXBwb3J0IHVuaWZvcm1zIGZvciBvcHNldCB2ZXJzaW9uID49IDkgKHNwYXRpYWwgPSB0cnVlKS5cbiAgY29uc3QgdXNlU2hhcGVzVW5pZm9ybXMgPSBzcGF0aWFsO1xuICBjb25zdCBzaGFwZU9yUmFuayA9IHVzZVNoYXBlc1VuaWZvcm1zID8geVNoYXBlLmxlbmd0aCA6IHlTaGFwZTtcbiAgY29uc3QgeCA9IGlucHV0VmFyaWFibGUoJ3gnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zLCBjb21wb25lbnRzKTtcbiAgY29uc3Qgc2NhbGUgPSBpbnB1dFZhcmlhYmxlKCdzY2FsZScsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMsIGNDb21wb25lbnRzKTtcbiAgY29uc3QgYmlhcyA9IGlucHV0VmFyaWFibGUoJ2JpYXMnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLCBjQ29tcG9uZW50cyk7XG4gIGNvbnN0IGlucHV0TWVhbiA9IGlucHV0VmFyaWFibGUoJ2lucHV0TWVhbicsIGlucHV0c1szXS5kYXRhVHlwZSwgaW5wdXRzWzNdLmRpbXMsIGNDb21wb25lbnRzKTtcbiAgY29uc3QgaW5wdXRWYXIgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dFZhcicsIGlucHV0c1s0XS5kYXRhVHlwZSwgaW5wdXRzWzRdLmRpbXMsIGNDb21wb25lbnRzKTtcbiAgY29uc3QgeSA9IG91dHB1dFZhcmlhYmxlKCd5JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBzaGFwZU9yUmFuaywgY29tcG9uZW50cyk7XG4gIC8vIFRPRE86IHN1cHBvcnQgaW5wdXRzIHdpdGggZGlmZmVyZW50IGRhdGEgdHlwZS4gQ3VycmVudCB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSBhbGwgaW5wdXRzIGhhdmUgdGhlIHNhbWUgZGF0YSB0eXBlLlxuICAvLyBPdGhlcndpc2UsIHRoZSBzaGFkZXIgY29tcGlsYXRpb24gd2lsbCBmYWlsLlxuICBjb25zdCBjYWxjQ09mZnNldCA9ICgpOiBzdHJpbmcgPT4ge1xuICAgIGxldCBjT2Zmc2V0ID0gJyc7XG4gICAgaWYgKHNwYXRpYWwpIHtcbiAgICAgIGNPZmZzZXQgPSBgbGV0IGNPZmZzZXQgPSAke1xuICAgICAgICB5U2hhcGUubGVuZ3RoID09PSAxXG4gICAgICAgICAgPyAnMHUnXG4gICAgICAgICAgOiBmb3JtYXQgPT09ICdOSFdDJ1xuICAgICAgICAgICAgPyBgb3V0cHV0SW5kaWNlc1ske3lTaGFwZS5sZW5ndGggLSAxfV0gLyAke2NvbXBvbmVudHN9YFxuICAgICAgICAgICAgOiAnb3V0cHV0SW5kaWNlc1sxXSdcbiAgICAgIH07YDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGZvcm1hdCA9PT0gJ05DSFcnKSB7XG4gICAgICAgIGNPZmZzZXQgPSBgXG4gICAgICAgICAgICAke3kuaW5kaWNlc1NldCgnb3V0cHV0SW5kaWNlcycsICcwJywgJzAnKX1cbiAgICAgICAgICAgIGxldCBjT2Zmc2V0ID0gJHt5LmluZGljZXNUb09mZnNldCgnb3V0cHV0SW5kaWNlcycpfTtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdXBkYXRlIEMgY2hhbm5lbC5cbiAgICAgICAgY09mZnNldCA9IGB2YXIgY0luZGljZXMgPSAke3NjYWxlLnR5cGUuaW5kaWNlc30oMCk7XG4gICAgICAgICAgICAgICAgICAgICAgIGNJbmRpY2VzWzBdID0gb3V0cHV0SW5kaWNlc1ske3lTaGFwZS5sZW5ndGggLSAxfV07YDtcbiAgICAgICAgLy8gdXBkYXRlIEQxIHggLi4uIHggRG4gY2hhbm5lbHMuXG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgc2NhbGUucmFuazsgaSsrKSB7XG4gICAgICAgICAgY09mZnNldCArPSBgY0luZGljZXNbJHtpfV0gPSBvdXRwdXRJbmRpY2VzWyR7aX1dO2A7XG4gICAgICAgIH1cbiAgICAgICAgY09mZnNldCArPSBgbGV0IGNPZmZzZXQgPSAke3NjYWxlLmluZGljZXNUb09mZnNldCgnY0luZGljZXMnKX07YDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNPZmZzZXQ7XG4gIH07XG4gIGNvbnN0IGdldEluZmVyZW5jZU1vZGVTaGFkZXJTb3VyY2UgPSAoaGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IGBcbiAgY29uc3QgZXBzaWxvbiA9ICR7ZXBzaWxvbn07XG4gICR7aGVscGVyLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0U2l6ZScsICd1MzInKS5kZWNsYXJlVmFyaWFibGVzKHgsIHNjYWxlLCBiaWFzLCBpbnB1dE1lYW4sIGlucHV0VmFyLCB5KX1cbiAgJHtoZWxwZXIubWFpblN0YXJ0KCl9XG4gICR7aGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dFNpemUnKX1cbiAgICB2YXIgb3V0cHV0SW5kaWNlcyA9ICR7eS5vZmZzZXRUb0luZGljZXMoYGdsb2JhbF9pZHggKiAke2NvbXBvbmVudHN9YCl9O1xuICAgICR7Y2FsY0NPZmZzZXQoKX1cbiAgICBsZXQgc2NhbGUgPSAke3NjYWxlLmdldEJ5T2Zmc2V0KCdjT2Zmc2V0Jyl9O1xuICAgIGxldCBiaWFzID0gJHtiaWFzLmdldEJ5T2Zmc2V0KCdjT2Zmc2V0Jyl9O1xuICAgIGxldCBpbnB1dE1lYW4gPSAke2lucHV0TWVhbi5nZXRCeU9mZnNldCgnY09mZnNldCcpfTtcbiAgICBsZXQgaW5wdXRWYXIgPSAke2lucHV0VmFyLmdldEJ5T2Zmc2V0KCdjT2Zmc2V0Jyl9O1xuICAgIGxldCB4ID0gJHt4LmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4Jyl9O1xuICAgIGxldCB2YWx1ZSA9ICh4IC0gaW5wdXRNZWFuKSAqIGludmVyc2VTcXJ0KGlucHV0VmFyICsgZXBzaWxvbikgKiBzY2FsZSArIGJpYXM7XG4gICAgJHt5LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3ZhbHVlJyl9XG4gIH1gO1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdCYXRjaE5vcm1hbGl6YXRpb24nLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmVwc2lsb259XyR7YXR0cmlidXRlcy5mb3JtYXR9XyR7c3BhdGlhbH1fJHtjb21wb25lbnRzfWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llczogdXNlU2hhcGVzVW5pZm9ybXMgPyBbJ3JhbmsnLCAndHlwZScsICd0eXBlJywgJ3R5cGUnLCAndHlwZSddIDogdW5kZWZpbmVkLFxuICAgIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlOiBnZXRJbmZlcmVuY2VNb2RlU2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBpbnB1dHNbMF0uZGltcywgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtczogdXNlU2hhcGVzVW5pZm9ybXNcbiAgICAgICAgPyBbeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSwgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoeVNoYXBlKV1cbiAgICAgICAgOiBbeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfV0sXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VCYXRjaE5vcm1BdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogQmF0Y2hOb3JtQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoYXR0cmlidXRlcyBhcyBPbWl0PEJhdGNoTm9ybUF0dHJpYnV0ZXMsIGtleW9mIEF0dHJpYnV0ZVdpdGhDYWNoZUtleT4pO1xuXG5leHBvcnQgY29uc3QgYmF0Y2hOb3JtID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IHZvaWQgPT4ge1xuICBjb25zdCB7IGlucHV0cywgb3V0cHV0Q291bnQgfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHVwZGF0ZWRBdHRyaWJ1dGVzID0gcGFyc2VCYXRjaE5vcm1BdHRyaWJ1dGVzKHsgLi4uYXR0cmlidXRlcywgb3V0cHV0Q291bnQgfSk7XG4gIGlmIChlbnYud2ViZ3B1LnZhbGlkYXRlSW5wdXRDb250ZW50KSB7XG4gICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCB1cGRhdGVkQXR0cmlidXRlcyk7XG4gIH1cbiAgaWYgKGF0dHJpYnV0ZXMudHJhaW5pbmdNb2RlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdCYXRjaE5vcm1hbGl6YXRpb24gdHJhaW5pbmdNb2RlIGlzIG5vdCBzdXBwb3J0ZWQgeWV0LicpO1xuICB9IGVsc2Uge1xuICAgIGNvbnRleHQuY29tcHV0ZShjcmVhdGVCYXRjaE5vcm1JbmZlcmVuY2VQcm9ncmFtSW5mbyhpbnB1dHMsIHVwZGF0ZWRBdHRyaWJ1dGVzKSk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbyB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciB9IGZyb20gJy4vY29tbW9uJztcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiB2b2lkID0+IHtcbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hvdWxkIGhhdmUgMyBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBpZiAoIVszMjAsIDY0MCwgMTI4MF0uaW5jbHVkZXMoaW5wdXRzWzBdLmRpbXNbMl0pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdudW1iZXIgb2YgY2hhbm5lbHMgc2hvdWxkIGJlIDMyMCwgNjQwIG9yIDEyODAnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JpYXMgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAxIGRpbWVuc2lvbnMnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltc1syXSAhPT0gaW5wdXRzWzFdLmRpbXNbMF0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2xhc3QgZGltZW5zaW9uIG9mIGlucHV0IGFuZCBiaWFzIGFyZSBub3QgdGhlIHNhbWUnKTtcbiAgfVxufTtcblxuY29uc3QgY3JlYXRlQmlhc0FkZFByb2dyYW1JbmZvID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuXG4gIGNvbnN0IGNoYW5uZWxzID0gaW5wdXRzWzBdLmRpbXNbMl07XG4gIC8vIHNpbmNlIGNoYW5uZWwgbnVtYmVyIGNhbiBiZSBvbmx5IDMyMC82NDAvMTI4MCwgaXQncyBhbHdheXMgZGl2aXNhYmxlIGJ5IDRcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIDQ7XG5cbiAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBkYXRhVHlwZSwgb3V0cHV0U2hhcGUsIDQpO1xuICBjb25zdCBiaWFzID0gaW5wdXRWYXJpYWJsZSgnYmlhcycsIGRhdGFUeXBlLCBbY2hhbm5lbHNdLCA0KTtcbiAgY29uc3QgcmVzaWR1YWwgPSBpbnB1dFZhcmlhYmxlKCdyZXNpZHVhbCcsIGRhdGFUeXBlLCBvdXRwdXRTaGFwZSwgNCk7XG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBkYXRhVHlwZSwgb3V0cHV0U2hhcGUsIDQpO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICBjb25zdCBjaGFubmVscyA9ICR7Y2hhbm5lbHN9dSAvIDQ7XG4gICR7c2hhZGVySGVscGVyLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIGJpYXMsIHJlc2lkdWFsLCBvdXRwdXQpfVxuXG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMob3V0cHV0U2l6ZSl9XG4gICAgbGV0IHZhbHVlID0gJHtpbnB1dC5nZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcpfVxuICAgICAgKyAke2JpYXMuZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHggJSBjaGFubmVscycpfSArICR7cmVzaWR1YWwuZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnKX07XG4gICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAndmFsdWUnKX1cbiAgfWA7XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnQmlhc0FkZCcsXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBiaWFzQWRkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUJpYXNBZGRQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cykpO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge1xuICBpbnB1dFZhcmlhYmxlLFxuICBvdXRwdXRWYXJpYWJsZSxcbiAgU2hhZGVySGVscGVyLFxuICB0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlLFxuICBVbmlmb3JtRGF0YUVsZW1lbnRUeXBlLFxuICBVbmlmb3Jtc0FycmF5VHlwZSxcbn0gZnJvbSAnLi9jb21tb24nO1xuXG50eXBlIEJ1aWx0aW5GdW5jdGlvbk5hbWUgPSBzdHJpbmc7XG50eXBlIEVsZW1lbnR3aXNlQ3VzdG9tRXhwcmVzc2lvbiA9IChleHByZXNzaW9uOiBzdHJpbmcpID0+IHN0cmluZztcbnR5cGUgRWxlbWVudHdpc2VGdW5jdGlvbkNhbGwgPSBCdWlsdGluRnVuY3Rpb25OYW1lIHwgRWxlbWVudHdpc2VDdXN0b21FeHByZXNzaW9uO1xuXG5jb25zdCBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1TaGFkZXIgPSAoXG4gIHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyLFxuICBkYXRhc2l6ZTogbnVtYmVyLFxuICBpbnB1dERhdGFUeXBlOiBudW1iZXIsXG4gIG91dHB1dERhdGFUeXBlOiBudW1iZXIsXG4gIGZ1bmNDYWxsOiBFbGVtZW50d2lzZUZ1bmN0aW9uQ2FsbCxcbiAgYWRkaXRpb25hbEltcGxlbWVudGF0aW9uPzogc3RyaW5nLFxuICBhZGRpdGlvbmFsVW5pZm9ybXNUeXBlPzogVW5pZm9ybXNBcnJheVR5cGUsXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCB2ZWNTaXplID0gTWF0aC5jZWlsKGRhdGFzaXplIC8gNCk7XG5cbiAgbGV0IGV4cHJlc3Npb24gPSAnJztcbiAgaWYgKHR5cGVvZiBmdW5jQ2FsbCA9PT0gJ3N0cmluZycpIHtcbiAgICBleHByZXNzaW9uID0gYCR7ZnVuY0NhbGx9KGEpYDtcbiAgfSBlbHNlIHtcbiAgICBleHByZXNzaW9uID0gZnVuY0NhbGwoJ2EnKTtcbiAgfVxuXG4gIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXREYXRhJywgaW5wdXREYXRhVHlwZSwgW3ZlY1NpemVdLCA0KTtcbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dERhdGEnLCBvdXRwdXREYXRhVHlwZSwgW3ZlY1NpemVdLCA0KTtcbiAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW3sgbmFtZTogJ3ZlY19zaXplJywgdHlwZTogJ3UzMicgfV07XG4gIGlmIChhZGRpdGlvbmFsVW5pZm9ybXNUeXBlKSB7XG4gICAgdW5pZm9ybXMucHVzaCguLi5hZGRpdGlvbmFsVW5pZm9ybXNUeXBlKTtcbiAgfVxuXG4gIHJldHVybiBgXG4gICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBvdXRwdXQpfVxuXG4gICR7YWRkaXRpb25hbEltcGxlbWVudGF0aW9uID8/ICcnfVxuXG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLnZlY19zaXplJyl9XG5cbiAgICBsZXQgYSA9ICR7aW5wdXQuZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnKX07XG4gICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCBleHByZXNzaW9uKX1cbiAgfWA7XG59O1xuXG5jb25zdCBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvID0gKFxuICBpbnB1dDogVGVuc29yVmlldyxcbiAgbmFtZTogc3RyaW5nLFxuICBmdW5jQ2FsbDogRWxlbWVudHdpc2VGdW5jdGlvbkNhbGwsXG4gIGFkZGl0aW9uYWxJbXBsZW1lbnRhdGlvbj86IHN0cmluZyxcbiAgY2FjaGVLZXk/OiBzdHJpbmcsXG4gIG91dHB1dERhdGFUeXBlOiBudW1iZXIgPSBpbnB1dC5kYXRhVHlwZSxcbiAgYWRkaXRpb25hbFVuaWZvcm1zPzogUHJvZ3JhbVVuaWZvcm1bXSxcbiAgYWRkaXRpb25hbFVuaWZvcm1zVHlwZT86IFVuaWZvcm1zQXJyYXlUeXBlLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IE1hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShpbnB1dC5kaW1zKSAvIDQpIH0sXG4gIF07XG4gIGlmIChhZGRpdGlvbmFsVW5pZm9ybXMpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5hZGRpdGlvbmFsVW5pZm9ybXMpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGNhY2hlS2V5LCBpbnB1dERlcGVuZGVuY2llczogWyd0eXBlJ10gfSxcbiAgICBnZXRTaGFkZXJTb3VyY2U6IChzaGFkZXJIZWxwZXIpID0+XG4gICAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1TaGFkZXIoXG4gICAgICAgIHNoYWRlckhlbHBlcixcbiAgICAgICAgU2hhcGVVdGlsLnNpemUoaW5wdXQuZGltcyksXG4gICAgICAgIGlucHV0LmRhdGFUeXBlLFxuICAgICAgICBvdXRwdXREYXRhVHlwZSxcbiAgICAgICAgZnVuY0NhbGwsXG4gICAgICAgIGFkZGl0aW9uYWxJbXBsZW1lbnRhdGlvbixcbiAgICAgICAgYWRkaXRpb25hbFVuaWZvcm1zVHlwZSxcbiAgICAgICksXG4gICAgZ2V0UnVuRGF0YTogKGlucHV0VGVuc29ycykgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IGlucHV0LmRpbXMsIGRhdGFUeXBlOiBvdXRwdXREYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHtcbiAgICAgICAgeDogTWF0aC5jZWlsKFNoYXBlVXRpbC5zaXplKGlucHV0VGVuc29yc1swXS5kaW1zKSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovIC8gNCAvKiB2ZWMgc2l6ZSAqLyksXG4gICAgICB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFicyA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0FicycsICdhYnMnKSk7XG59O1xuXG5leHBvcnQgY29uc3QgYWNvcyA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0Fjb3MnLCAnYWNvcycpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBhY29zaCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0Fjb3NoJywgJ2Fjb3NoJykpO1xufTtcblxuZXhwb3J0IGNvbnN0IGFzaW4gPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdBc2luJywgJ2FzaW4nKSk7XG59O1xuXG5leHBvcnQgY29uc3QgYXNpbmggPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdBc2luaCcsICdhc2luaCcpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBhdGFuID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnQXRhbicsICdhdGFuJykpO1xufTtcbmV4cG9ydCBjb25zdCBhdGFuaCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0F0YW5oJywgJ2F0YW5oJykpO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBDYXN0QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IHRvOiBudW1iZXI7XG4gIHJlYWRvbmx5IHNhdHVyYXRlPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNvbnN0IHBhcnNlQ2FzdEF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBDYXN0QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoYXR0cmlidXRlcyBhcyB7IHRvOiBudW1iZXIgfSk7XG5cbmV4cG9ydCBjb25zdCBjYXN0ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBDYXN0QXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBsZXQgZnVuYzogRWxlbWVudHdpc2VGdW5jdGlvbkNhbGw7XG4gIHN3aXRjaCAoYXR0cmlidXRlcy50bykge1xuICAgIGNhc2UgRGF0YVR5cGUuZmxvYXQxNjpcbiAgICAgIGZ1bmMgPSAndmVjNDxmMTY+JztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgRGF0YVR5cGUuZmxvYXQ6XG4gICAgICBmdW5jID0gJ3ZlYzQ8ZjMyPic7XG4gICAgICBicmVhaztcbiAgICBjYXNlIERhdGFUeXBlLnVpbnQzMjpcbiAgICAgIGZ1bmMgPSAndmVjNDx1MzI+JztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgRGF0YVR5cGUuaW50MzI6XG4gICAgICBmdW5jID0gJ3ZlYzQ8aTMyPic7XG4gICAgICBicmVhaztcbiAgICBjYXNlIERhdGFUeXBlLmJvb2w6XG4gICAgICBmdW5jID0gJ3ZlYzQ8Ym9vbD4nO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBub3Qgc3VwcG9ydGVkIHR5cGUgKHNwZWNpZmllZCBpbiBhdHRyaWJ1dGUgJ3RvJyBmcm9tICdDYXN0JyBvcGVyYXRvcik6ICR7YXR0cmlidXRlcy50b31gKTtcbiAgfVxuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0Nhc3QnLCBmdW5jLCB1bmRlZmluZWQsIGF0dHJpYnV0ZXMuY2FjaGVLZXksIGF0dHJpYnV0ZXMudG8pLFxuICApO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBDbGlwQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IG1pbjogbnVtYmVyO1xuICByZWFkb25seSBtYXg6IG51bWJlcjtcbn1cblxuY29uc3QgZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiBDbGlwQXR0cmlidXRlcyA9PiB7XG4gIGxldCBtaW46IG51bWJlcjtcbiAgbGV0IG1heDogbnVtYmVyO1xuICBjb25zdCBoYXNNaW4gPSBpbnB1dHMubGVuZ3RoID49IDIgJiYgaW5wdXRzWzFdLmRhdGEgIT09IDA7XG4gIGNvbnN0IGhhc01heCA9IGlucHV0cy5sZW5ndGggPj0gMyAmJiBpbnB1dHNbMl0uZGF0YSAhPT0gMDtcblxuICBzd2l0Y2ggKGlucHV0c1swXS5kYXRhVHlwZSkge1xuICAgIGNhc2UgRGF0YVR5cGUuZmxvYXQ6XG4gICAgICBtaW4gPSBoYXNNaW4gPyBpbnB1dHNbMV0uZ2V0RmxvYXQzMkFycmF5KClbMF0gOiAtMy40MDI4MjM0NjYzODUyODg2ZTM4O1xuICAgICAgbWF4ID0gaGFzTWF4ID8gaW5wdXRzWzJdLmdldEZsb2F0MzJBcnJheSgpWzBdIDogMy40MDI4MjM0NjYzODUyODg2ZTM4O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBEYXRhVHlwZS5mbG9hdDE2OlxuICAgICAgbWluID0gaGFzTWluID8gaW5wdXRzWzFdLmdldFVpbnQxNkFycmF5KClbMF0gOiA2NDUxMTsgLy8gdWludDE2KDY0NTExKSA8LT4gZmxvYXQxNigtNjU1MDQuMClcbiAgICAgIG1heCA9IGhhc01heCA/IGlucHV0c1syXS5nZXRVaW50MTZBcnJheSgpWzBdIDogMzE3NDM7IC8vIHVpbnQxNigzMTc0MykgPC0+IGZsb2F0MTYoNjU1MDQuMClcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydCBkYXRhIHR5cGUnKTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBtaW4sIG1heCB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjbGlwID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBjbGlwQXR0cmlidXRlczogQ2xpcEF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgY29uc3QgYXR0cmlidXRlcyA9IGNsaXBBdHRyaWJ1dGVzID8gY2xpcEF0dHJpYnV0ZXMgOiBnZW5lcmF0ZUNsaXBBdHRyaWJ1dGVzRnJvbUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZShjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSk7XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKFxuICAgICAgY29udGV4dC5pbnB1dHNbMF0sXG4gICAgICAnQ2xpcCcsXG4gICAgICAoYSkgPT4gYGNsYW1wKCR7YX0sIHZlYzQ8JHtkYXRhVHlwZX0+KHVuaWZvcm1zLm1pbiksIHZlYzQ8JHtkYXRhVHlwZX0+KHVuaWZvcm1zLm1heCkpYCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBbXG4gICAgICAgIHsgdHlwZTogY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUsIGRhdGE6IGF0dHJpYnV0ZXMubWluIH0sXG4gICAgICAgIHsgdHlwZTogY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUsIGRhdGE6IGF0dHJpYnV0ZXMubWF4IH0sXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICB7IG5hbWU6ICdtaW4nLCB0eXBlOiBkYXRhVHlwZSBhcyBVbmlmb3JtRGF0YUVsZW1lbnRUeXBlIH0sXG4gICAgICAgIHsgbmFtZTogJ21heCcsIHR5cGU6IGRhdGFUeXBlIGFzIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUgfSxcbiAgICAgIF0sXG4gICAgKSxcbiAgICB7IGlucHV0czogWzBdIH0sXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgY2VpbCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0NlaWwnLCAnY2VpbCcpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb3MgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdDb3MnLCAnY29zJykpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvc2ggPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdDb3NoJywgJ2Nvc2gnKSk7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEFscGhhQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGFscGhhOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBwYXJzZUFscGhhQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEFscGhhQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoYXR0cmlidXRlcyBhcyB7IGFscGhhOiBudW1iZXIgfSk7XG5cbmV4cG9ydCBjb25zdCBlbHUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEFscGhhQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpO1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLFxuICAgICAgJ0VsdScsXG4gICAgICAoYSkgPT4gYGVsdV92ZjMyKCR7YX0pYCxcbiAgICAgIGBcbiAgY29uc3QgZWx1X2FscGhhXyA9ICR7ZGF0YVR5cGV9KCR7YXR0cmlidXRlcy5hbHBoYX0pO1xuXG4gIGZuIGVsdV9mMzIoYTogJHtkYXRhVHlwZX0pIC0+ICR7ZGF0YVR5cGV9IHtcbiAgcmV0dXJuIHNlbGVjdCgoZXhwKGEpIC0gMS4wKSAqIGVsdV9hbHBoYV8sIGEsIGEgPj0gMC4wKTtcbiAgfVxuXG4gIGZuIGVsdV92ZjMyKHY6IHZlYzQ8JHtkYXRhVHlwZX0+KSAtPiB2ZWM0PCR7ZGF0YVR5cGV9PiB7XG4gIHJldHVybiB2ZWM0KGVsdV9mMzIodi54KSwgZWx1X2YzMih2LnkpLCBlbHVfZjMyKHYueiksIGVsdV9mMzIodi53KSk7XG4gIH1gLFxuICAgICAgYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICApLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGVyZkltcGwgPSAodmFyVHlwZSA9ICdmMzInKSA9PiBgXG5jb25zdCByMDogJHt2YXJUeXBlfSA9IDAuMzI3NTkxMTtcbmNvbnN0IHIxOiAke3ZhclR5cGV9ID0gMC4yNTQ4Mjk1OTI7XG5jb25zdCByMjogJHt2YXJUeXBlfSA9IC0wLjI4NDQ5NjczNjtcbmNvbnN0IHIzOiAke3ZhclR5cGV9ID0gMS40MjE0MTM3NDE7XG5jb25zdCByNDogJHt2YXJUeXBlfSA9IC0xLjQ1MzE1MjAyNztcbmNvbnN0IHI1OiAke3ZhclR5cGV9ID0gMS4wNjE0MDU0Mjk7XG5cbmZuIGVyZl92ZjMyKHY6IHZlYzQ8JHt2YXJUeXBlfT4pIC0+IHZlYzQ8JHt2YXJUeXBlfT4ge1xuICBsZXQgYWJzdiA9IGFicyh2KTtcbiAgbGV0IHggPSAxLjAgLyAoMS4wICsgcjAgKiBhYnN2KTtcbiAgcmV0dXJuIHNpZ24odikgKiAoMS4wIC0gKCgoKHI1ICogeCArIHI0KSAqIHggKyByMykgKiB4ICsgcjIpICogeCArIHIxKSAqIHggKiBleHAoLWFic3YgKiBhYnN2KSk7XG59YDtcblxuZXhwb3J0IGNvbnN0IGVyZiA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0VyZicsIChhKSA9PiBgZXJmX3ZmMzIoJHthfSlgLCBlcmZJbXBsKGRhdGFUeXBlKSkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGV4cCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0V4cCcsICdleHAnKSk7XG59O1xuXG5leHBvcnQgY29uc3QgZmxvb3IgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdGbG9vcicsICdmbG9vcicpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZWx1ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZShjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSk7XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKFxuICAgICAgY29udGV4dC5pbnB1dHNbMF0sXG4gICAgICAnR2VsdScsXG4gICAgICAoYSkgPT4gYDAuNSAqICR7YX0gKiAoMS4wICsgZXJmX3ZmMzIoJHthfSAqIDAuNzA3MTA2NzgxMTg2NTQ3NSkpYCxcbiAgICAgIGVyZkltcGwoZGF0YVR5cGUpLFxuICAgICksXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgbGVha3lSZWx1ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBbHBoYUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlKGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oXG4gICAgICBjb250ZXh0LmlucHV0c1swXSxcbiAgICAgICdMZWFreVJlbHUnLFxuICAgICAgKGEpID0+IGBzZWxlY3QobGVha3lfcmVsdV9hbHBoYV8gKiAke2F9LCAke2F9LCAke2F9ID49IHZlYzQ8JHtkYXRhVHlwZX0+KDAuMCkpYCxcbiAgICAgIGBjb25zdCBsZWFreV9yZWx1X2FscGhhXyA9ICR7ZGF0YVR5cGV9KCR7YXR0cmlidXRlcy5hbHBoYX0pO2AsXG4gICAgICBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICksXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3Qgbm90ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCAnTm90JywgKGEpID0+IGAhJHthfWApKTtcbn07XG5cbmV4cG9ydCBjb25zdCBuZWcgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdOZWcnLCAoYSkgPT4gYC0ke2F9YCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlY2lwcm9jYWwgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdSZWNpcHJvY2FsJywgKGEpID0+IGAxLjAvJHthfWApKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWx1ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZShjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSk7XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKFxuICAgICAgY29udGV4dC5pbnB1dHNbMF0sXG4gICAgICAnUmVsdScsXG4gICAgICAoYSkgPT4gYHNlbGVjdCh2ZWM0PCR7ZGF0YVR5cGV9PigwLjApLCAke2F9LCAke2F9ID4gdmVjNDwke2RhdGFUeXBlfT4oMC4wKSlgLFxuICAgICksXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbW9pZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ1NpZ21vaWQnLCAoYSkgPT4gYCgxLjAgLyAoMS4wICsgZXhwKC0ke2F9KSkpYCkpO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBIYXJkU2lnbW9pZEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhbHBoYTogbnVtYmVyO1xuICByZWFkb25seSBiZXRhOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBwYXJzZUhhcmRTaWdtb2lkQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEhhcmRTaWdtb2lkQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoXG4gICAgYXR0cmlidXRlcyBhcyB7XG4gICAgICBhbHBoYTogbnVtYmVyO1xuICAgICAgYmV0YTogbnVtYmVyO1xuICAgIH0sXG4gICk7XG5cbmV4cG9ydCBjb25zdCBoYXJkU2lnbW9pZCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogSGFyZFNpZ21vaWRBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZShjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSk7XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKFxuICAgICAgY29udGV4dC5pbnB1dHNbMF0sXG4gICAgICAnSGFyZFNpZ21vaWQnLFxuICAgICAgKGEpID0+XG4gICAgICAgIGBtYXgodmVjNDwke2RhdGFUeXBlfT4oMC4wKSwgbWluKHZlYzQ8JHtkYXRhVHlwZX0+KDEuMCksICR7YXR0cmlidXRlcy5hbHBoYX0gKiAke2F9ICsgdmVjNDwke2RhdGFUeXBlfT4oJHthdHRyaWJ1dGVzLmJldGF9KSkpYCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgKSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaW4gPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdTaW4nLCAnc2luJykpO1xufTtcblxuZXhwb3J0IGNvbnN0IHNpbmggPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdTaW5oJywgJ3NpbmgnKSk7XG59O1xuXG5leHBvcnQgY29uc3Qgc3FydCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ1NxcnQnLCAnc3FydCcpKTtcbn07XG5cbmV4cG9ydCBjb25zdCB0YW4gPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdUYW4nLCAndGFuJykpO1xufTtcblxuZXhwb3J0IGNvbnN0IHRhbmhFeHByZXNzaW9uID0gKGE6IHN0cmluZykgPT4gYHNpZ24oJHthfSkgKiAoMSAtIGV4cCgtMiAqIGFicygke2F9KSkpIC8gKDEgKyBleHAoLTIgKiBhYnMoJHthfSkpKWA7XG5cbmV4cG9ydCBjb25zdCB0YW5oID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIC8vIFRPRE86IHJldmlzaXQgYWZ0ZXIgaHR0cHM6Ly9naXRodWIuY29tL2dwdXdlYi9ncHV3ZWIvaXNzdWVzLzQ0NTggaXMgcmVzb2x2ZWRcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sICdUYW5oJywgdGFuaEV4cHJlc3Npb24pKTtcbn07XG5cbmV4cG9ydCBjb25zdCBmYXN0R2VsdUltcGwgPSAodmFyVHlwZSA9ICdmMzInKSA9PiBgXG5jb25zdCBmYXN0X2dlbHVfYTogJHt2YXJUeXBlfSA9IDAuNTtcbmNvbnN0IGZhc3RfZ2VsdV9iOiAke3ZhclR5cGV9ID0gMC43OTc4ODQ1NjA4MDI4NjU0O1xuY29uc3QgZmFzdF9nZWx1X2M6ICR7dmFyVHlwZX0gPSAwLjAzNTY3NzQwODEzNjMwMDEyNTtcblxuZm4gdGFuaF92KHY6IHZlYzQ8JHt2YXJUeXBlfT4pIC0+IHZlYzQ8JHt2YXJUeXBlfT4ge1xuICByZXR1cm4gJHt0YW5oRXhwcmVzc2lvbigndicpfTtcbn1cbmA7XG5cbmV4cG9ydCBjb25zdCBmYXN0R2VsdUV4cHJlc3Npb24gPSAoeDogc3RyaW5nKSA9PlxuICBgKGZhc3RfZ2VsdV9hICsgZmFzdF9nZWx1X2EgKiB0YW5oX3YoJHt4fSAqIChmYXN0X2dlbHVfYyAqICR7eH0gKiAke3h9ICsgZmFzdF9nZWx1X2IpKSkgKiAke3h9YDtcblxuZXhwb3J0IGNvbnN0IGZhc3RHZWx1ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFZhbHVlVHlwZShjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSk7XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvKFxuICAgICAgY29udGV4dC5pbnB1dHNbMF0sXG4gICAgICAnRmFzdEdlbHUnLFxuICAgICAgZmFzdEdlbHVFeHByZXNzaW9uLFxuICAgICAgZmFzdEdlbHVJbXBsKGRhdGFUeXBlKSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlLFxuICAgICksXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgdGhyZXNob2xkZWRSZWx1ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBbHBoYUF0dHJpYnV0ZXMpOiBudW1iZXIgPT4ge1xuICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpO1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLFxuICAgICAgJ1RocmVzaG9sZGVkUmVsdScsXG4gICAgICAoYSkgPT4gYHNlbGVjdCh2ZWM0PCR7ZGF0YVR5cGV9PigwLjApLCAke2F9LCAke2F9ID4gdGhyZXNob2xkZWRfcmVsdV9hbHBoYV8pYCxcbiAgICAgIGBjb25zdCB0aHJlc2hvbGRlZF9yZWx1X2FscGhhXyA9IHZlYzQ8JHtkYXRhVHlwZX0+KCR7YXR0cmlidXRlcy5hbHBoYX0pO2AsXG4gICAgICBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICksXG4gICk7XG4gIHJldHVybiAwO1xufTtcblxuZXhwb3J0IGNvbnN0IGxvZyA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0c1swXSwgJ0xvZycsICdsb2cnKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcXVpY2tHZWx1SW1wbCA9ICh2YXJUeXBlOiBzdHJpbmcsIGFscGhhOiBudW1iZXIpID0+IGBcbmNvbnN0IGFscGhhID0gdmVjNDwke3ZhclR5cGV9Pigke2FscGhhfSk7XG5jb25zdCBvbmUgPSAke3ZhclR5cGV9KDEuMCk7XG5jb25zdCB6ZXJvID0gJHt2YXJUeXBlfSgwLjApO1xuXG5mbiBxdWlja19nZWx1X2ltcGwoeDogdmVjNDwke3ZhclR5cGV9PikgLT4gdmVjNDwke3ZhclR5cGV9PiB7XG4gIGxldCB2ID0geCAqYWxwaGE7XG4gIHZhciB4MSA6IHZlYzQ8JHt2YXJUeXBlfT47XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSA9IGkgKyAxKSB7XG4gICAgaWYgKHZbaV0gPj0gemVybykge1xuICAgICAgeDFbaV0gPSBvbmUgLyAob25lICsgZXhwKC12W2ldKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHgxW2ldID0gb25lIC0gb25lIC8gKG9uZSArIGV4cCh2W2ldKSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB4ICogeDE7XG59XG5gO1xuXG5leHBvcnQgY29uc3QgcXVpY2tHZWx1RXhwcmVzc2lvbiA9ICh4OiBzdHJpbmcpID0+IGBxdWlja19nZWx1X2ltcGwoJHt4fSlgO1xuXG5leHBvcnQgY29uc3QgcXVpY2tnZWx1ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBbHBoYUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgY29uc3QgZFR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlKGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oXG4gICAgICBjb250ZXh0LmlucHV0c1swXSxcbiAgICAgICdRdWlja0dlbHUnLFxuICAgICAgcXVpY2tHZWx1RXhwcmVzc2lvbixcbiAgICAgIHF1aWNrR2VsdUltcGwoZFR5cGUsIGF0dHJpYnV0ZXMuYWxwaGEpLFxuICAgICAgYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlLFxuICAgICksXG4gICk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGlucHV0VmFyaWFibGUsIG91dHB1dFZhcmlhYmxlLCBTaGFkZXJIZWxwZXIsIHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSB9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7IGVyZkltcGwgfSBmcm9tICcuL3VuYXJ5LW9wJztcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiB2b2lkID0+IHtcbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hvdWxkIGhhdmUgMyBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBpZiAoIVsyNTYwLCA1MTIwLCAxMDI0MF0uaW5jbHVkZXMoaW5wdXRzWzBdLmRpbXNbMl0pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdoaWRkZW4gc3RhdGUgc2hvdWxkIGJlIDI1NjAsIDUxMjAgb3IgMTAyNDAnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2JpYXMgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAxIGRpbWVuc2lvbnMnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltc1syXSAhPT0gaW5wdXRzWzFdLmRpbXNbMF0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2xhc3QgZGltZW5zaW9uIG9mIGlucHV0IGFuZCBiaWFzIGFyZSBub3QgdGhlIHNhbWUnKTtcbiAgfVxufTtcblxuY29uc3QgY3JlYXRlQmlhc1NwbGl0R2VsdVByb2dyYW1JbmZvID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gIG91dHB1dFNoYXBlWzJdID0gb3V0cHV0U2hhcGVbMl0gLyAyO1xuXG4gIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zLCA0KTtcbiAgY29uc3QgYmlhcyA9IGlucHV0VmFyaWFibGUoJ2JpYXMnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIFtpbnB1dHNbMF0uZGltc1syXV0sIDQpO1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZSwgNCk7XG5cbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIDQ7XG4gIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKGlucHV0c1swXS5kYXRhVHlwZSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gIGNvbnN0IE1fU1FSVDIgPSBzcXJ0KDIuMCk7XG4gIGNvbnN0IGhhbGZDaGFubmVscyA9ICR7aW5wdXRzWzBdLmRpbXNbMl0gLyA0IC8gMn11O1xuXG4gICR7c2hhZGVySGVscGVyLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIGJpYXMsIG91dHB1dCl9XG5cbiAgJHtlcmZJbXBsKGRhdGFUeXBlKX1cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKG91dHB1dFNpemUpfVxuICAgIGxldCBiaWFzSWR4ID0gZ2xvYmFsX2lkeCAlIGhhbGZDaGFubmVscztcbiAgICBsZXQgYmF0Y2hJbmRleCA9IGdsb2JhbF9pZHggLyBoYWxmQ2hhbm5lbHM7XG4gICAgbGV0IGlucHV0T2Zmc2V0ID0gYmlhc0lkeCArIGJhdGNoSW5kZXggKiBoYWxmQ2hhbm5lbHMgKiAyO1xuICAgIGxldCB2YWx1ZUxlZnQgPSBpbnB1dFtpbnB1dE9mZnNldF0gKyBiaWFzW2JpYXNJZHhdO1xuICAgIGxldCB2YWx1ZVJpZ2h0ID0gaW5wdXRbaW5wdXRPZmZzZXQgKyBoYWxmQ2hhbm5lbHNdICsgYmlhc1tiaWFzSWR4ICsgaGFsZkNoYW5uZWxzXTtcbiAgICBsZXQgZ2VsdVJpZ2h0ID0gdmFsdWVSaWdodCAqIDAuNSAqIChlcmZfdmYzMih2YWx1ZVJpZ2h0IC8gTV9TUVJUMikgKyAxKTtcblxuICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3ZhbHVlTGVmdCAqIGdlbHVSaWdodCcpfVxuICB9YDtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdCaWFzU3BsaXRHZWx1JyxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGJpYXNTcGxpdEdlbHUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlQmlhc1NwbGl0R2VsdVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzKSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbyB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsIGlucHV0VmFyaWFibGUsIG91dHB1dFZhcmlhYmxlLCBTaGFkZXJIZWxwZXIgfSBmcm9tICcuL2NvbW1vbic7XG5cbnR5cGUgQnVpbHRpbkZ1bmN0aW9uTmFtZSA9IHN0cmluZztcbnR5cGUgQmluYXJ5Q3VzdG9tRXhwcmVzc2lvbiA9IChleHByZXNzaW9uQTogc3RyaW5nLCBleHByZXNzaW9uQjogc3RyaW5nKSA9PiBzdHJpbmc7XG50eXBlIEJpbmFyeUZ1bmN0aW9uQ2FsbCA9XG4gIHwgQnVpbHRpbkZ1bmN0aW9uTmFtZVxuICB8IEJpbmFyeUN1c3RvbUV4cHJlc3Npb25cbiAgfCB7XG4gICAgICBzY2FsYXI6IEJpbmFyeUN1c3RvbUV4cHJlc3Npb247XG4gICAgICB2ZWN0b3I6IEJpbmFyeUN1c3RvbUV4cHJlc3Npb247XG4gICAgfTtcblxuY29uc3QgY3JlYXRlQmluYXJ5T3BQcm9ncmFtU2hhZGVyID0gKFxuICBzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcixcbiAgZGltc0E6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkaW1zQjogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGRpbXNPdXRwdXQ6IHJlYWRvbmx5IG51bWJlcltdLFxuICB2ZWN0b3JpemU6IGJvb2xlYW4sXG4gIGRvQnJvYWRjYXN0OiBib29sZWFuLFxuICBzaGFyZWREaW1lbnNpb25EaXZpc2libGVCeTQ6IGJvb2xlYW4sXG4gIGZ1bmNDYWxsOiBCaW5hcnlGdW5jdGlvbkNhbGwsXG4gIHR5cGVBOiBudW1iZXIsXG4gIHR5cGVCOiBudW1iZXIsXG4gIHR5cGVPdXRwdXQ6IG51bWJlcixcbiAgYWRkaXRpb25hbEltcGxlbWVudGF0aW9uPzogc3RyaW5nLFxuKSA9PiB7XG4gIGxldCBleHByZXNzaW9uU2NhbGFyOiBCaW5hcnlDdXN0b21FeHByZXNzaW9uO1xuICBsZXQgZXhwcmVzc2lvblZlY3RvcjogQmluYXJ5Q3VzdG9tRXhwcmVzc2lvbjtcbiAgaWYgKHR5cGVvZiBmdW5jQ2FsbCA9PT0gJ3N0cmluZycpIHtcbiAgICBleHByZXNzaW9uU2NhbGFyID0gZXhwcmVzc2lvblZlY3RvciA9IChhLCBiKSA9PiBgJHtmdW5jQ2FsbH0oKCR7YX0pLCgke2J9KSlgO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBmdW5jQ2FsbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV4cHJlc3Npb25TY2FsYXIgPSBleHByZXNzaW9uVmVjdG9yID0gZnVuY0NhbGw7XG4gIH0gZWxzZSB7XG4gICAgZXhwcmVzc2lvblNjYWxhciA9IGZ1bmNDYWxsLnNjYWxhcjtcbiAgICBleHByZXNzaW9uVmVjdG9yID0gZnVuY0NhbGwudmVjdG9yO1xuICB9XG5cbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dERhdGEnLCB0eXBlT3V0cHV0LCBkaW1zT3V0cHV0Lmxlbmd0aCwgNCk7XG4gIGNvbnN0IGEgPSBpbnB1dFZhcmlhYmxlKCdhRGF0YScsIHR5cGVBLCBkaW1zQS5sZW5ndGgsIDQpO1xuICBjb25zdCBiID0gaW5wdXRWYXJpYWJsZSgnYkRhdGEnLCB0eXBlQiwgZGltc0IubGVuZ3RoLCA0KTtcblxuICBsZXQgYXNzaWdubWVudDogc3RyaW5nO1xuICBpZiAodmVjdG9yaXplKSB7XG4gICAgaWYgKGRvQnJvYWRjYXN0KSB7XG4gICAgICBjb25zdCBpc0FPbmVFbGVtZW50ID0gU2hhcGVVdGlsLnNpemUoZGltc0EpID09PSAxO1xuICAgICAgY29uc3QgaXNCT25lRWxlbWVudCA9IFNoYXBlVXRpbC5zaXplKGRpbXNCKSA9PT0gMTtcbiAgICAgIGNvbnN0IGFMYXN0RGltRGl2aXNpYmxlQnk0ID0gZGltc0EubGVuZ3RoID4gMCAmJiBkaW1zQVtkaW1zQS5sZW5ndGggLSAxXSAlIDQgPT09IDA7XG4gICAgICBjb25zdCBiTGFzdERpbURpdmlzaWJsZUJ5NCA9IGRpbXNCLmxlbmd0aCA+IDAgJiYgZGltc0JbZGltc0IubGVuZ3RoIC0gMV0gJSA0ID09PSAwO1xuICAgICAgaWYgKGlzQU9uZUVsZW1lbnQgfHwgaXNCT25lRWxlbWVudCkge1xuICAgICAgICBhc3NpZ25tZW50ID0gb3V0cHV0LnNldEJ5T2Zmc2V0KFxuICAgICAgICAgICdnbG9iYWxfaWR4JyxcbiAgICAgICAgICBleHByZXNzaW9uVmVjdG9yKFxuICAgICAgICAgICAgaXNBT25lRWxlbWVudCA/IGAke2EudHlwZS52YWx1ZX0oJHthLmdldEJ5T2Zmc2V0KCcwJyl9LngpYCA6IGEuZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnKSxcbiAgICAgICAgICAgIGlzQk9uZUVsZW1lbnQgPyBgJHtiLnR5cGUudmFsdWV9KCR7Yi5nZXRCeU9mZnNldCgnMCcpfS54KWAgOiBiLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JyksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFzc2lnbm1lbnQgPSBgXG4gICAgICAgICAgICBsZXQgb3V0cHV0SW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCAqIDR1Jyl9O1xuICAgICAgICAgICAgbGV0IG9mZnNldEEgPSAke2EuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoJ291dHB1dEluZGljZXMnLCBvdXRwdXQpfTtcbiAgICAgICAgICAgIGxldCBvZmZzZXRCID0gJHtiLmJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0KCdvdXRwdXRJbmRpY2VzJywgb3V0cHV0KX07XG4gICAgICAgICAgICAke291dHB1dC5zZXRCeU9mZnNldChcbiAgICAgICAgICAgICAgJ2dsb2JhbF9pZHgnLFxuICAgICAgICAgICAgICBleHByZXNzaW9uVmVjdG9yKFxuICAgICAgICAgICAgICAgIHNoYXJlZERpbWVuc2lvbkRpdmlzaWJsZUJ5NCB8fCBhTGFzdERpbURpdmlzaWJsZUJ5NFxuICAgICAgICAgICAgICAgICAgPyBhLmdldEJ5T2Zmc2V0KCdvZmZzZXRBIC8gNHUnKVxuICAgICAgICAgICAgICAgICAgOiBgJHthLnR5cGUudmFsdWV9KCR7YS5nZXRCeU9mZnNldCgnb2Zmc2V0QSAvIDR1Jyl9W29mZnNldEEgJSA0dV0pYCxcbiAgICAgICAgICAgICAgICBzaGFyZWREaW1lbnNpb25EaXZpc2libGVCeTQgfHwgYkxhc3REaW1EaXZpc2libGVCeTRcbiAgICAgICAgICAgICAgICAgID8gYi5nZXRCeU9mZnNldCgnb2Zmc2V0QiAvIDR1JylcbiAgICAgICAgICAgICAgICAgIDogYCR7Yi50eXBlLnZhbHVlfSgke2IuZ2V0QnlPZmZzZXQoJ29mZnNldEIgLyA0dScpfVtvZmZzZXRCICUgNHVdKWAsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApfVxuICAgICAgICAgIGA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2lnbm1lbnQgPSBvdXRwdXQuc2V0QnlPZmZzZXQoXG4gICAgICAgICdnbG9iYWxfaWR4JyxcbiAgICAgICAgZXhwcmVzc2lvblZlY3RvcihhLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JyksIGIuZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnKSksXG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoIWRvQnJvYWRjYXN0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIG5lY2Vzc2FyeSB0byB1c2Ugc2NhbGFyIGltcGxlbWVudGF0aW9uIGZvciBlbGVtZW50LXdpc2UgYmluYXJ5IG9wIGltcGxlbWVudGF0aW9uLicpO1xuICAgIH1cblxuICAgIGNvbnN0IHNpbmdsZUFzc2lnbm1lbnQgPSAocmVzU3RyOiBzdHJpbmcsIHg6IG51bWJlciwgdHlwZUNhc3QgPSAnJykgPT4ge1xuICAgICAgY29uc3QgZXhwcmVzc2lvbkEgPSBgYURhdGFbaW5kZXhBJHt4fV1bY29tcG9uZW50QSR7eH1dYDtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb25CID0gYGJEYXRhW2luZGV4QiR7eH1dW2NvbXBvbmVudEIke3h9XWA7XG4gICAgICByZXR1cm4gYFxuICAgICAgICAgICAgbGV0IG91dHB1dEluZGljZXMke3h9ID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKGBnbG9iYWxfaWR4ICogNHUgKyAke3h9dWApfTtcbiAgICAgICAgICAgIGxldCBvZmZzZXRBJHt4fSA9ICR7YS5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldChgb3V0cHV0SW5kaWNlcyR7eH1gLCBvdXRwdXQpfTtcbiAgICAgICAgICAgIGxldCBvZmZzZXRCJHt4fSA9ICR7Yi5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldChgb3V0cHV0SW5kaWNlcyR7eH1gLCBvdXRwdXQpfTtcbiAgICAgICAgICAgIGxldCBpbmRleEEke3h9ID0gb2Zmc2V0QSR7eH0gLyA0dTtcbiAgICAgICAgICAgIGxldCBpbmRleEIke3h9ID0gb2Zmc2V0QiR7eH0gLyA0dTtcbiAgICAgICAgICAgIGxldCBjb21wb25lbnRBJHt4fSA9IG9mZnNldEEke3h9ICUgNHU7XG4gICAgICAgICAgICBsZXQgY29tcG9uZW50QiR7eH0gPSBvZmZzZXRCJHt4fSAlIDR1O1xuICAgICAgICAgICAgJHtyZXNTdHJ9WyR7eH1dID0gJHt0eXBlQ2FzdH0oJHtleHByZXNzaW9uU2NhbGFyKGV4cHJlc3Npb25BLCBleHByZXNzaW9uQil9KTtcbiAgICAgICAgICBgO1xuICAgIH07XG4gICAgaWYgKHR5cGVPdXRwdXQgPT09IERhdGFUeXBlLmJvb2wpIHtcbiAgICAgIGFzc2lnbm1lbnQgPSBgXG4gICAgICAgICAgICB2YXIgZGF0YSA9IHZlYzQ8dTMyPigwKTtcbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDAsICd1MzInKX1cbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDEsICd1MzInKX1cbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDIsICd1MzInKX1cbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDMsICd1MzInKX1cbiAgICAgICAgICAgIG91dHB1dERhdGFbZ2xvYmFsX2lkeF0gPSBkb3QodmVjNDx1MzI+KDB4MSwgMHgxMDAsIDB4MTAwMDAsIDB4MTAwMDAwMCksIHZlYzQ8dTMyPihkYXRhKSk7YDtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzaWdubWVudCA9IGBcbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnb3V0cHV0RGF0YVtnbG9iYWxfaWR4XScsIDApfVxuICAgICAgICAgICAgJHtzaW5nbGVBc3NpZ25tZW50KCdvdXRwdXREYXRhW2dsb2JhbF9pZHhdJywgMSl9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ291dHB1dERhdGFbZ2xvYmFsX2lkeF0nLCAyKX1cbiAgICAgICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnb3V0cHV0RGF0YVtnbG9iYWxfaWR4XScsIDMpfVxuICAgICAgICAgIGA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGBcbiAgICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3JtKCd2ZWNfc2l6ZScsICd1MzInKS5kZWNsYXJlVmFyaWFibGVzKGEsIGIsIG91dHB1dCl9XG5cbiAgICAgICAgJHthZGRpdGlvbmFsSW1wbGVtZW50YXRpb24gPz8gJyd9XG5cbiAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLnZlY19zaXplJyl9XG4gICAgICAgICR7YXNzaWdubWVudH1cbiAgICAgIH1gO1xufTtcblxuY29uc3QgY3JlYXRlQmluYXJ5T3BQcm9ncmFtSW5mbyA9IChcbiAgbmFtZTogc3RyaW5nLFxuICBjYWNoZUtleTogc3RyaW5nLFxuICBhOiBUZW5zb3JWaWV3LFxuICBiOiBUZW5zb3JWaWV3LFxuICBmdW5jQ2FsbDogQmluYXJ5RnVuY3Rpb25DYWxsLFxuICBhZGRpdGlvbmFsSW1wbGVtZW50YXRpb24/OiBzdHJpbmcsXG4gIG91dHB1dERhdGFUeXBlOiBudW1iZXIgPSBhLmRhdGFUeXBlLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBhRGltcyA9IGEuZGltcy5tYXAoKHgpID0+IE51bWJlcih4KSA/PyAxKTtcbiAgY29uc3QgYkRpbXMgPSBiLmRpbXMubWFwKCh4KSA9PiBOdW1iZXIoeCkgPz8gMSk7XG4gIGNvbnN0IGlzQnJvYWRjYXN0ID0gIVNoYXBlVXRpbC5hcmVFcXVhbChhRGltcywgYkRpbXMpO1xuICBsZXQgb3V0cHV0U2hhcGUgPSBhRGltcztcbiAgbGV0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShhRGltcyk7XG5cbiAgbGV0IHZlY3Rvcml6ZSA9IGZhbHNlO1xuICBsZXQgc2hhcmVkRGltZW5zaW9uRGl2aXNpYmxlQnk0ID0gZmFsc2U7XG5cbiAgLy8gVE9ETzogZGVhbCB3aXRoIHplcm8tc2l6ZWQgdGVuc29ycyAoZWcuIGRpbXM9WzEsMF0pXG4gIGNvbnN0IGNhY2hlS2V5QXV4ID0gW2lzQnJvYWRjYXN0XTtcbiAgaWYgKGlzQnJvYWRjYXN0KSB7XG4gICAgY29uc3QgY2FsY3VsYXRlZFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoYURpbXMsIGJEaW1zLCBmYWxzZSk7XG4gICAgaWYgKCFjYWxjdWxhdGVkU2hhcGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHBlcmZvcm0gYmluYXJ5IG9wIG9uIHRoZSBnaXZlbiB0ZW5zb3JzXCIpO1xuICAgIH1cbiAgICBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZWRTaGFwZS5zbGljZSgpO1xuICAgIG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gICAgY29uc3QgaXNBT25lRWxlbWVudCA9IFNoYXBlVXRpbC5zaXplKGFEaW1zKSA9PT0gMTtcbiAgICBjb25zdCBpc0JPbmVFbGVtZW50ID0gU2hhcGVVdGlsLnNpemUoYkRpbXMpID09PSAxO1xuICAgIGNvbnN0IGFMYXN0RGltRGl2aXNpYmxlQnk0ID0gYURpbXMubGVuZ3RoID4gMCAmJiBhRGltc1thRGltcy5sZW5ndGggLSAxXSAlIDQgPT09IDA7XG4gICAgY29uc3QgYkxhc3REaW1EaXZpc2libGVCeTQgPSBiRGltcy5sZW5ndGggPiAwICYmIGJEaW1zW2JEaW1zLmxlbmd0aCAtIDFdICUgNCA9PT0gMDtcbiAgICBjYWNoZUtleUF1eC5wdXNoKGlzQU9uZUVsZW1lbnQpO1xuICAgIGNhY2hlS2V5QXV4LnB1c2goaXNCT25lRWxlbWVudCk7XG4gICAgY2FjaGVLZXlBdXgucHVzaChhTGFzdERpbURpdmlzaWJsZUJ5NCk7XG4gICAgY2FjaGVLZXlBdXgucHVzaChiTGFzdERpbURpdmlzaWJsZUJ5NCk7XG4gICAgLy8gY2hlY2sgd2hldGhlciB2ZWN0b3JpemUgY2FuIGJlIGVuYWJsZWRcbiAgICBsZXQgc2hhcmVkRGltZW5zaW9uID0gMTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IG91dHB1dFNoYXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBkaW1BID0gYURpbXNbYURpbXMubGVuZ3RoIC0gaV07XG4gICAgICBjb25zdCBkaW1CID0gYkRpbXNbYkRpbXMubGVuZ3RoIC0gaV07XG4gICAgICBpZiAoZGltQSA9PT0gZGltQikge1xuICAgICAgICBzaGFyZWREaW1lbnNpb24gKj0gZGltQTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2hhcmVkRGltZW5zaW9uICUgNCA9PT0gMCkge1xuICAgICAgc2hhcmVkRGltZW5zaW9uRGl2aXNpYmxlQnk0ID0gdHJ1ZTtcbiAgICAgIHZlY3Rvcml6ZSA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChpc0FPbmVFbGVtZW50IHx8IGlzQk9uZUVsZW1lbnQgfHwgYUxhc3REaW1EaXZpc2libGVCeTQgfHwgYkxhc3REaW1EaXZpc2libGVCeTQpIHtcbiAgICAgIHZlY3Rvcml6ZSA9IHRydWU7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIGVsZW1lbnQtd2lzZVxuICAgIHZlY3Rvcml6ZSA9IHRydWU7XG4gIH1cbiAgY2FjaGVLZXlBdXgucHVzaCh2ZWN0b3JpemUpO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZSxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogY2FjaGVLZXkgKyBjYWNoZUtleUF1eC5tYXAoKHgpID0+IHgudG9TdHJpbmcoKSkuam9pbignXycpLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuaycsICdyYW5rJ10sXG4gICAgfSxcbiAgICBnZXRTaGFkZXJTb3VyY2U6IChzaGFkZXJIZWxwZXIpID0+XG4gICAgICBjcmVhdGVCaW5hcnlPcFByb2dyYW1TaGFkZXIoXG4gICAgICAgIHNoYWRlckhlbHBlcixcbiAgICAgICAgYURpbXMsXG4gICAgICAgIGJEaW1zLFxuICAgICAgICBvdXRwdXRTaGFwZSxcbiAgICAgICAgdmVjdG9yaXplLFxuICAgICAgICBpc0Jyb2FkY2FzdCxcbiAgICAgICAgc2hhcmVkRGltZW5zaW9uRGl2aXNpYmxlQnk0LFxuICAgICAgICBmdW5jQ2FsbCxcbiAgICAgICAgYS5kYXRhVHlwZSxcbiAgICAgICAgYi5kYXRhVHlwZSxcbiAgICAgICAgb3V0cHV0RGF0YVR5cGUsXG4gICAgICAgIGFkZGl0aW9uYWxJbXBsZW1lbnRhdGlvbixcbiAgICAgICksXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogb3V0cHV0RGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8gLyA0IC8qIGNvbXBvbmVudCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zOiBbXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBNYXRoLmNlaWwoU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gNCkgfSxcbiAgICAgICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoYURpbXMsIGJEaW1zLCBvdXRwdXRTaGFwZSksXG4gICAgICBdLFxuICAgIH0pLFxuICB9O1xufTtcblxuY29uc3QgcnVuQmluYXJ5T3AgPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBuYW1lOiBzdHJpbmcsXG4gIGZ1bmNDYWxsOiBCaW5hcnlGdW5jdGlvbkNhbGwsXG4gIGFkZGl0aW9uYWxJbXBsZW1lbnRhdGlvbj86IHN0cmluZyxcbiAgY2FjaGVLZXk/OiBzdHJpbmcsXG4gIG91dHB1dERhdGFUeXBlPzogbnVtYmVyLFxuKTogdm9pZCA9PiB7XG4gIGNvbnRleHQuY29tcHV0ZShcbiAgICBjcmVhdGVCaW5hcnlPcFByb2dyYW1JbmZvKFxuICAgICAgbmFtZSxcbiAgICAgIGNhY2hlS2V5ID8/ICcnLFxuICAgICAgY29udGV4dC5pbnB1dHNbMF0sXG4gICAgICBjb250ZXh0LmlucHV0c1sxXSxcbiAgICAgIGZ1bmNDYWxsLFxuICAgICAgYWRkaXRpb25hbEltcGxlbWVudGF0aW9uLFxuICAgICAgb3V0cHV0RGF0YVR5cGUsXG4gICAgKSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBhZGQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgcnVuQmluYXJ5T3AoY29udGV4dCwgJ0FkZCcsIChhLCBiKSA9PiBgJHthfSske2J9YCk7XG59O1xuXG5leHBvcnQgY29uc3QgZGl2ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIHJ1bkJpbmFyeU9wKGNvbnRleHQsICdEaXYnLCAoYSwgYikgPT4gYCR7YX0vJHtifWApO1xufTtcblxuZXhwb3J0IGNvbnN0IGVxdWFsID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIHJ1bkJpbmFyeU9wKFxuICAgIGNvbnRleHQsXG4gICAgJ0VxdWFsJyxcbiAgICB7IHNjYWxhcjogKGEsIGIpID0+IGB1MzIoJHthfT09JHtifSlgLCB2ZWN0b3I6IChhLCBiKSA9PiBgdmVjNDx1MzI+KCR7YX09PSR7Yn0pYCB9LFxuICAgIHVuZGVmaW5lZCxcbiAgICB1bmRlZmluZWQsXG4gICAgRGF0YVR5cGUuYm9vbCxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBtdWwgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgcnVuQmluYXJ5T3AoY29udGV4dCwgJ011bCcsIChhLCBiKSA9PiBgJHthfSoke2J9YCk7XG59O1xuXG5leHBvcnQgY29uc3QgcG93ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIGNvbnN0IHR5cGUgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dCcsIGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlLCBjb250ZXh0LmlucHV0c1swXS5kaW1zKS50eXBlLnZhbHVlO1xuICBjb25zdCByb3VuZFN0ciA9IHR5cGUgPT09ICdpMzInID8gJ3JvdW5kJyA6ICcnO1xuICBydW5CaW5hcnlPcChcbiAgICBjb250ZXh0LFxuICAgICdQb3cnLFxuICAgIHsgc2NhbGFyOiAoYSwgYikgPT4gYHBvd19jdXN0b20oJHthfSwke2J9KWAsIHZlY3RvcjogKGEsIGIpID0+IGBwb3dfdmVjdG9yX2N1c3RvbSgke2F9LCR7Yn0pYCB9LFxuICAgIGBcbiAgICBmbiBwb3dfY3VzdG9tKGEgOiAke3R5cGV9LCBiIDogJHt0eXBlfSkgLT4gJHt0eXBlfSB7XG4gICAgICBpZiAoYiA9PSAke3R5cGV9KDAuMCkpIHtcbiAgICAgICAgcmV0dXJuICR7dHlwZX0oMS4wKTtcbiAgICAgIH0gZWxzZSBpZiAoYSA8ICR7dHlwZX0oMC4wKSAmJiBmMzIoYikgIT0gZmxvb3IoZjMyKGIpKSkge1xuICAgICAgICByZXR1cm4gJHt0eXBlfShwb3coZjMyKGEpLCBmMzIoYikpKTsgLy8gTmFOXG4gICAgICB9XG4gICAgICByZXR1cm4gc2VsZWN0KHNpZ24oYSksICR7dHlwZX0oMS4wKSwgcm91bmQoZjMyKGFicyhiKSAlICR7dHlwZX0oMi4wKSkpICE9IDEuMCkgKiAke3R5cGV9KCR7cm91bmRTdHJ9KHBvdyhmMzIoYWJzKGEpKSwgZjMyKGIpKSkpO1xuICAgIH1cbiAgICBmbiBwb3dfdmVjdG9yX2N1c3RvbShhIDogdmVjNDwke3R5cGV9PiwgYiA6IHZlYzQ8JHt0eXBlfT4pIC0+IHZlYzQ8JHt0eXBlfT4ge1xuICAgICAgLy8gVE9ETzogaW1wbGVtZW50IHZlY3Rvcml6ZWQgcG93XG4gICAgICByZXR1cm4gdmVjNDwke3R5cGV9Pihwb3dfY3VzdG9tKGEueCwgYi54KSwgcG93X2N1c3RvbShhLnksIGIueSksIHBvd19jdXN0b20oYS56LCBiLnopLCBwb3dfY3VzdG9tKGEudywgYi53KSk7XG4gICAgfVxuICAgICAgYCxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBzdWIgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgcnVuQmluYXJ5T3AoY29udGV4dCwgJ1N1YicsIChhLCBiKSA9PiBgJHthfS0ke2J9YCk7XG59O1xuXG5leHBvcnQgY29uc3QgZ3JlYXRlciA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBydW5CaW5hcnlPcChcbiAgICBjb250ZXh0LFxuICAgICdHcmVhdGVyJyxcbiAgICB7IHNjYWxhcjogKGEsIGIpID0+IGB1MzIoJHthfT4ke2J9KWAsIHZlY3RvcjogKGEsIGIpID0+IGB2ZWM0PHUzMj4oJHthfT4ke2J9KWAgfSxcbiAgICB1bmRlZmluZWQsXG4gICAgdW5kZWZpbmVkLFxuICAgIERhdGFUeXBlLmJvb2wsXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgbGVzcyA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBydW5CaW5hcnlPcChcbiAgICBjb250ZXh0LFxuICAgICdMZXNzJyxcbiAgICB7IHNjYWxhcjogKGEsIGIpID0+IGB1MzIoJHthfTwke2J9KWAsIHZlY3RvcjogKGEsIGIpID0+IGB2ZWM0PHUzMj4oJHthfTwke2J9KWAgfSxcbiAgICB1bmRlZmluZWQsXG4gICAgdW5kZWZpbmVkLFxuICAgIERhdGFUeXBlLmJvb2wsXG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgZ3JlYXRlck9yRXF1YWwgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgcnVuQmluYXJ5T3AoXG4gICAgY29udGV4dCxcbiAgICAnR3JlYXRlck9yRXF1YWwnLFxuICAgIHsgc2NhbGFyOiAoYSwgYikgPT4gYHUzMigke2F9Pj0ke2J9KWAsIHZlY3RvcjogKGEsIGIpID0+IGB2ZWM0PHUzMj4oJHthfT49JHtifSlgIH0sXG4gICAgdW5kZWZpbmVkLFxuICAgIHVuZGVmaW5lZCxcbiAgICBEYXRhVHlwZS5ib29sLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGxlc3NPckVxdWFsID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0KTogdm9pZCA9PiB7XG4gIHJ1bkJpbmFyeU9wKFxuICAgIGNvbnRleHQsXG4gICAgJ0xlc3NPckVxdWFsJyxcbiAgICB7IHNjYWxhcjogKGEsIGIpID0+IGB1MzIoJHthfTw9JHtifSlgLCB2ZWN0b3I6IChhLCBiKSA9PiBgdmVjNDx1MzI+KCR7YX08PSR7Yn0pYCB9LFxuICAgIHVuZGVmaW5lZCxcbiAgICB1bmRlZmluZWQsXG4gICAgRGF0YVR5cGUuYm9vbCxcbiAgKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBJbmRpY2VzSGVscGVyLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbmNhdEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLCBheGlzOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RvbyBmZXcgaW5wdXRzJyk7XG4gIH1cbiAgY29uc3QgcmVmZXJlbmNlSW5kZXggPSAwO1xuICBjb25zdCByZWZlcmVuY2VJbnB1dCA9IGlucHV0c1tyZWZlcmVuY2VJbmRleF07XG4gIGNvbnN0IGlucHV0VHlwZSA9IHJlZmVyZW5jZUlucHV0LmRhdGFUeXBlO1xuICBjb25zdCBpbnB1dFJhbmsgPSByZWZlcmVuY2VJbnB1dC5kaW1zLmxlbmd0aDtcbiAgaW5wdXRzLmZvckVhY2goKGlucHV0LCBpKSA9PiB7XG4gICAgaWYgKGkgPT09IHJlZmVyZW5jZUluZGV4KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIG1ha2Ugc3VyZSB0eXBlcyBvZiBhbGwgaW5wdXRzIG1hdGNoXG4gICAgaWYgKGlucHV0LmRhdGFUeXBlICE9PSBpbnB1dFR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgdGVuc29ycyBzaG91bGQgYmUgb25lIHR5cGUnKTtcbiAgICB9XG4gICAgLy8gbWFrZSBzdXJlIHRoZSBkaW1lbnNpb25hbGl0eSBvZiBhbGwgaW5wdXRzIGFyZSB0aGUgc2FtZVxuICAgIGlmIChpbnB1dC5kaW1zLmxlbmd0aCAhPT0gaW5wdXRSYW5rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHRlbnNvcnMgc2hvdWxkIGhhdmUgdGhlIHNhbWUgc2hhcGUnKTtcbiAgICB9XG4gICAgaW5wdXQuZGltcy5mb3JFYWNoKChkaW0sIGkpID0+IHtcbiAgICAgIGlmIChpICE9PSBheGlzICYmIGRpbSAhPT0gcmVmZXJlbmNlSW5wdXQuZGltc1tpXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vbiBjb25jYXQgZGltZW5zaW9ucyBtdXN0IG1hdGNoJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufTtcblxuY29uc3QgY2FsY3VsYXRlSW5wdXRJbmRleEltcGwgPSAobnVtYmVyT2ZUZW5zb3JzOiBudW1iZXIsIHNpemVJbkNvbmNhdEF4aXNTdHI6IHN0cmluZyk6IHN0cmluZyA9PiBgXG4gIGZuIGNhbGN1bGF0ZUlucHV0SW5kZXgoaW5kZXg6IHUzMikgLT4gdTMyIHtcbiAgICBsZXQgc2l6ZUluQ29uY2F0QXhpcyA9IGFycmF5PHUzMiwgJHtudW1iZXJPZlRlbnNvcnN9dT4oJHtzaXplSW5Db25jYXRBeGlzU3RyfSk7XG4gICAgZm9yICh2YXIgaTogdTMyID0gMHU7IGkgPCAke251bWJlck9mVGVuc29yc307IGkgKz0gMXUgKSB7XG4gICAgICBpZiAoaW5kZXggPCBzaXplSW5Db25jYXRBeGlzW2ldKSB7XG4gICAgICAgIHJldHVybiBpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gJHtudW1iZXJPZlRlbnNvcnN9dTtcbiAgfWA7XG5cbmNvbnN0IGFzc2lnbk91dHB1dERhdGEgPSAoaW5wdXRzOiByZWFkb25seSBJbmRpY2VzSGVscGVyW10sIG91dHB1dDogSW5kaWNlc0hlbHBlcikgPT4ge1xuICBjb25zdCBudW1iZXJPZlRlbnNvcnMgPSBpbnB1dHMubGVuZ3RoO1xuXG4gIGNvbnN0IGNvZGVMaW5lczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZlRlbnNvcnM7ICsraSkge1xuICAgIGNvbnN0IHJldHVyblNuaXBwZXQgPSBvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCBpbnB1dHNbaV0uZ2V0QnlJbmRpY2VzKCdpbmRpY2VzJykpO1xuICAgIGlmIChudW1iZXJPZlRlbnNvcnMgPT09IDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKHJldHVyblNuaXBwZXQpO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gMCkge1xuICAgICAgY29kZUxpbmVzLnB1c2goYGlmIChpbnB1dEluZGV4ID09ICR7aX11KSB7ICR7cmV0dXJuU25pcHBldH0gfWApO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gbnVtYmVyT2ZUZW5zb3JzIC0gMSkge1xuICAgICAgY29kZUxpbmVzLnB1c2goYGVsc2UgeyAke3JldHVyblNuaXBwZXR9IH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZUxpbmVzLnB1c2goYGVsc2UgaWYgKGlucHV0SW5kZXggPT0gJHtpfSkgeyAke3JldHVyblNuaXBwZXR9IH1gKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IGNyZWF0ZUNvbmNhdFByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYWRqdXN0ZWRBeGlzOiBudW1iZXIsXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbiAgZGF0YVR5cGU6IERhdGFUeXBlLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuXG4gIGNvbnN0IHNpemVJbkNvbmNhdEF4aXMgPSBuZXcgQXJyYXk8bnVtYmVyPihpbnB1dHMubGVuZ3RoKTtcbiAgY29uc3QgaW5wdXRWYXJzID0gbmV3IEFycmF5PEluZGljZXNIZWxwZXI+KGlucHV0cy5sZW5ndGgpO1xuXG4gIGxldCBwcmV2aW91c1N1bSA9IDA7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gW107XG4gIGNvbnN0IGlucHV0UmFua3MgPSBbXTtcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW3sgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH1dO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7ICsraSkge1xuICAgIHByZXZpb3VzU3VtICs9IGlucHV0c1tpXS5kaW1zW2FkanVzdGVkQXhpc107XG4gICAgc2l6ZUluQ29uY2F0QXhpc1tpXSA9IHByZXZpb3VzU3VtO1xuICAgIGlucHV0UmFua3MucHVzaChpbnB1dHNbaV0uZGltcy5sZW5ndGgpO1xuICAgIGlucHV0VmFyc1tpXSA9IGlucHV0VmFyaWFibGUoYGlucHV0JHtpfWAsIGRhdGFUeXBlLCBpbnB1dFJhbmtzW2ldKTtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCdyYW5rJyk7XG4gICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHNpemVJbkNvbmNhdEF4aXNbaV0gfSk7XG4gIH1cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyArK2kpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbaV0uZGltcykpO1xuICB9XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dHB1dFNoYXBlKSk7XG5cbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBpbmRpY2VzQXhpcyA9IG91dHB1dC5pbmRpY2VzR2V0KCdpbmRpY2VzJywgYWRqdXN0ZWRBeGlzKTtcbiAgY29uc3Qgc2l6ZUluQ29uY2F0QXhpc1N0ciA9IEFycmF5LmZyb20oQXJyYXkoc2l6ZUluQ29uY2F0QXhpcy5sZW5ndGgpLmtleXMoKSlcbiAgICAubWFwKChpKSA9PiBgdW5pZm9ybXMuc2l6ZUluQ29uY2F0QXhpcyR7aX1gKVxuICAgIC5qb2luKCcsJyk7XG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuXG4gICR7KCgpID0+IHtcbiAgICBzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3JtKCdvdXRwdXRTaXplJywgJ3UzMicpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3JtKGBzaXplSW5Db25jYXRBeGlzJHtpfWAsICd1MzInKTtcbiAgICB9XG4gICAgcmV0dXJuIHNoYWRlckhlbHBlci5kZWNsYXJlVmFyaWFibGVzKC4uLmlucHV0VmFycywgb3V0cHV0KTtcbiAgfSkoKX1cblxuICAke2NhbGN1bGF0ZUlucHV0SW5kZXhJbXBsKHNpemVJbkNvbmNhdEF4aXMubGVuZ3RoLCBzaXplSW5Db25jYXRBeGlzU3RyKX1cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRTaXplJyl9XG5cbiAgICB2YXIgaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcblxuICAgIGxldCBpbnB1dEluZGV4ID0gY2FsY3VsYXRlSW5wdXRJbmRleCgke2luZGljZXNBeGlzfSk7XG4gICAgaWYgKGlucHV0SW5kZXggIT0gMHUpIHtcbiAgICAgIGxldCBzaXplSW5Db25jYXRBeGlzID0gYXJyYXk8dTMyLCAke3NpemVJbkNvbmNhdEF4aXMubGVuZ3RofXU+KCR7c2l6ZUluQ29uY2F0QXhpc1N0cn0pO1xuICAgICAgJHtpbmRpY2VzQXhpc30gLT0gc2l6ZUluQ29uY2F0QXhpc1tpbnB1dEluZGV4IC0gMXVdO1xuICAgIH1cblxuICAgICR7YXNzaWduT3V0cHV0RGF0YShpbnB1dFZhcnMsIG91dHB1dCl9XG4gIH1gO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0NvbmNhdCcsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7YWRqdXN0ZWRBeGlzfWAsIGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY29uY2F0ID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBDb25jYXRBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGNvbnN0IGlucHV0cyA9IGNvbnRleHQuaW5wdXRzO1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGFkanVzdGVkQXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGFkanVzdGVkQXhpcyk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgpO1xuICBvdXRwdXRTaGFwZVthZGp1c3RlZEF4aXNdID0gaW5wdXRzLnJlZHVjZShcbiAgICAoc3VtLCBpbnB1dCkgPT4gc3VtICsgKGlucHV0LmRpbXMubGVuZ3RoID4gYWRqdXN0ZWRBeGlzID8gaW5wdXQuZGltc1thZGp1c3RlZEF4aXNdIDogMCksXG4gICAgMCxcbiAgKTtcbiAgLy8gMCBsZW5ndGggdGVuc29ycyBhcmUgdmFsaWQgZm9yIGNvbmNhdCwgcmVtb3ZlIHRoZW1cbiAgY29uc3Qgbm9uRW1wdHlJbnB1dHMgPSBpbnB1dHMuZmlsdGVyKChpbnB1dCkgPT4gU2hhcGVVdGlsLnNpemUoaW5wdXQuZGltcykgPiAwKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUNvbmNhdFByb2dyYW1JbmZvKG5vbkVtcHR5SW5wdXRzLCBhZGp1c3RlZEF4aXMsIG91dHB1dFNoYXBlLCBpbnB1dHNbMF0uZGF0YVR5cGUpLCB7XG4gICAgaW5wdXRzOiBub25FbXB0eUlucHV0cyxcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDb25jYXRBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogQ29uY2F0QXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBhdHRyaWJ1dGVzLmF4aXMgYXMgbnVtYmVyIH0pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IE1BWF9DTElQLCBNSU5fQ0xJUCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IFVuaWZvcm1zQXJyYXlUeXBlIH0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMge1xuICByZWFkb25seSBhY3RpdmF0aW9uOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNsaXBNaW4/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGNsaXBNYXg/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGFscGhhPzogbnVtYmVyO1xuICByZWFkb25seSBiZXRhPzogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgZ2V0QWN0aXZhdGlvblNuaXBwZXQgPSAoXG4gIGF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG4gIHZhbHVlVHlwZTogc3RyaW5nLFxuICBiYXNlVHlwZSA9ICdmMzInLFxuKTogc3RyaW5nID0+IHtcbiAgc3dpdGNoIChhdHRyaWJ1dGVzLmFjdGl2YXRpb24pIHtcbiAgICBjYXNlICdSZWx1JzpcbiAgICAgIHJldHVybiBgdmFsdWUgPSBtYXgodmFsdWUsICR7dmFsdWVUeXBlfSgwLjApKTtgO1xuICAgIGNhc2UgJ1NpZ21vaWQnOlxuICAgICAgcmV0dXJuIGB2YWx1ZSA9ICgke3ZhbHVlVHlwZX0oMS4wKSAvICgke3ZhbHVlVHlwZX0oMS4wKSArIGV4cCgtdmFsdWUpKSk7YDtcbiAgICBjYXNlICdDbGlwJzpcbiAgICAgIHJldHVybiBgdmFsdWUgPSBjbGFtcCh2YWx1ZSwgJHt2YWx1ZVR5cGV9KCR7YmFzZVR5cGV9KHVuaWZvcm1zLmNsaXBfbWluKSksICR7dmFsdWVUeXBlfSgke1xuICAgICAgICBiYXNlVHlwZVxuICAgICAgfSh1bmlmb3Jtcy5jbGlwX21heCkpKTtgO1xuICAgIGNhc2UgJ0hhcmRTaWdtb2lkJzpcbiAgICAgIHJldHVybiBgdmFsdWUgPSBtYXgoJHt2YWx1ZVR5cGV9KDAuMCksIG1pbigke3ZhbHVlVHlwZX0oMS4wKSwgJHtiYXNlVHlwZX0odW5pZm9ybXMuYWxwaGEpICogdmFsdWUgKyAke1xuICAgICAgICBiYXNlVHlwZVxuICAgICAgfSh1bmlmb3Jtcy5iZXRhKSkpO2A7XG4gICAgY2FzZSAnTGVha3lSZWx1JzpcbiAgICAgIHJldHVybiBgdmFsdWUgPSBzZWxlY3QoJHtiYXNlVHlwZX0odW5pZm9ybXMuYWxwaGEpICogdmFsdWUsIHZhbHVlLCB2YWx1ZSA+PSAke3ZhbHVlVHlwZX0oMC4wKSk7YDtcbiAgICBjYXNlICdUYW5oJzpcbiAgICAgIHJldHVybiBgbGV0IGUyeCA9IGV4cCgtMi4wICogYWJzKHZhbHVlKSk7XG4gICAgICAgICAgICAgIHZhbHVlID0gc2lnbih2YWx1ZSkgKiAoMS4wIC0gZTJ4KSAvICgxLjAgKyBlMngpO1xuICAgICAgICBgO1xuICAgIGNhc2UgJyc6XG4gICAgICByZXR1cm4gJyc7XG4gICAgLy8gVE9ETzogYWRkaW5nIG90aGVyIGFjdGl2YXRpb25zIHRoYXQgY2FuIGJlIGZ1c2VkLlxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGFjdGl2YXRpb24gJHthdHRyaWJ1dGVzLmFjdGl2YXRpb259YCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhID0gKFxuICBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxuICBwcm9ncmFtVW5pZm9ybTogUHJvZ3JhbVVuaWZvcm1bXSxcbikgPT4ge1xuICBpZiAoYXR0cmlidXRlcy5hY3RpdmF0aW9uID09PSAnQ2xpcCcpIHtcbiAgICBwcm9ncmFtVW5pZm9ybS5wdXNoKFxuICAgICAgeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogYXR0cmlidXRlcy5jbGlwTWF4ISB9LFxuICAgICAgeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogYXR0cmlidXRlcy5jbGlwTWluISB9LFxuICAgICk7XG4gIH0gZWxzZSBpZiAoYXR0cmlidXRlcy5hY3RpdmF0aW9uID09PSAnSGFyZFNpZ21vaWQnKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm0ucHVzaChcbiAgICAgIHsgdHlwZTogRGF0YVR5cGUuZmxvYXQsIGRhdGE6IGF0dHJpYnV0ZXMuYWxwaGEhIH0sXG4gICAgICB7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBhdHRyaWJ1dGVzLmJldGEhIH0sXG4gICAgKTtcbiAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzLmFjdGl2YXRpb24gPT09ICdMZWFreVJlbHUnKSB7XG4gICAgcHJvZ3JhbVVuaWZvcm0ucHVzaCh7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBhdHRyaWJ1dGVzLmFscGhhISB9KTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGFwcGVuZEFjdGl2YXRpb25Vbmlmb3JtcyA9IChhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUpID0+IHtcbiAgaWYgKGF0dHJpYnV0ZXMuYWN0aXZhdGlvbiA9PT0gJ0NsaXAnKSB7XG4gICAgdW5pZm9ybXMucHVzaCh7IG5hbWU6ICdjbGlwX21heCcsIHR5cGU6ICdmMzInIH0sIHsgbmFtZTogJ2NsaXBfbWluJywgdHlwZTogJ2YzMicgfSk7XG4gIH0gZWxzZSBpZiAoYXR0cmlidXRlcy5hY3RpdmF0aW9uID09PSAnSGFyZFNpZ21vaWQnKSB7XG4gICAgdW5pZm9ybXMucHVzaCh7IG5hbWU6ICdhbHBoYScsIHR5cGU6ICdmMzInIH0sIHsgbmFtZTogJ2JldGEnLCB0eXBlOiAnZjMyJyB9KTtcbiAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzLmFjdGl2YXRpb24gPT09ICdMZWFreVJlbHUnKSB7XG4gICAgdW5pZm9ybXMucHVzaCh7IG5hbWU6ICdhbHBoYScsIHR5cGU6ICdmMzInIH0pO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzID0gKFxuICBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZCxcbik6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhY3RpdmF0aW9uID0gKGF0dHJpYnV0ZXM/LmFjdGl2YXRpb24gYXMgc3RyaW5nKSB8fCAnJztcbiAgaWYgKGFjdGl2YXRpb24gPT09ICdIYXJkU2lnbW9pZCcpIHtcbiAgICBjb25zdCBbYWxwaGEsIGJldGFdID0gKGF0dHJpYnV0ZXM/LmFjdGl2YXRpb25fcGFyYW1zIGFzIFtudW1iZXIsIG51bWJlcl0pIHx8IFswLjIsIDAuNV07XG4gICAgcmV0dXJuIHsgYWN0aXZhdGlvbiwgYWxwaGEsIGJldGEgfTtcbiAgfSBlbHNlIGlmIChhY3RpdmF0aW9uID09PSAnQ2xpcCcpIHtcbiAgICBjb25zdCBbY2xpcE1pbiwgY2xpcE1heF0gPSAoYXR0cmlidXRlcz8uYWN0aXZhdGlvbl9wYXJhbXMgYXMgW251bWJlciwgbnVtYmVyXSkgfHwgW01JTl9DTElQLCBNQVhfQ0xJUF07XG4gICAgcmV0dXJuIHsgYWN0aXZhdGlvbiwgY2xpcE1heCwgY2xpcE1pbiB9O1xuICB9IGVsc2UgaWYgKGFjdGl2YXRpb24gPT09ICdMZWFreVJlbHUnKSB7XG4gICAgY29uc3QgW2FscGhhXSA9IChhdHRyaWJ1dGVzPy5hY3RpdmF0aW9uX3BhcmFtcyBhcyBbbnVtYmVyXSkgfHwgWzAuMDFdO1xuICAgIHJldHVybiB7IGFjdGl2YXRpb24sIGFscGhhIH07XG4gIH1cbiAgcmV0dXJuIHsgYWN0aXZhdGlvbiB9O1xufTtcbiIsICIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbi8vIHNhbXBsZWQgZnJvbSBbQHRlbnNvcmZsb3cvdGZqc10gdGZqcy1iYWNrZW5kLXdlYmdwdS9zcmMvYWN0aXZhdGlvbl91dGlsLnRzXG4vL1xuLy8gbW9kaWZpZWQgdG8gZml0IHRoZSBuZWVkcyBvZiB0aGUgcHJvamVjdFxuXG5leHBvcnQgY29uc3QgdHlwZVNuaXBwZXQgPSAoY29tcG9uZW50OiBudW1iZXIsIGRhdGFUeXBlOiBzdHJpbmcpID0+IHtcbiAgc3dpdGNoIChjb21wb25lbnQpIHtcbiAgICBjYXNlIDE6XG4gICAgICByZXR1cm4gZGF0YVR5cGU7XG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuIGB2ZWMyPCR7ZGF0YVR5cGV9PmA7XG4gICAgY2FzZSAzOlxuICAgICAgcmV0dXJuIGB2ZWMzPCR7ZGF0YVR5cGV9PmA7XG4gICAgY2FzZSA0OlxuICAgICAgcmV0dXJuIGB2ZWM0PCR7ZGF0YVR5cGV9PmA7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtjb21wb25lbnR9LWNvbXBvbmVudCBpcyBub3Qgc3VwcG9ydGVkLmApO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgYmlhc1NuaXBwZXQgPSAoaGFzQmlhczogYm9vbGVhbik6IHN0cmluZyA9PiBgXG4gICAgICAke2hhc0JpYXMgPyAndmFsdWUgPSB2YWx1ZSArIGdldEJpYXNCeU91dHB1dENvb3Jkcyhjb29yZHMpOycgOiAnJ31cbiAgICAgIGA7XG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vLyBzYW1wbGVkIGZyb20gW0B0ZW5zb3JmbG93L3RmanNdIHRmanMtY29yZS9zcmMvb3BzL2NvbnZfdXRpbC50c1xuLy9cbi8vIG1vZGlmaWVkIHRvIGZpdCB0aGUgbmVlZHMgb2YgdGhlIHByb2plY3RcblxuZXhwb3J0IGNvbnN0IHV0aWxGdW5jdGlvbnMgPSAoc3RyaWRlU3RyOiBzdHJpbmcpID0+IGBcbmZuIGdldEluZGV4RnJvbUNvb3JkczREKGNvb3JkcyA6IHZlYzQ8aTMyPiwgc2hhcGUgOiB2ZWM0PGkzMj4pIC0+IGkzMiB7XG4gIHJldHVybiBkb3QoY29vcmRzLCB2ZWM0PGkzMj4oXG4gICAgICBzaGFwZS55ICogc2hhcGUueiAqIHNoYXBlLncsIHNoYXBlLnogKiBzaGFwZS53LCBzaGFwZS53LCAxKSk7XG59XG5mbiBnZXRPdXRwdXRJbmRleEZyb21Db29yZHMoY29vcmRzIDogdmVjNDxpMzI+KSAtPiBpMzIge1xuICByZXR1cm4gZG90KGNvb3JkcywgdmVjNDxpMzI+KFxuICAgIGkzMigke3N0cmlkZVN0cn0ueCksIGkzMigke3N0cmlkZVN0cn0ueSksIGkzMigke3N0cmlkZVN0cn0ueiksIDEpKTtcbn1cbmA7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgZ2V0RWxlbWVudEF0LFxuICBnZXRNYXhDb21wb25lbnRzLFxuICBJbmRpY2VzSGVscGVyLFxuICBpbnB1dFZhcmlhYmxlLFxuICBpbnRlcm5hbFZhcmlhYmxlLFxuICBvdXRwdXRWYXJpYWJsZSxcbiAgU2hhZGVySGVscGVyLFxuICB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQge1xuICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMsXG4gIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3Jtc0RhdGEsXG4gIGdldEFjdGl2YXRpb25TbmlwcGV0LFxuICBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLFxufSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuXG4vLyBIZWxwZXIgdGhhdCBjb252ZXJ0IG91dHB1dCBiYXRjaCBpbmRpY2VzIHRvIGlucHV0IGJhdGNoIGluZGljZXMgdXNpbmcgb25seSB0aGUgcmFuayBhbmRcbi8vIHRoZSBzaGFwZSBpbmZvcm1hdGlvbiBpbiB1bmlmb3JtXG5leHBvcnQgY29uc3QgY29udmVydE91dHB1dEJhdGNoSW5kaWNlc1RvSW5wdXRCYXRjaEluZGljZXMgPSAoXG4gIHRhcmdldEluZGljZXNOYW1lOiBzdHJpbmcsXG4gIGlucHV0VmFyaWFibGU6IEluZGljZXNIZWxwZXIsXG4gIGlucHV0QmF0Y2hSYW5rOiBudW1iZXIsXG4gIG91dHB1dEJhdGNoUmFuazogbnVtYmVyLFxuICBiYXRjaEluZGljZXNOYW1lOiBzdHJpbmcsXG4pID0+IHtcbiAgLy8gQXNzdW1lIG91dHB1dEJhdGNoUmFuayA+PSBpbnB1dEJhdGNoUmFuaywgdGhlIGZpcnN0IG91dHB1dEJhdGNoUmFuayAtIGlucHV0QmF0Y2hSYW5rIG9mXG4gIC8vIG91dHB1dEJhdGNoUmFuayBzaG91bGQgYmUgaWdub3JlZC5cbiAgY29uc3QgZXh0ZW5kaW5nSW5wdXRSYW5rID0gb3V0cHV0QmF0Y2hSYW5rIC0gaW5wdXRCYXRjaFJhbms7XG4gIHJldHVybiBgXG4gICAgICAke0FycmF5LmZyb20oeyBsZW5ndGg6IGlucHV0QmF0Y2hSYW5rIH0pXG4gICAgICAgIC5tYXAoXG4gICAgICAgICAgKF8sIGkpID0+IGBcbiAgICAgIGlmICgke2dldEVsZW1lbnRBdChpbnB1dFZhcmlhYmxlLnNoYXBlLCBpLCBpbnB1dFZhcmlhYmxlLnJhbmspfSAhPSAxKSB7XG4gICAgICAgICR7aW5wdXRWYXJpYWJsZS5pbmRpY2VzU2V0KHRhcmdldEluZGljZXNOYW1lLCBpLCBnZXRFbGVtZW50QXQoYmF0Y2hJbmRpY2VzTmFtZSwgaSArIGV4dGVuZGluZ0lucHV0UmFuaywgb3V0cHV0QmF0Y2hSYW5rKSl9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAke2lucHV0VmFyaWFibGUuaW5kaWNlc1NldCh0YXJnZXRJbmRpY2VzTmFtZSwgaSwgMCl9XG4gICAgICB9YCxcbiAgICAgICAgKVxuICAgICAgICAuam9pbignJyl9XG5gO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU5haXZlTWF0bXVsUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhY3RpdmF0aW9uQXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICByZXNoYXBlZE91dHB1dFNoYXBlPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGlzQ2hhbm5lbHNMYXN0ID0gZmFsc2UgLyogb25seSB1c2VkIGZvciBjb252MmRCeU1hdE11bCovLFxuICBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbj86IChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pID0+IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG5cbiAgY29uc3QgTSA9IGFTaGFwZVthU2hhcGUubGVuZ3RoIC0gMl07XG4gIGNvbnN0IE4gPSBiU2hhcGVbYlNoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBLID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3QgY29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMoTik7XG4gIGNvbnN0IGFDb21wb25lbnRzID0gZ2V0TWF4Q29tcG9uZW50cyhLKTtcbiAgY29uc3Qgb3V0cHV0TnVtYmVyID0gZ2V0TWF4Q29tcG9uZW50cyhNKTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIGNvbXBvbmVudHMgLyBvdXRwdXROdW1iZXI7XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3Qgb3V0ZXJEaW1zID0gcmVzaGFwZWRPdXRwdXRTaGFwZSA/IHJlc2hhcGVkT3V0cHV0U2hhcGUuc2xpY2UoMCwgLTIpIDogb3V0cHV0U2hhcGUuc2xpY2UoMCwgLTIpO1xuICBjb25zdCBiYXRjaFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRlckRpbXMpO1xuICBjb25zdCBvdXRwdXRTaGFwZUluU2hhZGVyID0gW2JhdGNoU2l6ZSwgTSwgTl07XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IE0gfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogTiB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBLIH0sXG4gIF07XG4gIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3Jtc0RhdGEoYWN0aXZhdGlvbkF0dHJpYnV0ZXMsIHByb2dyYW1Vbmlmb3Jtcyk7XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dGVyRGltcywgYVNoYXBlLCBiU2hhcGUpKTtcbiAgaWYgKGhhc0JpYXMpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMl0uZGltcykpO1xuICB9XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dHB1dFNoYXBlSW5TaGFkZXIpKTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBiYXRjaERpbXMgPSBpbnRlcm5hbFZhcmlhYmxlKCdiYXRjaF9kaW1zJywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRlckRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBhID0gaW5wdXRWYXJpYWJsZSgnYScsIGlucHV0c1swXS5kYXRhVHlwZSwgYVNoYXBlLmxlbmd0aCwgYUNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGIgPSBpbnB1dFZhcmlhYmxlKCdiJywgaW5wdXRzWzFdLmRhdGFUeXBlLCBiU2hhcGUubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZUluU2hhZGVyLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgY29uc3QgYmFzZVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUob3V0cHV0LnR5cGUudGVuc29yKTtcbiAgICBjb25zdCBhcHBseUFjdGl2YXRpb24gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhY3RpdmF0aW9uQXR0cmlidXRlcywgb3V0cHV0LnR5cGUudmFsdWUsIGJhc2VUeXBlKTtcbiAgICBjb25zdCBpbnB1dFZhcmlhYmxlcyA9IFthLCBiXTtcbiAgICBsZXQgcHJvY2Vzc0JpYXMgPSAnJztcbiAgICBpZiAoaGFzQmlhcykge1xuICAgICAgY29uc3QgYmlhc0NvbXBvbmVudHMgPSBpc0NoYW5uZWxzTGFzdCA/IGNvbXBvbmVudHMgOiAxO1xuICAgICAgaW5wdXRWYXJpYWJsZXMucHVzaChpbnB1dFZhcmlhYmxlKCdiaWFzJywgaW5wdXRzWzJdLmRhdGFUeXBlLCBpbnB1dHNbMl0uZGltcy5sZW5ndGgsIGJpYXNDb21wb25lbnRzKSk7XG4gICAgICBwcm9jZXNzQmlhcyA9IGAke1xuICAgICAgICBpc0NoYW5uZWxzTGFzdCA/IGB2YWx1ZSArPSBiaWFzW2NvbCAvICR7Ymlhc0NvbXBvbmVudHN9XTtgIDogYHZhbHVlICs9ICR7b3V0cHV0LnR5cGUudmFsdWV9KGJpYXNbcm93ICsgaV0pO2BcbiAgICAgIH1gO1xuICAgIH1cblxuICAgIGNvbnN0IHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSA9IFtcbiAgICAgIHsgbmFtZTogJ291dHB1dF9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ00nLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnTicsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdLJywgdHlwZTogJ3UzMicgfSxcbiAgICBdO1xuICAgIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3JtcyhhY3RpdmF0aW9uQXR0cmlidXRlcywgdW5pZm9ybXMpO1xuXG4gICAgY29uc3QgY2FsY1Jlc3VsdCA9ICgpOiBzdHJpbmcgPT4ge1xuICAgICAgbGV0IGNhbGNTdHIgPSBgdmFyIGFfZGF0YTogJHthLnR5cGUudmFsdWV9O2A7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFDb21wb25lbnRzOyBpKyspIHtcbiAgICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgICAgIGxldCBiX2RhdGEke2l9ID0gYlsoYl9vZmZzZXQgKyAoayArICR7aX0pICogdW5pZm9ybXMuTiArIGNvbCkgLyAke2NvbXBvbmVudHN9XTtgO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXROdW1iZXI7IGkrKykge1xuICAgICAgICBjYWxjU3RyICs9IGBhX2RhdGEgPSBhWyhhX29mZnNldCArIChyb3cgKyAke2l9KSAqIHVuaWZvcm1zLksgKyBrKSAvICR7YUNvbXBvbmVudHN9XTtgO1xuXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYUNvbXBvbmVudHM7IGorKykge1xuICAgICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgICAgdmFsdWVzWyR7aX1dID0gZm1hKCR7Yi50eXBlLnZhbHVlfShhX2RhdGEke2FDb21wb25lbnRzID09PSAxID8gJycgOiBgWyR7an1dYH0pLCBiX2RhdGEke2p9LCB2YWx1ZXNbJHtpfV0pO1xcbmA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBjYWxjU3RyO1xuICAgIH07XG5cbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlclxuICAgIC5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKVxuICAgIC5yZWdpc3RlckludGVybmFsVmFyaWFibGVzKGJhdGNoRGltcylcbiAgICAuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcmlhYmxlcywgb3V0cHV0KX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cbiAgICBsZXQgY29sID0gKGdsb2JhbF9pZHggJSAodW5pZm9ybXMuTiAvICR7Y29tcG9uZW50c30pKSAqICR7Y29tcG9uZW50c307XG4gICAgdmFyIGluZGV4MSA9IGdsb2JhbF9pZHggLyAodW5pZm9ybXMuTiAvICR7Y29tcG9uZW50c30pO1xuICAgIGxldCBzdHJpZGUxID0gdW5pZm9ybXMuTSAvICR7b3V0cHV0TnVtYmVyfTtcbiAgICBsZXQgcm93ID0gKGluZGV4MSAlIHN0cmlkZTEpICogJHtvdXRwdXROdW1iZXJ9O1xuICAgIGxldCBiYXRjaCA9IGluZGV4MSAvIHN0cmlkZTE7XG5cbiAgICAke291dHB1dFNoYXBlLmxlbmd0aCA9PT0gMiA/ICcnIDogYGxldCBiYXRjaF9pbmRpY2VzID0gJHtiYXRjaERpbXMub2Zmc2V0VG9JbmRpY2VzKCdiYXRjaCcpfTtgfVxuXG4gICAgdmFyIGFfaW5kaWNlczogJHthLnR5cGUuaW5kaWNlc307XG4gICAgJHtjb252ZXJ0T3V0cHV0QmF0Y2hJbmRpY2VzVG9JbnB1dEJhdGNoSW5kaWNlcygnYV9pbmRpY2VzJywgYSwgYS5yYW5rIC0gMiwgYmF0Y2hEaW1zLnJhbmssICdiYXRjaF9pbmRpY2VzJyl9XG4gICAgJHthLmluZGljZXNTZXQoJ2FfaW5kaWNlcycsIGEucmFuayAtIDIsIDApfVxuICAgICR7YS5pbmRpY2VzU2V0KCdhX2luZGljZXMnLCBhLnJhbmsgLSAxLCAwKX1cbiAgICBsZXQgYV9vZmZzZXQgPSAke2EuaW5kaWNlc1RvT2Zmc2V0KCdhX2luZGljZXMnKX07XG5cbiAgICB2YXIgYl9pbmRpY2VzOiAke2IudHlwZS5pbmRpY2VzfTtcbiAgICAke2NvbnZlcnRPdXRwdXRCYXRjaEluZGljZXNUb0lucHV0QmF0Y2hJbmRpY2VzKCdiX2luZGljZXMnLCBiLCBiLnJhbmsgLSAyLCBiYXRjaERpbXMucmFuaywgJ2JhdGNoX2luZGljZXMnKX1cbiAgICAke2IuaW5kaWNlc1NldCgnYl9pbmRpY2VzJywgYi5yYW5rIC0gMiwgMCl9XG4gICAgJHtiLmluZGljZXNTZXQoJ2JfaW5kaWNlcycsIGIucmFuayAtIDEsIDApfVxuICAgIGxldCBiX29mZnNldCA9ICR7Yi5pbmRpY2VzVG9PZmZzZXQoJ2JfaW5kaWNlcycpfTtcbiAgICB2YXIgdmFsdWVzOiBhcnJheTwke291dHB1dC50eXBlLnZhbHVlfSwgJHtvdXRwdXROdW1iZXJ9PjtcbiAgICBmb3IgKHZhciBrOiB1MzIgPSAwdTsgayA8IHVuaWZvcm1zLks7IGsgPSBrICsgJHthQ29tcG9uZW50c30pIHtcbiAgICAgICR7Y2FsY1Jlc3VsdCgpfVxuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMHU7IGkgPCAke291dHB1dE51bWJlcn11OyBpKyspIHtcbiAgICAgIHZhciB2YWx1ZSA9IHZhbHVlc1tpXTtcbiAgICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAgIGxldCBjdXJfaW5kaWNlcyA9ICR7b3V0cHV0LnR5cGUuaW5kaWNlc30oYmF0Y2gsIHJvdyArIGksIGNvbCk7XG4gICAgICBsZXQgb2Zmc2V0ID0gJHtvdXRwdXQuaW5kaWNlc1RvT2Zmc2V0KCdjdXJfaW5kaWNlcycpfTtcbiAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KGBvZmZzZXQgLyAke2NvbXBvbmVudHN9YCwgJ3ZhbHVlJyl9O1xuICAgIH1cbiAgfVxuICBgO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdNYXRNdWxOYWl2ZScsXG4gICAgc2hhZGVyQ2FjaGU6IHtcbiAgICAgIGhpbnQ6IGAke2FjdGl2YXRpb25BdHRyaWJ1dGVzLmFjdGl2YXRpb259OyR7Y29tcG9uZW50c307JHthQ29tcG9uZW50c307JHtvdXRwdXROdW1iZXJ9OyR7aXNDaGFubmVsc0xhc3R9YCxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiBoYXNCaWFzID8gWydyYW5rJywgJ3JhbmsnLCAncmFuayddIDogWydyYW5rJywgJ3JhbmsnXSxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBkaW1zOiBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbiA/IHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uKG91dHB1dFNoYXBlKSA6IG91dHB1dFNoYXBlLFxuICAgICAgICAgIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vLyBzYW1wbGVkIGZyb20gW0B0ZW5zb3JmbG93L3RmanNdIHRmanMtYmFja2VuZC13ZWJncHUvc3JjL21hdG11bF9wYWNrZWRfd2ViZ3B1LnRzXG4vL1xuLy8gbW9kaWZpZWQgdG8gZml0IHRoZSBuZWVkcyBvZiB0aGUgcHJvamVjdFxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQge1xuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgSW5kaWNlc0hlbHBlcixcbiAgaW5wdXRWYXJpYWJsZSxcbiAgaW50ZXJuYWxWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlLFxuICBVbmlmb3Jtc0FycmF5VHlwZSxcbn0gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7XG4gIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3JtcyxcbiAgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zRGF0YSxcbiAgZ2V0QWN0aXZhdGlvblNuaXBwZXQsXG4gIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsXG59IGZyb20gJy4uL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgY29udmVydE91dHB1dEJhdGNoSW5kaWNlc1RvSW5wdXRCYXRjaEluZGljZXMgfSBmcm9tICcuLi9tYXRtdWwtc2hhZGVycyc7XG5cbmltcG9ydCB7IHR5cGVTbmlwcGV0IH0gZnJvbSAnLi9hY3RpdmF0aW9uX3V0aWwnO1xuXG5jb25zdCB3cml0ZURhdGFUb1N1YkFWZWM0U25pcHBldCA9ICh0cmFuc3Bvc2U6IGJvb2xlYW4sIGJhdGNoRGltcz86IEluZGljZXNIZWxwZXIpID0+IHtcbiAgaWYgKHRyYW5zcG9zZSkge1xuICAgIHJldHVybiBgXG4gICAgICAgIG1tX0FzdWJbaW5wdXRSb3ddW2lucHV0Q29sXSA9IG1tX3JlYWRBKGJhdGNoLFxuICAgICAgICAgIGtTdGFydCArIGlucHV0Um93LFxuICAgICAgICAgIGdsb2JhbFJvd1N0YXJ0IC8gaW5uZXJFbGVtZW50U2l6ZSArIGlucHV0Q29sJHtiYXRjaERpbXMgPyAnLCBiYXRjaEluZGljZXMnIDogJyd9KTtcbiAgICAgICAgYDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYFxuICAgICAgICBtbV9Bc3ViW2lucHV0Um93XVtpbnB1dENvbF0gPSBtbV9yZWFkQShiYXRjaCxcbiAgICAgICAgICBnbG9iYWxSb3cgKyBpbm5lclJvdyxcbiAgICAgICAgICBrU3RhcnQgLyBpbm5lckVsZW1lbnRTaXplICsgaW5wdXRDb2wke2JhdGNoRGltcyA/ICcsIGJhdGNoSW5kaWNlcycgOiAnJ30pO1xuICAgICAgICBgO1xuICB9XG59O1xuXG5jb25zdCBjYWxjdWxhdGVSZXN1bHRTbmlwcGV0ID0gKHRyYW5zcG9zZUE6IGJvb2xlYW4sIGlubmVyRWxlbWVudFNpemU6IG51bWJlcikgPT4ge1xuICBpZiAodHJhbnNwb3NlQSkge1xuICAgIHJldHVybiBgXG4gICAgICAgIGxldCBBQ2FjaGVkMCA9IG1tX0FzdWJbayAqIGlubmVyRWxlbWVudFNpemVdW2xvY2FsUm93XTtcbiAgICAgICAgbGV0IEFDYWNoZWQxID0gbW1fQXN1YltrICogaW5uZXJFbGVtZW50U2l6ZSArIDFdW2xvY2FsUm93XTtcbiAgICAgICAgbGV0IEFDYWNoZWQyID0gbW1fQXN1YltrICogaW5uZXJFbGVtZW50U2l6ZSArIDJdW2xvY2FsUm93XTtcbiAgICAgICAgJHtpbm5lckVsZW1lbnRTaXplID09PSAzID8gJycgOiAnbGV0IEFDYWNoZWQzID0gbW1fQXN1YltrICogaW5uZXJFbGVtZW50U2l6ZSArIDNdW2xvY2FsUm93XTsnfVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJvd1BlclRocmVhZDsgaSA9IGkgKyAxKSB7XG4gICAgICAgICAgYWNjW2ldID0gQkNhY2hlZDAgKiBBQ2FjaGVkMFtpXSArIGFjY1tpXTtcbiAgICAgICAgICBhY2NbaV0gPSBCQ2FjaGVkMSAqIEFDYWNoZWQxW2ldICsgYWNjW2ldO1xuICAgICAgICAgIGFjY1tpXSA9IEJDYWNoZWQyICogQUNhY2hlZDJbaV0gKyBhY2NbaV07XG4gICAgICAgICAgJHtpbm5lckVsZW1lbnRTaXplID09PSAzID8gJycgOiAnYWNjW2ldID0gQkNhY2hlZDMgKiBBQ2FjaGVkM1tpXSArIGFjY1tpXTsnfVxuICAgICAgICB9YDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJvd1BlclRocmVhZDsgaSA9IGkgKyAxKSB7XG4gICAgICAgICAgbGV0IEFDYWNoZWQgPSBtbV9Bc3ViW3RpbGVSb3cgKyBpXVtrXTtcbiAgICAgICAgICBhY2NbaV0gPSBCQ2FjaGVkMCAqIEFDYWNoZWQueCArIGFjY1tpXTtcbiAgICAgICAgICBhY2NbaV0gPSBCQ2FjaGVkMSAqIEFDYWNoZWQueSArIGFjY1tpXTtcbiAgICAgICAgICBhY2NbaV0gPSBCQ2FjaGVkMiAqIEFDYWNoZWQueiArIGFjY1tpXTtcbiAgICAgICAgICAke2lubmVyRWxlbWVudFNpemUgPT09IDMgPyAnJyA6ICdhY2NbaV0gPSBCQ2FjaGVkMyAqIEFDYWNoZWQudyArIGFjY1tpXTsnfVxuICAgICAgICB9YDtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IG1ha2VNYXRNdWxQYWNrZWRWZWM0U291cmNlID0gKFxuICB3b3JrUGVyVGhyZWFkOiBudW1iZXJbXSxcbiAgd29ya2dyb3VwU2l6ZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICB0eXBlID0gJ2YzMicsXG4gIGJhdGNoRGltcz86IEluZGljZXNIZWxwZXIsXG4gIHRyYW5zcG9zZUEgPSBmYWxzZSxcbiAgdGlsZUlubmVyID0gMzIsXG4gIHNwbGl0SyA9IGZhbHNlLFxuICBzcGxpdGVkRGltSW5uZXIgPSAzMixcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHRpbGVBT3V0ZXIgPSB3b3JrZ3JvdXBTaXplWzFdICogd29ya1BlclRocmVhZFsxXTtcbiAgY29uc3QgdGlsZUJPdXRlciA9IHdvcmtncm91cFNpemVbMF0gKiB3b3JrUGVyVGhyZWFkWzBdO1xuICBjb25zdCB0aWxlQVdpZHRoID0gdHJhbnNwb3NlQSA/IHRpbGVBT3V0ZXIgOiB0aWxlSW5uZXI7XG4gIGNvbnN0IHRpbGVBSGlnaHQgPSB0cmFuc3Bvc2VBID8gdGlsZUlubmVyIDogdGlsZUFPdXRlcjtcbiAgY29uc3QgaW5uZXJFbGVtZW50U2l6ZSA9IHRpbGVBV2lkdGggLyB3b3JrZ3JvdXBTaXplWzBdO1xuICBjb25zdCByb3dQZXJUaHJlYWRCID0gdGlsZUlubmVyIC8gd29ya2dyb3VwU2l6ZVsxXTtcblxuICBpZiAoXG4gICAgIShcbiAgICAgICgodHJhbnNwb3NlQSAmJiBpbm5lckVsZW1lbnRTaXplID09PSA0ICYmIHdvcmtQZXJUaHJlYWRbMV0gPT09IDQpIHx8XG4gICAgICAgICghdHJhbnNwb3NlQSAmJiAoaW5uZXJFbGVtZW50U2l6ZSA9PT0gMyB8fCBpbm5lckVsZW1lbnRTaXplID09PSA0KSkpICYmXG4gICAgICB0aWxlQVdpZHRoICUgd29ya2dyb3VwU2l6ZVswXSA9PT0gMCAmJlxuICAgICAgdGlsZUlubmVyICUgd29ya2dyb3VwU2l6ZVsxXSA9PT0gMCAmJlxuICAgICAgd29ya1BlclRocmVhZFswXSA9PT0gNFxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJZiB0cmFuc3Bvc2VBICR7dHJhbnNwb3NlQX0gaXMgdHJ1ZSwgaW5uZXJFbGVtZW50U2l6ZSAke2lubmVyRWxlbWVudFNpemV9IGFuZCB3b3JrUGVyVGhyZWFkWzFdICR7d29ya1BlclRocmVhZFsxXX0gbXVzdCBiZSA0LlxuICAgICAgT3RoZXJ3aXNlLCBpbm5lckVsZW1lbnRTaXplICR7aW5uZXJFbGVtZW50U2l6ZX0gbXVzdCBiZSAzIG9yIDQuXG4gIHRpbGVBV2lkdGggJHt0aWxlQVdpZHRofSBtdXN0IGJlIGRpdmlzaWJsZSBieSB3b3JrZ3JvdXBTaXplWzBdJHt3b3JrZ3JvdXBTaXplWzBdfS4gdGlsZUlubmVyICR7dGlsZUlubmVyfSBtdXN0IGJlIGRpdmlzaWJsZSBieSB3b3JrZ3JvdXBTaXplWzFdICR7d29ya2dyb3VwU2l6ZVsxXX0uIGNvbFBlclRocmVhZCAke3dvcmtQZXJUaHJlYWRbMF19IG11c3QgYmUgNC5gKTtcbiAgfVxuICByZXR1cm4gYFxudmFyPHdvcmtncm91cD4gbW1fQXN1YjogYXJyYXk8YXJyYXk8dmVjJHtpbm5lckVsZW1lbnRTaXplfTwke3R5cGV9PiwgJHt0aWxlQVdpZHRoIC8gaW5uZXJFbGVtZW50U2l6ZX0+LCAke3RpbGVBSGlnaHR9PjtcbnZhcjx3b3JrZ3JvdXA+IG1tX0JzdWI6IGFycmF5PGFycmF5PHZlYzQ8JHt0eXBlfT4sICR7dGlsZUJPdXRlciAvIHdvcmtQZXJUaHJlYWRbMF19PiwgJHt0aWxlSW5uZXJ9PjtcblxuY29uc3Qgcm93UGVyVGhyZWFkID0gJHt3b3JrUGVyVGhyZWFkWzFdfTtcbmNvbnN0IGNvbFBlclRocmVhZCA9ICR7d29ya1BlclRocmVhZFswXX07XG5jb25zdCBpbm5lckVsZW1lbnRTaXplID0gJHtpbm5lckVsZW1lbnRTaXplfTtcbmNvbnN0IHRpbGVJbm5lciA9ICR7dGlsZUlubmVyfTtcblxuQGNvbXB1dGUgQHdvcmtncm91cF9zaXplKCR7d29ya2dyb3VwU2l6ZVswXX0sICR7d29ya2dyb3VwU2l6ZVsxXX0sICR7d29ya2dyb3VwU2l6ZVsyXX0pXG5mbiBtYWluKEBidWlsdGluKGxvY2FsX2ludm9jYXRpb25faWQpIGxvY2FsSWQgOiB2ZWMzPHUzMj4sXG4gICAgICAgIEBidWlsdGluKGdsb2JhbF9pbnZvY2F0aW9uX2lkKSBnbG9iYWxJZCA6IHZlYzM8dTMyPixcbiAgICAgICAgQGJ1aWx0aW4od29ya2dyb3VwX2lkKSB3b3JrZ3JvdXBJZCA6IHZlYzM8dTMyPikge1xuICBsZXQgbG9jYWxSb3cgPSBpMzIobG9jYWxJZC55KTtcbiAgbGV0IHRpbGVSb3cgPSBsb2NhbFJvdyAqIHJvd1BlclRocmVhZDtcbiAgbGV0IHRpbGVDb2wgPSBpMzIobG9jYWxJZC54KTtcblxuICBsZXQgZ2xvYmFsUm93ID1pMzIoZ2xvYmFsSWQueSkgKiByb3dQZXJUaHJlYWQ7XG4gIGxldCBnbG9iYWxDb2wgPSBpMzIoZ2xvYmFsSWQueCk7XG4gIGxldCBiYXRjaCA9ICR7c3BsaXRLID8gJzAnIDogJ2kzMihnbG9iYWxJZC56KSd9O1xuICAke2JhdGNoRGltcyA/IGBsZXQgYmF0Y2hJbmRpY2VzID0gJHtiYXRjaERpbXMub2Zmc2V0VG9JbmRpY2VzKCd1MzIoYmF0Y2gpJyl9O2AgOiAnJ31cbiAgbGV0IGdsb2JhbFJvd1N0YXJ0ID0gaTMyKHdvcmtncm91cElkLnkpICogJHt0aWxlQU91dGVyfTtcblxuICBsZXQgbnVtX3RpbGVzID0gJHtzcGxpdEsgPyBgJHtNYXRoLmNlaWwoc3BsaXRlZERpbUlubmVyIC8gdGlsZUlubmVyKX1gIDogJyh1bmlmb3Jtcy5kaW1faW5uZXIgLSAxKSAvIHRpbGVJbm5lciArIDEnfTtcbiAgdmFyIGtTdGFydCA9ICR7c3BsaXRLID8gYGkzMihnbG9iYWxJZC56KSAqICR7c3BsaXRlZERpbUlubmVyfWAgOiAnMCd9O1xuXG4gIHZhciBhY2M6IGFycmF5PHZlYzQ8JHt0eXBlfT4sIHJvd1BlclRocmVhZD47XG5cbiAgLy8gTG9vcCBvdmVyIHNoYXJlZCBkaW1lbnNpb24uXG4gIGxldCB0aWxlUm93QiA9IGxvY2FsUm93ICogJHtyb3dQZXJUaHJlYWRCfTtcbiAgZm9yICh2YXIgdCA9IDA7IHQgPCBudW1fdGlsZXM7IHQgPSB0ICsgMSkge1xuICAgICAgLy8gTG9hZCBvbmUgdGlsZSBvZiBBIGludG8gbG9jYWwgbWVtb3J5LlxuICAgICAgZm9yICh2YXIgaW5uZXJSb3cgPSAwOyBpbm5lclJvdyA8IHJvd1BlclRocmVhZDsgaW5uZXJSb3cgPSBpbm5lclJvdyArIDEpIHtcbiAgICAgICAgICBsZXQgaW5wdXRSb3cgPSB0aWxlUm93ICsgaW5uZXJSb3c7XG4gICAgICAgICAgbGV0IGlucHV0Q29sID0gdGlsZUNvbDtcbiAgICAgICAgICAke3dyaXRlRGF0YVRvU3ViQVZlYzRTbmlwcGV0KHRyYW5zcG9zZUEsIGJhdGNoRGltcyl9XG4gICAgICB9XG5cbiAgICAgIC8vIExvYWQgb25lIHRpbGUgb2YgQiBpbnRvIGxvY2FsIG1lbW9yeS5cbiAgICAgIGZvciAodmFyIGlubmVyUm93ID0gMDsgaW5uZXJSb3cgPCAke3Jvd1BlclRocmVhZEJ9OyBpbm5lclJvdyA9IGlubmVyUm93ICsgMSkge1xuICAgICAgICAgIGxldCBpbnB1dFJvdyA9IHRpbGVSb3dCICsgaW5uZXJSb3c7XG4gICAgICAgICAgbGV0IGlucHV0Q29sID0gdGlsZUNvbDtcbiAgICAgICAgICBtbV9Cc3ViW2lucHV0Um93XVtpbnB1dENvbF0gPSBtbV9yZWFkQihiYXRjaCwga1N0YXJ0ICsgaW5wdXRSb3csIGdsb2JhbENvbCR7XG4gICAgICAgICAgICBiYXRjaERpbXMgPyAnLCBiYXRjaEluZGljZXMnIDogJydcbiAgICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGtTdGFydCA9IGtTdGFydCArIHRpbGVJbm5lcjtcbiAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgICAgLy8gQ29tcHV0ZSBhY2MgdmFsdWVzIGZvciBhIHNpbmdsZSB0aHJlYWQuXG4gICAgICBmb3IgKHZhciBrID0gMDsgayA8IHRpbGVJbm5lciAvIGlubmVyRWxlbWVudFNpemU7IGsgPSBrICsgMSkge1xuICAgICAgICAgIGxldCBCQ2FjaGVkMCA9IG1tX0JzdWJbayAqIGlubmVyRWxlbWVudFNpemVdW3RpbGVDb2xdO1xuICAgICAgICAgIGxldCBCQ2FjaGVkMSA9IG1tX0JzdWJbayAqIGlubmVyRWxlbWVudFNpemUgKyAxXVt0aWxlQ29sXTtcbiAgICAgICAgICBsZXQgQkNhY2hlZDIgPSBtbV9Cc3ViW2sgKiBpbm5lckVsZW1lbnRTaXplICsgMl1bdGlsZUNvbF07XG4gICAgICAgICAgJHtpbm5lckVsZW1lbnRTaXplID09PSAzID8gJycgOiAnbGV0IEJDYWNoZWQzID0gbW1fQnN1YltrICogaW5uZXJFbGVtZW50U2l6ZSArIDNdW3RpbGVDb2xdOyd9XG5cbiAgICAgICAgICAke2NhbGN1bGF0ZVJlc3VsdFNuaXBwZXQodHJhbnNwb3NlQSwgaW5uZXJFbGVtZW50U2l6ZSl9XG4gICAgICB9XG5cbiAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcbiAgfVxuXG4gIGZvciAodmFyIGlubmVyUm93ID0gMDsgaW5uZXJSb3cgPCByb3dQZXJUaHJlYWQ7IGlubmVyUm93ID0gaW5uZXJSb3cgKyAxKSB7XG4gICAgICBtbV93cml0ZShiYXRjaCwgZ2xvYmFsUm93ICsgaW5uZXJSb3csIGdsb2JhbENvbCwgYWNjW2lubmVyUm93XSk7XG4gIH1cbn1gO1xufTtcblxuY29uc3Qgd3JpdGVEYXRhVG9TdWJBU25pcHBldCA9ICh0cmFuc3Bvc2U6IGJvb2xlYW4sIGJhdGNoRGltcz86IEluZGljZXNIZWxwZXIpID0+IHtcbiAgaWYgKHRyYW5zcG9zZSkge1xuICAgIHJldHVybiBgXG4gICAgICAgICAgICBtbV9Bc3ViW2lucHV0Um93XVtpbnB1dENvbF0gPSBtbV9yZWFkQShiYXRjaCxcbiAgICAgICAgICAgICAga1N0YXJ0ICsgaW5wdXRSb3csXG4gICAgICAgICAgICAgIGdsb2JhbFJvd1N0YXJ0ICsgaW5wdXRDb2wke2JhdGNoRGltcyA/ICcsIGJhdGNoSW5kaWNlcycgOiAnJ30pO1xuICAgICAgICAgICAgYDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYFxuICAgICAgICAgICAgbW1fQXN1YltpbnB1dFJvd11baW5wdXRDb2xdID0gbW1fcmVhZEEoYmF0Y2gsXG4gICAgICAgICAgICAgIGdsb2JhbFJvd1N0YXJ0ICsgaW5wdXRSb3csXG4gICAgICAgICAgICAgIGtTdGFydCArIGlucHV0Q29sJHtiYXRjaERpbXMgPyAnLCBiYXRjaEluZGljZXMnIDogJyd9KTtcbiAgICAgICAgICAgIGA7XG4gIH1cbn07XG5cbmNvbnN0IHJlYWREYXRhRnJvbVN1YkFTbmlwcGV0ID0gKHRyYW5zcG9zZUE6IGJvb2xlYW4pID0+XG4gIHRyYW5zcG9zZUEgPyAnbGV0IEFDYWNoZWQgPSBtbV9Bc3ViW2tdW3RpbGVSb3cgKyBpbm5lclJvd107JyA6ICdsZXQgQUNhY2hlZCA9IG1tX0FzdWJbdGlsZVJvdyArIGlubmVyUm93XVtrXTsnO1xuXG4vLyBzZXF1ZW50aWFsQWNjZXNzQnlUaHJlYWRzIG1lYW5zIHNlcXVlbnRpYWwgZGF0YSBpbiBtZW1vcnkgaXMgYWNjZXNzZWQgYnlcbi8vIHRocmVhZHMsIGluc3RlYWQgb2YgYSBzaW5nbGUgdGhyZWFkIChkZWZhdWx0IGJlaGF2aW9yKS5cbmV4cG9ydCBjb25zdCBtYWtlTWF0TXVsUGFja2VkU291cmNlID0gKFxuICB3b3JrUGVyVGhyZWFkOiBudW1iZXJbXSxcbiAgd29ya2dyb3VwU2l6ZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICB0eXBlID0gJ2YzMicsXG4gIGJhdGNoRGltcz86IEluZGljZXNIZWxwZXIsXG4gIHRyYW5zcG9zZUEgPSBmYWxzZSxcbiAgdGlsZUlubmVyID0gMzIsXG4gIHNwbGl0SyA9IGZhbHNlLFxuICBzcGxpdGVkRGltSW5uZXIgPSAzMixcbiAgc2VxdWVudGlhbEFjY2Vzc0J5VGhyZWFkcyA9IGZhbHNlLFxuKTogc3RyaW5nID0+IHtcbiAgY29uc3QgdGlsZUFPdXRlciA9IHdvcmtQZXJUaHJlYWRbMV0gKiB3b3JrZ3JvdXBTaXplWzFdO1xuICBjb25zdCB0aWxlQk91dGVyID0gd29ya1BlclRocmVhZFswXSAqIHdvcmtncm91cFNpemVbMF07XG4gIGNvbnN0IHRpbGVBV2lkdGggPSB0cmFuc3Bvc2VBID8gdGlsZUFPdXRlciA6IHRpbGVJbm5lcjtcbiAgY29uc3QgdGlsZUFIaWdodCA9IHRyYW5zcG9zZUEgPyB0aWxlSW5uZXIgOiB0aWxlQU91dGVyO1xuXG4gIGlmIChcbiAgICAhKHRpbGVBSGlnaHQgJSB3b3JrZ3JvdXBTaXplWzFdID09PSAwICYmIHRpbGVBV2lkdGggJSB3b3JrZ3JvdXBTaXplWzBdID09PSAwICYmIHRpbGVJbm5lciAlIHdvcmtncm91cFNpemVbMV0gPT09IDApXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGB0aWxlQUhpZ2h0ICR7dGlsZUFIaWdodH0gbXVzdCBiZSBkaXZpc2libGUgYnkgd29ya2dyb3VwU2l6ZVsxXSR7d29ya2dyb3VwU2l6ZVsxXX0sIHRpbGVBV2lkdGggJHt0aWxlQVdpZHRofSBtdXN0IGJlIGRpdmlzaWJsZSBieSB3b3JrZ3JvdXBTaXplWzBdJHt3b3JrZ3JvdXBTaXplWzBdfSwgdGlsZUlubmVyICR7dGlsZUlubmVyfSBtdXN0IGJlIGRpdmlzaWJsZSBieSB3b3JrZ3JvdXBTaXplWzFdJHt3b3JrZ3JvdXBTaXplWzFdfWAsXG4gICAgKTtcbiAgfVxuICBjb25zdCByb3dQZXJUaHJlYWRBID0gdGlsZUFIaWdodCAvIHdvcmtncm91cFNpemVbMV07XG4gIGNvbnN0IGNvbFBlclRocmVhZEEgPSB0aWxlQVdpZHRoIC8gd29ya2dyb3VwU2l6ZVswXTtcbiAgY29uc3Qgcm93UGVyVGhyZWFkQiA9IHRpbGVJbm5lciAvIHdvcmtncm91cFNpemVbMV07XG4gIGNvbnN0IG1hdG11bFNuaXBwZXQgPSBzZXF1ZW50aWFsQWNjZXNzQnlUaHJlYWRzXG4gICAgPyBgXG4gICAgbGV0IGxvY2FsUm93ID0gaTMyKGxvY2FsSWQueSk7XG4gICAgbGV0IGxvY2FsQ29sID0gaTMyKGxvY2FsSWQueCk7XG4gICAgbGV0IGdsb2JhbFJvd1N0YXJ0ID0gaTMyKHdvcmtncm91cElkLnkpICogJHt0aWxlQU91dGVyfTtcbiAgICBsZXQgZ2xvYmFsQ29sU3RhcnQgPSBpMzIod29ya2dyb3VwSWQueCkgKiAke3RpbGVCT3V0ZXJ9O1xuXG4gICAgLy8gTG9vcCBvdmVyIHNoYXJlZCBkaW1lbnNpb24uXG4gICAgZm9yICh2YXIgdCA9IDA7IHQgPCBudW1fdGlsZXM7IHQgPSB0ICsgMSkge1xuICAgICAgLy8gTG9hZCBvbmUgdGlsZSBvZiBBIGludG8gbG9jYWwgbWVtb3J5LlxuICAgICAgZm9yICh2YXIgaW5wdXRSb3cgPSBsb2NhbFJvdzsgaW5wdXRSb3cgPCAke3RpbGVBSGlnaHR9OyBpbnB1dFJvdyA9IGlucHV0Um93ICsgJHt3b3JrZ3JvdXBTaXplWzFdfSkge1xuICAgICAgICBmb3IgKHZhciBpbnB1dENvbCA9IGxvY2FsQ29sOyBpbnB1dENvbCA8ICR7dGlsZUFXaWR0aH07IGlucHV0Q29sID0gaW5wdXRDb2wgKyAke3dvcmtncm91cFNpemVbMF19KSB7XG4gICAgICAgICAgJHt3cml0ZURhdGFUb1N1YkFTbmlwcGV0KHRyYW5zcG9zZUEsIGJhdGNoRGltcyl9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIExvYWQgb25lIHRpbGUgb2YgQiBpbnRvIGxvY2FsIG1lbW9yeS5cbiAgICAgIGZvciAodmFyIGlucHV0Um93ID0gbG9jYWxSb3c7IGlucHV0Um93IDwgJHt0aWxlSW5uZXJ9OyBpbnB1dFJvdyA9IGlucHV0Um93ICsgJHt3b3JrZ3JvdXBTaXplWzFdfSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaW5wdXRDb2wgPSBsb2NhbENvbDsgaW5wdXRDb2wgPCAke3RpbGVCT3V0ZXJ9OyBpbnB1dENvbCA9IGlucHV0Q29sICsgJHt3b3JrZ3JvdXBTaXplWzBdfSkge1xuICAgICAgICAgIG1tX0JzdWJbaW5wdXRSb3ddW2lucHV0Q29sXSA9IG1tX3JlYWRCKGJhdGNoLFxuICAgICAgICAgICAga1N0YXJ0ICsgaW5wdXRSb3csXG4gICAgICAgICAgICBnbG9iYWxDb2xTdGFydCArIGlucHV0Q29sJHtiYXRjaERpbXMgPyAnLCBiYXRjaEluZGljZXMnIDogJyd9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAga1N0YXJ0ID0ga1N0YXJ0ICsgdGlsZUlubmVyO1xuICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuXG4gICAgICAvLyBDb21wdXRlIGFjYyB2YWx1ZXMgZm9yIGEgc2luZ2xlIHRocmVhZC5cbiAgICAgIHZhciBCQ2FjaGVkIDogYXJyYXk8JHt0eXBlfSwgY29sUGVyVGhyZWFkPjtcbiAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgdGlsZUlubmVyOyBrID0gayArIDEpIHtcbiAgICAgICAgZm9yICh2YXIgaW5uZXIgPSAwOyBpbm5lciA8IGNvbFBlclRocmVhZDsgaW5uZXIgPSBpbm5lciArIDEpIHtcbiAgICAgICAgICBCQ2FjaGVkW2lubmVyXSA9IG1tX0JzdWJba11bbG9jYWxDb2wgKyBpbm5lciAqICR7d29ya2dyb3VwU2l6ZVswXX1dO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGlubmVyUm93ID0gMDsgaW5uZXJSb3cgPCByb3dQZXJUaHJlYWQ7IGlubmVyUm93ID0gaW5uZXJSb3cgKyAxKSB7XG4gICAgICAgICAgbGV0IEFDYWNoZWQgPSAke1xuICAgICAgICAgICAgdHJhbnNwb3NlQVxuICAgICAgICAgICAgICA/IGBtbV9Bc3ViW2tdW2xvY2FsUm93ICsgaW5uZXJSb3cgKiAke3dvcmtncm91cFNpemVbMV19XTtgXG4gICAgICAgICAgICAgIDogYG1tX0FzdWJbbG9jYWxSb3cgKyBpbm5lclJvdyAqICR7d29ya2dyb3VwU2l6ZVsxXX1dW2tdO2BcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yICh2YXIgaW5uZXJDb2wgPSAwOyBpbm5lckNvbCA8IGNvbFBlclRocmVhZDsgaW5uZXJDb2wgPSBpbm5lckNvbCArIDEpIHtcbiAgICAgICAgICAgIGFjY1tpbm5lclJvd11baW5uZXJDb2xdID0gYWNjW2lubmVyUm93XVtpbm5lckNvbF0gK1xuICAgICAgICAgICAgICAgIEFDYWNoZWQgKiBCQ2FjaGVkW2lubmVyQ29sXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcbiAgICB9XG4gICAgZm9yICh2YXIgaW5uZXJSb3cgPSAwOyBpbm5lclJvdyA8IHJvd1BlclRocmVhZDsgaW5uZXJSb3cgPSBpbm5lclJvdyArIDEpIHtcbiAgICAgIGxldCBnUm93ID0gZ2xvYmFsUm93U3RhcnQgKyBsb2NhbFJvdyArIGlubmVyUm93ICogJHt3b3JrZ3JvdXBTaXplWzFdfTtcbiAgICAgIGZvciAodmFyIGlubmVyQ29sID0gMDsgaW5uZXJDb2wgPCBjb2xQZXJUaHJlYWQ7IGlubmVyQ29sID0gaW5uZXJDb2wgKyAxKSB7XG4gICAgICAgIGxldCBnQ29sID0gZ2xvYmFsQ29sU3RhcnQgKyBsb2NhbENvbCArIGlubmVyQ29sICogJHt3b3JrZ3JvdXBTaXplWzBdfTtcbiAgICAgICAgbW1fd3JpdGUoYmF0Y2gsIGdSb3csIGdDb2wsIGFjY1tpbm5lclJvd11baW5uZXJDb2xdKTtcbiAgICAgIH1cbiAgICB9XG4gICAgYFxuICAgIDogYFxubGV0IHRpbGVSb3cgPSBpMzIobG9jYWxJZC55KSAqIHJvd1BlclRocmVhZDtcbmxldCB0aWxlQ29sID0gaTMyKGxvY2FsSWQueCkgKiBjb2xQZXJUaHJlYWQ7XG5cbmxldCBnbG9iYWxSb3cgPSBpMzIoZ2xvYmFsSWQueSkgKiByb3dQZXJUaHJlYWQ7XG5sZXQgZ2xvYmFsQ29sID0gaTMyKGdsb2JhbElkLngpICogY29sUGVyVGhyZWFkO1xubGV0IGdsb2JhbFJvd1N0YXJ0ID0gaTMyKHdvcmtncm91cElkLnkpICogJHt0aWxlQU91dGVyfTtcblxubGV0IHRpbGVSb3dBID0gaTMyKGxvY2FsSWQueSkgKiAke3Jvd1BlclRocmVhZEF9O1xubGV0IHRpbGVDb2xBID0gaTMyKGxvY2FsSWQueCkgKiAke2NvbFBlclRocmVhZEF9O1xubGV0IHRpbGVSb3dCID0gaTMyKGxvY2FsSWQueSkgKiAke3Jvd1BlclRocmVhZEJ9O1xuLy8gTG9vcCBvdmVyIHNoYXJlZCBkaW1lbnNpb24uXG5mb3IgKHZhciB0ID0gMDsgdCA8IG51bV90aWxlczsgdCA9IHQgKyAxKSB7XG4gIC8vIExvYWQgb25lIHRpbGUgb2YgQSBpbnRvIGxvY2FsIG1lbW9yeS5cbiAgZm9yICh2YXIgaW5uZXJSb3cgPSAwOyBpbm5lclJvdyA8ICR7cm93UGVyVGhyZWFkQX07IGlubmVyUm93ID0gaW5uZXJSb3cgKyAxKSB7XG4gICAgZm9yICh2YXIgaW5uZXJDb2wgPSAwOyBpbm5lckNvbCA8ICR7Y29sUGVyVGhyZWFkQX07IGlubmVyQ29sID0gaW5uZXJDb2wgKyAxKSB7XG4gICAgICBsZXQgaW5wdXRSb3cgPSB0aWxlUm93QSArIGlubmVyUm93O1xuICAgICAgbGV0IGlucHV0Q29sID0gdGlsZUNvbEEgKyBpbm5lckNvbDtcbiAgICAgICR7d3JpdGVEYXRhVG9TdWJBU25pcHBldCh0cmFuc3Bvc2VBLCBiYXRjaERpbXMpfVxuICAgIH1cbiAgfVxuXG4gIC8vIExvYWQgb25lIHRpbGUgb2YgQiBpbnRvIGxvY2FsIG1lbW9yeS5cbiAgZm9yICh2YXIgaW5uZXJSb3cgPSAwOyBpbm5lclJvdyA8ICR7cm93UGVyVGhyZWFkQn07IGlubmVyUm93ID0gaW5uZXJSb3cgKyAxKSB7XG4gICAgZm9yICh2YXIgaW5uZXJDb2wgPSAwOyBpbm5lckNvbCA8IGNvbFBlclRocmVhZDsgaW5uZXJDb2wgPSBpbm5lckNvbCArIDEpIHtcbiAgICAgIGxldCBpbnB1dFJvdyA9IHRpbGVSb3dCICsgaW5uZXJSb3c7XG4gICAgICBsZXQgaW5wdXRDb2wgPSB0aWxlQ29sICsgaW5uZXJDb2w7XG4gICAgICBtbV9Cc3ViW2lucHV0Um93XVtpbnB1dENvbF0gPSBtbV9yZWFkQihiYXRjaCxcbiAgICAgICAga1N0YXJ0ICsgaW5wdXRSb3csXG4gICAgICAgIGdsb2JhbENvbCArIGlubmVyQ29sJHtiYXRjaERpbXMgPyAnLCBiYXRjaEluZGljZXMnIDogJyd9KTtcbiAgICB9XG4gIH1cbiAga1N0YXJ0ID0ga1N0YXJ0ICsgdGlsZUlubmVyO1xuICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgLy8gQ29tcHV0ZSBhY2MgdmFsdWVzIGZvciBhIHNpbmdsZSB0aHJlYWQuXG4gIHZhciBCQ2FjaGVkIDogYXJyYXk8JHt0eXBlfSwgY29sUGVyVGhyZWFkPjtcbiAgZm9yICh2YXIgayA9IDA7IGsgPCB0aWxlSW5uZXI7IGsgPSBrICsgMSkge1xuICAgIGZvciAodmFyIGlubmVyID0gMDsgaW5uZXIgPCBjb2xQZXJUaHJlYWQ7IGlubmVyID0gaW5uZXIgKyAxKSB7XG4gICAgICBCQ2FjaGVkW2lubmVyXSA9IG1tX0JzdWJba11bdGlsZUNvbCArIGlubmVyXTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpbm5lclJvdyA9IDA7IGlubmVyUm93IDwgcm93UGVyVGhyZWFkOyBpbm5lclJvdyA9IGlubmVyUm93ICsgMSkge1xuICAgICAgJHtyZWFkRGF0YUZyb21TdWJBU25pcHBldCh0cmFuc3Bvc2VBKX1cbiAgICAgIGZvciAodmFyIGlubmVyQ29sID0gMDsgaW5uZXJDb2wgPCBjb2xQZXJUaHJlYWQ7IGlubmVyQ29sID0gaW5uZXJDb2wgKyAxKSB7XG4gICAgICAgIGFjY1tpbm5lclJvd11baW5uZXJDb2xdID0gYWNjW2lubmVyUm93XVtpbm5lckNvbF0gKyBBQ2FjaGVkICogQkNhY2hlZFtpbm5lckNvbF07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgd29ya2dyb3VwQmFycmllcigpO1xufVxuXG5mb3IgKHZhciBpbm5lclJvdyA9IDA7IGlubmVyUm93IDwgcm93UGVyVGhyZWFkOyBpbm5lclJvdyA9IGlubmVyUm93ICsgMSkge1xuICBmb3IgKHZhciBpbm5lckNvbCA9IDA7IGlubmVyQ29sIDwgY29sUGVyVGhyZWFkOyBpbm5lckNvbCA9IGlubmVyQ29sICsgMSkge1xuICAgIG1tX3dyaXRlKGJhdGNoLCBnbG9iYWxSb3cgKyBpbm5lclJvdywgZ2xvYmFsQ29sICsgaW5uZXJDb2wsXG4gICAgICAgIGFjY1tpbm5lclJvd11baW5uZXJDb2xdKTtcbiAgfVxufVxuYDtcblxuICByZXR1cm4gYFxuICB2YXI8d29ya2dyb3VwPiBtbV9Bc3ViIDogYXJyYXk8YXJyYXk8JHt0eXBlfSwgJHt0aWxlQVdpZHRofT4sICR7dGlsZUFIaWdodH0+O1xuICB2YXI8d29ya2dyb3VwPiBtbV9Cc3ViIDogYXJyYXk8YXJyYXk8JHt0eXBlfSwgJHt0aWxlQk91dGVyfT4sICR7dGlsZUlubmVyfT47XG4gIGNvbnN0IHJvd1BlclRocmVhZCA9ICR7d29ya1BlclRocmVhZFsxXX07XG4gIGNvbnN0IGNvbFBlclRocmVhZCA9ICR7d29ya1BlclRocmVhZFswXX07XG4gIGNvbnN0IHRpbGVJbm5lciA9ICR7dGlsZUlubmVyfTtcblxuQGNvbXB1dGUgQHdvcmtncm91cF9zaXplKCR7d29ya2dyb3VwU2l6ZVswXX0sICR7d29ya2dyb3VwU2l6ZVsxXX0sICR7d29ya2dyb3VwU2l6ZVsyXX0pXG5mbiBtYWluKEBidWlsdGluKGxvY2FsX2ludm9jYXRpb25faWQpIGxvY2FsSWQgOiB2ZWMzPHUzMj4sXG4gICAgICAgIEBidWlsdGluKGdsb2JhbF9pbnZvY2F0aW9uX2lkKSBnbG9iYWxJZCA6IHZlYzM8dTMyPixcbiAgICAgICAgQGJ1aWx0aW4od29ya2dyb3VwX2lkKSB3b3JrZ3JvdXBJZCA6IHZlYzM8dTMyPikge1xuICAgIGxldCBiYXRjaCA9ICR7c3BsaXRLID8gJzAnIDogJ2kzMihnbG9iYWxJZC56KSd9O1xuICAgICR7YmF0Y2hEaW1zID8gYGxldCBiYXRjaEluZGljZXMgPSAke2JhdGNoRGltcy5vZmZzZXRUb0luZGljZXMoJ3UzMihiYXRjaCknKX07YCA6ICcnfVxuICAgIGxldCBudW1fdGlsZXMgPSAke1xuICAgICAgc3BsaXRLID8gYCR7TWF0aC5jZWlsKHNwbGl0ZWREaW1Jbm5lciAvIHRpbGVJbm5lcil9YCA6ICcodW5pZm9ybXMuZGltX2lubmVyIC0gMSkgLyB0aWxlSW5uZXIgKyAxJ1xuICAgIH07XG4gICAgdmFyIGtTdGFydCA9ICR7c3BsaXRLID8gYGkzMihnbG9iYWxJZC56KSAqICR7c3BsaXRlZERpbUlubmVyfWAgOiAnMCd9O1xuXG4gICAgdmFyIGFjYyA6IGFycmF5PGFycmF5PCR7dHlwZX0sIGNvbFBlclRocmVhZD4sIHJvd1BlclRocmVhZD47XG4gICAgJHttYXRtdWxTbmlwcGV0fVxuICB9XG5gO1xufTtcblxuY29uc3QgbWF0TXVsUmVhZFdyaXRlRm5Tb3VyY2UgPSAoXG4gIGNvbXBvbmVudDogbnVtYmVyLFxuICBoYXNCaWFzOiBib29sZWFuLFxuICBhcHBseUFjdGl2YXRpb246IHN0cmluZyxcbiAgdmFyaWFibGVzOiBJbmRpY2VzSGVscGVyW10sXG4gIGlzQ2hhbm5lbHNMYXN0ID0gZmFsc2UsXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBbYmF0Y2hWYXJpYWJsZSwgYVZhcmlhYmxlLCBiVmFyaWFibGUsIG91dHB1dFZhcmlhYmxlXSA9IHZhcmlhYmxlcztcbiAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUodmFyaWFibGVzWzBdLnR5cGUudGVuc29yKTtcblxuICBjb25zdCBzb3VyY2UgPSBgXG4gICAgZm4gbW1fcmVhZEEoYmF0Y2g6IGkzMiwgcm93OiBpMzIsIGNvbEluOiBpMzIsIGJhdGNoSW5kaWNlczogJHtiYXRjaFZhcmlhYmxlLnR5cGUuaW5kaWNlc30pIC0+ICR7dHlwZVNuaXBwZXQoXG4gICAgICBjb21wb25lbnQsXG4gICAgICBkYXRhVHlwZSxcbiAgICApfSB7XG4gICAgICB2YXIgdmFsdWUgPSAke3R5cGVTbmlwcGV0KGNvbXBvbmVudCwgZGF0YVR5cGUpfSgwLjApO1xuICAgICAgbGV0IGNvbCA9IGNvbEluICogJHtjb21wb25lbnR9O1xuICAgICAgaWYocm93IDwgdW5pZm9ybXMuZGltX2Ffb3V0ZXIgJiYgY29sIDwgdW5pZm9ybXMuZGltX2lubmVyKVxuICAgICAge1xuICAgICAgICB2YXIgYUluZGljZXM6ICR7YVZhcmlhYmxlLnR5cGUuaW5kaWNlc307XG4gICAgICAgICR7Y29udmVydE91dHB1dEJhdGNoSW5kaWNlc1RvSW5wdXRCYXRjaEluZGljZXMoXG4gICAgICAgICAgJ2FJbmRpY2VzJyxcbiAgICAgICAgICBhVmFyaWFibGUsXG4gICAgICAgICAgYVZhcmlhYmxlLnJhbmsgLSAyLFxuICAgICAgICAgIGJhdGNoVmFyaWFibGUucmFuayxcbiAgICAgICAgICAnYmF0Y2hJbmRpY2VzJyxcbiAgICAgICAgKX1cbiAgICAgICAgJHthVmFyaWFibGUuaW5kaWNlc1NldCgnYUluZGljZXMnLCBhVmFyaWFibGUucmFuayAtIDIsICd1MzIocm93KScpfVxuICAgICAgICAke2FWYXJpYWJsZS5pbmRpY2VzU2V0KCdhSW5kaWNlcycsIGFWYXJpYWJsZS5yYW5rIC0gMSwgJ3UzMihjb2xJbiknKX1cbiAgICAgICAgdmFsdWUgPSAke2FWYXJpYWJsZS5nZXRCeUluZGljZXMoJ2FJbmRpY2VzJyl9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGZuIG1tX3JlYWRCKGJhdGNoOiBpMzIsIHJvdzogaTMyLCBjb2xJbjogaTMyLCBiYXRjaEluZGljZXM6ICR7YmF0Y2hWYXJpYWJsZS50eXBlLmluZGljZXN9KSAtPiAke3R5cGVTbmlwcGV0KFxuICAgICAgY29tcG9uZW50LFxuICAgICAgZGF0YVR5cGUsXG4gICAgKX0ge1xuICAgICAgdmFyIHZhbHVlID0gJHt0eXBlU25pcHBldChjb21wb25lbnQsIGRhdGFUeXBlKX0oMC4wKTtcbiAgICAgIGxldCBjb2wgPSBjb2xJbiAqICR7Y29tcG9uZW50fTtcbiAgICAgIGlmKHJvdyA8IHVuaWZvcm1zLmRpbV9pbm5lciAmJiBjb2wgPCB1bmlmb3Jtcy5kaW1fYl9vdXRlcilcbiAgICAgIHtcbiAgICAgICAgdmFyIGJJbmRpY2VzOiAke2JWYXJpYWJsZS50eXBlLmluZGljZXN9O1xuICAgICAgICAke2NvbnZlcnRPdXRwdXRCYXRjaEluZGljZXNUb0lucHV0QmF0Y2hJbmRpY2VzKFxuICAgICAgICAgICdiSW5kaWNlcycsXG4gICAgICAgICAgYlZhcmlhYmxlLFxuICAgICAgICAgIGJWYXJpYWJsZS5yYW5rIC0gMixcbiAgICAgICAgICBiYXRjaFZhcmlhYmxlLnJhbmssXG4gICAgICAgICAgJ2JhdGNoSW5kaWNlcycsXG4gICAgICAgICl9XG4gICAgICAgICR7YlZhcmlhYmxlLmluZGljZXNTZXQoJ2JJbmRpY2VzJywgYlZhcmlhYmxlLnJhbmsgLSAyLCAndTMyKHJvdyknKX1cbiAgICAgICAgJHtiVmFyaWFibGUuaW5kaWNlc1NldCgnYkluZGljZXMnLCBiVmFyaWFibGUucmFuayAtIDEsICd1MzIoY29sSW4pJyl9XG4gICAgICAgIHZhbHVlID0gJHtiVmFyaWFibGUuZ2V0QnlJbmRpY2VzKCdiSW5kaWNlcycpfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBmbiBtbV93cml0ZShiYXRjaDogaTMyLCByb3c6IGkzMiwgY29sSW46IGkzMiwgdmFsdWVJbjogJHt0eXBlU25pcHBldChjb21wb25lbnQsIGRhdGFUeXBlKX0pIHtcbiAgICAgIGxldCBjb2wgPSBjb2xJbiAqICR7Y29tcG9uZW50fTtcbiAgICAgIGlmIChyb3cgPCB1bmlmb3Jtcy5kaW1fYV9vdXRlciAmJiBjb2wgPCB1bmlmb3Jtcy5kaW1fYl9vdXRlcikge1xuICAgICAgICB2YXIgdmFsdWUgPSB2YWx1ZUluO1xuICAgICAgICBsZXQgY29vcmRzID0gdmVjMzxpMzI+KGJhdGNoLCByb3csIGNvbEluKTtcbiAgICAgICAgJHtcbiAgICAgICAgICBoYXNCaWFzXG4gICAgICAgICAgICA/IGB2YWx1ZSA9IHZhbHVlICsgJHtpc0NoYW5uZWxzTGFzdCA/ICdiaWFzW2NvbEluXScgOiBgJHt0eXBlU25pcHBldChjb21wb25lbnQsIGRhdGFUeXBlKX0oYmlhc1tyb3ddKWB9O2BcbiAgICAgICAgICAgIDogJydcbiAgICAgICAgfVxuICAgICAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAgICAgJHtvdXRwdXRWYXJpYWJsZS5zZXRCeUluZGljZXMoJ3ZlYzM8dTMyPihjb29yZHMpJywgJ3ZhbHVlJyl9XG4gICAgICB9XG4gICAgfVxuICAgIGA7XG4gIHJldHVybiBzb3VyY2U7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhY3RpdmF0aW9uQXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyxcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICByZXNoYXBlZE91dHB1dFNoYXBlPzogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGlzQ2hhbm5lbHNMYXN0ID0gZmFsc2UgLyogb25seSB1c2VkIGZvciBjb252MmRCeU1hdE11bCovLFxuICBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbj86IChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pID0+IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dGVyRGltc0EgPSBhU2hhcGUuc2xpY2UoMCwgLTIpO1xuICBjb25zdCBvdXRlckRpbXNCID0gYlNoYXBlLnNsaWNlKDAsIC0yKTtcbiAgY29uc3Qgb3V0ZXJEaW1zID0gcmVzaGFwZWRPdXRwdXRTaGFwZSA/IHJlc2hhcGVkT3V0cHV0U2hhcGUuc2xpY2UoMCwgLTIpIDogb3V0cHV0U2hhcGUuc2xpY2UoMCwgLTIpO1xuICBjb25zdCBiYXRjaFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRlckRpbXMpO1xuICBjb25zdCBkaW1BT3V0ZXIgPSBhU2hhcGVbYVNoYXBlLmxlbmd0aCAtIDJdO1xuICBjb25zdCBkaW1Jbm5lciA9IGFTaGFwZVthU2hhcGUubGVuZ3RoIC0gMV07XG4gIGNvbnN0IGRpbUJPdXRlciA9IGJTaGFwZVtiU2hhcGUubGVuZ3RoIC0gMV07XG4gIGNvbnN0IGlzVmVjNCA9IGRpbUlubmVyICUgNCA9PT0gMCAmJiBkaW1CT3V0ZXIgJSA0ID09PSAwO1xuXG4gIC8vIFRPRE86IGZpbmUgdHVuZSBzaXplXG4gIGNvbnN0IGVsZW1lbnRzUGVyVGhyZWFkID0gZGltQU91dGVyIDw9IDggPyBbNCwgMSwgMV0gOiBbNCwgNCwgMV07XG4gIGNvbnN0IHdvcmtncm91cFNpemU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFs4LCA4LCAxXTtcbiAgY29uc3QgZGlzcGF0Y2ggPSBbXG4gICAgTWF0aC5jZWlsKGRpbUJPdXRlciAvIHdvcmtncm91cFNpemVbMF0gLyBlbGVtZW50c1BlclRocmVhZFswXSksXG4gICAgTWF0aC5jZWlsKGRpbUFPdXRlciAvIHdvcmtncm91cFNpemVbMV0gLyBlbGVtZW50c1BlclRocmVhZFsxXSksXG4gICAgTWF0aC5jZWlsKGJhdGNoU2l6ZSAvIHdvcmtncm91cFNpemVbMl0gLyBlbGVtZW50c1BlclRocmVhZFsyXSksXG4gIF07XG5cbiAgY29uc3QgY29tcG9uZW50cyA9IGlzVmVjNCA/IDQgOiAxO1xuICBjb25zdCBhU2hhcGVUZW1wID0gWy4uLm91dGVyRGltc0EsIGRpbUFPdXRlciwgZGltSW5uZXIgLyBjb21wb25lbnRzXTtcbiAgY29uc3QgYVJhbmsgPSBhU2hhcGVUZW1wLmxlbmd0aDtcbiAgY29uc3QgYlNoYXBlVGVtcCA9IFsuLi5vdXRlckRpbXNCLCBkaW1Jbm5lciwgZGltQk91dGVyIC8gY29tcG9uZW50c107XG4gIGNvbnN0IGJSYW5rID0gYlNoYXBlVGVtcC5sZW5ndGg7XG4gIGNvbnN0IG91dHB1dFNoYXBlVGVtcCA9IFtiYXRjaFNpemUsIGRpbUFPdXRlciwgZGltQk91dGVyIC8gY29tcG9uZW50c107XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBkaW1BT3V0ZXIgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBkaW1CT3V0ZXIgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBkaW1Jbm5lciB9LFxuICBdO1xuICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhKGFjdGl2YXRpb25BdHRyaWJ1dGVzLCBwcm9ncmFtVW5pZm9ybXMpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhvdXRlckRpbXMsIGFTaGFwZVRlbXAsIGJTaGFwZVRlbXApKTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3JhbmsnLCAncmFuayddO1xuXG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgaWYgKGhhc0JpYXMpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMl0uZGltcykpO1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3JhbmsnKTtcbiAgfVxuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhvdXRwdXRTaGFwZVRlbXApKTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBiYXRjaFJhbmsgPSBvdXRlckRpbXMubGVuZ3RoO1xuICAgIGNvbnN0IGJhdGNoRGltcyA9IGludGVybmFsVmFyaWFibGUoJ2JhdGNoRGltcycsIGlucHV0c1swXS5kYXRhVHlwZSwgYmF0Y2hSYW5rLCAxKTtcbiAgICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShpbnB1dHNbMF0uZGF0YVR5cGUpO1xuXG4gICAgY29uc3QgQSA9IGlucHV0VmFyaWFibGUoJ2EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGFSYW5rLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBCID0gaW5wdXRWYXJpYWJsZSgnYicsIGlucHV0c1sxXS5kYXRhVHlwZSwgYlJhbmssIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdyZXN1bHQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlVGVtcC5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGlucHV0VmFyaWFibGVzID0gW0EsIEJdO1xuICAgIGlmIChoYXNCaWFzKSB7XG4gICAgICBjb25zdCBiaWFzQ29tcG9uZW50cyA9IGlzQ2hhbm5lbHNMYXN0ID8gY29tcG9uZW50cyA6IDE7XG4gICAgICBpbnB1dFZhcmlhYmxlcy5wdXNoKGlucHV0VmFyaWFibGUoJ2JpYXMnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLmxlbmd0aCwgYmlhc0NvbXBvbmVudHMpKTtcbiAgICB9XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnZGltX2Ffb3V0ZXInLCB0eXBlOiAnaTMyJyB9LFxuICAgICAgeyBuYW1lOiAnZGltX2Jfb3V0ZXInLCB0eXBlOiAnaTMyJyB9LFxuICAgICAgeyBuYW1lOiAnZGltX2lubmVyJywgdHlwZTogJ2kzMicgfSxcbiAgICBdO1xuICAgIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3JtcyhhY3RpdmF0aW9uQXR0cmlidXRlcywgdW5pZm9ybXMpO1xuICAgIGNvbnN0IGJhc2VUeXBlID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKG91dHB1dC50eXBlLnRlbnNvcik7XG4gICAgY29uc3QgYXBwbHlBY3RpdmF0aW9uID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYWN0aXZhdGlvbkF0dHJpYnV0ZXMsIG91dHB1dC50eXBlLnZhbHVlLCBiYXNlVHlwZSk7XG4gICAgY29uc3QgZGVjbGFyZUZ1bmN0aW9ucyA9IG1hdE11bFJlYWRXcml0ZUZuU291cmNlKFxuICAgICAgY29tcG9uZW50cyxcbiAgICAgIGhhc0JpYXMsXG4gICAgICBhcHBseUFjdGl2YXRpb24sXG4gICAgICBbYmF0Y2hEaW1zLCBBLCBCLCBvdXRwdXRdLFxuICAgICAgaXNDaGFubmVsc0xhc3QsXG4gICAgKTtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlclxuICAgIC5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKVxuICAgIC5yZWdpc3RlckludGVybmFsVmFyaWFibGVzKGJhdGNoRGltcylcbiAgICAuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcmlhYmxlcywgb3V0cHV0KX1cbiAgJHtkZWNsYXJlRnVuY3Rpb25zfVxuICAke1xuICAgIGlzVmVjNFxuICAgICAgPyBtYWtlTWF0TXVsUGFja2VkVmVjNFNvdXJjZShlbGVtZW50c1BlclRocmVhZCwgd29ya2dyb3VwU2l6ZSwgZGF0YVR5cGUsIGJhdGNoRGltcylcbiAgICAgIDogbWFrZU1hdE11bFBhY2tlZFNvdXJjZShlbGVtZW50c1BlclRocmVhZCwgd29ya2dyb3VwU2l6ZSwgZGF0YVR5cGUsIGJhdGNoRGltcylcbiAgfVxuICAgICAgICAgICAgICAgICAgIGA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ01hdE11bCcsXG4gICAgc2hhZGVyQ2FjaGU6IHtcbiAgICAgIGhpbnQ6IGAke2VsZW1lbnRzUGVyVGhyZWFkfTske2FjdGl2YXRpb25BdHRyaWJ1dGVzLmFjdGl2YXRpb259OyR7aXNWZWM0fTske2lzQ2hhbm5lbHNMYXN0fWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llcyxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBkaW1zOiBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbiA/IHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uKG91dHB1dFNoYXBlKSA6IG91dHB1dFNoYXBlLFxuICAgICAgICAgIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBkaXNwYXRjaFswXSwgeTogZGlzcGF0Y2hbMV0sIHo6IGRpc3BhdGNoWzJdIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcbiIsICIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbi8vIHNhbXBsZWQgZnJvbSBbQHRlbnNvcmZsb3cvdGZqc10gdGZqcy1iYWNrZW5kLXdlYmdwdS9zcmMvY29udjJkX21tX3dlYmdwdS50c1xuLy9cbi8vIG1vZGlmaWVkIHRvIGZpdCB0aGUgbmVlZHMgb2YgdGhlIHByb2plY3RcblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBMT0dfREVCVUcgfSBmcm9tICcuLi8uLi8uLi9sb2cnO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQge1xuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlLFxuICBVbmlmb3Jtc0FycmF5VHlwZSxcbn0gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7IENvbnZBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vY29udic7XG5pbXBvcnQgeyBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMsIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3Jtc0RhdGEsIGdldEFjdGl2YXRpb25TbmlwcGV0IH0gZnJvbSAnLi4vZnVzZS11dGlscyc7XG5cbmltcG9ydCB7IGJpYXNTbmlwcGV0LCB0eXBlU25pcHBldCB9IGZyb20gJy4vYWN0aXZhdGlvbl91dGlsJztcbmltcG9ydCB7IHV0aWxGdW5jdGlvbnMgfSBmcm9tICcuL2NvbnZfdXRpbCc7XG5pbXBvcnQgeyBtYWtlTWF0TXVsUGFja2VkU291cmNlLCBtYWtlTWF0TXVsUGFja2VkVmVjNFNvdXJjZSB9IGZyb20gJy4vbWF0bXVsX3BhY2tlZF93ZWJncHUnO1xuXG5jb25zdCBjb252MmRDb21tb25TbmlwcGV0ID0gKFxuICBpc0NoYW5uZWxzTGFzdDogYm9vbGVhbixcbiAgZml0QU91dGVyOiBib29sZWFuLFxuICBmaXRCT3V0ZXI6IGJvb2xlYW4sXG4gIGZpdElubmVyOiBib29sZWFuLFxuICBhZGRCaWFzID0gZmFsc2UsXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuICBpbm5lckVsZW1lbnRTaXplWCA9IDQsXG4gIGlubmVyRWxlbWVudFNpemVXID0gNCxcbiAgaW5uZXJFbGVtZW50U2l6ZSA9IDQsXG4gIGRhdGFUeXBlID0gJ2YzMicsXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBnZXRYU25pcHBldCA9IChpbm5lckVsZW1lbnRTaXplOiBudW1iZXIpID0+IHtcbiAgICBzd2l0Y2ggKGlubmVyRWxlbWVudFNpemUpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuICdyZXNEYXRhID0geFt4SW5kZXhdOyc7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiBgcmVzRGF0YSA9IHZlYzM8JHtkYXRhVHlwZX0+KHhbeEluZGV4XSwgeFt4SW5kZXggKyAxXSwgeFt4SW5kZXggKyAyXSk7YDtcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgcmV0dXJuICdyZXNEYXRhID0geFt4SW5kZXggLyA0XTsnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbm5lckVsZW1lbnRTaXplICR7aW5uZXJFbGVtZW50U2l6ZX0gaXMgbm90IHN1cHBvcnRlZC5gKTtcbiAgICB9XG4gIH07XG4gIGNvbnN0IGdldFdTbmlwcGV0ID0gKGlubmVyRWxlbWVudFNpemU6IG51bWJlcikgPT4ge1xuICAgIHN3aXRjaCAoaW5uZXJFbGVtZW50U2l6ZSkge1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gJ3JldHVybiB3W3JvdyAqIGkzMih1bmlmb3Jtcy53X3NoYXBlWzNdKSArIGNvbEluXTsnO1xuICAgICAgY2FzZSA0OlxuICAgICAgICByZXR1cm4gJ3JldHVybiB3W3JvdyAqIGkzMih1bmlmb3Jtcy53X3NoYXBlWzNdKSAvIDQgKyBjb2xJbl07JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5uZXJFbGVtZW50U2l6ZSAke2lubmVyRWxlbWVudFNpemV9IGlzIG5vdCBzdXBwb3J0ZWQuYCk7XG4gICAgfVxuICB9O1xuICBjb25zdCBjb29yZEFTbmlwcGV0ID0gaXNDaGFubmVsc0xhc3RcbiAgICA/IGBcbiAgICBsZXQgY29vcmQgPSB2ZWM0PGkzMj4oYmF0Y2gsIHhSb3csIHhDb2wsIHhDaCk7XG4gICAgYFxuICAgIDogYFxuICAgIGxldCBjb29yZCA9IHZlYzQ8aTMyPihiYXRjaCwgeENoLCB4Um93LCB4Q29sKTtcbiAgICBgO1xuXG4gIGNvbnN0IGNvb3JkUmVzU25pcHBldCA9IGlzQ2hhbm5lbHNMYXN0XG4gICAgPyBgXG4gICAgbGV0IGNvb3JkcyA9IHZlYzQ8aTMyPihcbiAgICAgIGJhdGNoLFxuICAgICAgcm93IC8gb3V0V2lkdGgsXG4gICAgICByb3cgJSBvdXRXaWR0aCxcbiAgICAgIGNvbCk7XG4gICAgYFxuICAgIDogYFxuICAgIGxldCBjb29yZHMgPSB2ZWM0PGkzMj4oXG4gICAgICBiYXRjaCxcbiAgICAgIHJvdyxcbiAgICAgIGNvbCAvIG91dFdpZHRoLFxuICAgICAgY29sICUgb3V0V2lkdGgpO1xuICAgIGA7XG5cbiAgY29uc3QgeEhlaWdodCA9IGlzQ2hhbm5lbHNMYXN0ID8gJ2kzMih1bmlmb3Jtcy54X3NoYXBlWzFdKScgOiAnaTMyKHVuaWZvcm1zLnhfc2hhcGVbMl0pJztcbiAgY29uc3QgeFdpZHRoID0gaXNDaGFubmVsc0xhc3QgPyAnaTMyKHVuaWZvcm1zLnhfc2hhcGVbMl0pJyA6ICdpMzIodW5pZm9ybXMueF9zaGFwZVszXSknO1xuICBjb25zdCByb3cgPSBpc0NoYW5uZWxzTGFzdCA/ICdyb3cnIDogJ2NvbCc7XG4gIGNvbnN0IGNvbCA9IGlzQ2hhbm5lbHNMYXN0ID8gJ2NvbCcgOiAncm93JztcbiAgY29uc3QgcmVhZFhTbmlwcGV0ID0gYFxuICAgIGxldCBpbkNoYW5uZWxzID0gaTMyKHVuaWZvcm1zLndfc2hhcGVbMl0pO1xuICAgIGxldCBvdXRXaWR0aCA9ICR7aXNDaGFubmVsc0xhc3QgPyAnaTMyKHVuaWZvcm1zLnJlc3VsdF9zaGFwZVsyXSknIDogJ2kzMih1bmlmb3Jtcy5yZXN1bHRfc2hhcGVbM10pJ307XG4gICAgbGV0IG91dFJvdyA9ICR7cm93fSAvIG91dFdpZHRoO1xuICAgIGxldCBvdXRDb2wgPSAke3Jvd30gJSBvdXRXaWR0aDtcblxuICAgIGxldCBXUm93ID0gJHtjb2x9IC8gKGkzMih1bmlmb3Jtcy53X3NoYXBlWzFdKSAqIGluQ2hhbm5lbHMpO1xuICAgIGxldCBXQ29sID0gJHtjb2x9IC8gaW5DaGFubmVscyAlIGkzMih1bmlmb3Jtcy53X3NoYXBlWzFdKTtcbiAgICBsZXQgeFJvdyA9IG91dFJvdyAqIHVuaWZvcm1zLnN0cmlkZVswXSArIHVuaWZvcm1zLmRpbGF0aW9uWzBdICogV1JvdyAtIHVuaWZvcm1zLnBhZFswXTtcbiAgICBsZXQgeENvbCA9IG91dENvbCAqIHVuaWZvcm1zLnN0cmlkZVsxXSArIHVuaWZvcm1zLmRpbGF0aW9uWzFdICogV0NvbCAtIHVuaWZvcm1zLnBhZFsxXTtcbiAgICBsZXQgeENoID0gJHtjb2x9ICUgaW5DaGFubmVscztcbiAgICB2YXIgcmVzRGF0YSA9ICR7dHlwZVNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVgsIGRhdGFUeXBlKX0oMC4wKTtcbiAgICAvLyBUaGUgYm91bmRzIGNoZWNraW5nIGlzIGFsd2F5cyBuZWVkZWQgc2luY2Ugd2UgdXNlIGl0IHRvIHBhZCB6ZXJvIGZvclxuICAgIC8vIHRoZSAnc2FtZScgcGFkZGluZyB0eXBlLlxuICAgIGlmICh4Um93ID49IDAgJiYgeFJvdyA8ICR7eEhlaWdodH0gJiYgeENvbCA+PSAwICYmIHhDb2wgPCAke3hXaWR0aH0pIHtcbiAgICAgICR7Y29vcmRBU25pcHBldH1cbiAgICAgIGxldCB4SW5kZXggPSBnZXRJbmRleEZyb21Db29yZHM0RChjb29yZCwgdmVjNDxpMzI+KHVuaWZvcm1zLnhfc2hhcGUpKTtcbiAgICAgICR7Z2V0WFNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVgpfVxuICAgIH1cbiAgICByZXR1cm4gcmVzRGF0YTtgO1xuXG4gIGNvbnN0IHNhbXBsZVggPSBpc0NoYW5uZWxzTGFzdFxuICAgID8gZml0QU91dGVyICYmIGZpdElubmVyXG4gICAgICA/IGBcbiAgICBsZXQgY29sID0gY29sSW4gKiAke2lubmVyRWxlbWVudFNpemVYfTtcbiAgICAke3JlYWRYU25pcHBldH1gXG4gICAgICA6IGBcbiAgICBsZXQgY29sID0gY29sSW4gKiAke2lubmVyRWxlbWVudFNpemVYfTtcbiAgICBpZiAocm93IDwgdW5pZm9ybXMuZGltX2Ffb3V0ZXIgJiYgY29sIDwgdW5pZm9ybXMuZGltX2lubmVyKSB7XG4gICAgICAke3JlYWRYU25pcHBldH1cbiAgICB9XG4gICAgcmV0dXJuICR7dHlwZVNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVgsIGRhdGFUeXBlKX0oMC4wKTtgXG4gICAgOiBmaXRJbm5lciAmJiBmaXRCT3V0ZXJcbiAgICAgID8gYFxuICAgIGxldCBjb2wgPSBjb2xJbiAqICR7aW5uZXJFbGVtZW50U2l6ZVh9O1xuICAgICR7cmVhZFhTbmlwcGV0fWBcbiAgICAgIDogYFxuICAgIGxldCBjb2wgPSBjb2xJbiAqICR7aW5uZXJFbGVtZW50U2l6ZVh9O1xuICAgIGlmIChyb3cgPCB1bmlmb3Jtcy5kaW1faW5uZXIgJiYgY29sIDwgdW5pZm9ybXMuZGltX2Jfb3V0ZXIpIHtcbiAgICAgICR7cmVhZFhTbmlwcGV0fVxuICAgIH1cbiAgICByZXR1cm4gJHt0eXBlU25pcHBldChpbm5lckVsZW1lbnRTaXplWCwgZGF0YVR5cGUpfSgwLjApO2A7XG5cbiAgY29uc3Qgc2FtcGxlVyA9IGlzQ2hhbm5lbHNMYXN0XG4gICAgPyBmaXRJbm5lciAmJiBmaXRCT3V0ZXJcbiAgICAgID8gZ2V0V1NuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVcpXG4gICAgICA6IGBcbiAgICBsZXQgY29sID0gY29sSW4gKiAke2lubmVyRWxlbWVudFNpemVXfTtcbiAgICBpZiAocm93IDwgdW5pZm9ybXMuZGltX2lubmVyICYmIGNvbCA8IHVuaWZvcm1zLmRpbV9iX291dGVyKSB7XG4gICAgICAke2dldFdTbmlwcGV0KGlubmVyRWxlbWVudFNpemVXKX1cbiAgICB9XG4gICAgcmV0dXJuICR7dHlwZVNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVcsIGRhdGFUeXBlKX0oMC4wKTtgXG4gICAgOiBgXG4gICAgbGV0IGNvbCA9IGNvbEluICogJHtpbm5lckVsZW1lbnRTaXplV307XG4gICAgaWYgKHJvdyA8IHVuaWZvcm1zLmRpbV9pbm5lciAmJiBjb2wgPCB1bmlmb3Jtcy5kaW1fYV9vdXRlcikge1xuICAgICAgJHtnZXRXU25pcHBldChpbm5lckVsZW1lbnRTaXplVyl9XG4gICAgfVxuICAgIHJldHVybiAke3R5cGVTbmlwcGV0KGlubmVyRWxlbWVudFNpemVXLCBkYXRhVHlwZSl9KDAuMCk7YDtcblxuICBjb25zdCByZXNUeXBlID0gdHlwZVNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZSwgZGF0YVR5cGUpO1xuICBjb25zdCBhVHlwZSA9IGlzQ2hhbm5lbHNMYXN0ID8gdHlwZVNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVgsIGRhdGFUeXBlKSA6IHR5cGVTbmlwcGV0KGlubmVyRWxlbWVudFNpemVXLCBkYXRhVHlwZSk7XG4gIGNvbnN0IGJUeXBlID0gaXNDaGFubmVsc0xhc3QgPyB0eXBlU25pcHBldChpbm5lckVsZW1lbnRTaXplVywgZGF0YVR5cGUpIDogdHlwZVNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZVgsIGRhdGFUeXBlKTtcbiAgY29uc3QgYXBwbHlBY3RpdmF0aW9uID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcywgcmVzVHlwZSwgZGF0YVR5cGUpO1xuICBjb25zdCB1c2VyQ29kZSA9IGBcbiAgICBmbiBtbV9yZWFkQShiYXRjaDogaTMyLCByb3cgOiBpMzIsIGNvbEluIDogaTMyKSAtPiAke2FUeXBlfSB7XG4gICAgICAke2lzQ2hhbm5lbHNMYXN0ID8gc2FtcGxlWCA6IHNhbXBsZVd9XG4gICAgfVxuXG4gICAgZm4gbW1fcmVhZEIoYmF0Y2g6IGkzMiwgcm93IDogaTMyLCBjb2xJbiA6IGkzMikgLT4gJHtiVHlwZX0ge1xuICAgICAgJHtpc0NoYW5uZWxzTGFzdCA/IHNhbXBsZVcgOiBzYW1wbGVYfVxuICAgIH1cblxuICAgIGZuIG1tX3dyaXRlKGJhdGNoOiBpMzIsIHJvdyA6IGkzMiwgY29sSW4gOiBpMzIsIHZhbHVlSW4gOiAke3Jlc1R5cGV9KSB7XG4gICAgICBsZXQgY29sID0gY29sSW4gKiAke2lubmVyRWxlbWVudFNpemV9O1xuICAgICAgaWYgKHJvdyA8IHVuaWZvcm1zLmRpbV9hX291dGVyICYmIGNvbCA8IHVuaWZvcm1zLmRpbV9iX291dGVyKVxuICAgICAge1xuICAgICAgdmFyIHZhbHVlID0gdmFsdWVJbjtcbiAgICAgIGxldCBvdXRXaWR0aCA9ICR7aXNDaGFubmVsc0xhc3QgPyAnaTMyKHVuaWZvcm1zLnJlc3VsdF9zaGFwZVsyXSknIDogJ2kzMih1bmlmb3Jtcy5yZXN1bHRfc2hhcGVbM10pJ307XG4gICAgICAke2Nvb3JkUmVzU25pcHBldH1cbiAgICAgICR7Ymlhc1NuaXBwZXQoYWRkQmlhcyl9XG4gICAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAgIHNldE91dHB1dEF0Q29vcmRzKGNvb3Jkc1swXSwgY29vcmRzWzFdLCBjb29yZHNbMl0sIGNvb3Jkc1szXSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1gO1xuICByZXR1cm4gdXNlckNvZGU7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlQ29udjJETWF0TXVsUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkaW1BT3V0ZXI6IG51bWJlcixcbiAgZGltQk91dGVyOiBudW1iZXIsXG4gIGRpbUlubmVyOiBudW1iZXIsXG4gIGhhc0JpYXM6IGJvb2xlYW4sXG4gIHNlcXVlbnRpYWxBY2Nlc3NCeVRocmVhZHM6IGJvb2xlYW4sXG4gIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uPzogKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSkgPT4gbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlzQ2hhbm5lbHNMYXN0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJztcbiAgY29uc3QgaW5DaGFubmVscyA9IGlzQ2hhbm5lbHNMYXN0ID8gaW5wdXRzWzBdLmRpbXNbM10gOiBpbnB1dHNbMF0uZGltc1sxXTtcbiAgY29uc3QgYmF0Y2hTaXplID0gb3V0cHV0U2hhcGVbMF07XG4gIGNvbnN0IG91dFdpZHRoID0gaXNDaGFubmVsc0xhc3QgPyBvdXRwdXRTaGFwZVsyXSA6IG91dHB1dFNoYXBlWzNdO1xuICBjb25zdCBvdXRIZWlnaHQgPSBpc0NoYW5uZWxzTGFzdCA/IG91dHB1dFNoYXBlWzFdIDogb3V0cHV0U2hhcGVbMl07XG4gIGNvbnN0IG91dENoYW5uZWxzID0gaXNDaGFubmVsc0xhc3QgPyBvdXRwdXRTaGFwZVszXSA6IG91dHB1dFNoYXBlWzFdO1xuICAvLyBUT0RPOiBlbmFibGUgdmVjNCBmb3IgTkNIV1xuICBjb25zdCBpc1ZlYzQgPSBpc0NoYW5uZWxzTGFzdCAmJiAoaW5DaGFubmVscyAlIDQgPT09IDAgfHwgaW5DaGFubmVscyAlIDMgPT09IDApICYmIG91dENoYW5uZWxzICUgNCA9PT0gMDtcblxuICAvLyBUT0RPOiBmaW5lIHR1bmUgc2l6ZVxuICBjb25zdCBkaXNwYXRjaFggPSBpc0NoYW5uZWxzTGFzdCA/IG91dENoYW5uZWxzIDogb3V0V2lkdGggKiBvdXRIZWlnaHQ7XG4gIGNvbnN0IGRpc3BhdGNoWSA9IGlzQ2hhbm5lbHNMYXN0ID8gb3V0V2lkdGggKiBvdXRIZWlnaHQgOiBvdXRDaGFubmVscztcbiAgY29uc3Qgd29ya0dyb3VwU2l6ZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzgsIDgsIDFdO1xuICBjb25zdCBlbGVtZW50c1BlclRocmVhZCA9IGRpbUFPdXRlciA8PSA4ID8gWzQsIDEsIDFdIDogWzQsIDQsIDFdO1xuICBjb25zdCBkaXNwYXRjaCA9IFtcbiAgICBNYXRoLmNlaWwoZGlzcGF0Y2hYIC8gd29ya0dyb3VwU2l6ZVswXSAvIGVsZW1lbnRzUGVyVGhyZWFkWzBdKSxcbiAgICBNYXRoLmNlaWwoZGlzcGF0Y2hZIC8gd29ya0dyb3VwU2l6ZVsxXSAvIGVsZW1lbnRzUGVyVGhyZWFkWzFdKSxcbiAgICBNYXRoLmNlaWwoYmF0Y2hTaXplIC8gd29ya0dyb3VwU2l6ZVsyXSAvIGVsZW1lbnRzUGVyVGhyZWFkWzJdKSxcbiAgXTtcblxuICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiBgW2NvbnYyZF9tbV93ZWJncHVdIGRpc3BhdGNoID0gJHtkaXNwYXRjaH1gKTtcblxuICBjb25zdCBpbm5lckVsZW1lbnRTaXplID0gaXNWZWM0ID8gKGlzQ2hhbm5lbHNMYXN0ICYmIGluQ2hhbm5lbHMgJSA0ICE9PSAwID8gMyA6IDQpIDogMTtcbiAgY29uc3QgdGlsZUFPdXRlciA9IHdvcmtHcm91cFNpemVbMV0gKiBlbGVtZW50c1BlclRocmVhZFsxXTtcbiAgY29uc3QgdGlsZUJPdXRlciA9IHdvcmtHcm91cFNpemVbMF0gKiBlbGVtZW50c1BlclRocmVhZFswXTtcbiAgY29uc3QgdGlsZUlubmVyID0gTWF0aC5tYXgod29ya0dyb3VwU2l6ZVswXSAqIGlubmVyRWxlbWVudFNpemUsIHdvcmtHcm91cFNpemVbMV0pO1xuICBjb25zdCBmaXRBT3V0ZXIgPSBkaW1BT3V0ZXIgJSB0aWxlQU91dGVyID09PSAwO1xuICBjb25zdCBmaXRCT3V0ZXIgPSBkaW1CT3V0ZXIgJSB0aWxlQk91dGVyID09PSAwO1xuICBjb25zdCBmaXRJbm5lciA9IGRpbUlubmVyICUgdGlsZUlubmVyID09PSAwO1xuICBjb25zdCBlbGVtZW50c1NpemUgPSBpc1ZlYzQgPyBbaW5uZXJFbGVtZW50U2l6ZSwgNCwgNF0gOiBbMSwgMSwgMV07XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IGRpbUFPdXRlciB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IGRpbUJPdXRlciB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IGRpbUlubmVyIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5pbnQzMiwgZGF0YTogW2F0dHJpYnV0ZXMucGFkc1swXSwgYXR0cmlidXRlcy5wYWRzWzFdXSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IGF0dHJpYnV0ZXMuc3RyaWRlcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IGF0dHJpYnV0ZXMuZGlsYXRpb25zIH0sXG4gIF07XG4gIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3Jtc0RhdGEoYXR0cmlidXRlcywgcHJvZ3JhbVVuaWZvcm1zKTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5kaW1zKSk7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWydyYW5rJywgJ3JhbmsnXTtcbiAgaWYgKGhhc0JpYXMpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMl0uZGltcykpO1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3JhbmsnKTtcbiAgfVxuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhvdXRwdXRTaGFwZSkpO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSA9IFtcbiAgICAgIHsgbmFtZTogJ2RpbV9hX291dGVyJywgdHlwZTogJ2kzMicgfSxcbiAgICAgIHsgbmFtZTogJ2RpbV9iX291dGVyJywgdHlwZTogJ2kzMicgfSxcbiAgICAgIHsgbmFtZTogJ2RpbV9pbm5lcicsIHR5cGU6ICdpMzInIH0sXG4gICAgICB7IG5hbWU6ICdwYWQnLCB0eXBlOiAnaTMyJywgbGVuZ3RoOiAyIH0sXG4gICAgICB7IG5hbWU6ICdzdHJpZGUnLCB0eXBlOiAnaTMyJywgbGVuZ3RoOiAyIH0sXG4gICAgICB7IG5hbWU6ICdkaWxhdGlvbicsIHR5cGU6ICdpMzInLCBsZW5ndGg6IDIgfSxcbiAgICBdO1xuICAgIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3JtcyhhdHRyaWJ1dGVzLCB1bmlmb3Jtcyk7XG5cbiAgICAvLyBUT0RPOiBzdXBwb3J0IGNvbXBvbmVudCAyLCAzLlxuICAgIGNvbnN0IGNvbXBvbmVudHMgPSBpc1ZlYzQgPyA0IDogMTtcbiAgICBjb25zdCB0ID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKGlucHV0c1swXS5kYXRhVHlwZSk7XG4gICAgbGV0IGRlY2xhcmVGdW5jdGlvbnMgPSBgXG4gICAgICBmbiBzZXRPdXRwdXRBdEluZGV4KGZsYXRJbmRleCA6IGkzMiwgdmFsdWUgOiAke2lzVmVjNCA/IGB2ZWM0PCR7dH0+YCA6IHR9KSB7XG4gICAgICAgIHJlc3VsdFtmbGF0SW5kZXhdID0gJHtpc1ZlYzQgPyBgdmVjNDwke3R9PmAgOiB0fSh2YWx1ZSk7XG4gICAgICB9XG4gICAgICBmbiBzZXRPdXRwdXRBdENvb3JkcyhkMCA6IGkzMiwgZDEgOiBpMzIsIGQyIDogaTMyLCBkMyA6IGkzMiwgdmFsdWUgOiAke2lzVmVjNCA/IGB2ZWM0PCR7dH0+YCA6IHR9KSB7XG4gICAgICAgIGxldCBmbGF0SW5kZXggPSBnZXRPdXRwdXRJbmRleEZyb21Db29yZHModmVjNDxpMzI+KGQwLCBkMSwgZDIsIGQzKSk7XG4gICAgICAgIHNldE91dHB1dEF0SW5kZXgoZmxhdEluZGV4ICR7aXNWZWM0ID8gJy8gNCcgOiAnJ30sIHZhbHVlKTtcbiAgICAgIH1gO1xuICAgIGNvbnN0IHggPSBpbnB1dFZhcmlhYmxlKFxuICAgICAgJ3gnLFxuICAgICAgaW5wdXRzWzBdLmRhdGFUeXBlLFxuICAgICAgaW5wdXRzWzBdLmRpbXMubGVuZ3RoLFxuICAgICAgaW5uZXJFbGVtZW50U2l6ZSA9PT0gMyA/IDEgOiBpbm5lckVsZW1lbnRTaXplLFxuICAgICk7XG4gICAgY29uc3QgdyA9IGlucHV0VmFyaWFibGUoJ3cnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgY29uc3QgaW5wdXRWYXJpYWJsZXMgPSBbeCwgd107XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ3Jlc3VsdCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBpZiAoaGFzQmlhcykge1xuICAgICAgY29uc3QgYmlhcyA9IGlucHV0VmFyaWFibGUoJ2JpYXMnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgICBpbnB1dFZhcmlhYmxlcy5wdXNoKGJpYXMpO1xuICAgICAgZGVjbGFyZUZ1bmN0aW9ucyArPSBgXG4gICAgICAgIGZuIGdldEJpYXNCeU91dHB1dENvb3Jkcyhjb29yZHMgOiB2ZWM0PGkzMj4pIC0+ICR7aXNWZWM0ID8gYHZlYzQ8JHt0fT5gIDogdH0ge1xuICAgICAgICAgIHJldHVybiBiaWFzW2Nvb3Jkcy4ke2lzQ2hhbm5lbHNMYXN0ID8gJ3cnIDogJ3knfSR7aXNWZWM0ID8gJy8gNCcgOiAnJ31dO1xuICAgICAgICB9YDtcbiAgICB9XG5cbiAgICByZXR1cm4gYFxuICAgICAgICAke3V0aWxGdW5jdGlvbnMoJ3VuaWZvcm1zLnJlc3VsdF9zdHJpZGVzJyl9XG4gICAgICAgIC8vc3RydWN0IFVuaWZvcm1zIHsgeFNoYXBlIDogdmVjNDxpMzI+LCB3U2hhcGUgOiB2ZWM0PGkzMj4sIG91dFNoYXBlIDogdmVjNDxpMzI+LFxuICAgICAgICAvLyAgb3V0U2hhcGVTdHJpZGVzOiB2ZWMzPGkzMj4sIGZpbHRlckRpbXMgOiB2ZWMyPGkzMj4sIHBhZCA6IHZlYzI8aTMyPiwgc3RyaWRlIDogdmVjMjxpMzI+LFxuICAgICAgICAvLyAgZGlsYXRpb24gOiB2ZWMyPGkzMj4sIGRpbUFPdXRlciA6IGkzMiwgZGltQk91dGVyIDogaTMyLCBkaW1Jbm5lciA6IGkzMiB9O1xuICAgICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKC4uLmlucHV0VmFyaWFibGVzLCBvdXRwdXQpfVxuICAgICAgICAke2RlY2xhcmVGdW5jdGlvbnN9XG4gICAgICAgICR7Y29udjJkQ29tbW9uU25pcHBldChcbiAgICAgICAgICBpc0NoYW5uZWxzTGFzdCxcbiAgICAgICAgICBmaXRBT3V0ZXIsXG4gICAgICAgICAgZml0Qk91dGVyLFxuICAgICAgICAgIGZpdElubmVyLFxuICAgICAgICAgIGhhc0JpYXMsXG4gICAgICAgICAgYXR0cmlidXRlcyxcbiAgICAgICAgICBlbGVtZW50c1NpemVbMF0sXG4gICAgICAgICAgZWxlbWVudHNTaXplWzFdLFxuICAgICAgICAgIGVsZW1lbnRzU2l6ZVsyXSxcbiAgICAgICAgICB0LFxuICAgICAgICApfVxuICAgICAgICAke1xuICAgICAgICAgIGlzVmVjNFxuICAgICAgICAgICAgPyBtYWtlTWF0TXVsUGFja2VkVmVjNFNvdXJjZShlbGVtZW50c1BlclRocmVhZCwgd29ya0dyb3VwU2l6ZSwgdCwgdW5kZWZpbmVkLCAhaXNDaGFubmVsc0xhc3QsIHRpbGVJbm5lcilcbiAgICAgICAgICAgIDogbWFrZU1hdE11bFBhY2tlZFNvdXJjZShcbiAgICAgICAgICAgICAgICBlbGVtZW50c1BlclRocmVhZCxcbiAgICAgICAgICAgICAgICB3b3JrR3JvdXBTaXplLFxuICAgICAgICAgICAgICAgIHQsXG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICFpc0NoYW5uZWxzTGFzdCxcbiAgICAgICAgICAgICAgICB0aWxlSW5uZXIsXG4gICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxBY2Nlc3NCeVRocmVhZHMsXG4gICAgICAgICAgICAgIClcbiAgICAgICAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0NvbnYyRE1hdE11bCcsXG4gICAgc2hhZGVyQ2FjaGU6IHtcbiAgICAgIGhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9OyR7aW5uZXJFbGVtZW50U2l6ZX07JHtpc1ZlYzR9OyR7Zml0QU91dGVyfTske2ZpdEJPdXRlcn07JHtmaXRJbm5lcn07JHt0aWxlQU91dGVyfTske3RpbGVCT3V0ZXJ9OyR7dGlsZUlubmVyfWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llcyxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBkaW1zOiBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbiA/IHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uKG91dHB1dFNoYXBlKSA6IG91dHB1dFNoYXBlLFxuICAgICAgICAgIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBkaXNwYXRjaFswXSwgeTogZGlzcGF0Y2hbMV0sIHo6IGRpc3BhdGNoWzJdIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcbiIsICIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbi8vIHNhbXBsZWQgZnJvbSBbQHRlbnNvcmZsb3cvdGZqc10gdGZqcy1iYWNrZW5kLXdlYmdwdS9zcmMvY29udjNkX25haXZlX3dlYmdwdS50c1xuLy9cbi8vIG1vZGlmaWVkIHRvIGZpdCB0aGUgbmVlZHMgb2YgdGhlIHByb2plY3RcblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBMT0dfREVCVUcgfSBmcm9tICcuLi8uLi8uLi9sb2cnO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgUHJvZ3JhbUluZm8sIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7XG4gIGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLFxuICBnZXRFbGVtZW50QXQsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZSxcbiAgVW5pZm9ybXNBcnJheVR5cGUsXG59IGZyb20gJy4uL2NvbW1vbic7XG5pbXBvcnQgeyBDb252QXR0cmlidXRlcyB9IGZyb20gJy4uL2NvbnYnO1xuaW1wb3J0IHsgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zLCBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhLCBnZXRBY3RpdmF0aW9uU25pcHBldCB9IGZyb20gJy4uL2Z1c2UtdXRpbHMnO1xuXG5pbXBvcnQgeyB0eXBlU25pcHBldCB9IGZyb20gJy4vYWN0aXZhdGlvbl91dGlsJztcblxuY29uc3QgYXJyYXlQcm9kdWN0ID0gKGFycjogbnVtYmVyW10pID0+IHtcbiAgbGV0IHByb2R1Y3QgPSAxO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHByb2R1Y3QgKj0gYXJyW2ldO1xuICB9XG4gIHJldHVybiBwcm9kdWN0O1xufTtcblxuY29uc3QgcGFyc2UzVHVwbGVQYXJhbSA9IChwYXJhbTogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdKTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0+XG4gIHR5cGVvZiBwYXJhbSA9PT0gJ251bWJlcicgPyBbcGFyYW0sIHBhcmFtLCBwYXJhbV0gOiBwYXJhbTtcblxuY29uc3QgZ2V0RWZmZWN0aXZlRmlsdGVyU2l6ZSA9IChmaWx0ZXJTaXplOiBudW1iZXIsIGRpbGF0aW9uOiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICBpZiAoZGlsYXRpb24gPD0gMSkge1xuICAgIHJldHVybiBmaWx0ZXJTaXplO1xuICB9XG5cbiAgcmV0dXJuIGZpbHRlclNpemUgKyAoZmlsdGVyU2l6ZSAtIDEpICogKGRpbGF0aW9uIC0gMSk7XG59O1xuXG5jb25zdCBjb21wdXRlRGVmYXVsdFBhZCA9IChcbiAgaW5wdXRTaGFwZTogW251bWJlciwgbnVtYmVyXSB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICBmaWVsZFNpemU6IG51bWJlcixcbiAgc3RyaWRlOiBudW1iZXIsXG4gIGRpbGF0aW9uID0gMSxcbik6IG51bWJlciA9PiB7XG4gIGNvbnN0IGVmZmVjdGl2ZUZpZWxkU2l6ZSA9IGdldEVmZmVjdGl2ZUZpbHRlclNpemUoZmllbGRTaXplLCBkaWxhdGlvbik7XG4gIHJldHVybiBNYXRoLmZsb29yKChpbnB1dFNoYXBlWzBdICogKHN0cmlkZSAtIDEpIC0gc3RyaWRlICsgZWZmZWN0aXZlRmllbGRTaXplKSAvIDIpO1xufTtcblxuY29uc3QgY29tcHV0ZU91dHB1dFNoYXBlNEQgPSAoXG4gIGluU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICBvdXRDaGFubmVsczogbnVtYmVyLFxuICBzdHJpZGVzOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gIHplcm9QYWQ/OiBudW1iZXIsXG4pOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9PiB7XG4gIGlmICh6ZXJvUGFkID09IG51bGwpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICB6ZXJvUGFkID0gY29tcHV0ZURlZmF1bHRQYWQoaW5TaGFwZSwgZmlsdGVyU2hhcGVbMF0sIHN0cmlkZXNbMF0pO1xuICB9XG4gIGNvbnN0IG91dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFswLCAwLCAwLCBvdXRDaGFubmVsc107XG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCAzOyBpbmRleCsrKSB7XG4gICAgaWYgKGluU2hhcGVbaW5kZXhdICsgMiAqIHplcm9QYWQgPj0gZmlsdGVyU2hhcGVbaW5kZXhdKSB7XG4gICAgICBvdXRTaGFwZVtpbmRleF0gPSBNYXRoLnRydW5jKChpblNoYXBlW2luZGV4XSAtIGZpbHRlclNoYXBlW2luZGV4XSArIDIgKiB6ZXJvUGFkKSAvIHN0cmlkZXNbaW5kZXhdICsgMSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXRTaGFwZTtcbn07XG5cbmNvbnN0IGdldDNEUGFkQW5kT3V0SW5mbyA9IChcbiAgcGFkOiBudW1iZXIgfCBzdHJpbmcgfCBudW1iZXJbXSxcbiAgaW5EZXB0aDogbnVtYmVyLFxuICBpbkhlaWdodDogbnVtYmVyLFxuICBpbldpZHRoOiBudW1iZXIsXG4gIHN0cmlkZURlcHRoOiBudW1iZXIsXG4gIHN0cmlkZUhlaWdodDogbnVtYmVyLFxuICBzdHJpZGVXaWR0aDogbnVtYmVyLFxuICBmaWx0ZXJEZXB0aDogbnVtYmVyLFxuICBmaWx0ZXJIZWlnaHQ6IG51bWJlcixcbiAgZmlsdGVyV2lkdGg6IG51bWJlcixcbik6IHsgcGFkSW5mbzogUGFkSW5mbzNEOyBvdXREZXB0aDogbnVtYmVyOyBvdXRIZWlnaHQ6IG51bWJlcjsgb3V0V2lkdGg6IG51bWJlciB9ID0+IHtcbiAgbGV0IHBhZEluZm86IFBhZEluZm8zRDtcbiAgbGV0IG91dERlcHRoOiBudW1iZXI7XG4gIGxldCBvdXRIZWlnaHQ6IG51bWJlcjtcbiAgbGV0IG91dFdpZHRoOiBudW1iZXI7XG5cbiAgaWYgKHBhZCA9PT0gJ1ZBTElEJykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICAgIHBhZCA9IDA7XG4gIH1cblxuICBpZiAodHlwZW9mIHBhZCA9PT0gJ251bWJlcicpIHtcbiAgICBwYWRJbmZvID0geyB0b3A6IHBhZCwgYm90dG9tOiBwYWQsIGxlZnQ6IHBhZCwgcmlnaHQ6IHBhZCwgZnJvbnQ6IHBhZCwgYmFjazogcGFkIH07XG4gICAgY29uc3Qgb3V0U2hhcGUgPSBjb21wdXRlT3V0cHV0U2hhcGU0RChcbiAgICAgIFtpbkRlcHRoLCBpbkhlaWdodCwgaW5XaWR0aCwgMV0sXG4gICAgICBbZmlsdGVyRGVwdGgsIGZpbHRlckhlaWdodCwgZmlsdGVyV2lkdGhdLFxuICAgICAgMSxcbiAgICAgIFtzdHJpZGVEZXB0aCwgc3RyaWRlSGVpZ2h0LCBzdHJpZGVXaWR0aF0sXG4gICAgICBwYWQsXG4gICAgKTtcbiAgICBvdXREZXB0aCA9IG91dFNoYXBlWzBdO1xuICAgIG91dEhlaWdodCA9IG91dFNoYXBlWzFdO1xuICAgIG91dFdpZHRoID0gb3V0U2hhcGVbMl07XG4gIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShwYWQpKSB7XG4gICAgaWYgKCFwYWQuZXZlcnkoKHZhbCwgXywgYXJyKSA9PiB2YWwgPT09IGFyclswXSkpIHtcbiAgICAgIHRocm93IEVycm9yKGBVbnN1cHBvcnRlZCBwYWRkaW5nIHBhcmFtZXRlcjogJHtwYWR9YCk7XG4gICAgfVxuICAgIHBhZEluZm8gPSB7IHRvcDogcGFkWzBdLCBib3R0b206IHBhZFsxXSwgbGVmdDogcGFkWzJdLCByaWdodDogcGFkWzNdLCBmcm9udDogcGFkWzRdLCBiYWNrOiBwYWRbNV0gfTtcbiAgICBjb25zdCBvdXRTaGFwZSA9IGNvbXB1dGVPdXRwdXRTaGFwZTREKFxuICAgICAgW2luRGVwdGgsIGluSGVpZ2h0LCBpbldpZHRoLCAxXSxcbiAgICAgIFtmaWx0ZXJEZXB0aCwgZmlsdGVySGVpZ2h0LCBmaWx0ZXJXaWR0aF0sXG4gICAgICAxLFxuICAgICAgW3N0cmlkZURlcHRoLCBzdHJpZGVIZWlnaHQsIHN0cmlkZVdpZHRoXSxcbiAgICAgIHBhZFswXSxcbiAgICApO1xuICAgIG91dERlcHRoID0gb3V0U2hhcGVbMF07XG4gICAgb3V0SGVpZ2h0ID0gb3V0U2hhcGVbMV07XG4gICAgb3V0V2lkdGggPSBvdXRTaGFwZVsyXTtcbiAgfSBlbHNlIGlmIChwYWQgPT09ICdTQU1FX1VQUEVSJykge1xuICAgIC8vIFRPRE86IHN1cHBvcnQgJ1NBTUVfTE9XRVInLlxuICAgIG91dERlcHRoID0gTWF0aC5jZWlsKGluRGVwdGggLyBzdHJpZGVEZXB0aCk7XG4gICAgb3V0SGVpZ2h0ID0gTWF0aC5jZWlsKGluSGVpZ2h0IC8gc3RyaWRlSGVpZ2h0KTtcbiAgICBvdXRXaWR0aCA9IE1hdGguY2VpbChpbldpZHRoIC8gc3RyaWRlV2lkdGgpO1xuICAgIGNvbnN0IHBhZEFsb25nRGVwdGggPSAob3V0RGVwdGggLSAxKSAqIHN0cmlkZURlcHRoICsgZmlsdGVyRGVwdGggLSBpbkRlcHRoO1xuICAgIGNvbnN0IHBhZEFsb25nSGVpZ2h0ID0gKG91dEhlaWdodCAtIDEpICogc3RyaWRlSGVpZ2h0ICsgZmlsdGVySGVpZ2h0IC0gaW5IZWlnaHQ7XG4gICAgY29uc3QgcGFkQWxvbmdXaWR0aCA9IChvdXRXaWR0aCAtIDEpICogc3RyaWRlV2lkdGggKyBmaWx0ZXJXaWR0aCAtIGluV2lkdGg7XG4gICAgY29uc3QgZnJvbnQgPSBNYXRoLmZsb29yKHBhZEFsb25nRGVwdGggLyAyKTtcbiAgICBjb25zdCBiYWNrID0gcGFkQWxvbmdEZXB0aCAtIGZyb250O1xuICAgIGNvbnN0IHRvcCA9IE1hdGguZmxvb3IocGFkQWxvbmdIZWlnaHQgLyAyKTtcbiAgICBjb25zdCBib3R0b20gPSBwYWRBbG9uZ0hlaWdodCAtIHRvcDtcbiAgICBjb25zdCBsZWZ0ID0gTWF0aC5mbG9vcihwYWRBbG9uZ1dpZHRoIC8gMik7XG4gICAgY29uc3QgcmlnaHQgPSBwYWRBbG9uZ1dpZHRoIC0gbGVmdDtcblxuICAgIHBhZEluZm8gPSB7IHRvcCwgYm90dG9tLCBsZWZ0LCByaWdodCwgZnJvbnQsIGJhY2sgfTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBFcnJvcihgVW5rbm93biBwYWRkaW5nIHBhcmFtZXRlcjogJHtwYWR9YCk7XG4gIH1cbiAgcmV0dXJuIHsgcGFkSW5mbywgb3V0RGVwdGgsIG91dEhlaWdodCwgb3V0V2lkdGggfTtcbn07XG5cbnR5cGUgUGFkSW5mbzNEID0ge1xuICB0b3A6IG51bWJlcjtcbiAgbGVmdDogbnVtYmVyO1xuICByaWdodDogbnVtYmVyO1xuICBib3R0b206IG51bWJlcjtcbiAgZnJvbnQ6IG51bWJlcjtcbiAgYmFjazogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgQ29udjNESW5mbyA9IHtcbiAgYmF0Y2hTaXplOiBudW1iZXI7XG4gIGluRGVwdGg6IG51bWJlcjtcbiAgaW5IZWlnaHQ6IG51bWJlcjtcbiAgaW5XaWR0aDogbnVtYmVyO1xuICBpbkNoYW5uZWxzOiBudW1iZXI7XG4gIG91dERlcHRoOiBudW1iZXI7XG4gIG91dEhlaWdodDogbnVtYmVyO1xuICBvdXRXaWR0aDogbnVtYmVyO1xuICBvdXRDaGFubmVsczogbnVtYmVyO1xuICBkYXRhRm9ybWF0OiAnY2hhbm5lbHNGaXJzdCcgfCAnY2hhbm5lbHNMYXN0JztcbiAgc3RyaWRlRGVwdGg6IG51bWJlcjtcbiAgc3RyaWRlSGVpZ2h0OiBudW1iZXI7XG4gIHN0cmlkZVdpZHRoOiBudW1iZXI7XG4gIGRpbGF0aW9uRGVwdGg6IG51bWJlcjtcbiAgZGlsYXRpb25IZWlnaHQ6IG51bWJlcjtcbiAgZGlsYXRpb25XaWR0aDogbnVtYmVyO1xuICBmaWx0ZXJEZXB0aDogbnVtYmVyO1xuICBmaWx0ZXJIZWlnaHQ6IG51bWJlcjtcbiAgZmlsdGVyV2lkdGg6IG51bWJlcjtcbiAgZWZmZWN0aXZlRmlsdGVyRGVwdGg6IG51bWJlcjtcbiAgZWZmZWN0aXZlRmlsdGVySGVpZ2h0OiBudW1iZXI7XG4gIGVmZmVjdGl2ZUZpbHRlcldpZHRoOiBudW1iZXI7XG4gIHBhZEluZm86IFBhZEluZm8zRDtcbiAgaW5TaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgb3V0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVDb252M0RJbmZvID0gKFxuICBpblNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgc3RyaWRlczogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICBkaWxhdGlvbnM6IG51bWJlciB8IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgcGFkOiBudW1iZXIgfCBzdHJpbmcgfCBudW1iZXJbXSxcbiAgZGVwdGh3aXNlID0gZmFsc2UsXG4gIGRhdGFGb3JtYXQ6ICdjaGFubmVsc0ZpcnN0JyB8ICdjaGFubmVsc0xhc3QnID0gJ2NoYW5uZWxzTGFzdCcsXG4pOiBDb252M0RJbmZvID0+IHtcbiAgbGV0IGJhdGNoU2l6ZSwgaW5EZXB0aCwgaW5IZWlnaHQsIGluV2lkdGgsIGluQ2hhbm5lbHM7XG4gIGlmIChkYXRhRm9ybWF0ID09PSAnY2hhbm5lbHNMYXN0Jykge1xuICAgIFtiYXRjaFNpemUsIGluRGVwdGgsIGluSGVpZ2h0LCBpbldpZHRoLCBpbkNoYW5uZWxzXSA9IGluU2hhcGU7XG4gIH0gZWxzZSBpZiAoZGF0YUZvcm1hdCA9PT0gJ2NoYW5uZWxzRmlyc3QnKSB7XG4gICAgW2JhdGNoU2l6ZSwgaW5DaGFubmVscywgaW5EZXB0aCwgaW5IZWlnaHQsIGluV2lkdGhdID0gaW5TaGFwZTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gZGF0YUZvcm1hdCAke2RhdGFGb3JtYXR9YCk7XG4gIH1cbiAgY29uc3QgW2ZpbHRlckNoYW5uZWxzLCAsIGZpbHRlckRlcHRoLCBmaWx0ZXJIZWlnaHQsIGZpbHRlcldpZHRoXSA9IGZpbHRlclNoYXBlO1xuXG4gIGNvbnN0IFtzdHJpZGVEZXB0aCwgc3RyaWRlSGVpZ2h0LCBzdHJpZGVXaWR0aF0gPSBwYXJzZTNUdXBsZVBhcmFtKHN0cmlkZXMpO1xuICBjb25zdCBbZGlsYXRpb25EZXB0aCwgZGlsYXRpb25IZWlnaHQsIGRpbGF0aW9uV2lkdGhdID0gcGFyc2UzVHVwbGVQYXJhbShkaWxhdGlvbnMpO1xuXG4gIGNvbnN0IGVmZmVjdGl2ZUZpbHRlckRlcHRoID0gZ2V0RWZmZWN0aXZlRmlsdGVyU2l6ZShmaWx0ZXJEZXB0aCwgZGlsYXRpb25EZXB0aCk7XG4gIGNvbnN0IGVmZmVjdGl2ZUZpbHRlckhlaWdodCA9IGdldEVmZmVjdGl2ZUZpbHRlclNpemUoZmlsdGVySGVpZ2h0LCBkaWxhdGlvbkhlaWdodCk7XG4gIGNvbnN0IGVmZmVjdGl2ZUZpbHRlcldpZHRoID0gZ2V0RWZmZWN0aXZlRmlsdGVyU2l6ZShmaWx0ZXJXaWR0aCwgZGlsYXRpb25XaWR0aCk7XG4gIGNvbnN0IHsgcGFkSW5mbywgb3V0RGVwdGgsIG91dEhlaWdodCwgb3V0V2lkdGggfSA9IGdldDNEUGFkQW5kT3V0SW5mbyhcbiAgICBwYWQsXG4gICAgaW5EZXB0aCxcbiAgICBpbkhlaWdodCxcbiAgICBpbldpZHRoLFxuICAgIHN0cmlkZURlcHRoLFxuICAgIHN0cmlkZUhlaWdodCxcbiAgICBzdHJpZGVXaWR0aCxcbiAgICBlZmZlY3RpdmVGaWx0ZXJEZXB0aCxcbiAgICBlZmZlY3RpdmVGaWx0ZXJIZWlnaHQsXG4gICAgZWZmZWN0aXZlRmlsdGVyV2lkdGgsXG4gICk7XG5cbiAgY29uc3Qgb3V0Q2hhbm5lbHMgPSBkZXB0aHdpc2UgPyBmaWx0ZXJDaGFubmVscyAqIGluQ2hhbm5lbHMgOiBmaWx0ZXJDaGFubmVscztcblxuICBsZXQgb3V0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMCwgMCwgMCwgMCwgMF07XG4gIGlmIChkYXRhRm9ybWF0ID09PSAnY2hhbm5lbHNGaXJzdCcpIHtcbiAgICBvdXRTaGFwZSA9IFtiYXRjaFNpemUsIG91dENoYW5uZWxzLCBvdXREZXB0aCwgb3V0SGVpZ2h0LCBvdXRXaWR0aF07XG4gIH0gZWxzZSBpZiAoZGF0YUZvcm1hdCA9PT0gJ2NoYW5uZWxzTGFzdCcpIHtcbiAgICBvdXRTaGFwZSA9IFtiYXRjaFNpemUsIG91dERlcHRoLCBvdXRIZWlnaHQsIG91dFdpZHRoLCBvdXRDaGFubmVsc107XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhdGNoU2l6ZSxcbiAgICBkYXRhRm9ybWF0LFxuICAgIGluRGVwdGgsXG4gICAgaW5IZWlnaHQsXG4gICAgaW5XaWR0aCxcbiAgICBpbkNoYW5uZWxzLFxuICAgIG91dERlcHRoLFxuICAgIG91dEhlaWdodCxcbiAgICBvdXRXaWR0aCxcbiAgICBvdXRDaGFubmVscyxcbiAgICBwYWRJbmZvLFxuICAgIHN0cmlkZURlcHRoLFxuICAgIHN0cmlkZUhlaWdodCxcbiAgICBzdHJpZGVXaWR0aCxcbiAgICBmaWx0ZXJEZXB0aCxcbiAgICBmaWx0ZXJIZWlnaHQsXG4gICAgZmlsdGVyV2lkdGgsXG4gICAgZWZmZWN0aXZlRmlsdGVyRGVwdGgsXG4gICAgZWZmZWN0aXZlRmlsdGVySGVpZ2h0LFxuICAgIGVmZmVjdGl2ZUZpbHRlcldpZHRoLFxuICAgIGRpbGF0aW9uRGVwdGgsXG4gICAgZGlsYXRpb25IZWlnaHQsXG4gICAgZGlsYXRpb25XaWR0aCxcbiAgICBpblNoYXBlLFxuICAgIG91dFNoYXBlLFxuICAgIGZpbHRlclNoYXBlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnYzRE5haXZlUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBmaWx0ZXJEaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgcGFkczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGRhdGFGb3JtYXQ6IHN0cmluZyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaXNDaGFubmVsTGFzdCA9IGRhdGFGb3JtYXQgPT09ICdjaGFubmVsc0xhc3QnO1xuICBjb25zdCBpbkNoYW5uZWxzID0gaXNDaGFubmVsTGFzdCA/IGlucHV0c1swXS5kaW1zWzNdIDogaW5wdXRzWzBdLmRpbXNbMV07XG4gIC8vIFRPRE86IGVuYWJsZSB2ZWM0LlxuICBjb25zdCBpc1ZlYzQgPSBmYWxzZTtcbiAgY29uc3Qgd29ya0dyb3VwU2l6ZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzY0LCAxLCAxXTtcbiAgY29uc3QgZGlzcGF0Y2hMYXlvdXQgPSB7IHg6IG91dHB1dFNoYXBlLm1hcCgoXywgaSkgPT4gaSkgfTtcbiAgY29uc3QgZGlzcGF0Y2ggPSBbTWF0aC5jZWlsKGFycmF5UHJvZHVjdChkaXNwYXRjaExheW91dC54Lm1hcCgoZCkgPT4gb3V0cHV0U2hhcGVbZF0pKSAvIHdvcmtHcm91cFNpemVbMF0pLCAxLCAxXTtcblxuICBMT0dfREVCVUcoJ3ZlcmJvc2UnLCAoKSA9PiBgW2NvbnYzZF9uYWl2ZV93ZWJncHVdIGRpc3BhdGNoID0gJHtkaXNwYXRjaH1gKTtcblxuICBjb25zdCBpbm5lckVsZW1lbnRTaXplID0gaXNWZWM0ID8gKGlzQ2hhbm5lbExhc3QgJiYgaW5DaGFubmVscyAlIDQgIT09IDAgPyAzIDogNCkgOiAxO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZmlsdGVyRGltcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwYWRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGF0dHJpYnV0ZXMuc3RyaWRlcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBhdHRyaWJ1dGVzLmRpbGF0aW9ucyB9LFxuICBdO1xuICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhKGF0dHJpYnV0ZXMsIHByb2dyYW1Vbmlmb3Jtcyk7XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcykpO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFsncmFuaycsICdyYW5rJ107XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID09PSAzO1xuICBpZiAoaGFzQmlhcykge1xuICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0c1syXS5kaW1zKSk7XG4gICAgaW5wdXREZXBlbmRlbmNpZXMucHVzaCgncmFuaycpO1xuICB9XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dHB1dFNoYXBlKSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnZmlsdGVyX2RpbXMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBmaWx0ZXJEaW1zLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAncGFkcycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IHBhZHMubGVuZ3RoIH0sXG4gICAgICB7IG5hbWU6ICdzdHJpZGVzJywgdHlwZTogJ3UzMicsIGxlbmd0aDogYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnZGlsYXRpb25zJywgdHlwZTogJ3UzMicsIGxlbmd0aDogYXR0cmlidXRlcy5kaWxhdGlvbnMubGVuZ3RoIH0sXG4gICAgXTtcbiAgICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMoYXR0cmlidXRlcywgdW5pZm9ybXMpO1xuICAgIC8vIFRPRE86IHN1cHBvcnQgY29tcG9uZW50IDIsIDMuXG4gICAgY29uc3QgY29tcG9uZW50cyA9IGlzVmVjNCA/IDQgOiAxO1xuICAgIGNvbnN0IHQgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUoaW5wdXRzWzBdLmRhdGFUeXBlKTtcblxuICAgIGNvbnN0IHggPSBpbnB1dFZhcmlhYmxlKFxuICAgICAgJ3gnLFxuICAgICAgaW5wdXRzWzBdLmRhdGFUeXBlLFxuICAgICAgaW5wdXRzWzBdLmRpbXMubGVuZ3RoLFxuICAgICAgaW5uZXJFbGVtZW50U2l6ZSA9PT0gMyA/IDEgOiBpbm5lckVsZW1lbnRTaXplLFxuICAgICk7XG4gICAgY29uc3QgdyA9IGlucHV0VmFyaWFibGUoJ1cnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgY29uc3QgaW5wdXRWYXJpYWJsZXMgPSBbeCwgd107XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ3Jlc3VsdCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBsZXQgZGVjbGFyZUZ1bmN0aW9ucyA9ICcnO1xuICAgIGlmIChoYXNCaWFzKSB7XG4gICAgICBjb25zdCBiaWFzID0gaW5wdXRWYXJpYWJsZSgnYmlhcycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICAgIGlucHV0VmFyaWFibGVzLnB1c2goYmlhcyk7XG4gICAgICBkZWNsYXJlRnVuY3Rpb25zICs9IGBcbiAgICAgICAgZm4gZ2V0Qmlhc0J5T3V0cHV0Q29vcmRzKGNvb3JkcyA6IGFycmF5PHUzMiwgNT4pIC0+ICR7aXNWZWM0ID8gYHZlYzQ8JHt0fT5gIDogdH0ge1xuICAgICAgICAgIHJldHVybiBiaWFzWyR7aXNDaGFubmVsTGFzdCA/IGdldEVsZW1lbnRBdCgnY29vcmRzJywgNCwgNSkgOiBnZXRFbGVtZW50QXQoJ2Nvb3JkcycsIDEsIDUpfSR7XG4gICAgICAgICAgICBpc1ZlYzQgPyAnLyA0JyA6ICcnXG4gICAgICAgICAgfV07XG4gICAgICAgIH1gO1xuICAgIH1cbiAgICBjb25zdCByZXNUeXBlID0gdHlwZVNuaXBwZXQoaW5uZXJFbGVtZW50U2l6ZSwgdCk7XG4gICAgY29uc3QgYXBwbHlBY3RpdmF0aW9uID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcywgcmVzVHlwZSwgdCk7XG5cbiAgICByZXR1cm4gYFxuICAgICAgICAgICAgJHtkZWNsYXJlRnVuY3Rpb25zfVxuICAgICAgICAgICAgZm4gZ2V0WChkMCA6IHUzMiwgZDEgOiB1MzIsIGQyIDogdTMyLCBkMyA6IHUzMiwgZDQgOiB1MzIpIC0+IGYzMiB7XG4gICAgICAgICAgICAgIGxldCBhSW5kaWNlcyA9IGFycmF5PHUzMiwgNT4oZDAsIGQxLCBkMiwgZDMsIGQ0KTtcbiAgICAgICAgICAgICAgcmV0dXJuICR7eC5nZXRCeUluZGljZXMoJ2FJbmRpY2VzJyl9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm4gZ2V0VyhkMCA6IHUzMiwgZDEgOiB1MzIsIGQyIDogdTMyLCBkMyA6IHUzMiwgZDQgOiB1MzIpIC0+IGYzMiB7XG4gICAgICAgICAgICAgIGxldCBhSW5kaWNlcyA9IGFycmF5PHUzMiwgNT4oZDAsIGQxLCBkMiwgZDMsIGQ0KTtcbiAgICAgICAgICAgICAgcmV0dXJuICR7dy5nZXRCeUluZGljZXMoJ2FJbmRpY2VzJyl9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cbiAgICAgICAgICAgICAgbGV0IGNvb3JkcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcbiAgICAgICAgICAgICAgbGV0IGJhdGNoID0gJHtnZXRFbGVtZW50QXQoJ2Nvb3JkcycsIDAsIHgucmFuayl9O1xuICAgICAgICAgICAgICBsZXQgZDIgPSAke1xuICAgICAgICAgICAgICAgIGlzQ2hhbm5lbExhc3QgPyBnZXRFbGVtZW50QXQoJ2Nvb3JkcycsIHgucmFuayAtIDEsIHgucmFuaykgOiBnZXRFbGVtZW50QXQoJ2Nvb3JkcycsIDEsIHgucmFuaylcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgbGV0IHhGUkNDb3JuZXIgPSB2ZWMzPHUzMj4oJHtcbiAgICAgICAgICAgICAgICBpc0NoYW5uZWxMYXN0ID8gZ2V0RWxlbWVudEF0KCdjb29yZHMnLCAxLCB4LnJhbmspIDogZ2V0RWxlbWVudEF0KCdjb29yZHMnLCAyLCB4LnJhbmspXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICR7aXNDaGFubmVsTGFzdCA/IGdldEVsZW1lbnRBdCgnY29vcmRzJywgMiwgeC5yYW5rKSA6IGdldEVsZW1lbnRBdCgnY29vcmRzJywgMywgeC5yYW5rKX0sXG4gICAgICAgICAgICAgICR7XG4gICAgICAgICAgICAgICAgaXNDaGFubmVsTGFzdCA/IGdldEVsZW1lbnRBdCgnY29vcmRzJywgMywgeC5yYW5rKSA6IGdldEVsZW1lbnRBdCgnY29vcmRzJywgNCwgeC5yYW5rKVxuICAgICAgICAgICAgICB9KSAqIHVuaWZvcm1zLnN0cmlkZXMgLSB1bmlmb3Jtcy5wYWRzO1xuICAgICAgICAgICAgICBsZXQgeEZDb3JuZXIgPSB4RlJDQ29ybmVyLng7XG4gICAgICAgICAgICAgIGxldCB4UkNvcm5lciA9IHhGUkNDb3JuZXIueTtcbiAgICAgICAgICAgICAgbGV0IHhDQ29ybmVyID0geEZSQ0Nvcm5lci56O1xuICAgICAgICAgICAgICBsZXQgeFNoYXBlWSA9ICR7XG4gICAgICAgICAgICAgICAgaXNDaGFubmVsTGFzdFxuICAgICAgICAgICAgICAgICAgPyBnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCAxLCB4LnJhbmspXG4gICAgICAgICAgICAgICAgICA6IGdldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zaGFwZScsIDIsIHgucmFuaylcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgbGV0IHhTaGFwZVogPSAke1xuICAgICAgICAgICAgICAgIGlzQ2hhbm5lbExhc3RcbiAgICAgICAgICAgICAgICAgID8gZ2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgMiwgeC5yYW5rKVxuICAgICAgICAgICAgICAgICAgOiBnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCAzLCB4LnJhbmspXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIGxldCB4U2hhcGVXID0gJHtcbiAgICAgICAgICAgICAgICBpc0NoYW5uZWxMYXN0XG4gICAgICAgICAgICAgICAgICA/IGdldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zaGFwZScsIDMsIHgucmFuaylcbiAgICAgICAgICAgICAgICAgIDogZ2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgNCwgeC5yYW5rKVxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBsZXQgeFNoYXBlVSA9ICR7XG4gICAgICAgICAgICAgICAgaXNDaGFubmVsTGFzdFxuICAgICAgICAgICAgICAgICAgPyBnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCA0LCB4LnJhbmspXG4gICAgICAgICAgICAgICAgICA6IGdldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zaGFwZScsIDEsIHgucmFuaylcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgbGV0IGlucHV0RGVwdGhOZWFyZXN0VmVjNCA9ICh4U2hhcGVVIC8gNCkgKiA0O1xuICAgICAgICAgICAgICBsZXQgaW5wdXREZXB0aFZlYzRSZW1haW5kZXIgPSB4U2hhcGVVICUgNDtcblxuICAgICAgICAgICAgICB2YXIgdmFsdWUgPSAwLjA7XG4gICAgICAgICAgICAgIGZvciAodmFyIHdGID0gMHU7IHdGIDwgdW5pZm9ybXMuZmlsdGVyX2RpbXNbMF07IHdGKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgeEYgPSB4RkNvcm5lciArIHdGICogdW5pZm9ybXMuZGlsYXRpb25zWzBdO1xuICAgICAgICAgICAgICAgIGlmICh4RiA8IDAgfHwgeEYgPj0geFNoYXBlWSkge1xuICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgd1IgPSAwdTsgd1IgPCB1bmlmb3Jtcy5maWx0ZXJfZGltc1sxXTsgd1IrKykge1xuICAgICAgICAgICAgICAgICAgbGV0IHhSID0geFJDb3JuZXIgKyB3UiAqIHVuaWZvcm1zLmRpbGF0aW9uc1sxXTtcbiAgICAgICAgICAgICAgICAgIGlmICh4UiA8IDAgfHwgeFIgPj0geFNoYXBlWikge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgZm9yICh2YXIgd0MgPSAwdTsgd0MgPCB1bmlmb3Jtcy5maWx0ZXJfZGltc1syXTsgd0MrKykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgeEMgPSB4Q0Nvcm5lciArIHdDICogdW5pZm9ybXMuZGlsYXRpb25zWzJdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoeEMgPCAwIHx8IHhDID49IHhTaGFwZVcpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGQxID0gMHU7IGQxIDwgaW5wdXREZXB0aE5lYXJlc3RWZWM0OyBkMSArPSA0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2hhbm5lbExhc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPyBgbGV0IHhWYWx1ZXMgPSB2ZWM0PGYzMj4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgZDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsIGQxICsgMSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgZDEgKyAyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCBkMSArIDMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogYGxldCB4VmFsdWVzID0gdmVjNDxmMzI+KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIGQxLCB4RiwgeFIsIHhDKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCBkMSArIDEsIHhGLCB4UiwgeEMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIGQxICsgMiwgeEYsIHhSLCB4QyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgZDEgKyAzLCB4RiwgeFIsIHhDKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYFxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgd1ZhbHVlcyA9IHZlYzQ8ZjMyPihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFcoZDIsIGQxLCB3Riwgd1IsIHdDKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFcoZDIsIGQxICsgMSwgd0YsIHdSLCB3QyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRXKGQyLCBkMSArIDIsIHdGLCB3Uiwgd0MpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0VyhkMiwgZDEgKyAzLCB3Riwgd1IsIHdDKSk7XG4gICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gZG90KHhWYWx1ZXMsIHdWYWx1ZXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dERlcHRoVmVjNFJlbWFpbmRlciA9PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAke1xuICAgICAgICAgICAgICAgICAgICAgICAgICBpc0NoYW5uZWxMYXN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBgdmFsdWUgKz0gZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgaW5wdXREZXB0aE5lYXJlc3RWZWM0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAqIGdldFcoZDIsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCwgd0YsIHdSLCB3Qyk7YFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogYHZhbHVlICs9IGdldFgoYmF0Y2gsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCwgeEYsIHhSLCB4QylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKiBnZXRXKGQyLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQsIHdGLCB3Uiwgd0MpO2BcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbnB1dERlcHRoVmVjNFJlbWFpbmRlciA9PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2hhbm5lbExhc3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPyBgbGV0IHhWYWx1ZXMgPSB2ZWMyPGYzMj4oXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCB4RiwgeFIsIHhDLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgaW5wdXREZXB0aE5lYXJlc3RWZWM0ICsgMSkpO1xuICAgICAgICAgICAgICAgICAgICAgIGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgOiBgbGV0IHhWYWx1ZXMgPSB2ZWMyPGYzMj4oXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQsIHhGLCB4UiwgeEMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgaW5wdXREZXB0aE5lYXJlc3RWZWM0ICsgMSwgeEYsIHhSLCB4QykpO1xuICAgICAgICAgICAgICAgICAgICBgXG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBsZXQgd1ZhbHVlcyA9IHZlYzI8ZjMyPihcbiAgICAgICAgICAgICAgICAgICAgICBnZXRXKGQyLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQsIHdGLCB3Uiwgd0MpLFxuICAgICAgICAgICAgICAgICAgICAgIGdldFcoZDIsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCArIDEsIHdGLCB3Uiwgd0MpKTtcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBkb3QoeFZhbHVlcywgd1ZhbHVlcyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5wdXREZXB0aFZlYzRSZW1haW5kZXIgPT0gMykge1xuICAgICAgICAgICAgICAgICAgICAgICR7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NoYW5uZWxMYXN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgID8gYGxldCB4VmFsdWVzID0gdmVjMzxmMzI+KFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgaW5wdXREZXB0aE5lYXJlc3RWZWM0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldFgoYmF0Y2gsIHhGLCB4UiwgeEMsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCArIDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgeEYsIHhSLCB4QywgaW5wdXREZXB0aE5lYXJlc3RWZWM0ICsgMikpO1xuICAgICAgICAgICAgICAgICAgICAgIGBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgOiBgbGV0IHhWYWx1ZXMgPSB2ZWMzPGYzMj4oXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQsIHhGLCB4UiwgeEMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0WChiYXRjaCwgaW5wdXREZXB0aE5lYXJlc3RWZWM0ICsgMSwgeEYsIHhSLCB4QyksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRYKGJhdGNoLCBpbnB1dERlcHRoTmVhcmVzdFZlYzQgKyAyLCB4RiwgeFIsIHhDKSk7XG4gICAgICAgICAgICAgICAgICAgIGBcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGxldCB3VmFsdWVzID0gdmVjMzxmMzI+KFxuICAgICAgICAgICAgICAgICAgICAgIGdldFcoZDIsIGlucHV0RGVwdGhOZWFyZXN0VmVjNCwgd0YsIHdSLCB3QyksXG4gICAgICAgICAgICAgICAgICAgICAgZ2V0VyhkMiwgaW5wdXREZXB0aE5lYXJlc3RWZWM0ICsgMSwgd0YsIHdSLCB3QyksXG4gICAgICAgICAgICAgICAgICAgICAgZ2V0VyhkMiwgaW5wdXREZXB0aE5lYXJlc3RWZWM0ICsgMiwgd0YsIHdSLCB3QykpO1xuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IGRvdCh4VmFsdWVzLCB3VmFsdWVzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAke2hhc0JpYXMgPyAndmFsdWUgPSB2YWx1ZSArIGdldEJpYXNCeU91dHB1dENvb3Jkcyhjb29yZHMpJyA6ICcnfTtcbiAgICAgICAgICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICAgICAgICAgIHJlc3VsdFtnbG9iYWxfaWR4XSA9IGYzMih2YWx1ZSk7XG4gICAgICAgICAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0NvbnYzRE5haXZlJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2lzQ2hhbm5lbExhc3R9OyR7aW5uZXJFbGVtZW50U2l6ZX07JHtoYXNCaWFzfWAsIGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBkaXNwYXRjaFswXSwgeTogZGlzcGF0Y2hbMV0sIHo6IGRpc3BhdGNoWzJdIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBQcm9ncmFtSW5mbywgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgZ2V0TWF4Q29tcG9uZW50cyxcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlLFxuICBVbmlmb3Jtc0FycmF5VHlwZSxcbn0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0IHsgQ29udkF0dHJpYnV0ZXMgfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHsgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zLCBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXNEYXRhLCBnZXRBY3RpdmF0aW9uU25pcHBldCB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5cbi8qKlxuICogbmFpdmUgZ3JvdXBlZCBjb252IGltcGxlbWVudGF0aW9uLCBzdXBwb3J0cyAxZC8yZCBjb252XG4gKiBAcGFyYW0gc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24gLSBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBzcXVlZXplIHRoZSBvdXRwdXQgc2hhcGUsIG9ubHkgdXNlZCBpbiBjb252MWRcbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUdyb3VwZWRDb252UHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbj86IChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pID0+IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IHByb2Nlc3NCaWFzID0gaGFzQmlhcyA/ICd2YWx1ZSArPSBiW291dHB1dF9jaGFubmVsXTsnIDogJyc7XG4gIGNvbnN0IHhTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCB3U2hhcGUgPSBpbnB1dHNbMV0uZGltcztcblxuICBjb25zdCBpc0NoYW5uZWxMYXN0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJztcbiAgY29uc3Qgb3V0cHV0Q2hhbm5lbHMgPSBpc0NoYW5uZWxMYXN0ID8gb3V0cHV0U2hhcGVbM10gOiBvdXRwdXRTaGFwZVsxXTtcbiAgY29uc3Qgb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA9IG91dHB1dENoYW5uZWxzIC8gYXR0cmlidXRlcy5ncm91cDtcbiAgY29uc3QgY29tcG9uZW50cyA9IGlzQ2hhbm5lbExhc3QgJiYgb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA+PSA0ID8gZ2V0TWF4Q29tcG9uZW50cyhvdXRwdXRDaGFubmVscykgOiAxO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gY29tcG9uZW50cztcblxuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYXR0cmlidXRlcy5kaWxhdGlvbnMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogW2F0dHJpYnV0ZXMuc3RyaWRlc1swXSwgYXR0cmlidXRlcy5zdHJpZGVzWzFdXSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBbYXR0cmlidXRlcy5wYWRzWzBdLCBhdHRyaWJ1dGVzLnBhZHNbMV1dIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dENoYW5uZWxzUGVyR3JvdXAgfSxcbiAgXTtcbiAgYXBwZW5kQWN0aXZhdGlvblVuaWZvcm1zRGF0YShhdHRyaWJ1dGVzLCBwcm9ncmFtVW5pZm9ybXMpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaChcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyh4U2hhcGUsIFt3U2hhcGVbMF0sIHdTaGFwZVsxXSwgd1NoYXBlWzJdLCB3U2hhcGVbM10gLyBjb21wb25lbnRzXSksXG4gICk7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gaGFzQmlhcyA/IFsncmFuaycsICdyYW5rJywgJ3JhbmsnXSA6IFsncmFuaycsICdyYW5rJ107XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKFxuICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKFtvdXRwdXRTaGFwZVswXSwgb3V0cHV0U2hhcGVbMV0sIG91dHB1dFNoYXBlWzJdLCBvdXRwdXRTaGFwZVszXSAvIGNvbXBvbmVudHNdKSxcbiAgKTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGJhc2VUeXBlID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKG91dHB1dC50eXBlLnRlbnNvcik7XG4gICAgY29uc3QgYXBwbHlBY3RpdmF0aW9uID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcywgb3V0cHV0LnR5cGUudmFsdWUsIGJhc2VUeXBlKTtcbiAgICBjb25zdCB4ID0gaW5wdXRWYXJpYWJsZSgneCcsIGlucHV0c1swXS5kYXRhVHlwZSwgeFNoYXBlLmxlbmd0aCk7XG4gICAgY29uc3QgdyA9IGlucHV0VmFyaWFibGUoJ3cnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIHdTaGFwZS5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGlucHV0VmFycyA9IFt4LCB3XTtcbiAgICBpZiAoaGFzQmlhcykge1xuICAgICAgaW5wdXRWYXJzLnB1c2goaW5wdXRWYXJpYWJsZSgnYicsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMsIGNvbXBvbmVudHMpKTtcbiAgICB9XG5cbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdkaWxhdGlvbnMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBhdHRyaWJ1dGVzLmRpbGF0aW9ucy5sZW5ndGggfSxcbiAgICAgIHsgbmFtZTogJ3N0cmlkZXMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiAyIH0sXG4gICAgICB7IG5hbWU6ICdwYWRzJywgdHlwZTogJ3UzMicsIGxlbmd0aDogMiB9LFxuICAgICAgeyBuYW1lOiAnb3V0cHV0X2NoYW5uZWxzX3Blcl9ncm91cCcsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcbiAgICBhcHBlbmRBY3RpdmF0aW9uVW5pZm9ybXMoYXR0cmlidXRlcywgdW5pZm9ybXMpO1xuXG4gICAgY29uc3QgY2FsY3VsYXRlUmVzdWx0ID0gaXNDaGFubmVsTGFzdFxuICAgICAgPyBgXG4gICAgICBmb3IgKHZhciB3SGVpZ2h0OiB1MzIgPSAwdTsgd0hlaWdodCA8IHVuaWZvcm1zLndfc2hhcGVbMF07IHdIZWlnaHQrKykge1xuICAgICAgICBsZXQgeEhlaWdodCA9IHhSQ0Nvcm5lci54ICsgd0hlaWdodCAqIHVuaWZvcm1zLmRpbGF0aW9uc1swXTtcblxuICAgICAgICBpZiAoeEhlaWdodCA8IDB1IHx8IHhIZWlnaHQgPj0gdW5pZm9ybXMueF9zaGFwZVsxXSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgd1dpZHRoOiB1MzIgPSAwdTsgd1dpZHRoIDwgdW5pZm9ybXMud19zaGFwZVsxXTsgd1dpZHRoKyspIHtcbiAgICAgICAgICBsZXQgeFdpZHRoID0geFJDQ29ybmVyLnkgKyB3V2lkdGggKiB1bmlmb3Jtcy5kaWxhdGlvbnNbMV07XG4gICAgICAgICAgaWYgKHhXaWR0aCA8IDB1IHx8IHhXaWR0aCA+PSB1bmlmb3Jtcy54X3NoYXBlWzJdKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKHZhciB3SW5DaGFubmVsOiB1MzIgPSAwdTsgd0luQ2hhbm5lbCA8IHVuaWZvcm1zLndfc2hhcGVbMl07IHdJbkNoYW5uZWwrKykge1xuICAgICAgICAgICAgbGV0IGlucHV0X2NoYW5uZWwgPSBpbl9jaGFubmVsX29mZnNldCArIHdJbkNoYW5uZWw7XG4gICAgICAgICAgICBsZXQgeFZhbCA9ICR7eC5nZXQoJ2JhdGNoJywgJ3hIZWlnaHQnLCAneFdpZHRoJywgJ2lucHV0X2NoYW5uZWwnKX07XG4gICAgICAgICAgICBsZXQgd1ZhbCA9ICR7dy5nZXQoJ3dIZWlnaHQnLCAnd1dpZHRoJywgJ3dJbkNoYW5uZWwnLCAnb3V0cHV0X2NoYW5uZWwnKX07XG4gICAgICAgICAgICB2YWx1ZSArPSB4VmFsICogd1ZhbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGBcbiAgICAgIDogYFxuICAgICAgZm9yICh2YXIgd0luQ2hhbm5lbDogdTMyID0gMHU7IHdJbkNoYW5uZWwgPCB1bmlmb3Jtcy53X3NoYXBlWzFdOyB3SW5DaGFubmVsKyspIHtcbiAgICAgICAgbGV0IGlucHV0X2NoYW5uZWwgPSBpbl9jaGFubmVsX29mZnNldCArIHdJbkNoYW5uZWw7XG4gICAgICAgIGZvciAodmFyIHdIZWlnaHQ6IHUzMiA9IDB1OyB3SGVpZ2h0IDwgdW5pZm9ybXMud19zaGFwZVsyXTsgd0hlaWdodCsrKSB7XG4gICAgICAgICAgbGV0IHhIZWlnaHQgPSB4UkNDb3JuZXIueCArIHdIZWlnaHQgKiB1bmlmb3Jtcy5kaWxhdGlvbnNbMF07XG5cbiAgICAgICAgICBpZiAoeEhlaWdodCA8IDB1IHx8IHhIZWlnaHQgPj0gdW5pZm9ybXMueF9zaGFwZVsyXSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yICh2YXIgd1dpZHRoOiB1MzIgPSAwdTsgd1dpZHRoIDwgdW5pZm9ybXMud19zaGFwZVszXTsgd1dpZHRoKyspIHtcbiAgICAgICAgICAgIGxldCB4V2lkdGggPSB4UkNDb3JuZXIueSArIHdXaWR0aCAqIHVuaWZvcm1zLmRpbGF0aW9uc1sxXTtcbiAgICAgICAgICAgIGlmICh4V2lkdGggPCAwdSB8fCB4V2lkdGggPj0gdW5pZm9ybXMueF9zaGFwZVszXSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHhWYWwgPSAke3guZ2V0KCdiYXRjaCcsICdpbnB1dF9jaGFubmVsJywgJ3hIZWlnaHQnLCAneFdpZHRoJyl9O1xuICAgICAgICAgICAgbGV0IHdWYWwgPSAke3cuZ2V0KCdvdXRwdXRfY2hhbm5lbCcsICd3SW5DaGFubmVsJywgJ3dIZWlnaHQnLCAnd1dpZHRoJyl9O1xuICAgICAgICAgICAgdmFsdWUgKz0geFZhbCAqIHdWYWw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBgXG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJzLCBvdXRwdXQpfVxuXG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG5cbiAgICBsZXQgb3V0cHV0SW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcbiAgICBsZXQgYmF0Y2g6IHUzMiA9IG91dHB1dEluZGljZXNbMF07XG4gICAgbGV0IG91dHB1dF9jaGFubmVsOiB1MzIgPSBvdXRwdXRJbmRpY2VzWyR7aXNDaGFubmVsTGFzdCA/IDMgOiAxfV07XG4gICAgbGV0IHhSQ0Nvcm5lcjogdmVjMjx1MzI+ID0gdmVjMjx1MzI+KG91dHB1dEluZGljZXNbJHtpc0NoYW5uZWxMYXN0ID8gMSA6IDJ9XSwgb3V0cHV0SW5kaWNlc1ske1xuICAgICAgaXNDaGFubmVsTGFzdCA/IDIgOiAzXG4gICAgfV0pICogdW5pZm9ybXMuc3RyaWRlcyAtIHVuaWZvcm1zLnBhZHM7XG4gICAgbGV0IGdyb3VwX2lkOiB1MzIgPSBvdXRwdXRfY2hhbm5lbCAqICR7Y29tcG9uZW50c30gLyB1bmlmb3Jtcy5vdXRwdXRfY2hhbm5lbHNfcGVyX2dyb3VwO1xuICAgIHZhciBpbl9jaGFubmVsX29mZnNldCA9IGdyb3VwX2lkICogdW5pZm9ybXMud19zaGFwZVske2lzQ2hhbm5lbExhc3QgPyAyIDogMX1dO1xuXG4gICAgdmFyIHZhbHVlOiAke291dHB1dC50eXBlLnZhbHVlfSA9ICR7b3V0cHV0LnR5cGUudmFsdWV9KDApO1xuICAgICR7Y2FsY3VsYXRlUmVzdWx0fVxuICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAndmFsdWUnKX1cbiAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0dyb3VwZWRDb252JyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fV8ke2NvbXBvbmVudHN9YCwgaW5wdXREZXBlbmRlbmNpZXMgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW1xuICAgICAgICB7XG4gICAgICAgICAgZGltczogc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24gPyBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbihvdXRwdXRTaGFwZSkgOiBvdXRwdXRTaGFwZSxcbiAgICAgICAgICBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlR3JvdXBlZENvbnZWZWN0b3JpemVQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uPzogKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSkgPT4gbnVtYmVyW10sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgY29uc3QgY29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMob3V0cHV0U2hhcGVbM10pO1xuICBjb25zdCBvdXRwdXROdW1iZXIgPSBnZXRNYXhDb21wb25lbnRzKG91dHB1dFNoYXBlWzJdKTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIGNvbXBvbmVudHMgLyBvdXRwdXROdW1iZXI7XG4gIGNvbnN0IHhTaGFwZSA9IFtpbnB1dHNbMF0uZGltc1swXSwgaW5wdXRzWzBdLmRpbXNbMV0sIGlucHV0c1swXS5kaW1zWzJdLCBpbnB1dHNbMF0uZGltc1szXSAvIGNvbXBvbmVudHNdO1xuICBjb25zdCB3U2hhcGUgPSBbaW5wdXRzWzFdLmRpbXNbMF0sIGlucHV0c1sxXS5kaW1zWzFdLCBpbnB1dHNbMV0uZGltc1syXSwgaW5wdXRzWzFdLmRpbXNbM10gLyBjb21wb25lbnRzXTtcbiAgY29uc3Qgb3V0cHV0U2hhcGVJblNoYWRlciA9IFtvdXRwdXRTaGFwZVswXSwgb3V0cHV0U2hhcGVbMV0sIG91dHB1dFNoYXBlWzJdLCBvdXRwdXRTaGFwZVszXSAvIGNvbXBvbmVudHNdO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IFthdHRyaWJ1dGVzLnN0cmlkZXNbMF0sIGF0dHJpYnV0ZXMuc3RyaWRlc1sxXV0gfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmludDMyLCBkYXRhOiBbYXR0cmlidXRlcy5wYWRzWzBdLCBhdHRyaWJ1dGVzLnBhZHNbMV1dIH0sXG4gIF07XG4gIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3Jtc0RhdGEoYXR0cmlidXRlcywgcHJvZ3JhbVVuaWZvcm1zKTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoeFNoYXBlLCB3U2hhcGUsIG91dHB1dFNoYXBlSW5TaGFkZXIpKTtcbiAgY29uc3QgeE51bWJlciA9IChvdXRwdXROdW1iZXIgLSAxKSAqIGF0dHJpYnV0ZXMuc3RyaWRlc1sxXSArIHdTaGFwZVsxXTtcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGVJblNoYWRlci5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGJhc2VUeXBlID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKG91dHB1dC50eXBlLnRlbnNvcik7XG4gICAgY29uc3QgYXBwbHlBY3RpdmF0aW9uID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcywgb3V0cHV0LnR5cGUudmFsdWUsIGJhc2VUeXBlKTtcbiAgICBjb25zdCB4ID0gaW5wdXRWYXJpYWJsZSgneCcsIGlucHV0c1swXS5kYXRhVHlwZSwgeFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgY29uc3QgdyA9IGlucHV0VmFyaWFibGUoJ3cnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIHdTaGFwZS5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGlucHV0VmFycyA9IFt4LCB3XTtcbiAgICBpZiAoaGFzQmlhcykge1xuICAgICAgaW5wdXRWYXJzLnB1c2goaW5wdXRWYXJpYWJsZSgnYicsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMsIGNvbXBvbmVudHMpKTtcbiAgICB9XG4gICAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGJbb3V0cHV0X2NoYW5uZWxdOycgOiAnJztcbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdzdHJpZGVzJywgdHlwZTogJ2kzMicsIGxlbmd0aDogMiB9LFxuICAgICAgeyBuYW1lOiAncGFkcycsIHR5cGU6ICdpMzInLCBsZW5ndGg6IDIgfSxcbiAgICBdO1xuICAgIGFwcGVuZEFjdGl2YXRpb25Vbmlmb3JtcyhhdHRyaWJ1dGVzLCB1bmlmb3Jtcyk7XG4gICAgcmV0dXJuIGBcbiAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcnMsIG91dHB1dCl9XG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgbGV0IHdpZHRoMCA9IHVuaWZvcm1zLm91dHB1dF9zaGFwZVszXTtcbiAgICBsZXQgb3V0cHV0X2NoYW5uZWwgPSBnbG9iYWxfaWR4ICUgd2lkdGgwO1xuICAgIHZhciBpbmRleDEgPSBnbG9iYWxfaWR4IC8gd2lkdGgwO1xuICAgIGxldCB3aWR0aDEgPSB1bmlmb3Jtcy5vdXRwdXRfc2hhcGVbMl0gLyAke291dHB1dE51bWJlcn11O1xuICAgIGxldCBjb2wgPSAoaW5kZXgxICUgd2lkdGgxKSAqICR7b3V0cHV0TnVtYmVyfXU7XG4gICAgaW5kZXgxID0gaW5kZXgxIC8gd2lkdGgxO1xuICAgIGxldCByb3cgPSBpbmRleDEgJSB1bmlmb3Jtcy5vdXRwdXRfc2hhcGVbMV07XG4gICAgbGV0IGJhdGNoID0gaW5kZXgxIC8gdW5pZm9ybXMub3V0cHV0X3NoYXBlWzFdO1xuXG4gICAgbGV0IHhfY29ybmVyID0gdmVjMjxpMzI+KGkzMihyb3cpLCBpMzIoY29sKSkgKiB1bmlmb3Jtcy5zdHJpZGVzIC0gdW5pZm9ybXMucGFkcztcblxuICAgIHZhciB4X3ZhbHM6IGFycmF5PCR7eC50eXBlLnZhbHVlfSwgJHt4TnVtYmVyfT47XG4gICAgdmFyIHZhbHVlczogYXJyYXk8JHtvdXRwdXQudHlwZS52YWx1ZX0sICR7b3V0cHV0TnVtYmVyfT47XG4gICAgbGV0IGlucHV0X2NoYW5uZWwgPSBvdXRwdXRfY2hhbm5lbDtcbiAgICAvLyBVc2UgY29uc3RhbnQgaW5zdGVhZCBvZiB1bmlmb3JtIGNhbiBnaXZlIGJldHRlciBwZXJmb3JtYW5jZSBmb3IgdydzIGhlaWdodC93aWR0aC5cbiAgICBmb3IgKHZhciB3X2hlaWdodDogdTMyID0gMHU7IHdfaGVpZ2h0IDwgJHt3U2hhcGVbMF19OyB3X2hlaWdodCsrKSB7XG4gICAgICBsZXQgeF9oZWlnaHQgPSB4X2Nvcm5lci54ICsgaTMyKHdfaGVpZ2h0KTtcbiAgICAgIGlmICh4X2hlaWdodCA+PSAwICYmIHUzMih4X2hlaWdodCkgPCB1bmlmb3Jtcy54X3NoYXBlWzFdKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgJHt4TnVtYmVyfTsgaSsrKSB7XG4gICAgICAgICAgbGV0IHhfd2lkdGggPSB4X2Nvcm5lci55ICsgaTtcbiAgICAgICAgICBpZiAoeF93aWR0aCA+PSAwICYmIHUzMih4X3dpZHRoKSA8IHVuaWZvcm1zLnhfc2hhcGVbMl0pIHtcbiAgICAgICAgICAgIHhfdmFsc1tpXSA9ICR7eC5nZXQoJ2JhdGNoJywgJ3UzMih4X2hlaWdodCknLCAndTMyKHhfd2lkdGgpJywgJ2lucHV0X2NoYW5uZWwnKX07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHhfdmFsc1tpXSA9ICR7eC50eXBlLnZhbHVlfSgwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgd193aWR0aDogdTMyID0gMHU7IHdfd2lkdGggPCAke3dTaGFwZVsxXX07IHdfd2lkdGgrKykge1xuICAgICAgICAgIGxldCB3X3ZhbCA9ICR7dy5nZXQoJ3dfaGVpZ2h0JywgJ3dfd2lkdGgnLCAnMCcsICdvdXRwdXRfY2hhbm5lbCcpfTtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMHU7IGkgPCAke291dHB1dE51bWJlcn11OyBpKyspIHtcbiAgICAgICAgICAgIHZhbHVlc1tpXSA9IGZtYSh4X3ZhbHNbaSAqIHUzMih1bmlmb3Jtcy5zdHJpZGVzWzFdKSArIHdfd2lkdGhdLCB3X3ZhbCwgdmFsdWVzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMHU7IGkgPCAke291dHB1dE51bWJlcn11OyBpKyspIHtcbiAgICAgIHZhciB2YWx1ZSA9IHZhbHVlc1tpXTtcbiAgICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAgICR7b3V0cHV0LnNldCgnYmF0Y2gnLCAncm93JywgJ2NvbCArIGknLCAnb3V0cHV0X2NoYW5uZWwnLCAndmFsdWUnKX07XG4gICAgfVxuICB9YDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdHcm91cGVkQ29udi1WZWN0b3JpemUnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2NvbXBvbmVudHN9OyR7b3V0cHV0TnVtYmVyfTske3hOdW1iZXJ9OyR7d1NoYXBlWzBdfTske3dTaGFwZVsxXX1gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXM6IGhhc0JpYXMgPyBbJ3JhbmsnLCAncmFuaycsICd0eXBlJ10gOiBbJ3JhbmsnLCAncmFuayddLFxuICAgIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGRpbXM6IHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uID8gc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24ob3V0cHV0U2hhcGUpIDogb3V0cHV0U2hhcGUsXG4gICAgICAgICAgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFBvb2xDb252VXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0IH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVDb252MkRNYXRNdWxQcm9ncmFtSW5mbyB9IGZyb20gJy4vM3JkLXBhcnR5L2NvbnYyZF9tbV93ZWJncHUnO1xuaW1wb3J0IHsgY29tcHV0ZUNvbnYzREluZm8sIGNyZWF0ZUNvbnYzRE5haXZlUHJvZ3JhbUluZm8gfSBmcm9tICcuLzNyZC1wYXJ0eS9jb252M2RfbmFpdmVfd2ViZ3B1JztcbmltcG9ydCB7IGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvIH0gZnJvbSAnLi8zcmQtcGFydHkvbWF0bXVsX3BhY2tlZF93ZWJncHUnO1xuaW1wb3J0IHsgY3JlYXRlR3JvdXBlZENvbnZQcm9ncmFtSW5mbywgY3JlYXRlR3JvdXBlZENvbnZWZWN0b3JpemVQcm9ncmFtSW5mbyB9IGZyb20gJy4vY29udi1ncm91cGVkJztcbmltcG9ydCB7IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsIHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQgeyBjcmVhdGVOYWl2ZU1hdG11bFByb2dyYW1JbmZvIH0gZnJvbSAnLi9tYXRtdWwtc2hhZGVycyc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZU91dHB1dFNoYXBlID0gKFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhZGp1c3RQYWRzOiByZWFkb25seSBudW1iZXJbXSxcbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGlzQ2hhbm5lbExhc3Q6IGJvb2xlYW4sXG4pOiBudW1iZXJbXSA9PiB7XG4gIGNvbnN0IGJhdGNoU2l6ZSA9IGlucHV0U2hhcGVbMF07XG4gIGNvbnN0IGlucHV0U3BhdGlhbFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZShpc0NoYW5uZWxMYXN0ID8gMSA6IDIsIGlzQ2hhbm5lbExhc3QgPyAzIDogNCk7XG4gIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRTcGF0aWFsU2hhcGUubGVuZ3RoO1xuICBjb25zdCBvdXRDaGFubmVscyA9IGtlcm5lbFNoYXBlWzBdO1xuICBjb25zdCBrZXJuZWxTcGF0aWFsU2hhcGUgPSBrZXJuZWxTaGFwZS5zbGljZSgyKTtcbiAgY29uc3QgZGlsYXRlZEtlcm5lbFNoYXBlID0ga2VybmVsU3BhdGlhbFNoYXBlLm1hcCgodiwgaSkgPT4gdiArICh2IC0gMSkgKiAoZGlsYXRpb25zW2ldIC0gMSkpO1xuICBjb25zdCBpbnB1dFNwYXRpYWxTaGFwZVdpdGhQYWQgPSBpbnB1dFNwYXRpYWxTaGFwZS5tYXAoKHYsIGkpID0+IHYgKyBhZGp1c3RQYWRzW2ldICsgYWRqdXN0UGFkc1tpICsgc3BhdGlhbFJhbmtdKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNwYXRpYWxTaGFwZVdpdGhQYWQubWFwKCh2LCBpKSA9PlxuICAgIE1hdGguZmxvb3IoKHYgLSBkaWxhdGVkS2VybmVsU2hhcGVbaV0gKyBzdHJpZGVzW2ldKSAvIHN0cmlkZXNbaV0pLFxuICApO1xuICBvdXRwdXRTaGFwZS5zcGxpY2UoMCwgMCwgYmF0Y2hTaXplKTtcbiAgb3V0cHV0U2hhcGUuc3BsaWNlKGlzQ2hhbm5lbExhc3QgPyAzIDogMSwgMCwgb3V0Q2hhbm5lbHMpO1xuICByZXR1cm4gb3V0cHV0U2hhcGU7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZBdHRyaWJ1dGVzIGV4dGVuZHMgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcywgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXV0b1BhZDogc3RyaW5nO1xuICByZWFkb25seSBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBmb3JtYXQ6ICdOSFdDJyB8ICdOQ0hXJztcbiAgcmVhZG9ubHkgZ3JvdXA6IG51bWJlcjtcbiAgcmVhZG9ubHkga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBwYWRzOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHdJc0NvbnN0OiBib29sZWFuO1xufVxuXG4vLyBmb3IgdHJhbnNwb3Npbmcgd2VpZ2h0IHRlbnNvciBmcm9tIFtNLCBDL2dyb3VwLCBLSCwgS1ddIHRvIFtLSCwgS1csIEMvZ3JvdXAsIE1dXG5jb25zdCB3ZWlnaHRUcmFuc3Bvc2VBdHRyaWJ1dGUgPSBbMiwgMywgMSwgMF07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICAvLyBSZWZlciB0byB0aGUgYmVsb3cgbGluayBmb3IgYWxsIGlucHV0IGNoZWNrc1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFzdGVyL2RvY3MvT3BlcmF0b3JzLm1kI0NvbnZcbiAgaWYgKCFpbnB1dHMgfHwgKGlucHV0cy5sZW5ndGggIT09IDIgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgcmVxdWlyZXMgMiBvciAzIGlucHV0cycpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCA+IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2dyZWF0ZXIgdGhhbiA1RCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSBpbnB1dHNbMV0uZGltcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZpbHRlciBkb2VzIG5vdCBoYXZlIHNhbWUgZGltZW5zaW9uIGFzIGlucHV0Jyk7XG4gIH1cblxuICAvLyBGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMXG4gIGNvbnN0IGRhdGFDaGFubmVsID0gaW5wdXRzWzBdLmRpbXNbYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJyA/IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDEgOiAxXTtcbiAgY29uc3QgZmlsdGVySW5DaGFubmVsID0gaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwO1xuICBpZiAoZGF0YUNoYW5uZWwgIT09IGZpbHRlckluQ2hhbm5lbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTCcpO1xuICB9XG5cbiAgLy8gaWYgYmlhcyBpcyBwcm92aWRlZCBpdCBzaG91bGQgYmUgMUQgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgZmVhdHVyZSBtYXBzXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIChpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgfHwgaW5wdXRzWzFdLmRpbXNbMF0gIT09IGlucHV0c1syXS5kaW1zWzBdKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBiaWFzJyk7XG4gIH1cblxuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDI7XG4gIC8vIHdyb25nIGRpbGF0aW9ucyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuZGlsYXRpb25zLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRpbGF0aW9ucyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBzdHJpZGVzIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHN0cmlkZXMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3JvbmcgcGFkcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMucGFkcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rICogMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgcGFkcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFuayAqIDJ9RGApO1xuICB9XG5cbiAgLy8gaWYga2VybmVsU2hhcGUgaXMgc3BlY2lmaWVkLCBpdCdzIGRhdGEgbGVuZ3RoIG11c3QgYmUgMiBsZXNzIHRoYW4gZGltcyBsZW5ndGggb2YgdGhlIHdlaWdodHMgdGVuc29yXG4gIC8vICh0aGUgZmlyc3QgMiBkaW1zIGFyZSBiYXRjaF9zaXplIGFuZCBjaGFubmVscylcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSAwICYmIGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGtlcm5lbCBzaGFwZScpO1xuICB9XG59O1xuXG5jb25zdCBnZXRBZGp1c3RlZENvbnZBdHRyaWJ1dGVzID0gPFQgZXh0ZW5kcyBDb252QXR0cmlidXRlcz4oYXR0cmlidXRlczogVCwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiBUID0+IHtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIG5vdCB3ZWxsIHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlcywgaW5mZXIgaXQgZnJvbSB0aGUgd2VpZ2h0IHRlbnNvciBkaW1zXG4gIGlmIChrZXJuZWxTaGFwZS5sZW5ndGggPCBpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAga2VybmVsU2hhcGUucHVzaCguLi5BcnJheShpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyIC0ga2VybmVsU2hhcGUubGVuZ3RoKS5maWxsKDApKTtcbiAgfVxuICBmb3IgKGxldCBpID0gMjsgaSA8IGlucHV0c1sxXS5kaW1zLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGtlcm5lbFNoYXBlW2kgLSAyXSA9PT0gMCkge1xuICAgICAga2VybmVsU2hhcGVbaSAtIDJdID0gaW5wdXRzWzFdLmRpbXNbaV07XG4gICAgfVxuICB9XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMuc2xpY2UoKTtcbiAgUG9vbENvbnZVdGlsLmFkanVzdFBhZHNCYXNlZE9uQXV0b1BhZChcbiAgICBpbnB1dHNbMF0uZGltcyxcbiAgICBhdHRyaWJ1dGVzLnN0cmlkZXMsXG4gICAgYXR0cmlidXRlcy5kaWxhdGlvbnMsXG4gICAga2VybmVsU2hhcGUsXG4gICAgcGFkcyxcbiAgICBhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnLFxuICAgIGF0dHJpYnV0ZXMuYXV0b1BhZCxcbiAgKTtcblxuICAvLyBhbHdheXMgcmV0dXJuIGEgbmV3IG9iamVjdCBzbyBkb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsIGF0dHJpYnV0ZXNcbiAgY29uc3QgbmV3QXR0cmlidXRlczogVCA9IE9iamVjdC5hc3NpZ24oe30sIGF0dHJpYnV0ZXMpO1xuICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHsga2VybmVsU2hhcGUsIHBhZHMgfSk7XG4gIHJldHVybiBuZXdBdHRyaWJ1dGVzO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ29udkF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBDb252QXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGFjdGl2YXRpb25BdHRyaWJ1dGVzID0gcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpO1xuICAvLyBUT0RPIDogTWFrZSB0aGlzIGdlbmVyaWMgZW5vdWdoIHRvIGNvbXB1dGUgZGVmYXVsdCBhdHRyaWJ1dGVzIGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGNvbnN0IGZvcm1hdCA9IGF0dHJpYnV0ZXMuZm9ybWF0IGFzICdOSFdDJyB8ICdOQ0hXJztcbiAgY29uc3QgYXV0b1BhZCA9IFsnTk9UU0VUJywgJ1ZBTElEJywgJ1NBTUVfVVBQRVInLCAnU0FNRV9MT1dFUiddW2F0dHJpYnV0ZXMuYXV0b19wYWQgYXMgbnVtYmVyXTtcbiAgY29uc3QgZGlsYXRpb25zID0gYXR0cmlidXRlcy5kaWxhdGlvbnMgYXMgbnVtYmVyW107XG4gIGNvbnN0IGdyb3VwID0gYXR0cmlidXRlcy5ncm91cCBhcyBudW1iZXI7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxfc2hhcGUgYXMgbnVtYmVyW107XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMgYXMgbnVtYmVyW107XG4gIGNvbnN0IHN0cmlkZXMgPSBhdHRyaWJ1dGVzLnN0cmlkZXMgYXMgbnVtYmVyW107XG4gIGNvbnN0IHdJc0NvbnN0ID0gKGF0dHJpYnV0ZXMud19pc19jb25zdCBhcyAoKSA9PiBib29sZWFuKSgpO1xuXG4gIHJldHVybiB7XG4gICAgYXV0b1BhZCxcbiAgICBmb3JtYXQsXG4gICAgZGlsYXRpb25zLFxuICAgIGdyb3VwLFxuICAgIGtlcm5lbFNoYXBlLFxuICAgIHBhZHMsXG4gICAgc3RyaWRlcyxcbiAgICB3SXNDb25zdCxcbiAgICAuLi5hY3RpdmF0aW9uQXR0cmlidXRlcyxcbiAgICBjYWNoZUtleTogYCR7YXR0cmlidXRlcy5mb3JtYXR9OyR7YWN0aXZhdGlvbkF0dHJpYnV0ZXMuYWN0aXZhdGlvbn07YCxcbiAgfTtcbn07XG5cbmNvbnN0IGNvbnYyZCA9IChcbiAgY29udGV4dDogQ29tcHV0ZUNvbnRleHQsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyxcbiAgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24/OiAoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKSA9PiBudW1iZXJbXSxcbik6IHZvaWQgPT4ge1xuICAvLyBjaGVjayBhdHRyaWJ1dGVzXG5cbiAgLy8gY29uc3QgaGFzUHJlbHVBY3RpdmF0aW9uV2VpZ2h0cyA9IGZhbHNlOyAvKiBUT0RPOiBhZGQgc3VwcG9ydCBmb3IgcHJlbHUgYWN0aXZhdGlvbiB3ZWlnaHRzICovXG4gIGNvbnN0IGlzQ2hhbm5lbHNMYXN0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVPdXRwdXRTaGFwZShcbiAgICBpbnB1dHNbMF0uZGltcyxcbiAgICBpbnB1dHNbMV0uZGltcyxcbiAgICBhdHRyaWJ1dGVzLmRpbGF0aW9ucyxcbiAgICBhdHRyaWJ1dGVzLnBhZHMsXG4gICAgYXR0cmlidXRlcy5zdHJpZGVzLFxuICAgIGlzQ2hhbm5lbHNMYXN0LFxuICApO1xuICBpZiAoYXR0cmlidXRlcy5ncm91cCAhPT0gMSkge1xuICAgIGNvbnN0IGNvbnZJbnB1dHMgPSBbaW5wdXRzWzBdXTtcbiAgICBpZiAoaXNDaGFubmVsc0xhc3QpIHtcbiAgICAgIGNvbnN0IHRyYW5zcG9zZWRXZWlnaHQgPVxuICAgICAgICAoY29udGV4dC5rZXJuZWxDdXN0b21EYXRhLndUIGFzIFRlbnNvclZpZXcgfCB1bmRlZmluZWQpID8/XG4gICAgICAgIGNvbnRleHQuY29tcHV0ZShjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhpbnB1dHNbMV0sIHdlaWdodFRyYW5zcG9zZUF0dHJpYnV0ZSksIHtcbiAgICAgICAgICBpbnB1dHM6IFsxXSxcbiAgICAgICAgICBvdXRwdXRzOiBbYXR0cmlidXRlcy53SXNDb25zdCA/IC0yIDogLTFdLFxuICAgICAgICB9KVswXTtcbiAgICAgIGlmIChhdHRyaWJ1dGVzLndJc0NvbnN0ICYmICFjb250ZXh0Lmtlcm5lbEN1c3RvbURhdGEud1QpIHtcbiAgICAgICAgY29udGV4dC5rZXJuZWxDdXN0b21EYXRhLndUID0gdHJhbnNwb3NlZFdlaWdodDtcbiAgICAgIH1cbiAgICAgIGNvbnZJbnB1dHMucHVzaCh0cmFuc3Bvc2VkV2VpZ2h0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udklucHV0cy5wdXNoKGlucHV0c1sxXSk7XG4gICAgfVxuICAgIGlmIChpbnB1dHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBjb252SW5wdXRzLnB1c2goaW5wdXRzWzJdKTtcbiAgICB9XG4gICAgLy8gTlZJRElBIEdQVSB3aXRoIGFtcGVyZSBhcmNoaXRlY3R1cmUgZmFpbHMgd2l0aCBiZWxvdyAyIGNhc2VzLCBidXQgd2UgY291bGRuJ3QgcmVwcm8gdGhlbSB3aXRoIGFueSBvdGhlclxuICAgIC8vIEdQVXMuIFNvIGp1c3QgZGlzYWJsZSB2ZWN0b3JpemUgb24gTlZJRElBIGFtcGVyZSB0byBlbnN1cmUgYWx3YXlzIGNvcnJlY3Qgb3V0cHV0cy5cbiAgICAvLyBbd2ViZ3B1XUNvbnYgLSBjb252IC0gdmVjdG9yaXplIGdyb3VwIC0gQlxuICAgIC8vIFt3ZWJncHVdQ29udiAtIGNvbnYgLSB2ZWN0b3JpemUgZ3JvdXAgLSBEXG4gICAgY29uc3QgZW5hYmxlR3JvdXBlZENvbnZWZWN0b3JpemUgPSAhY29udGV4dC5hZGFwdGVySW5mby5pc0FyY2hpdGVjdHVyZSgnYW1wZXJlJyk7XG4gICAgaWYgKFxuICAgICAgZW5hYmxlR3JvdXBlZENvbnZWZWN0b3JpemUgJiZcbiAgICAgIGlzQ2hhbm5lbHNMYXN0ICYmXG4gICAgICBpbnB1dHNbMV0uZGltc1swXSA9PT0gYXR0cmlidXRlcy5ncm91cCAmJlxuICAgICAgaW5wdXRzWzFdLmRpbXNbMV0gPT09IDEgJiZcbiAgICAgIGF0dHJpYnV0ZXMuZGlsYXRpb25zWzBdID09PSAxICYmXG4gICAgICBhdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXSA9PT0gMVxuICAgICkge1xuICAgICAgY29udGV4dC5jb21wdXRlKFxuICAgICAgICBjcmVhdGVHcm91cGVkQ29udlZlY3Rvcml6ZVByb2dyYW1JbmZvKGNvbnZJbnB1dHMsIGF0dHJpYnV0ZXMsIG91dHB1dFNoYXBlLCBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbiksXG4gICAgICAgIHsgaW5wdXRzOiBjb252SW5wdXRzIH0sXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlR3JvdXBlZENvbnZQcm9ncmFtSW5mbyhjb252SW5wdXRzLCBhdHRyaWJ1dGVzLCBvdXRwdXRTaGFwZSwgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24pLCB7XG4gICAgICAgIGlucHV0czogY29udklucHV0cyxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA9PT0gMztcbiAgY29uc3QgaW5wdXRIZWlnaHQgPSBpbnB1dHNbMF0uZGltc1tpc0NoYW5uZWxzTGFzdCA/IDEgOiAyXTtcbiAgY29uc3QgaW5wdXRXaWR0aCA9IGlucHV0c1swXS5kaW1zW2lzQ2hhbm5lbHNMYXN0ID8gMiA6IDNdO1xuICBjb25zdCBpbnB1dENoYW5uZWxzID0gaW5wdXRzWzBdLmRpbXNbaXNDaGFubmVsc0xhc3QgPyAzIDogMV07XG4gIGNvbnN0IHdlaWdodEhlaWdodCA9IGlucHV0c1sxXS5kaW1zWzJdO1xuICBjb25zdCB3ZWlnaHRXaWR0aCA9IGlucHV0c1sxXS5kaW1zWzNdO1xuXG4gIGNvbnN0IG91dEhlaWdodCA9IG91dHB1dFNoYXBlW2lzQ2hhbm5lbHNMYXN0ID8gMSA6IDJdO1xuICBjb25zdCBvdXRXaWR0aCA9IG91dHB1dFNoYXBlW2lzQ2hhbm5lbHNMYXN0ID8gMiA6IDNdO1xuICBjb25zdCBvdXRDaGFubmVscyA9IG91dHB1dFNoYXBlW2lzQ2hhbm5lbHNMYXN0ID8gMyA6IDFdO1xuXG4gIGNvbnN0IHNhbWVTaXplID1cbiAgICBpc0NoYW5uZWxzTGFzdCAmJlxuICAgIHdlaWdodEhlaWdodCA9PT0gaW5wdXRIZWlnaHQgJiZcbiAgICB3ZWlnaHRXaWR0aCA9PT0gaW5wdXRXaWR0aCAmJlxuICAgIGF0dHJpYnV0ZXMucGFkc1swXSA9PT0gMCAmJlxuICAgIGF0dHJpYnV0ZXMucGFkc1sxXSA9PT0gMDtcbiAgaWYgKFxuICAgIHNhbWVTaXplIHx8XG4gICAgKHdlaWdodEhlaWdodCA9PT0gMSAmJlxuICAgICAgd2VpZ2h0V2lkdGggPT09IDEgJiZcbiAgICAgIGF0dHJpYnV0ZXMuZGlsYXRpb25zWzBdID09PSAxICYmXG4gICAgICBhdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXSA9PT0gMSAmJlxuICAgICAgYXR0cmlidXRlcy5zdHJpZGVzWzBdID09PSAxICYmXG4gICAgICBhdHRyaWJ1dGVzLnN0cmlkZXNbMV0gPT09IDEgJiZcbiAgICAgIGF0dHJpYnV0ZXMucGFkc1swXSA9PT0gMCAmJlxuICAgICAgYXR0cmlidXRlcy5wYWRzWzFdID09PSAwKVxuICApIHtcbiAgICAvLyBjb252MmRCeU1hdE11bFxuICAgIGNvbnN0IGJhdGNoID0gb3V0cHV0U2hhcGVbMF07XG4gICAgbGV0IHhSZXNoYXBlZCwgd1Jlc2hhcGVkLCBtYXRtdWxPdXRwdXRTaGFwZTtcbiAgICBjb25zdCBtYXRtdWxJbnB1dHMgPSBbXTtcbiAgICBpZiAoaXNDaGFubmVsc0xhc3QpIHtcbiAgICAgIGNvbnN0IHRyYW5zcG9zZWRXZWlnaHQgPVxuICAgICAgICAoY29udGV4dC5rZXJuZWxDdXN0b21EYXRhLndUIGFzIFRlbnNvclZpZXcgfCB1bmRlZmluZWQpID8/XG4gICAgICAgIGNvbnRleHQuY29tcHV0ZShjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhpbnB1dHNbMV0sIHdlaWdodFRyYW5zcG9zZUF0dHJpYnV0ZSksIHtcbiAgICAgICAgICBpbnB1dHM6IFsxXSxcbiAgICAgICAgICBvdXRwdXRzOiBbYXR0cmlidXRlcy53SXNDb25zdCA/IC0yIDogLTFdLFxuICAgICAgICB9KVswXTtcbiAgICAgIGlmIChhdHRyaWJ1dGVzLndJc0NvbnN0ICYmICFjb250ZXh0Lmtlcm5lbEN1c3RvbURhdGEud1QpIHtcbiAgICAgICAgY29udGV4dC5rZXJuZWxDdXN0b21EYXRhLndUID0gdHJhbnNwb3NlZFdlaWdodDtcbiAgICAgIH1cbiAgICAgIGlmIChzYW1lU2l6ZSkge1xuICAgICAgICBjb25zdCBzaGFyZWREaW0gPSBpbnB1dEhlaWdodCAqIGlucHV0V2lkdGggKiBpbnB1dENoYW5uZWxzO1xuICAgICAgICB4UmVzaGFwZWQgPSBpbnB1dHNbMF0ucmVzaGFwZShbMSwgYmF0Y2gsIHNoYXJlZERpbV0pO1xuICAgICAgICB3UmVzaGFwZWQgPSB0cmFuc3Bvc2VkV2VpZ2h0LnJlc2hhcGUoWzEsIHNoYXJlZERpbSwgb3V0Q2hhbm5lbHNdKTtcbiAgICAgICAgbWF0bXVsT3V0cHV0U2hhcGUgPSBbMSwgYmF0Y2gsIG91dENoYW5uZWxzXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHhSZXNoYXBlZCA9IGlucHV0c1swXS5yZXNoYXBlKFtiYXRjaCwgaW5wdXRIZWlnaHQgKiBpbnB1dFdpZHRoLCBpbnB1dENoYW5uZWxzXSk7XG4gICAgICAgIHdSZXNoYXBlZCA9IHRyYW5zcG9zZWRXZWlnaHQucmVzaGFwZShbMSwgaW5wdXRDaGFubmVscywgb3V0Q2hhbm5lbHNdKTtcbiAgICAgICAgbWF0bXVsT3V0cHV0U2hhcGUgPSBbYmF0Y2gsIG91dEhlaWdodCAqIG91dFdpZHRoLCBvdXRDaGFubmVsc107XG4gICAgICB9XG4gICAgICBtYXRtdWxJbnB1dHMucHVzaCh4UmVzaGFwZWQpO1xuICAgICAgbWF0bXVsSW5wdXRzLnB1c2god1Jlc2hhcGVkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgeFJlc2hhcGVkID0gaW5wdXRzWzBdLnJlc2hhcGUoW2JhdGNoLCBpbnB1dENoYW5uZWxzLCBpbnB1dEhlaWdodCAqIGlucHV0V2lkdGhdKTtcbiAgICAgIHdSZXNoYXBlZCA9IGlucHV0c1sxXS5yZXNoYXBlKFsxLCBvdXRDaGFubmVscywgaW5wdXRDaGFubmVsc10pO1xuICAgICAgbWF0bXVsT3V0cHV0U2hhcGUgPSBbYmF0Y2gsIG91dENoYW5uZWxzLCBvdXRIZWlnaHQgKiBvdXRXaWR0aF07XG4gICAgICBtYXRtdWxJbnB1dHMucHVzaCh3UmVzaGFwZWQpO1xuICAgICAgbWF0bXVsSW5wdXRzLnB1c2goeFJlc2hhcGVkKTtcbiAgICB9XG4gICAgaWYgKGhhc0JpYXMpIHtcbiAgICAgIG1hdG11bElucHV0cy5wdXNoKGlucHV0c1syXSk7XG4gICAgfVxuICAgIGNvbnN0IE4gPSBtYXRtdWxPdXRwdXRTaGFwZVsyXTtcbiAgICBjb25zdCBLID0gbWF0bXVsSW5wdXRzWzBdLmRpbXNbbWF0bXVsSW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMV07XG4gICAgLy8gVHVuZSB0aGUgdGhyZXNob2xkLlxuICAgIGlmIChOIDwgOCAmJiBLIDwgOCkge1xuICAgICAgY29udGV4dC5jb21wdXRlKFxuICAgICAgICBjcmVhdGVOYWl2ZU1hdG11bFByb2dyYW1JbmZvKFxuICAgICAgICAgIG1hdG11bElucHV0cyxcbiAgICAgICAgICBhdHRyaWJ1dGVzLFxuICAgICAgICAgIG91dHB1dFNoYXBlLFxuICAgICAgICAgIG1hdG11bE91dHB1dFNoYXBlLFxuICAgICAgICAgIGlzQ2hhbm5lbHNMYXN0LFxuICAgICAgICAgIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uLFxuICAgICAgICApLFxuICAgICAgICB7IGlucHV0czogbWF0bXVsSW5wdXRzIH0sXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZXh0LmNvbXB1dGUoXG4gICAgICAgIGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvKFxuICAgICAgICAgIG1hdG11bElucHV0cyxcbiAgICAgICAgICBhdHRyaWJ1dGVzLFxuICAgICAgICAgIG91dHB1dFNoYXBlLFxuICAgICAgICAgIG1hdG11bE91dHB1dFNoYXBlLFxuICAgICAgICAgIGlzQ2hhbm5lbHNMYXN0LFxuICAgICAgICAgIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uLFxuICAgICAgICApLFxuICAgICAgICB7IGlucHV0czogbWF0bXVsSW5wdXRzIH0sXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBUT0RPOiBpbXBsZW1lbnQgY29udjJkV2l0aEltMkNvbCgpXG5cbiAgY29uc3Qgc2VxdWVudGlhbEFjY2Vzc0J5VGhyZWFkcyA9IC8qIGJhY2tlbmQuYWRhcHRlckluZm8uaXNJbnRlbCgpICovIHRydWU7XG5cbiAgLy8gU1RFUC4xOiB0cmFuc3Bvc2Ugd2VpZ2h0XG4gIGNvbnN0IHRyYW5zcG9zZWRXZWlnaHQgPVxuICAgIChjb250ZXh0Lmtlcm5lbEN1c3RvbURhdGEud1QgYXMgVGVuc29yVmlldyB8IHVuZGVmaW5lZCkgPz9cbiAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5wdXRzWzFdLCB3ZWlnaHRUcmFuc3Bvc2VBdHRyaWJ1dGUpLCB7XG4gICAgICBpbnB1dHM6IFsxXSxcbiAgICAgIG91dHB1dHM6IFthdHRyaWJ1dGVzLndJc0NvbnN0ID8gLTIgOiAtMV0sXG4gICAgfSlbMF07XG4gIGlmIChhdHRyaWJ1dGVzLndJc0NvbnN0ICYmICFjb250ZXh0Lmtlcm5lbEN1c3RvbURhdGEud1QpIHtcbiAgICBjb250ZXh0Lmtlcm5lbEN1c3RvbURhdGEud1QgPSB0cmFuc3Bvc2VkV2VpZ2h0O1xuICB9XG5cbiAgLy8gU1RFUC4yOiBwcmVwYXJlIHJlc2hhcGVkIGlucHV0c1xuICBjb25zdCBjb252SW5wdXRzID0gW2lucHV0c1swXSwgdHJhbnNwb3NlZFdlaWdodF07XG4gIGlmIChoYXNCaWFzKSB7XG4gICAgY29udklucHV0cy5wdXNoKGlucHV0c1syXSk7XG4gIH1cblxuICAvLyBTVEVQLjM6IGNvbXB1dGUgbWF0bXVsXG4gIGNvbnN0IGRpbUFPdXRlciA9IGlzQ2hhbm5lbHNMYXN0ID8gb3V0SGVpZ2h0ICogb3V0V2lkdGggOiBvdXRDaGFubmVscztcbiAgY29uc3QgZGltQk91dGVyID0gaXNDaGFubmVsc0xhc3QgPyBvdXRDaGFubmVscyA6IG91dEhlaWdodCAqIG91dFdpZHRoO1xuICBjb25zdCBkaW1Jbm5lciA9IHdlaWdodEhlaWdodCAqIHdlaWdodFdpZHRoICogaW5wdXRDaGFubmVscztcbiAgY29udGV4dC5jb21wdXRlKFxuICAgIGNyZWF0ZUNvbnYyRE1hdE11bFByb2dyYW1JbmZvKFxuICAgICAgY29udklucHV0cyxcbiAgICAgIGF0dHJpYnV0ZXMsXG4gICAgICBvdXRwdXRTaGFwZSxcbiAgICAgIGRpbUFPdXRlcixcbiAgICAgIGRpbUJPdXRlcixcbiAgICAgIGRpbUlubmVyLFxuICAgICAgaGFzQmlhcyxcbiAgICAgIHNlcXVlbnRpYWxBY2Nlc3NCeVRocmVhZHMsXG4gICAgICBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbixcbiAgICApLFxuICAgIHsgaW5wdXRzOiBjb252SW5wdXRzIH0sXG4gICk7XG59O1xuXG5jb25zdCBjb252MWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIC8vIGV4dGVuZCB0aGUgaW5wdXQgdG8gMkQgYnkgYWRkaW5nIEggZGltZW5zaW9uXG4gIGNvbnN0IGlzQ2hhbm5lbExhc3QgPSBhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnO1xuICBjb25zdCBpbnB1dHMgPSBbXG4gICAgY29udGV4dC5pbnB1dHNbMF0ucmVzaGFwZShcbiAgICAgIGlzQ2hhbm5lbExhc3RcbiAgICAgICAgPyAvLyBbTiwgVywgQ10gLT4gW04sIEg9MSwgVywgQ11cbiAgICAgICAgICBbY29udGV4dC5pbnB1dHNbMF0uZGltc1swXSwgMSwgY29udGV4dC5pbnB1dHNbMF0uZGltc1sxXSwgY29udGV4dC5pbnB1dHNbMF0uZGltc1syXV1cbiAgICAgICAgOiAvLyBbTiwgQywgV10gLT4gW04sIEMsIEg9MSwgV11cbiAgICAgICAgICBbY29udGV4dC5pbnB1dHNbMF0uZGltc1swXSwgY29udGV4dC5pbnB1dHNbMF0uZGltc1sxXSwgMSwgY29udGV4dC5pbnB1dHNbMF0uZGltc1syXV0sXG4gICAgKSxcbiAgICAvL1tGSUxURVJfT1VUX0NIQU5ORUwsIEZJTFRFUl9JTl9DSEFOTkVMLCBrV10gLT4gW0ZJTFRFUl9PVVRfQ0hBTk5FTCwgRklMVEVSX0lOX0NIQU5ORUwsIGtIPTEsIGtXXVxuICAgIGNvbnRleHQuaW5wdXRzWzFdLnJlc2hhcGUoW2NvbnRleHQuaW5wdXRzWzFdLmRpbXNbMF0sIGNvbnRleHQuaW5wdXRzWzFdLmRpbXNbMV0sIDEsIGNvbnRleHQuaW5wdXRzWzFdLmRpbXNbMl1dKSxcbiAgXTtcbiAgaWYgKGNvbnRleHQuaW5wdXRzLmxlbmd0aCA9PT0gMykge1xuICAgIGlucHV0cy5wdXNoKGNvbnRleHQuaW5wdXRzWzJdKTtcbiAgfVxuICBjb25zdCBwYWRzID0gWzAsIGF0dHJpYnV0ZXMucGFkc1swXSwgMCwgYXR0cmlidXRlcy5wYWRzWzFdXTtcbiAgY29uc3Qgc3RyaWRlcyA9IFsxXS5jb25jYXQoYXR0cmlidXRlcy5zdHJpZGVzKTtcbiAgY29uc3QgZGlsYXRpb25zID0gWzFdLmNvbmNhdChhdHRyaWJ1dGVzLmRpbGF0aW9ucyk7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gWzFdLmNvbmNhdChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgY29uc3QgYWRqdXN0ZWRBdHRyaWJ1dGVzID0gZ2V0QWRqdXN0ZWRDb252QXR0cmlidXRlcyhcbiAgICB7IC4uLmF0dHJpYnV0ZXMsIHBhZHMsIHN0cmlkZXMsIGRpbGF0aW9ucywga2VybmVsU2hhcGUgfSxcbiAgICBpbnB1dHMsXG4gICk7XG4gIGNvbnYyZChjb250ZXh0LCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcywgKG91dHB1dFNoYXBlKSA9PlxuICAgIGlzQ2hhbm5lbExhc3QgPyBbb3V0cHV0U2hhcGVbMF0sIG91dHB1dFNoYXBlWzJdLCBvdXRwdXRTaGFwZVszXV0gOiBbb3V0cHV0U2hhcGVbMF0sIG91dHB1dFNoYXBlWzFdLCBvdXRwdXRTaGFwZVszXV0sXG4gICk7XG59O1xuXG5jb25zdCBjb252M2QgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBmb3JtYXQgPSBhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnID8gJ2NoYW5uZWxzTGFzdCcgOiAnY2hhbm5lbHNGaXJzdCc7XG4gIGNvbnN0IGFkanVzdGVkQXR0cmlidXRlcyA9IGdldEFkanVzdGVkQ29udkF0dHJpYnV0ZXMoYXR0cmlidXRlcywgaW5wdXRzKTtcbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMuYXV0b1BhZCA9PT0gJ05PVFNFVCcgPyBhdHRyaWJ1dGVzLnBhZHMgOiBhdHRyaWJ1dGVzLmF1dG9QYWQ7XG4gIGNvbnN0IGNvbnZJbmZvID0gY29tcHV0ZUNvbnYzREluZm8oXG4gICAgaW5wdXRzWzBdLmRpbXMgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgICBpbnB1dHNbMV0uZGltcyBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIGF0dHJpYnV0ZXMuc3RyaWRlcyBhcyBudW1iZXIgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sXG4gICAgYXR0cmlidXRlcy5kaWxhdGlvbnMgYXMgbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHBhZHMgYXMgc3RyaW5nIHwgbnVtYmVyW10sXG4gICAgZmFsc2UsXG4gICAgZm9ybWF0LFxuICApO1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAgY3JlYXRlQ29udjNETmFpdmVQcm9ncmFtSW5mbyhcbiAgICAgIGlucHV0cyxcbiAgICAgIGFkanVzdGVkQXR0cmlidXRlcyxcbiAgICAgIGNvbnZJbmZvLm91dFNoYXBlLFxuICAgICAgW2NvbnZJbmZvLmZpbHRlckRlcHRoLCBjb252SW5mby5maWx0ZXJIZWlnaHQsIGNvbnZJbmZvLmZpbHRlcldpZHRoXSxcbiAgICAgIFtjb252SW5mby5wYWRJbmZvLmZyb250LCBjb252SW5mby5wYWRJbmZvLnRvcCwgY29udkluZm8ucGFkSW5mby5sZWZ0XSxcbiAgICAgIGZvcm1hdCxcbiAgICApLFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbnYgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgaWYgKGNvbnRleHQuaW5wdXRzWzBdLmRpbXMubGVuZ3RoID09PSAzKSB7XG4gICAgY29udjFkKGNvbnRleHQsIGF0dHJpYnV0ZXMpO1xuICB9IGVsc2UgaWYgKGNvbnRleHQuaW5wdXRzWzBdLmRpbXMubGVuZ3RoID09PSA1KSB7XG4gICAgY29udjNkKGNvbnRleHQsIGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBhZGp1c3RlZEF0dHJpYnV0ZXMgPSBnZXRBZGp1c3RlZENvbnZBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIGNvbnRleHQuaW5wdXRzKTtcbiAgICBjb252MmQoY29udGV4dCwgY29udGV4dC5pbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyk7XG4gIH1cbn07XG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vLyBzYW1wbGVkIGZyb20gW0B0ZW5zb3JmbG93L3RmanNdIHRmanMtYmFja2VuZC13ZWJncHUvc3JjL2NvbnZfYmFja3Byb3Bfd2ViZ3B1LnRzXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgTE9HX0RFQlVHIH0gZnJvbSAnLi4vLi4vLi4vbG9nJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7IFByb2dyYW1JbmZvLCBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQge1xuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlLFxuICBVbmlmb3Jtc0FycmF5VHlwZSxcbiAgZ2V0TWF4Q29tcG9uZW50cyxcbn0gZnJvbSAnLi4vY29tbW9uJztcbmltcG9ydCB7IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vY29udi10cmFuc3Bvc2UnO1xuXG5leHBvcnQgY29uc3QgY3JlYXRlQ29udlRyYW5zcG9zZTJEUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyxcbiAgc3F1ZWV6ZU91dHB1dFNoYXBlRnVuY3Rpb24/OiAoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKSA9PiBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGF0dHJpYnV0ZXMub3V0cHV0U2hhcGU7XG4gIGNvbnN0IGlzQ2hhbm5lbHNMYXN0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJztcbiAgY29uc3QgZ3JvdXAgPSBhdHRyaWJ1dGVzLmdyb3VwO1xuICBjb25zdCB3U2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3QgaW5wdXRDaGFubmVsc1Blckdyb3VwID0gd1NoYXBlWzJdIC8gZ3JvdXA7XG4gIGNvbnN0IG91dHB1dENoYW5uZWxzUGVyR3JvdXAgPSB3U2hhcGVbM107XG4gIGNvbnN0IGFDb21wb25lbnRzID0gaXNDaGFubmVsc0xhc3QgPyBnZXRNYXhDb21wb25lbnRzKGlucHV0Q2hhbm5lbHNQZXJHcm91cCkgOiAxO1xuICBjb25zdCBwYWNrSW5wdXRBczQgPSBpc0NoYW5uZWxzTGFzdCAmJiBvdXRwdXRDaGFubmVsc1Blckdyb3VwID09PSAxICYmIGlucHV0Q2hhbm5lbHNQZXJHcm91cCA+PSA0O1xuICBjb25zdCBpbnB1dENoYW5uZWxzUGVyR3JvdXBJbnQgPSBwYWNrSW5wdXRBczRcbiAgICA/IE1hdGguZmxvb3IoaW5wdXRDaGFubmVsc1Blckdyb3VwIC8gNCkgKiA0XG4gICAgOiBNYXRoLmZsb29yKGlucHV0Q2hhbm5lbHNQZXJHcm91cCAvIGFDb21wb25lbnRzKSAqIGFDb21wb25lbnRzO1xuICBjb25zdCBpbnB1dENoYW5uZWxzUmVtYWluZGVyID0gaW5wdXRDaGFubmVsc1Blckdyb3VwIC0gaW5wdXRDaGFubmVsc1Blckdyb3VwSW50O1xuICBjb25zdCBjb21wb25lbnRzID0gaXNDaGFubmVsc0xhc3QgPyBnZXRNYXhDb21wb25lbnRzKG91dHB1dENoYW5uZWxzUGVyR3JvdXApIDogMTtcbiAgY29uc3QgYkNvbXBvbmVudHMgPSBpc0NoYW5uZWxzTGFzdCA/IChvdXRwdXRDaGFubmVsc1Blckdyb3VwID09PSAxID8gYUNvbXBvbmVudHMgOiBjb21wb25lbnRzKSA6IDE7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyBjb21wb25lbnRzO1xuICBjb25zdCBkaXNwYXRjaCA9IFtNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0KSwgMSwgMV07XG4gIExPR19ERUJVRygndmVyYm9zZScsICgpID0+IGBbY29udjJkX2JhY2twcm9wX3dlYmdwdV0gZGlzcGF0Y2ggPSAke2Rpc3BhdGNofWApO1xuXG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWydyYW5rJywgJ3JhbmsnXTtcbiAgY29uc3Qgc3RyaWRlcyA9IFthdHRyaWJ1dGVzLnN0cmlkZXNbMF0sIGF0dHJpYnV0ZXMuc3RyaWRlc1sxXV07XG4gIGNvbnN0IGZpbHRlckRpbXMgPSBbYXR0cmlidXRlcy5rZXJuZWxTaGFwZVtpc0NoYW5uZWxzTGFzdCA/IDEgOiAyXSwgYXR0cmlidXRlcy5rZXJuZWxTaGFwZVtpc0NoYW5uZWxzTGFzdCA/IDIgOiAzXV07XG4gIGNvbnN0IGRpbGF0aW9ucyA9IFthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXSwgYXR0cmlidXRlcy5kaWxhdGlvbnNbMV1dO1xuICBjb25zdCBlZmZlY3RpdmVGaWx0ZXJEaW1zID0gW1xuICAgIGZpbHRlckRpbXNbMF0gK1xuICAgICAgKGF0dHJpYnV0ZXMuZGlsYXRpb25zWzBdIDw9IDFcbiAgICAgICAgPyAwXG4gICAgICAgIDogKGF0dHJpYnV0ZXMua2VybmVsU2hhcGVbaXNDaGFubmVsc0xhc3QgPyAxIDogMl0gLSAxKSAqIChhdHRyaWJ1dGVzLmRpbGF0aW9uc1swXSAtIDEpKSxcbiAgICBmaWx0ZXJEaW1zWzFdICtcbiAgICAgIChhdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXSA8PSAxXG4gICAgICAgID8gMFxuICAgICAgICA6IChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2lzQ2hhbm5lbHNMYXN0ID8gMiA6IDNdIC0gMSkgKiAoYXR0cmlidXRlcy5kaWxhdGlvbnNbMV0gLSAxKSksXG4gIF07XG4gIGNvbnN0IHBhZHMgPSBbXG4gICAgZWZmZWN0aXZlRmlsdGVyRGltc1swXSAtIDEgLSBNYXRoLmZsb29yKChhdHRyaWJ1dGVzLnBhZHNbMF0gKyBhdHRyaWJ1dGVzLnBhZHNbMl0pIC8gMiksXG4gICAgZWZmZWN0aXZlRmlsdGVyRGltc1sxXSAtIDEgLSBNYXRoLmZsb29yKChhdHRyaWJ1dGVzLnBhZHNbMV0gKyBhdHRyaWJ1dGVzLnBhZHNbM10pIC8gMiksXG4gIF07XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHN0cmlkZXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZmlsdGVyRGltcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBkaWxhdGlvbnMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZWZmZWN0aXZlRmlsdGVyRGltcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IHBhZHMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogaW5wdXRDaGFubmVsc1Blckdyb3VwSW50IH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGlucHV0Q2hhbm5lbHNQZXJHcm91cCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRDaGFubmVsc1Blckdyb3VwIH0sXG4gICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5kaW1zKSxcbiAgXTtcbiAgaWYgKGhhc0JpYXMpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMl0uZGltcykpO1xuICAgIGlucHV0RGVwZW5kZW5jaWVzLnB1c2goJ3JhbmsnKTtcbiAgfVxuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhvdXRwdXRTaGFwZSkpO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IHVuaWZvcm1zOiBVbmlmb3Jtc0FycmF5VHlwZSA9IFtcbiAgICAgIHsgbmFtZTogJ291dHB1dF9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3N0cmlkZXMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBzdHJpZGVzLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnZmlsdGVyX2RpbXMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBmaWx0ZXJEaW1zLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnZGlsYXRpb25zJywgdHlwZTogJ3UzMicsIGxlbmd0aDogZmlsdGVyRGltcy5sZW5ndGggfSxcbiAgICAgIHsgbmFtZTogJ2VmZmVjdGl2ZV9maWx0ZXJfZGltcycsIHR5cGU6ICd1MzInLCBsZW5ndGg6IGVmZmVjdGl2ZUZpbHRlckRpbXMubGVuZ3RoIH0sXG4gICAgICB7IG5hbWU6ICdwYWRzJywgdHlwZTogJ2kzMicsIGxlbmd0aDogcGFkcy5sZW5ndGggfSxcbiAgICAgIHsgbmFtZTogJ2lucHV0X2NoYW5uZWxzX3Blcl9ncm91cF9pbnQnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnaW5wdXRfY2hhbm5lbHNfcGVyX2dyb3VwJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ291dHB1dF9jaGFubmVsc19wZXJfZ3JvdXAnLCB0eXBlOiAndTMyJyB9LFxuICAgIF07XG4gICAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUoaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgICBjb25zdCByb3dEaW0gPSBpc0NoYW5uZWxzTGFzdCA/IDEgOiAyO1xuICAgIGNvbnN0IGNvbERpbSA9IGlzQ2hhbm5lbHNMYXN0ID8gMiA6IDM7XG4gICAgY29uc3QgY2hhbm5lbERpbSA9IGlzQ2hhbm5lbHNMYXN0ID8gMyA6IDE7XG5cbiAgICBjb25zdCB3ID0gaW5wdXRWYXJpYWJsZSgnVycsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoLCBiQ29tcG9uZW50cyk7XG4gICAgY29uc3QgZHkgPSBpbnB1dFZhcmlhYmxlKCdEeScsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoLCBhQ29tcG9uZW50cyk7XG4gICAgY29uc3QgaW5wdXRWYXJpYWJsZXMgPSBbZHksIHddO1xuICAgIGlmIChoYXNCaWFzKSB7XG4gICAgICBpbnB1dFZhcmlhYmxlcy5wdXNoKGlucHV0VmFyaWFibGUoJ2JpYXMnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIFtvdXRwdXRTaGFwZVtjaGFubmVsRGltXV0ubGVuZ3RoLCBjb21wb25lbnRzKSk7XG4gICAgfVxuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdyZXN1bHQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG5cbiAgICBjb25zdCBjYWxjdWxhdGVSZXN1bHQgPSAoKTogc3RyaW5nID0+IHtcbiAgICAgIGxldCBjYWxjU3RyID0gJyc7XG4gICAgICBpZiAocGFja0lucHV0QXM0KSB7XG4gICAgICAgIGlmIChhQ29tcG9uZW50cyA9PT0gNCkge1xuICAgICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICBsZXQgeFZhbHVlID0gJHtkeS5nZXRCeU9mZnNldCgneF9vZmZzZXQnKX07XG4gICAgICAgIGxldCB3VmFsdWUgPSAke3cuZ2V0QnlPZmZzZXQoJ3dfb2Zmc2V0Jyl9O1xuICAgICAgICBkb3RQcm9kID0gZG90UHJvZCArIGRvdCh4VmFsdWUsIHdWYWx1ZSk7XG4gICAgICAgIHhfb2Zmc2V0ICs9IDF1O1xuICAgICAgICB3X29mZnNldCArPSAxdTtgO1xuICAgICAgICB9IGVsc2UgaWYgKGFDb21wb25lbnRzID09PSAyKSB7XG4gICAgICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgZG90UHJvZCA9IGRvdFByb2QgKyBkb3QodmVjNDwke2RhdGFUeXBlfT4oJHtkeS5nZXRCeU9mZnNldCgneF9vZmZzZXQnKX0sICR7ZHkuZ2V0QnlPZmZzZXQoJ3hfb2Zmc2V0ICsgMXUnKX0pLCB2ZWM0PCR7ZGF0YVR5cGV9Pigke3cuZ2V0QnlPZmZzZXQoJ3dfb2Zmc2V0Jyl9LCAke3cuZ2V0QnlPZmZzZXQoJ3dfb2Zmc2V0ICsgMXUnKX0pKTtcbiAgICAgICAgICB4X29mZnNldCArPSAydTtcbiAgICAgICAgICB3X29mZnNldCArPSAydTtgO1xuICAgICAgICB9IGVsc2UgaWYgKGFDb21wb25lbnRzID09PSAxKSB7XG4gICAgICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgZG90UHJvZCA9IGRvdFByb2QgKyBkb3QodmVjNDwke2RhdGFUeXBlfT4oJHtkeS5nZXRCeU9mZnNldCgneF9vZmZzZXQnKX0sICR7ZHkuZ2V0QnlPZmZzZXQoJ3hfb2Zmc2V0ICsgMXUnKX0sICR7ZHkuZ2V0QnlPZmZzZXQoJ3hfb2Zmc2V0ICsgMnUnKX0sICR7ZHkuZ2V0QnlPZmZzZXQoJ3hfb2Zmc2V0ICsgM3UnKX0pLCB2ZWM0PCR7ZGF0YVR5cGV9Pigke3cuZ2V0QnlPZmZzZXQoJ3dfb2Zmc2V0Jyl9LCAke3cuZ2V0QnlPZmZzZXQoJ3dfb2Zmc2V0ICsgMXUnKX0sICR7dy5nZXRCeU9mZnNldCgnd19vZmZzZXQgKyAydScpfSwgJHt3LmdldEJ5T2Zmc2V0KCd3X29mZnNldCArIDN1Jyl9KSk7XG4gICAgICAgICAgeF9vZmZzZXQgKz0gNHU7XG4gICAgICAgICAgd19vZmZzZXQgKz0gNHU7YDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgICAgICAgICBsZXQgeFZhbHVlID0gJHtcbiAgICAgICAgICAgICAgICAgICAgaXNDaGFubmVsc0xhc3RcbiAgICAgICAgICAgICAgICAgICAgICA/IGR5LmdldEJ5T2Zmc2V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICBgJHtkeS5pbmRpY2VzVG9PZmZzZXQoYCR7ZHkudHlwZS5pbmRpY2VzfShiYXRjaCwgaWR5UiwgaWR5QywgaW5wdXRDaGFubmVsKWApfSAvICR7YUNvbXBvbmVudHN9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICA6IGR5LmdldCgnYmF0Y2gnLCAnaW5wdXRDaGFubmVsJywgJ2lkeVInLCAnaWR5QycpXG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICBgO1xuICAgICAgICBpZiAoYUNvbXBvbmVudHMgPT09IDEpIHtcbiAgICAgICAgICBjYWxjU3RyICs9IGBcbiAgICAgICAgICBsZXQgd19vZmZzZXQgPSAke3cuaW5kaWNlc1RvT2Zmc2V0KGAke3cudHlwZS5pbmRpY2VzfSh1MzIod1JQZXJtKSwgdTMyKHdDUGVybSksIGlucHV0Q2hhbm5lbCwgd091dENoYW5uZWwpYCl9O1xuICAgICAgICAgIGxldCB3VmFsdWUgPSAke3cuZ2V0QnlPZmZzZXQoYHdfb2Zmc2V0IC8gJHtiQ29tcG9uZW50c31gKX07XG4gICAgICAgICAgZG90UHJvZCA9IGRvdFByb2QgKyB4VmFsdWUgKiB3VmFsdWU7YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGFDb21wb25lbnRzOyBjKyspIHtcbiAgICAgICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgICAgbGV0IHdWYWx1ZSR7Y30gPSAke3cuZ2V0QnlPZmZzZXQoYCR7dy5pbmRpY2VzVG9PZmZzZXQoYCR7dy50eXBlLmluZGljZXN9KHUzMih3UlBlcm0pLCB1MzIod0NQZXJtKSwgaW5wdXRDaGFubmVsICsgJHtjfSwgd091dENoYW5uZWwpYCl9IC8gJHtiQ29tcG9uZW50c31gKX07XG4gICAgICAgICAgICBkb3RQcm9kID0gZG90UHJvZCArIHhWYWx1ZVske2N9XSAqIHdWYWx1ZSR7Y307YDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBjYWxjU3RyO1xuICAgIH07XG4gICAgY29uc3QgY2FsY3VsYXRlUmVtYWluZGVyID0gKCk6IHN0cmluZyA9PiB7XG4gICAgICBpZiAoaW5wdXRDaGFubmVsc1JlbWFpbmRlciA9PT0gMCkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG4gICAgICBpZiAoIXBhY2tJbnB1dEFzNCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHBhY2tJbnB1dEFzNCAke3BhY2tJbnB1dEFzNH0gaXMgbm90IHRydWUuYCk7XG4gICAgICB9XG4gICAgICBsZXQgY2FsY1N0ciA9ICcnO1xuICAgICAgaWYgKGFDb21wb25lbnRzID09PSAxKSB7XG4gICAgICAgIGNhbGNTdHIgKz0gJ2RvdFByb2QgPSBkb3RQcm9kJztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dENoYW5uZWxzUmVtYWluZGVyOyBpKyspIHtcbiAgICAgICAgICBjYWxjU3RyICs9IGBcbiAgICAgICAgICAgICsgJHtkeS5nZXRCeU9mZnNldChgeF9vZmZzZXQgKyAke2l9YCl9ICogJHt3LmdldEJ5T2Zmc2V0KGB3X29mZnNldCArICR7aX1gKX1gO1xuICAgICAgICB9XG4gICAgICAgIGNhbGNTdHIgKz0gJzsnO1xuICAgICAgfSBlbHNlIGlmIChhQ29tcG9uZW50cyA9PT0gMikge1xuICAgICAgICBpZiAoaW5wdXRDaGFubmVsc1JlbWFpbmRlciAhPT0gMikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBpbnB1dENoYW5uZWxzUmVtYWluZGVyICR7aW5wdXRDaGFubmVsc1JlbWFpbmRlcn0uYCk7XG4gICAgICAgIH1cbiAgICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgbGV0IHhWYWx1ZSA9ICR7ZHkuZ2V0QnlPZmZzZXQoJ3hfb2Zmc2V0Jyl9O1xuICAgICAgICAgIGxldCB3VmFsdWUgPSAke3cuZ2V0QnlPZmZzZXQoJ3dfb2Zmc2V0Jyl9O1xuICAgICAgICAgIGRvdFByb2QgPSBkb3RQcm9kICsgZG90KHhWYWx1ZSwgd1ZhbHVlKTtgO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNhbGNTdHI7XG4gICAgfTtcbiAgICBjb25zdCBjb2RlU25pcHBldCA9IGBcbiAgICAgICAgICAgIGxldCBvdXRwdXRJbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKGBnbG9iYWxfaWR4ICogJHtjb21wb25lbnRzfWApfTtcbiAgICAgICAgICAgIGxldCBiYXRjaCA9ICR7b3V0cHV0LmluZGljZXNHZXQoJ291dHB1dEluZGljZXMnLCAwKX07XG4gICAgICAgICAgICBsZXQgZDEgPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRJbmRpY2VzJywgY2hhbm5lbERpbSl9O1xuICAgICAgICAgICAgbGV0IHIgPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRJbmRpY2VzJywgcm93RGltKX07XG4gICAgICAgICAgICBsZXQgYyA9ICR7b3V0cHV0LmluZGljZXNHZXQoJ291dHB1dEluZGljZXMnLCBjb2xEaW0pfTtcbiAgICAgICAgICAgIGxldCBkeUNvcm5lciA9IHZlYzI8aTMyPihpMzIociksIGkzMihjKSkgLSB1bmlmb3Jtcy5wYWRzO1xuICAgICAgICAgICAgbGV0IGR5UkNvcm5lciA9IGR5Q29ybmVyLng7XG4gICAgICAgICAgICBsZXQgZHlDQ29ybmVyID0gZHlDb3JuZXIueTtcbiAgICAgICAgICAgIGxldCBncm91cElkID0gZDEgLyB1bmlmb3Jtcy5vdXRwdXRfY2hhbm5lbHNfcGVyX2dyb3VwO1xuICAgICAgICAgICAgbGV0IHdPdXRDaGFubmVsID0gZDEgLSBncm91cElkICogdW5pZm9ybXMub3V0cHV0X2NoYW5uZWxzX3Blcl9ncm91cDtcbiAgICAgICAgICAgIC8vIENvbnZvbHZlIGR5KD8sID8sIGQyKSB3aXRoIHcoOiwgOiwgZDEsIGQyKSB0byBjb21wdXRlIGR4KHhSLCB4QywgZDEpLlxuICAgICAgICAgICAgLy8gPyA9IHRvIGJlIGRldGVybWluZWQuIDogPSBhY3Jvc3MgYWxsIHZhbHVlcyBpbiB0aGF0IGF4aXMuXG4gICAgICAgICAgICB2YXIgZG90UHJvZCA9ICR7b3V0cHV0LnR5cGUudmFsdWV9KDAuMCk7XG4gICAgICAgICAgICB2YXIgd1I6IHUzMiA9IDA7XG4gICAgICAgICAgICBpZiAodW5pZm9ybXMuZGlsYXRpb25zLnggPT0gMSkge1xuICAgICAgICAgICAgICAvLyBNaW5pbXVtIHdSID49IDAgdGhhdCBzYXRpc2ZpZXMgKGR5UkNvcm5lciArIHdSKSAlICh1bmlmb3Jtcy5zdHJpZGVzLngpID09IDBcbiAgICAgICAgICAgICAgd1IgPSB1MzIoKChkeVJDb3JuZXIgKyBpMzIodW5pZm9ybXMuc3RyaWRlcy54KSAtIDEpIC8gaTMyKHVuaWZvcm1zLnN0cmlkZXMueCkpICogaTMyKHVuaWZvcm1zLnN0cmlkZXMueCkgLSBkeVJDb3JuZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICg7IHdSIDwgdW5pZm9ybXMuZWZmZWN0aXZlX2ZpbHRlcl9kaW1zLng7IHdSID0gd1IgKyAxKSB7XG4gICAgICAgICAgICAgIGlmICh3UiAlIHVuaWZvcm1zLmRpbGF0aW9ucy54ICE9IDApIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsZXQgZHlSID0gKCR7ZGF0YVR5cGV9KGR5UkNvcm5lcikgKyAke2RhdGFUeXBlfSh3UikpIC8gJHtkYXRhVHlwZX0odW5pZm9ybXMuc3RyaWRlc1swXSk7XG4gICAgICAgICAgICAgIGxldCB3UlBlcm0gPSB1bmlmb3Jtcy5maWx0ZXJfZGltcy54IC0gMSAtIHdSIC8gdW5pZm9ybXMuZGlsYXRpb25zLng7XG4gICAgICAgICAgICAgIGlmIChkeVIgPCAwLjAgfHwgZHlSID49ICR7ZGF0YVR5cGV9KHVuaWZvcm1zLkR5X3NoYXBlWyR7cm93RGltfV0pIHx8IGZyYWN0KGR5UikgPiAwLjAgfHxcbiAgICAgICAgICAgICAgICAgIHdSUGVybSA8IDApIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsZXQgaWR5UjogdTMyID0gdTMyKGR5Uik7XG4gICAgICAgICAgICAgIHZhciB3QzogdTMyID0gMDtcbiAgICAgICAgICAgICAgaWYgKHVuaWZvcm1zLmRpbGF0aW9ucy55ID09IDEpIHtcbiAgICAgICAgICAgICAgICAvLyBNaW5pbXVtIHdDID49IDAgdGhhdCBzYXRpc2ZpZXMgKGR5Q0Nvcm5lciArIHdDKSAlICh1bmlmb3Jtcy5zdHJpZGVzLnkpID09IDBcbiAgICAgICAgICAgICAgICB3QyA9IHUzMigoKGR5Q0Nvcm5lciArIGkzMih1bmlmb3Jtcy5zdHJpZGVzLnkpIC0gMSkgLyBpMzIodW5pZm9ybXMuc3RyaWRlcy55KSkgKiBpMzIodW5pZm9ybXMuc3RyaWRlcy55KSAtIGR5Q0Nvcm5lcik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZm9yICg7IHdDIDwgdW5pZm9ybXMuZWZmZWN0aXZlX2ZpbHRlcl9kaW1zLnk7IHdDID0gd0MgKyAxKSB7XG4gICAgICAgICAgICAgICAgaWYgKHdDICUgdW5pZm9ybXMuZGlsYXRpb25zLnkgIT0gMCkge1xuICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBkeUMgPSAoJHtkYXRhVHlwZX0oZHlDQ29ybmVyKSArICR7ZGF0YVR5cGV9KHdDKSkgLyAke2RhdGFUeXBlfSh1bmlmb3Jtcy5zdHJpZGVzLnkpO1xuICAgICAgICAgICAgICAgIGxldCB3Q1Blcm0gPSB1bmlmb3Jtcy5maWx0ZXJfZGltcy55IC0gMSAtIHdDIC8gdW5pZm9ybXMuZGlsYXRpb25zLnk7XG4gICAgICAgICAgICAgICAgaWYgKGR5QyA8IDAuMCB8fCBkeUMgPj0gJHtkYXRhVHlwZX0odW5pZm9ybXMuRHlfc2hhcGVbJHtjb2xEaW19XSkgfHxcbiAgICAgICAgICAgICAgICAgICAgZnJhY3QoZHlDKSA+IDAuMCB8fCB3Q1Blcm0gPCAwKSB7XG4gICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGlkeUM6IHUzMiA9IHUzMihkeUMpO1xuICAgICAgICAgICAgICAgIHZhciBpbnB1dENoYW5uZWwgPSBncm91cElkICogdW5pZm9ybXMuaW5wdXRfY2hhbm5lbHNfcGVyX2dyb3VwO1xuICAgICAgICAgICAgICAgICR7XG4gICAgICAgICAgICAgICAgICBwYWNrSW5wdXRBczRcbiAgICAgICAgICAgICAgICAgICAgPyBgXG4gICAgICAgICAgICAgICAgdmFyIHhfb2Zmc2V0ID0gJHtkeS5pbmRpY2VzVG9PZmZzZXQoYCR7ZHkudHlwZS5pbmRpY2VzfShiYXRjaCwgaWR5UiwgaWR5QywgaW5wdXRDaGFubmVsKWApfSAvICR7YUNvbXBvbmVudHN9O1xuICAgICAgICAgICAgICAgIHZhciB3X29mZnNldCA9ICR7dy5pbmRpY2VzVG9PZmZzZXQoYCR7dy50eXBlLmluZGljZXN9KHdSUGVybSwgd0NQZXJtLCBpbnB1dENoYW5uZWwsIHdPdXRDaGFubmVsKWApfSAvICR7YkNvbXBvbmVudHN9O1xuICAgICAgICAgICAgICAgICAgYFxuICAgICAgICAgICAgICAgICAgICA6ICcnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGQyOiB1MzIgPSAwOyBkMiA8IHVuaWZvcm1zLmlucHV0X2NoYW5uZWxzX3Blcl9ncm91cF9pbnQ7IGQyID0gZDIgKyAke3BhY2tJbnB1dEFzNCA/IDQgOiBhQ29tcG9uZW50c30pIHtcbiAgICAgICAgICAgICAgICAgICR7Y2FsY3VsYXRlUmVzdWx0KCl9XG4gICAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWwgPSBpbnB1dENoYW5uZWwgKyAke3BhY2tJbnB1dEFzNCA/IDQgOiBhQ29tcG9uZW50c307XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICR7Y2FsY3VsYXRlUmVtYWluZGVyKCl9XG4gICAgICAgICAgICAgICAgd0MgPSB3QyArIHVuaWZvcm1zLnN0cmlkZXMueSAtIDE7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgd1IgPSB3UiArIHVuaWZvcm1zLnN0cmlkZXNbMF0gLSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHZhbHVlID0gZG90UHJvZCR7aGFzQmlhcyA/IGAgKyBiaWFzW2QxIC8gJHtjb21wb25lbnRzfV1gIDogJyd9O1xuICAgICAgICAgICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAndmFsdWUnKX07XG4gICAgICAgICAgYDtcblxuICAgIHJldHVybiBgXG4gICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcmlhYmxlcywgb3V0cHV0KX1cbiAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX07XG4gICAgJHtjb2RlU25pcHBldH19YDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdDb252VHJhbnNwb3NlMkQnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2FDb21wb25lbnRzfSR7YkNvbXBvbmVudHN9JHtjb21wb25lbnRzfSR7cGFja0lucHV0QXM0fSR7aW5wdXRDaGFubmVsc1JlbWFpbmRlcn1gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXMsXG4gICAgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBkaXNwYXRjaFswXSwgeTogZGlzcGF0Y2hbMV0sIHo6IGRpc3BhdGNoWzJdIH0sXG4gICAgICBvdXRwdXRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBkaW1zOiBzcXVlZXplT3V0cHV0U2hhcGVGdW5jdGlvbiA/IHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uKG91dHB1dFNoYXBlKSA6IG91dHB1dFNoYXBlLFxuICAgICAgICAgIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlQ29udlRyYW5zcG9zZTJEUHJvZ3JhbUluZm8gfSBmcm9tICcuLzNyZC1wYXJ0eS9jb252X2JhY2twcm9wX3dlYmdwdSc7XG5pbXBvcnQgeyBDb252QXR0cmlidXRlcyB9IGZyb20gJy4vY29udic7XG5pbXBvcnQgeyBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHsgY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8gfSBmcm9tICcuL3RyYW5zcG9zZSc7XG5cbmNvbnN0IGNvbXB1dGVUb3RhbFBhZCA9IChcbiAgaW5EaW06IG51bWJlcixcbiAgc3RyaWRlOiBudW1iZXIsXG4gIGFkajogbnVtYmVyLFxuICBrZXJuZWw6IG51bWJlcixcbiAgZGlsYXRpb246IG51bWJlcixcbiAgb3V0U2l6ZTogbnVtYmVyLFxuKSA9PiAoaW5EaW0gLSAxKSAqIHN0cmlkZSArIGFkaiArIChrZXJuZWwgLSAxKSAqIGRpbGF0aW9uICsgMSAtIG91dFNpemU7XG5cbmNvbnN0IGRpc3RyaWJ1dGVQYWRkaW5nID0gKHRvdGFsUGFkOiBudW1iZXIsIGF1dG9QYWQ6IHN0cmluZywgcGFkczogbnVtYmVyW10sIGhlYWQ6IG51bWJlciwgdGFpbDogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IHNtYWxsUGFkID0gTWF0aC5mbG9vcih0b3RhbFBhZCAvIDIpO1xuICBpZiAoYXV0b1BhZCA9PT0gJ1NBTUVfVVBQRVInKSB7XG4gICAgcGFkc1toZWFkXSA9IHNtYWxsUGFkO1xuICAgIHBhZHNbdGFpbF0gPSB0b3RhbFBhZCAtIHNtYWxsUGFkO1xuICB9IGVsc2UgaWYgKGF1dG9QYWQgPT09ICdTQU1FX0xPV0VSJykge1xuICAgIHBhZHNbaGVhZF0gPSB0b3RhbFBhZCAtIHNtYWxsUGFkO1xuICAgIHBhZHNbdGFpbF0gPSBzbWFsbFBhZDtcbiAgfVxufTtcblxuY29uc3QgY2FsY3VsYXRlT3V0cHV0U2hhcGVBbmRQYWRzID0gKFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdXRvUGFkOiBzdHJpbmcsXG4gIGdyb3VwOiBudW1iZXIsXG4gIHBhZHM6IG51bWJlcltdLFxuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgaXNDaGFubmVsTGFzdDogYm9vbGVhbixcbiAgb3V0cHV0UGFkZGluZzogbnVtYmVyW10sXG4gIG91dHB1dFNoYXBlOiBudW1iZXJbXSxcbikgPT4ge1xuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0U2hhcGUubGVuZ3RoIC0gMjtcbiAgY29uc3QgdXBkYXRlT3V0cHV0U2hhcGUgPSBvdXRwdXRTaGFwZS5sZW5ndGggPT09IDA7XG4gIGlmIChvdXRwdXRQYWRkaW5nLmxlbmd0aCA8IHNwYXRpYWxSYW5rKSB7XG4gICAgb3V0cHV0UGFkZGluZy5wdXNoKC4uLkFycmF5KHNwYXRpYWxSYW5rIC0gb3V0cHV0UGFkZGluZy5sZW5ndGgpLmZpbGwoMCkpO1xuICB9XG4gIGNvbnN0IGJhdGNoU2l6ZSA9IGlucHV0U2hhcGVbMF07XG4gIGNvbnN0IG91dENoYW5uZWxzID0ga2VybmVsU2hhcGVbaXNDaGFubmVsTGFzdCA/IDMgOiAxXSAqIGdyb3VwO1xuICBmb3IgKGxldCBpID0gMCwgaiA9IGlucHV0U2hhcGUubGVuZ3RoIC0gc3BhdGlhbFJhbmsgLSAoaXNDaGFubmVsTGFzdCA/IDEgOiAwKTsgaSA8IHNwYXRpYWxSYW5rOyArK2ksICsraikge1xuICAgIGNvbnN0IGluU2l6ZSA9IGlucHV0U2hhcGVbal07XG4gICAgY29uc3Qgb3V0U2l6ZSA9IHVwZGF0ZU91dHB1dFNoYXBlID8gaW5TaXplICogc3RyaWRlc1tpXSA6IG91dHB1dFNoYXBlW2ldO1xuICAgIGNvbnN0IHRvdGFsUGFkID0gY29tcHV0ZVRvdGFsUGFkKGluU2l6ZSwgc3RyaWRlc1tpXSwgcGFkc1tpXSwga2VybmVsU2hhcGVbal0sIGRpbGF0aW9uc1tpXSwgb3V0U2l6ZSk7XG4gICAgZGlzdHJpYnV0ZVBhZGRpbmcodG90YWxQYWQsIGF1dG9QYWQsIHBhZHMsIGksIGkgKyBzcGF0aWFsUmFuayk7XG4gICAgaWYgKHVwZGF0ZU91dHB1dFNoYXBlKSB7XG4gICAgICBvdXRwdXRTaGFwZS5wdXNoKFxuICAgICAgICBzdHJpZGVzW2ldICogKGluU2l6ZSAtIDEpICtcbiAgICAgICAgICBvdXRwdXRQYWRkaW5nW2ldICtcbiAgICAgICAgICAoa2VybmVsU2hhcGVbal0gLSAxKSAqIGRpbGF0aW9uc1tpXSArXG4gICAgICAgICAgMSAtXG4gICAgICAgICAgcGFkc1tpXSAtXG4gICAgICAgICAgcGFkc1tpICsgc3BhdGlhbFJhbmtdLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgb3V0cHV0U2hhcGUuc3BsaWNlKDAsIDAsIGJhdGNoU2l6ZSk7XG4gIG91dHB1dFNoYXBlLnNwbGljZShpc0NoYW5uZWxMYXN0ID8gMyA6IDEsIDAsIG91dENoYW5uZWxzKTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgZXh0ZW5kcyBDb252QXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IG91dHB1dFBhZGRpbmc6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmNvbnN0IGdldEFkanVzdGVkQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgPSA8VCBleHRlbmRzIENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPihcbiAgYXR0cmlidXRlczogVCxcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4pOiBUID0+IHtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBvcCwgaW5mZXIgaXQgZnJvbSB0aGUgd2VpZ2h0IHRlbnNvciBkaW1zXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMCB8fCBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIsIDEpID09PSAwKSB7XG4gICAga2VybmVsU2hhcGUubGVuZ3RoID0gMDtcbiAgICBmb3IgKGxldCBpID0gMjsgaSA8IGlucHV0c1sxXS5kaW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0c1sxXS5kaW1zW2ldKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgaXNDaGFubmVsc0xhc3QgPSBhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnO1xuICBrZXJuZWxTaGFwZS5zcGxpY2UoMCwgMCwgaW5wdXRzWzFdLmRpbXNbMF0pO1xuICBrZXJuZWxTaGFwZS5zcGxpY2UoaXNDaGFubmVsc0xhc3QgPyAzIDogMSwgMCwgaW5wdXRzWzFdLmRpbXNbMV0pO1xuXG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLnNsaWNlKCk7XG4gIGNvbnN0IG91dHB1dFBhZGRpbmcgPSBhdHRyaWJ1dGVzLm91dHB1dFBhZGRpbmcuc2xpY2UoKTtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBsZXQgZGlsYXRpb25zID0gYXR0cmlidXRlcy5kaWxhdGlvbnMuc2xpY2UoKTtcbiAgaWYgKGRpbGF0aW9ucy5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKSA9PT0gMCkge1xuICAgIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMjtcbiAgICBkaWxhdGlvbnMgPSBuZXcgQXJyYXkoc3BhdGlhbFJhbmspLmZpbGwoMSk7XG4gIH1cbiAgbGV0IHN0cmlkZXMgPSBhdHRyaWJ1dGVzLnN0cmlkZXMuc2xpY2UoKTtcbiAgaWYgKHN0cmlkZXMucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCkgPT09IDApIHtcbiAgICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDI7XG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShzcGF0aWFsUmFuaykuZmlsbCgxKTtcbiAgfVxuICAvLyBJZiBvdXRwdXRTaGFwZSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgb3AsIGluZmVyIGl0IGZyb20gdGhlIHBhcmFtZXRlcnNcbiAgLy8gU2ltaWxhcmx5LCBhdXRvbWF0aWNhbGx5IGluZmVyIHBhZHMgaWYgbm90IHNwZWNpZmllZFxuICBjYWxjdWxhdGVPdXRwdXRTaGFwZUFuZFBhZHMoXG4gICAgaW5wdXRTaGFwZSxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBkaWxhdGlvbnMsXG4gICAgYXR0cmlidXRlcy5hdXRvUGFkLFxuICAgIGF0dHJpYnV0ZXMuZ3JvdXAsXG4gICAgcGFkcyxcbiAgICBzdHJpZGVzLFxuICAgIGlzQ2hhbm5lbHNMYXN0LFxuICAgIG91dHB1dFBhZGRpbmcsXG4gICAgb3V0cHV0U2hhcGUsXG4gICk7XG5cbiAgLy8gYWx3YXlzIHJldHVybiBhIG5ldyBvYmplY3Qgc28gZG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBhdHRyaWJ1dGVzXG4gIGNvbnN0IG5ld0F0dHJpYnV0ZXM6IFQgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKTtcbiAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBwYWRzLCBvdXRwdXRQYWRkaW5nLCBvdXRwdXRTaGFwZSwgZGlsYXRpb25zLCBzdHJpZGVzIH0pO1xuICByZXR1cm4gbmV3QXR0cmlidXRlcztcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhY3RpdmF0aW9uQXR0cmlidXRlcyA9IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTtcbiAgLy8gVE9ETyA6IE1ha2UgdGhpcyBnZW5lcmljIGVub3VnaCB0byBjb21wdXRlIGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBjb25zdCBmb3JtYXQgPSBhdHRyaWJ1dGVzLmZvcm1hdCBhcyAnTkhXQycgfCAnTkNIVyc7XG4gIGNvbnN0IGF1dG9QYWQgPSBbJ05PVFNFVCcsICdWQUxJRCcsICdTQU1FX1VQUEVSJywgJ1NBTUVfTE9XRVInXVtcbiAgICB0eXBlb2YgYXR0cmlidXRlcy5hdXRvUGFkID09ICd1bmRlZmluZWQnID8gMCA6IChhdHRyaWJ1dGVzLmF1dG9QYWQgYXMgbnVtYmVyKVxuICBdO1xuICBjb25zdCBkaWxhdGlvbnMgPSBhdHRyaWJ1dGVzLmRpbGF0aW9ucyBhcyBbbnVtYmVyLCBudW1iZXJdO1xuICBjb25zdCBncm91cCA9IGF0dHJpYnV0ZXMuZ3JvdXAgYXMgbnVtYmVyO1xuICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGUgYXMgW251bWJlciwgbnVtYmVyXTtcbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcyBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgY29uc3Qgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuc3RyaWRlcyBhcyBbbnVtYmVyLCBudW1iZXJdO1xuICBjb25zdCB3SXNDb25zdCA9IChhdHRyaWJ1dGVzLndJc0NvbnN0IGFzICgpID0+IGJvb2xlYW4pKCk7XG4gIGNvbnN0IG91dHB1dFBhZGRpbmcgPSBhdHRyaWJ1dGVzLm91dHB1dFBhZGRpbmcgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gYXR0cmlidXRlcy5vdXRwdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdO1xuICByZXR1cm4ge1xuICAgIGF1dG9QYWQsXG4gICAgZm9ybWF0LFxuICAgIGRpbGF0aW9ucyxcbiAgICBncm91cCxcbiAgICBrZXJuZWxTaGFwZSxcbiAgICBvdXRwdXRQYWRkaW5nLFxuICAgIG91dHB1dFNoYXBlLFxuICAgIHBhZHMsXG4gICAgc3RyaWRlcyxcbiAgICB3SXNDb25zdCxcbiAgICAuLi5hY3RpdmF0aW9uQXR0cmlidXRlcyxcbiAgICBjYWNoZUtleTogYCR7YXR0cmlidXRlcy5mb3JtYXR9OyR7YWN0aXZhdGlvbkF0dHJpYnV0ZXMuYWN0aXZhdGlvbn07YCxcbiAgfTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLCBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICAvLyBSZWZlciB0byB0aGUgYmVsb3cgbGluayBmb3IgYWxsIGlucHV0IGNoZWNrc1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL09wZXJhdG9ycy5tZCNDb252VHJhbnNwb3NlXG4gIGlmICghaW5wdXRzIHx8IChpbnB1dHMubGVuZ3RoICE9PSAyICYmIGlucHV0cy5sZW5ndGggIT09IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IHJlcXVpcmVzIDIgb3IgMyBpbnB1dHMnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQgJiYgaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSAzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgb25seSBzdXBwb3J0IDItZGltZW5zaW9uYWwgY29udicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdmaWx0ZXIgZG9lcyBub3QgaGF2ZSBzYW1lIGRpbWVuc2lvbiBhcyBpbnB1dCcpO1xuICB9XG5cbiAgLy8gRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTFxuICBjb25zdCBkYXRhQ2hhbm5lbCA9IGlucHV0c1swXS5kaW1zW2F0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQycgPyBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAxIDogMV07XG4gIGNvbnN0IGZpbHRlckluQ2hhbm5lbCA9IGlucHV0c1sxXS5kaW1zWzBdO1xuICBpZiAoZGF0YUNoYW5uZWwgIT09IGZpbHRlckluQ2hhbm5lbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTCcpO1xuICB9XG5cbiAgY29uc3QgZmVhdHVyZU1hcHMgPSBpbnB1dHNbMV0uZGltc1sxXSAqIGF0dHJpYnV0ZXMuZ3JvdXA7XG5cbiAgLy8gaWYgYmlhcyBpcyBwcm92aWRlZCBpdCBzaG91bGQgYmUgMUQgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgZmVhdHVyZSBtYXBzXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIChpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgfHwgaW5wdXRzWzJdLmRpbXNbMF0gIT09IGZlYXR1cmVNYXBzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBiaWFzJyk7XG4gIH1cblxuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDI7XG4gIGNvbnN0IGRpbGF0aW9uc1NldCA9IGF0dHJpYnV0ZXMuZGlsYXRpb25zLnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApID4gMDtcbiAgLy8gd3JvbmcgZGlsYXRpb25zIGRpbWVuc2lvblxuICBpZiAoZGlsYXRpb25zU2V0ICYmIGF0dHJpYnV0ZXMuZGlsYXRpb25zLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRpbGF0aW9ucyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICBjb25zdCBzdHJpZGVzU2V0ID0gYXR0cmlidXRlcy5zdHJpZGVzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApID4gMDtcbiAgLy8gV3Jvbmcgc3RyaWRlcyBkaW1lbnNpb25cbiAgaWYgKHN0cmlkZXNTZXQgJiYgYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHN0cmlkZXMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3JvbmcgcGFkcyBkaW1lbnNpb25cbiAgY29uc3QgcGFkc1NldCA9IGF0dHJpYnV0ZXMucGFkcy5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKSA+IDA7XG4gIGlmIChwYWRzU2V0ICYmIGF0dHJpYnV0ZXMucGFkcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rICogMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgcGFkcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFuayAqIDJ9RGApO1xuICB9XG5cbiAgLy8gV3Jvbmcgb3V0cHV0IHBhZGRpbmcgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLm91dHB1dFBhZGRpbmcubGVuZ3RoICE9PSBzcGF0aWFsUmFuayAmJiBhdHRyaWJ1dGVzLm91dHB1dFBhZGRpbmcubGVuZ3RoICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXRfcGFkZGluZyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBzcGVjaWZpZWQsIGl0J3MgZGF0YSBsZW5ndGggbXVzdCBiZSAyIGxlc3MgdGhhbiBkaW1zIGxlbmd0aCBvZiB0aGUgd2VpZ2h0cyB0ZW5zb3JcbiAgLy8gKHRoZSBmaXJzdCAyIGRpbXMgYXJlIGJhdGNoX3NpemUgYW5kIGNoYW5uZWxzKVxuICBjb25zdCBrZXJuZWxTaGFwZVNldCA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCkgPiAwO1xuICBpZiAoXG4gICAga2VybmVsU2hhcGVTZXQgJiZcbiAgICBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gMCAmJlxuICAgIGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBrZXJuZWwgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIGFzIHdpdGgga2VybmVsU2hhcGUsIG11c3QgaGF2ZSBzYW1lIG51bWJlciBvZiBzcGF0aWFsIGRpbXMgYXMgaW5wdXRcbiAgaWYgKGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUubGVuZ3RoICE9PSAwICYmIGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIG91dHB1dCBzaGFwZScpO1xuICB9XG59O1xuXG5jb25zdCBjb252VHJhbnNwb3NlMmQgPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMsXG4gIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uPzogKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSkgPT4gbnVtYmVyW10sXG4pOiB2b2lkID0+IHtcbiAgLy8gU1RFUC4xOiB0cmFuc3Bvc2Ugd2VpZ2h0XG4gIGNvbnN0IHRyYW5zcG9zZWRXZWlnaHQgPVxuICAgIChjb250ZXh0Lmtlcm5lbEN1c3RvbURhdGEud1QgYXMgVGVuc29yVmlldyB8IHVuZGVmaW5lZCkgPz9cbiAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5wdXRzWzFdLCBbMiwgMywgMCwgMV0pLCB7XG4gICAgICBpbnB1dHM6IFsxXSxcbiAgICAgIG91dHB1dHM6IFthdHRyaWJ1dGVzLndJc0NvbnN0ID8gLTIgOiAtMV0sXG4gICAgfSlbMF07XG4gIGlmIChhdHRyaWJ1dGVzLndJc0NvbnN0ICYmICFjb250ZXh0Lmtlcm5lbEN1c3RvbURhdGEud1QpIHtcbiAgICBjb250ZXh0Lmtlcm5lbEN1c3RvbURhdGEud1QgPSB0cmFuc3Bvc2VkV2VpZ2h0O1xuICB9XG5cbiAgLy8gU1RFUC4yOiBwcmVwYXJlIHJlc2hhcGVkIGlucHV0c1xuICBjb25zdCBjb252VHJhbnNwb3NlSW5wdXRzID0gW2lucHV0c1swXSwgdHJhbnNwb3NlZFdlaWdodF07XG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzKSB7XG4gICAgY29udlRyYW5zcG9zZUlucHV0cy5wdXNoKGlucHV0c1syXSk7XG4gIH1cbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUNvbnZUcmFuc3Bvc2UyRFByb2dyYW1JbmZvKGNvbnZUcmFuc3Bvc2VJbnB1dHMsIGF0dHJpYnV0ZXMsIHNxdWVlemVPdXRwdXRTaGFwZUZ1bmN0aW9uKSwge1xuICAgIGlucHV0czogY29udlRyYW5zcG9zZUlucHV0cyxcbiAgfSk7XG59O1xuXG5jb25zdCBjb252VHJhbnNwb3NlMWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIC8vIGV4dGVuZCB0aGUgaW5wdXQgdG8gMkQgYnkgYWRkaW5nIEggZGltZW5zaW9uXG4gIGNvbnN0IGlzQ2hhbm5lbExhc3QgPSBhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnO1xuXG4gIGNvbnN0IGlucHV0cyA9IFtcbiAgICBjb250ZXh0LmlucHV0c1swXS5yZXNoYXBlKFxuICAgICAgaXNDaGFubmVsTGFzdFxuICAgICAgICA/IC8vIFtOLCBXLCBDXSAtPiBbTiwgSD0xLCBXLCBDXVxuICAgICAgICAgIFtjb250ZXh0LmlucHV0c1swXS5kaW1zWzBdLCAxLCBjb250ZXh0LmlucHV0c1swXS5kaW1zWzFdLCBjb250ZXh0LmlucHV0c1swXS5kaW1zWzJdXVxuICAgICAgICA6IC8vIFtOLCBDLCBXXSAtPiBbTiwgQywgSD0xLCBXXVxuICAgICAgICAgIFtjb250ZXh0LmlucHV0c1swXS5kaW1zWzBdLCBjb250ZXh0LmlucHV0c1swXS5kaW1zWzFdLCAxLCBjb250ZXh0LmlucHV0c1swXS5kaW1zWzJdXSxcbiAgICApLFxuICAgIC8vW0ZJTFRFUl9PVVRfQ0hBTk5FTCwgRklMVEVSX0lOX0NIQU5ORUwsIGtXXSAtPiBbRklMVEVSX09VVF9DSEFOTkVMLCBGSUxURVJfSU5fQ0hBTk5FTCwga0g9MSwga1ddXG4gICAgY29udGV4dC5pbnB1dHNbMV0ucmVzaGFwZShbY29udGV4dC5pbnB1dHNbMV0uZGltc1swXSwgY29udGV4dC5pbnB1dHNbMV0uZGltc1sxXSwgMSwgY29udGV4dC5pbnB1dHNbMV0uZGltc1syXV0pLFxuICBdO1xuICBpZiAoY29udGV4dC5pbnB1dHMubGVuZ3RoID09PSAzKSB7XG4gICAgaW5wdXRzLnB1c2goY29udGV4dC5pbnB1dHNbMl0pO1xuICB9XG4gIGxldCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGU7XG4gIGlmIChrZXJuZWxTaGFwZS5sZW5ndGggPT09IDAgfHwga2VybmVsU2hhcGVbMF0gPT09IDApIHtcbiAgICBrZXJuZWxTaGFwZSA9IFtjb250ZXh0LmlucHV0c1sxXS5kaW1zWzJdXTtcbiAgfVxuICBsZXQgZGlsYXRpb25zID0gYXR0cmlidXRlcy5kaWxhdGlvbnM7XG4gIGlmIChkaWxhdGlvbnMubGVuZ3RoID09PSAwIHx8IGRpbGF0aW9uc1swXSA9PT0gMCkge1xuICAgIGRpbGF0aW9ucyA9IFsxXTtcbiAgfVxuICBsZXQgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuc3RyaWRlcztcbiAgaWYgKHN0cmlkZXMubGVuZ3RoID09PSAwIHx8IHN0cmlkZXNbMF0gPT09IDApIHtcbiAgICBzdHJpZGVzID0gWzFdO1xuICB9XG4gIGxldCBwYWRzID0gYXR0cmlidXRlcy5wYWRzO1xuICBpZiAocGFkcy5sZW5ndGggPT09IDApIHtcbiAgICBwYWRzID0gWzAsIDBdO1xuICB9XG4gIHBhZHMgPSBbMCwgcGFkc1swXSwgMCwgcGFkc1sxXV07XG4gIHN0cmlkZXMgPSBbMV0uY29uY2F0KHN0cmlkZXMpO1xuICBkaWxhdGlvbnMgPSBbMV0uY29uY2F0KGRpbGF0aW9ucyk7XG4gIGtlcm5lbFNoYXBlID0gWzFdLmNvbmNhdChrZXJuZWxTaGFwZSk7XG4gIGxldCBvdXRwdXRQYWRkaW5nID0gYXR0cmlidXRlcy5vdXRwdXRQYWRkaW5nO1xuICBvdXRwdXRQYWRkaW5nID0gWzBdLmNvbmNhdChvdXRwdXRQYWRkaW5nKTtcbiAgY29uc3QgYWRqdXN0ZWRBdHRyaWJ1dGVzID0gZ2V0QWRqdXN0ZWRDb252VHJhbnNwb3NlQXR0cmlidXRlcyhcbiAgICB7IC4uLmF0dHJpYnV0ZXMsIHBhZHMsIHN0cmlkZXMsIGRpbGF0aW9ucywga2VybmVsU2hhcGUsIG91dHB1dFBhZGRpbmcgfSxcbiAgICBpbnB1dHMsXG4gICk7XG5cbiAgY29udlRyYW5zcG9zZTJkKGNvbnRleHQsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzLCAob3V0cHV0U2hhcGUpID0+XG4gICAgaXNDaGFubmVsTGFzdCA/IFtvdXRwdXRTaGFwZVswXSwgb3V0cHV0U2hhcGVbMl0sIG91dHB1dFNoYXBlWzNdXSA6IFtvdXRwdXRTaGFwZVswXSwgb3V0cHV0U2hhcGVbMV0sIG91dHB1dFNoYXBlWzNdXSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb252VHJhbnNwb3NlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGlmIChjb250ZXh0LmlucHV0c1swXS5kaW1zLmxlbmd0aCA9PT0gMykge1xuICAgIGNvbnZUcmFuc3Bvc2UxZChjb250ZXh0LCBhdHRyaWJ1dGVzKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBhZGp1c3RlZEF0dHJpYnV0ZXMgPSBnZXRBZGp1c3RlZENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIGNvbnRleHQuaW5wdXRzKTtcbiAgICBjb252VHJhbnNwb3NlMmQoY29udGV4dCwgY29udGV4dC5pbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgZ2V0RWxlbWVudEF0LCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEN1bVN1bUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBleGNsdXNpdmU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IHJldmVyc2U6IGJvb2xlYW47XG59XG5jb25zdCBjcmVhdGVDdW1zdW1Qcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRUeXBlOiBudW1iZXIsXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBheGlzSW5wdXQ6IFRlbnNvclZpZXcsXG4gIGF0dHJpYnV0ZXM6IEN1bVN1bUF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShpbnB1dFNoYXBlKTsgLy8gb3V0cHV0U2hhcGUgaXMgc2FtZSBhcyBpbnB1dFNoYXBlLlxuICBjb25zdCByYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7IC8vIGlucHV0L291dHB1dCByYW5rXG4gIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBpbnB1dFR5cGUsIHJhbmspO1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRUeXBlLCByYW5rKTtcbiAgY29uc3QgYXhpc1ZhbHVlID1cbiAgICBheGlzSW5wdXQuZGF0YVR5cGUgPT09IERhdGFUeXBlLmludDMyID8gYXhpc0lucHV0LmdldEludDMyQXJyYXkoKVswXSA6IE51bWJlcihheGlzSW5wdXQuZ2V0QmlnSW50NjRBcnJheSgpWzBdKTtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF4aXNWYWx1ZSwgcmFuayk7XG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGluZGV4ID0gYCBpMzIoJHtpbnB1dC5pbmRpY2VzR2V0KCdpbnB1dEluZGljZXMnLCAndW5pZm9ybXMuYXhpcycpfSkgYDtcbiAgICBjb25zdCBtYXggPSBnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLmlucHV0X3NoYXBlJywgJ3VuaWZvcm1zLmF4aXMnLCByYW5rKTtcbiAgICBjb25zdCBsb3dlckxpbWl0ID0gYXR0cmlidXRlcy5yZXZlcnNlID8gaW5kZXggKyAoYXR0cmlidXRlcy5leGNsdXNpdmUgPyAnICsgMScgOiAnJykgOiAnMCc7XG4gICAgY29uc3QgdXBwZXJMaW1pdCA9IGF0dHJpYnV0ZXMucmV2ZXJzZSA/IG1heCA6IGluZGV4ICsgKGF0dHJpYnV0ZXMuZXhjbHVzaXZlID8gJycgOiAnICsgMScpO1xuICAgIHJldHVybiBgXG4gICAgICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXJcbiAgICAgICAgICAgICAgICAgIC5yZWdpc3RlclVuaWZvcm0oJ291dHB1dFNpemUnLCAndTMyJylcbiAgICAgICAgICAgICAgICAgIC5yZWdpc3RlclVuaWZvcm0oJ2F4aXMnLCAndTMyJylcbiAgICAgICAgICAgICAgICAgIC5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBvdXRwdXQpfVxuICAgICAgICAgICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0U2l6ZScpfVxuICAgICAgICAgICAgICAgICAgdmFyIGlucHV0SW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcbiAgICAgICAgICAgICAgICAgIHZhciBzdW0gPSAke291dHB1dC50eXBlLnZhbHVlfSgwKTtcbiAgICAgICAgICAgICAgICAgIGxldCBmaXJzdCA6IGkzMiA9ICR7bG93ZXJMaW1pdH07XG4gICAgICAgICAgICAgICAgICBsZXQgbGFzdCA6IGkzMiA9ICR7dXBwZXJMaW1pdH07XG4gICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIDogaTMyID0gZmlyc3Q7IGkgPCBsYXN0OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgJHtpbnB1dC5pbmRpY2VzU2V0KCdpbnB1dEluZGljZXMnLCAndW5pZm9ybXMuYXhpcycsICd1MzIoaSknKX07XG4gICAgICAgICAgICAgICAgICAgIHN1bSA9IHN1bSArICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dEluZGljZXMnKX07XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICdzdW0nKX07XG4gICAgICAgICAgICAgICAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0N1bVN1bScsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuayddIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IGlucHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dFR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXM6IFtcbiAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGF4aXMgfSxcbiAgICAgICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRTaGFwZSwgaW5wdXRTaGFwZSksXG4gICAgICBdLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjdW1zdW0gPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEN1bVN1bUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGNvbnRleHQuaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGlucHV0VHlwZSA9IGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlO1xuICBjb25zdCBheGlzID0gY29udGV4dC5pbnB1dHNbMV07XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVDdW1zdW1Qcm9ncmFtSW5mbyhpbnB1dFR5cGUsIGlucHV0U2hhcGUsIGF4aXMsIGF0dHJpYnV0ZXMpLCB7IGlucHV0czogWzBdIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ3VtU3VtQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEN1bVN1bUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBleGNsdXNpdmUgPSAoYXR0cmlidXRlcy5leGNsdXNpdmUgYXMgbnVtYmVyKSA9PT0gMTtcbiAgY29uc3QgcmV2ZXJzZSA9IChhdHRyaWJ1dGVzLnJldmVyc2UgYXMgbnVtYmVyKSA9PT0gMTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGV4Y2x1c2l2ZSwgcmV2ZXJzZSB9KTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgSW5kaWNlc0hlbHBlciwgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciB9IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBGb3JtYXRBdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgZm9ybWF0OiAnTkhXQycgfCAnTkNIVyc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwdGhUb1NwYWNlQXR0cmlidXRlcyBleHRlbmRzIEZvcm1hdEF0dHJpYnV0ZXMsIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGJsb2Nrc2l6ZTogbnVtYmVyO1xuICByZWFkb25seSBtb2RlOiBzdHJpbmc7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RlcHRoVG9TcGFjZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0RlcHRoVG9TcGFjZSByZXF1aXJlcyA0RCBpbnB1dC4nKTtcbiAgfVxufTtcblxuY29uc3QgcGVybUZ1bmN0aW9uQm9keSA9IChwZXJtOiBudW1iZXJbXSwgcmFuazogbnVtYmVyLCBpbnB1dDogSW5kaWNlc0hlbHBlciwgb3V0cHV0OiBJbmRpY2VzSGVscGVyKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmV2ZXJzZUZ1bmMgPSBbXTtcbiAgcmV2ZXJzZUZ1bmMucHVzaChgZm4gcGVybShpOiAke291dHB1dC50eXBlLmluZGljZXN9KSAtPiAke2lucHV0LnR5cGUuaW5kaWNlc30ge1xuICAgIHZhciBhOiAke2lucHV0LnR5cGUuaW5kaWNlc307YCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgcmV2ZXJzZUZ1bmMucHVzaChpbnB1dC5pbmRpY2VzU2V0KCdhJywgcGVybVtpXSwgYGlbJHtpfV1gKSk7XG4gIH1cbiAgcmV2ZXJzZUZ1bmMucHVzaCgncmV0dXJuIGE7fScpO1xuICByZXR1cm4gcmV2ZXJzZUZ1bmMuam9pbignXFxuJyk7XG59O1xuXG5jb25zdCBjcmVhdGVEZXB0aFRvU3BhY2VQcm9ncmFtSW5mbyA9IChpbnB1dFRlbnNvcjogVGVuc29yVmlldywgYXR0cmlidXRlczogRGVwdGhUb1NwYWNlQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgbGV0IG46IG51bWJlciwgaDogbnVtYmVyLCB3OiBudW1iZXIsIGM6IG51bWJlcjtcbiAgbGV0IHNoYXBlOiBudW1iZXJbXTtcbiAgbGV0IHBlcm06IG51bWJlcltdO1xuICBjb25zdCBpc0NoYW5uZWxMYXN0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJztcbiAgY29uc3QgYmxvY2tzaXplID0gYXR0cmlidXRlcy5ibG9ja3NpemU7XG4gIGNvbnN0IGlzRENSbW9kZSA9IGF0dHJpYnV0ZXMubW9kZSA9PT0gJ0RDUic7XG4gIGlmIChpc0NoYW5uZWxMYXN0KSB7XG4gICAgW24sIGgsIHcsIGNdID0gaW5wdXRUZW5zb3IuZGltcztcbiAgICBzaGFwZSA9IGlzRENSbW9kZVxuICAgICAgPyBbbiwgaCwgdywgYmxvY2tzaXplLCBibG9ja3NpemUsIGMgLyBibG9ja3NpemUgKiogMl1cbiAgICAgIDogW24sIGgsIHcsIGMgLyBibG9ja3NpemUgKiogMiwgYmxvY2tzaXplLCBibG9ja3NpemVdO1xuICAgIHBlcm0gPSBpc0RDUm1vZGUgPyBbMCwgMSwgMywgMiwgNCwgNV0gOiBbMCwgMSwgNCwgMiwgNSwgM107XG4gIH0gZWxzZSB7XG4gICAgW24sIGgsIHcsIGNdID0gW2lucHV0VGVuc29yLmRpbXNbMF0sIGlucHV0VGVuc29yLmRpbXNbMl0sIGlucHV0VGVuc29yLmRpbXNbM10sIGlucHV0VGVuc29yLmRpbXNbMV1dO1xuICAgIHNoYXBlID0gaXNEQ1Jtb2RlXG4gICAgICA/IFtuLCBibG9ja3NpemUsIGJsb2Nrc2l6ZSwgYyAvIGJsb2Nrc2l6ZSAqKiAyLCBoLCB3XVxuICAgICAgOiBbbiwgYyAvIGJsb2Nrc2l6ZSAqKiAyLCBibG9ja3NpemUsIGJsb2Nrc2l6ZSwgaCwgd107XG4gICAgcGVybSA9IGlzRENSbW9kZSA/IFswLCAzLCA0LCAxLCA1LCAyXSA6IFswLCAxLCA0LCAyLCA1LCAzXTtcbiAgfVxuICBjb25zdCByZXNoYXBlZElucHV0VGVuc29yID0gaW5wdXRUZW5zb3IucmVzaGFwZShzaGFwZSk7XG4gIGNvbnN0IHJlc2hhcGVkSW5wdXRSYW5rID0gcmVzaGFwZWRJbnB1dFRlbnNvci5kaW1zLmxlbmd0aDtcbiAgY29uc3QgaW5wdXREYXRhVHlwZSA9IGlucHV0VGVuc29yLmRhdGFUeXBlO1xuXG4gIGNvbnN0IHJlc2hhcGVkSW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdhJywgaW5wdXREYXRhVHlwZSwgcmVzaGFwZWRJbnB1dFJhbmspO1xuICBjb25zdCBwZXJtZWRPdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXREYXRhVHlwZSwgcmVzaGFwZWRJbnB1dFJhbmspO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMocmVzaGFwZWRJbnB1dCwgcGVybWVkT3V0cHV0KX1cblxuICAke3Blcm1GdW5jdGlvbkJvZHkocGVybSwgcmVzaGFwZWRJbnB1dFJhbmssIHJlc2hhcGVkSW5wdXQsIHBlcm1lZE91dHB1dCl9XG5cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cblxuICAgIGxldCBpbmRpY2VzID0gJHtwZXJtZWRPdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgIGxldCBhSW5kaWNlcyA9IHBlcm0oaW5kaWNlcyk7XG5cbiAgICAke3Blcm1lZE91dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIHJlc2hhcGVkSW5wdXQuZ2V0QnlJbmRpY2VzKCdhSW5kaWNlcycpKX1cbiAgfWA7XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnRGVwdGhUb1NwYWNlJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYCR7aW5wdXRUZW5zb3IuZGltc307JHthdHRyaWJ1dGVzLmJsb2Nrc2l6ZX07JHthdHRyaWJ1dGVzLm1vZGV9YCxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6IChpbnB1dHMpID0+IHtcbiAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gaXNDaGFubmVsTGFzdFxuICAgICAgICA/IFtuLCBoICogYmxvY2tzaXplLCB3ICogYmxvY2tzaXplLCBjIC8gYmxvY2tzaXplICoqIDJdXG4gICAgICAgIDogW24sIGMgLyBibG9ja3NpemUgKiogMiwgaCAqIGJsb2Nrc2l6ZSwgdyAqIGJsb2Nrc2l6ZV07XG4gICAgICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICAgICAgY29uc3Qgc2hhcGVCZWZvcmVQZXJtID0gcmVzaGFwZWRJbnB1dFRlbnNvci5kaW1zO1xuICAgICAgY29uc3Qgc2hhcGVBZnRlclBlcm0gPSBTaGFwZVV0aWwuc29ydEJhc2VkT25QZXJtKHNoYXBlQmVmb3JlUGVybSwgcGVybSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXM6IFtcbiAgICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgICAgICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKHNoYXBlQmVmb3JlUGVybSwgc2hhcGVBZnRlclBlcm0pLFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBkZXB0aFRvU3BhY2UgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IERlcHRoVG9TcGFjZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRGVwdGhUb1NwYWNlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sIGF0dHJpYnV0ZXMpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYmxvY2tzaXplOiBhdHRyaWJ1dGVzLmJsb2Nrc2l6ZSBhcyBudW1iZXIsXG4gICAgbW9kZTogYXR0cmlidXRlcy5tb2RlIGFzIHN0cmluZyxcbiAgICBmb3JtYXQ6IGF0dHJpYnV0ZXMuZm9ybWF0IGFzICdOSFdDJyB8ICdOQ0hXJyxcbiAgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsIGlucHV0VmFyaWFibGUsIG91dHB1dFZhcmlhYmxlLCBTaGFkZXJIZWxwZXIgfSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRWluc3VtQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGVxdWF0aW9uOiBzdHJpbmc7XG59XG4vLyBUaGUgZXF1YXRpb24gYXR0cmlidXRlIHZhbHVlIGlzIGEgc3RyaW5nIHdoaWNoIGNvbnNpc3RzIG9mIGxlZnQgaGFuZCBzaWRlIChMSFMpIGFuZCBvcHRpb25hbGx5IHJpZ2h0IGhhbmQgc2lkZSAoUkhTKVxuLy8gc2VwYXJhdGVkIGJ5ICctPicuIEV4LiBcImlqLGprIC0+IGlrXCIgZXhwcmVzc2VzIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuLy8gICAgIFwiaWotPmppXCIgZXhwcmVzc2VzIG1hdHJpeCB0cmFuc3Bvc2Vcbi8vICAgICAgXCJpaS0+aVwiIGRpYWdvbmFsIGVsZW1lbnRzIG9mIGEgc3F1YXJlIG1hdHJpeFxuLy8gTEhTIGNvbnNpc3RzIG9mIGEgc2VxdWVuY2Ugb2YgdGVybXMgc2VwYXJhdGVkIGJ5IGNvbW1hcy4gRWFjaCB0ZXJtIGNvcnJlc3BvbmRzIHRvIGFuIGlucHV0IHZhcmlhYmxlLlxuLy8gRWFjaCBzeW1ib2wgY29ycmVzcG9uZHMgdG8gYSBkaW1lbnNpb24gaW4gdGhlIGlucHV0IHZhcmlhYmxlLiBUaGUgc3ltYm9sIGNhbiBiZSBlaXRoZXIgYSBsZXR0ZXIsICdhJyB0byAneicgb3IgJ0EnIHRvXG4vLyAnWicgb3IgJy4uLicgdG8gcmVwcmVzZW50IGFyYml0cmFyeSBkaW1lbnNpb25zLlxuXG5jb25zdCBzeW1ib2xQYXR0ZXJuID0gJ1thLXpBLVpdfFxcXFwuXFxcXC5cXFxcLic7IC8vIFRoZSBwYXR0ZXJuIGVhY2ggc3ltYm9sIGluIGVhY2ggdGVybSBpbiB0aGUgc3ltYm9saWMgZXF1YXRpb24gc2hvdWxkIG1hdGNoXG5jb25zdCB0ZXJtUGF0dGVybiA9ICcoJyArIHN5bWJvbFBhdHRlcm4gKyAnKSsnOyAvLyBUaGUgcGF0dGVybiBlYWNoIHRlcm0gaW4gdGhlIHN5bWJvbGljIGVxdWF0aW9uIHNob3VsZCBtYXRjaFxuY29uc3QgdGVybVBhdHRlcm5Pbmx5ID0gJ14nICsgdGVybVBhdHRlcm4gKyAnJCc7IC8vIFRoZSBwYXR0ZXJucyBvbmx5IG1hdGNocyBhIHRlcm0gYmVnaW4gdG8gZW5kLlxuY29uc3QgbGhzUGF0dGVybiA9ICcoJyArIHRlcm1QYXR0ZXJuICsgJywpKicgKyB0ZXJtUGF0dGVybjsgLy8gVGhlIHBhdHRlcm4gdGhlIExIUyBzaG91bGQgbWF0Y2hcbmNvbnN0IGxoc1BhdHRlcm5Pbmx5ID0gJ14nICsgbGhzUGF0dGVybiArICckJzsgLy8gVGhlIHBhdHRlcm5zIG9ubHkgbWF0Y2hzIGEgTEhTIGJlZ2luIHRvIGVuZC5cblxuaW50ZXJmYWNlIFN5bWJvbEluZm8ge1xuICBjb3VudDogbnVtYmVyOyAvLyBTeW1ib2wgY29ycmVzcG9uZGluZyB0byBhIGRpbW1lbnNpb24gb2YgYW4gaW5wdXRcbiAgaW5wdXRJbmRpY2VzOiBudW1iZXJbXTsgLy8gTnVtYmVyIG9mIGlucHV0IHZhcmlhYmxlcyB0aGUgc3ltYm9sIGNvcnJlc3BvbmRzIHRvXG4gIGRpbVZhbHVlOiBudW1iZXI7IC8vIE51bWJlciBvZiBkaW1lbnNpb25zIHRoZSBzeW1ib2wgY29ycmVzcG9uZHMgdG9cbn1cblxuY2xhc3MgRWluc3VtVGVybSB7XG4gIGNvbnN0cnVjdG9yKGlucHV0SW5kZXggPSAtMSkge1xuICAgIHRoaXMuc3ltYm9sVG9JbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcltdPigpO1xuICAgIHRoaXMuaW5wdXRJbmRleCA9IGlucHV0SW5kZXg7XG4gIH1cblxuICAvLyBBZGQgYSBzeW1ib2wgdG8gdGhlIHRlcm1cbiAgYWRkU3ltYm9sKHN5bWJvbDogc3RyaW5nLCBpbmRleDogbnVtYmVyKSB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5zeW1ib2xUb0luZGljZXMuZ2V0KHN5bWJvbCk7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhbHVlID0gW2luZGV4XTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUucHVzaChpbmRleCk7XG4gICAgfVxuICAgIHRoaXMuc3ltYm9sVG9JbmRpY2VzLnNldChzeW1ib2wsIHZhbHVlKTtcbiAgfVxuXG4gIHN5bWJvbFRvSW5kaWNlczogTWFwPHN0cmluZywgbnVtYmVyW10+OyAvLyBNYXAgZnJvbSBzeW1ib2wgdG8gZGltZW5zaW9ucyBvZiB0aGUgaW5wdXQgY29ycmVzcG9uZGluZyB0byB0aGUgdGVybVxuICBpbnB1dEluZGV4OiBudW1iZXI7IC8vIC0xIGZvciBvdXRwdXQgYW5kIDAsIDEsIDIsIC4uLiBmb3IgaW5wdXRzXG59XG5cbmNsYXNzIEVpbnN1bUVxdWF0aW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gICAgcHVibGljIHJlYWRvbmx5IGVxdWF0aW9uOiBzdHJpbmcsXG4gICkge1xuICAgIHRoaXMuaGFzRWxsaXBzaXMgPSBmYWxzZTtcbiAgICB0aGlzLnN5bWJvbFRvSW5mbyA9IG5ldyBNYXA8c3RyaW5nLCBTeW1ib2xJbmZvPigpO1xuICAgIHRoaXMubGhzID0gbmV3IEFycmF5PEVpbnN1bVRlcm0+KCk7XG4gICAgdGhpcy5vdXRwdXREaW1zID0gW107XG4gICAgLy8gQXMgcmhzIG5lZWRzIHRvIGJlIHVwZGF0ZWQgYWxsb3cgdXNpbmcgbGV0IGluc3RlYWQgb2YgY29uc3QgZm9yIGJvdGggbGhzIGFuZCByaHMuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICAgIGxldCBbbGhzLCByaHNdID0gZXF1YXRpb24uaW5jbHVkZXMoJy0+JykgPyBlcXVhdGlvbi5zcGxpdCgnLT4nLCAyKSA6IFtlcXVhdGlvbiwgJyddO1xuICAgIGlmICghbGhzLm1hdGNoKFJlZ0V4cChsaHNQYXR0ZXJuT25seSkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgTEhTIHRlcm0nKTtcbiAgICB9XG4gICAgY29uc3QgaW5wdXRUZXJtcyA9IGxocy5zcGxpdCgnLCcpO1xuICAgIGlucHV0VGVybXMuZm9yRWFjaCgoaW5wdXRUZXJtLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgZGltcyA9IGlucHV0c1tpbmRleF0uZGltcy5zbGljZSgpO1xuICAgICAgaWYgKCFpbnB1dFRlcm0ubWF0Y2goUmVnRXhwKHRlcm1QYXR0ZXJuT25seSkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBMSFMgdGVybScpO1xuICAgICAgfVxuICAgICAgY29uc3QgZWluc3VtVGVybSA9IHRoaXMucHJvY2Vzc1Rlcm0oaW5wdXRUZXJtLCB0cnVlLCBkaW1zLCBpbmRleCk7XG4gICAgICB0aGlzLmxocy5wdXNoKGVpbnN1bVRlcm0pO1xuICAgIH0pO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgUkhTIGlmIG5vdCBzcGVjaWZpZWRcbiAgICBpZiAocmhzID09PSAnJykge1xuICAgICAgLy8gQ29uc3RydWN0IFJIUyBmcm9tIExIUyB0ZXJtcy9zeW1ib2xzXG4gICAgICByaHMgKz0gWy4uLnRoaXMuc3ltYm9sVG9JbmZvLmVudHJpZXMoKV1cbiAgICAgICAgLmZpbHRlcigoW3N5bSwgaW5mb10pID0+IGluZm8uY291bnQgPT09IDEgfHwgc3ltID09PSAnLi4uJylcbiAgICAgICAgLm1hcCgoW3N5bV0pID0+IHN5bSlcbiAgICAgICAgLmpvaW4oJycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXJocy5tYXRjaChSZWdFeHAodGVybVBhdHRlcm4pKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUkhTJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ29tcHV0ZSBvdXRwdXQgZGltc1xuICAgIGNvbnN0IHJoc1N5bWJvbHMgPSByaHMubWF0Y2goUmVnRXhwKHN5bWJvbFBhdHRlcm4sICdnJykpO1xuICAgIHJoc1N5bWJvbHM/LmZvckVhY2goKHN5bWJvbCkgPT4ge1xuICAgICAgaWYgKHN5bWJvbCA9PT0gJy4uLicpIHtcbiAgICAgICAgdGhpcy5vdXRwdXREaW1zID0gdGhpcy5vdXRwdXREaW1zLmNvbmNhdCh0aGlzLmVsbGlwc2lzRGltcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBpbmZvID0gdGhpcy5zeW1ib2xUb0luZm8uZ2V0KHN5bWJvbCk7XG4gICAgICAgIGlmIChpbmZvID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUkhTIHN5bWJvbCcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3V0cHV0RGltcy5wdXNoKGluZm8uZGltVmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMucmhzID0gdGhpcy5wcm9jZXNzVGVybShyaHMsIGZhbHNlLCB0aGlzLm91dHB1dERpbXMpO1xuICB9IC8vIEVuZCBvZiBFaW5zdW1FcWF0aW9uIGNvbnN0cnVjdG9yXG5cbiAgLy8gQWRkIGEgc3ltYm9sIHRvIHRoZSBlcXVhdGlvblxuICBhZGRTeW1ib2woc3ltYm9sOiBzdHJpbmcsIGRpbVZhbHVlOiBudW1iZXIsIGlucHV0SW5kZXg6IG51bWJlcikge1xuICAgIGxldCBpbmZvID0gdGhpcy5zeW1ib2xUb0luZm8uZ2V0KHN5bWJvbCk7XG4gICAgaWYgKGluZm8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGluZm8uZGltVmFsdWUgIT09IGRpbVZhbHVlICYmIGluZm8uY291bnQgIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb24gbWlzbWF0Y2gnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZm8uY291bnQrKztcbiAgICAgICAgaW5mby5pbnB1dEluZGljZXMucHVzaChpbnB1dEluZGV4KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaW5mbyA9IHsgY291bnQ6IDEsIGRpbVZhbHVlLCBpbnB1dEluZGljZXM6IFtpbnB1dEluZGV4XSB9O1xuICAgIH1cbiAgICB0aGlzLnN5bWJvbFRvSW5mby5zZXQoc3ltYm9sLCBpbmZvKTtcbiAgfVxuXG4gIC8vIFByb2Nlc3Mgb25lIGlucHV0L291dHB1dCB0ZXJtXG4gIHByb2Nlc3NUZXJtKHRlcm06IHN0cmluZywgaXNJbnB1dDogYm9vbGVhbiwgZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGluZGV4ID0gLTEpOiBFaW5zdW1UZXJtIHtcbiAgICBjb25zdCByYW5rID0gZGltcy5sZW5ndGg7XG4gICAgbGV0IGVsbGlwc2lzID0gZmFsc2U7XG4gICAgbGV0IGVsbGlwc2lzRGltcyA9IFtdO1xuICAgIGxldCBuZXh0RGltID0gMDtcbiAgICAvLyBGb3Igb3V0cHV0IGVtcHR5IHN0cmluZyBpcyBhbGxvd2VkIGJlY2F1c2UgdGhlIG91dHB1dCBtYXkgYmUgcmVkdWNlZCB0byBhIHNjYWxhciB2YWx1ZVxuICAgIGlmICghdGVybS5tYXRjaChSZWdFeHAodGVybVBhdHRlcm5Pbmx5KSkgJiYgIWlzSW5wdXQgJiYgdGVybSAhPT0gJycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBMSFMgdGVybScpO1xuICAgIH1cbiAgICBjb25zdCBpbmRleFN5bWJvbHMgPSB0ZXJtLm1hdGNoKFJlZ0V4cChzeW1ib2xQYXR0ZXJuLCAnZycpKTtcbiAgICBjb25zdCBlaW5zdW1UZXJtID0gbmV3IEVpbnN1bVRlcm0oaW5kZXgpO1xuICAgIC8vIHN5bWJvbCBjYW4gYmUgZWl0aGVyIGEgbGV0dHJlLCAnYScgdG8gJ3onIG9yICdBJyB0byAnWicsIG9yICcuLi4nXG4gICAgaW5kZXhTeW1ib2xzPy5mb3JFYWNoKChzeW1ib2w6IHN0cmluZywgaTogbnVtYmVyKSA9PiB7XG4gICAgICBpZiAoc3ltYm9sID09PSAnLi4uJykge1xuICAgICAgICBpZiAoZWxsaXBzaXMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ09ubHkgb25lIGVsbGlwc2lzIGlzIGFsbG93ZWQgcGVyIGlucHV0IHRlcm0nKTtcbiAgICAgICAgfVxuICAgICAgICBlbGxpcHNpcyA9IHRydWU7XG4gICAgICAgIGNvbnN0IGVsbGlwc2lzRGltTGVuZ3RoID0gcmFuayAtIGluZGV4U3ltYm9scy5sZW5ndGggKyAxO1xuICAgICAgICBpZiAoZWxsaXBzaXNEaW1MZW5ndGggPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFbGxpcHNpcyBvdXQgb2YgYm91bmRzJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxsaXBzaXNEaW1zID0gZGltcy5zbGljZShuZXh0RGltLCBuZXh0RGltICsgZWxsaXBzaXNEaW1MZW5ndGgpO1xuICAgICAgICBpZiAodGhpcy5oYXNFbGxpcHNpcykge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuZWxsaXBzaXNEaW1zLmxlbmd0aCAhPT0gZWxsaXBzaXNEaW1zLmxlbmd0aCB8fFxuICAgICAgICAgICAgdGhpcy5lbGxpcHNpc0RpbXMudG9TdHJpbmcoKSAhPT0gZWxsaXBzaXNEaW1zLnRvU3RyaW5nKClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRWxsaXBzaXMgZGltZW5zaW9ucyBtaXNtYXRjaCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc0lucHV0KSB7XG4gICAgICAgICAgdGhpcy5oYXNFbGxpcHNpcyA9IHRydWU7XG4gICAgICAgICAgdGhpcy5lbGxpcHNpc0RpbXMgPSBlbGxpcHNpc0RpbXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFbGxpcHNpcyBtdXN0IGJlIHNwZWNpZmllZCBpbiB0aGUgTEhTJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQWRkICcwJywgJzEnLCAnMicsICczJywgJzQnLCBldGMgdG8gcmVwcmVzZW50IGVsbGlwc2lzIGRpbWVuc2lvbnMgdG8gYXZvaWQgc3BlY2lhbCBoYW5kbGluZ1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGVsbGlwc2lzRGltcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgIGNvbnN0IHN5bWJvbCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoJzAnLmNoYXJDb2RlQXQoMCkgKyBqKTtcbiAgICAgICAgICBlaW5zdW1UZXJtLmFkZFN5bWJvbChzeW1ib2wsIGkgKyBqKTtcbiAgICAgICAgICB0aGlzLmFkZFN5bWJvbChzeW1ib2wsIGRpbXNbbmV4dERpbSsrXSwgaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlaW5zdW1UZXJtLmFkZFN5bWJvbChzeW1ib2wsIGkgKyAodGhpcy5oYXNFbGxpcHNpcyA/IHRoaXMuZWxsaXBzaXNEaW1zLmxlbmd0aCAtIDEgOiAwKSk7XG4gICAgICAgIHRoaXMuYWRkU3ltYm9sKHN5bWJvbCwgZGltc1tuZXh0RGltKytdLCBpbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGVpbnN1bVRlcm07XG4gIH1cblxuICBzeW1ib2xUb0luZm86IE1hcDxzdHJpbmcsIFN5bWJvbEluZm8+OyAvLyBBbGwgc3ltYm9scyBpbiB0aGUgZXF1YXRpb25cbiAgaGFzRWxsaXBzaXM6IGJvb2xlYW47IC8vIFRoZSBlcXVhdGlvbiBoYXMgZWxsaXBzaXMgb3Igbm90XG4gIGVsbGlwc2lzRGltczogbnVtYmVyW107IC8vIFRoZSBkaW1lbnNpb25zIG9mIHRoZSBlcXVhdGlvbiBlbGxpcHNpcyBjb3JyZXNwb25kcyB0by5cbiAgbGhzOiBFaW5zdW1UZXJtW107IC8vIFRlcm1zIG9uIHRoZSBsZWZ0LWhhbmQgc2lkZSBvZiB0aGUgZXF1YXRpb25cbiAgcmhzOiBFaW5zdW1UZXJtOyAvLyBUZXJtIG9uIHRoZSByaWdodC1oYW5kIHNpZGUgb2YgdGhlIGVxdWF0aW9uXG4gIG91dHB1dERpbXM6IG51bWJlcltdOyAvLyBPdXRwdXQgZGltZW5zaW9ucyBvZiB0aGUgZXF1YXRpb25cbn0gLy8gRW5kIG9mIGNsYXNzIEVpbnN1bUVxdWF0aW9uXG5cbmNvbnN0IGFwcGVuZE1heCA9IChuYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4gbmFtZSArICdfbWF4JztcblxuY29uc3QgY3JlYXRlRWluc3VtUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0U2hhcGVzOiBBcnJheTxyZWFkb25seSBudW1iZXJbXT4sXG4gIGRhdGFUeXBlOiBudW1iZXIsXG4gIGVpbnN1bUVxdWF0aW9uOiBFaW5zdW1FcXVhdGlvbixcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCByYW5rcyA9IGlucHV0U2hhcGVzLm1hcCgoZGltcykgPT4gZGltcy5sZW5ndGgpO1xuICBjb25zdCBpbnB1dFZhcnMgPSByYW5rcy5tYXAoKHJhbmssIGluZGV4KSA9PiBpbnB1dFZhcmlhYmxlKGBpbnB1dCR7aW5kZXh9YCwgZGF0YVR5cGUsIHJhbmspKTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCB1bmlmb3Jtc1N5bWJvbHMgPSBbLi4uZWluc3VtRXF1YXRpb24uc3ltYm9sVG9JbmZvLmtleXMoKV0uZmlsdGVyKFxuICAgIChzeW1ib2wpID0+ICFlaW5zdW1FcXVhdGlvbi5yaHMuc3ltYm9sVG9JbmRpY2VzLmhhcyhzeW1ib2wpLFxuICApO1xuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBpZHhDb3B5OiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IGluaXRQcm9kID0gJ3ZhciBwcm9kID0gMS4wOyc7XG4gICAgY29uc3QgaW5pdFN1bSA9ICd2YXIgc3VtID0gMC4wOyc7XG4gICAgY29uc3QgdXBkYXRlU3VtID0gJ3N1bSArPSBwcm9kOyc7XG4gICAgY29uc3QgcmVkdWNlT3BzU2V0SW5kaWNlczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCByZWR1Y2VPcHNMb29wSGVhZGVyczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCByZWR1Y2VPcHNMb29wRm9vdGVyczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCByZWR1Y2VPcENvbXB1dGU6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgaXNSZWR1Y2VPcHNXaXRob3V0TG9vcCA9IGVpbnN1bUVxdWF0aW9uLnN5bWJvbFRvSW5mby5zaXplID09PSBlaW5zdW1FcXVhdGlvbi5yaHMuc3ltYm9sVG9JbmRpY2VzLnNpemU7XG4gICAgZWluc3VtRXF1YXRpb24uc3ltYm9sVG9JbmZvLmZvckVhY2goKGluZm8sIHN5bWJvbCkgPT4ge1xuICAgICAgaWYgKGVpbnN1bUVxdWF0aW9uLnJocy5zeW1ib2xUb0luZGljZXMuaGFzKHN5bWJvbCkpIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kZXggPSBlaW5zdW1FcXVhdGlvbi5yaHMuc3ltYm9sVG9JbmRpY2VzLmdldChzeW1ib2wpPy5bMF07XG4gICAgICAgIGlmIChvdXRwdXRJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZWluc3VtRXF1YXRpb24ubGhzLmZvckVhY2goKHRlcm0sIGkpID0+IHtcbiAgICAgICAgICAgIGlmIChpbmZvLmlucHV0SW5kaWNlcy5pbmNsdWRlcyhpKSkge1xuICAgICAgICAgICAgICBjb25zdCBpbmRpY2VzID0gdGVybS5zeW1ib2xUb0luZGljZXMuZ2V0KHN5bWJvbCk7XG4gICAgICAgICAgICAgIGlmIChpbmRpY2VzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3ltYm9sIGVycm9yJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaW5kaWNlcy5mb3JFYWNoKChpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGlkeENvcHkucHVzaChcbiAgICAgICAgICAgICAgICAgIGAke2lucHV0VmFyc1tpXS5pbmRpY2VzU2V0KFxuICAgICAgICAgICAgICAgICAgICBgaW5wdXQke2l9SW5kaWNlc2AsXG4gICAgICAgICAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0SW5kaWNlcycsIG91dHB1dEluZGV4KSxcbiAgICAgICAgICAgICAgICAgICl9YCxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWluc3VtRXF1YXRpb24ubGhzLmZvckVhY2goKHRlcm0sIGkpID0+IHtcbiAgICAgICAgICBpZiAoaW5mby5pbnB1dEluZGljZXMuaW5jbHVkZXMoaSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGljZXMgPSB0ZXJtLnN5bWJvbFRvSW5kaWNlcy5nZXQoc3ltYm9sKTtcbiAgICAgICAgICAgIGlmIChpbmRpY2VzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN5bWJvbCBlcnJvcicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kaWNlcy5mb3JFYWNoKChpbmRleCkgPT4ge1xuICAgICAgICAgICAgICByZWR1Y2VPcHNTZXRJbmRpY2VzLnB1c2goYCR7aW5wdXRWYXJzW2ldLmluZGljZXNTZXQoYGlucHV0JHtpfUluZGljZXNgLCBpbmRleCwgYCR7c3ltYm9sfWApfWApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZWR1Y2VPcENvbXB1dGUucHVzaChgcHJvZCAqPSAke2lucHV0VmFyc1tpXS5nZXRCeUluZGljZXMoYGlucHV0JHtpfUluZGljZXNgKX07YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmVkdWNlT3BzTG9vcEhlYWRlcnMucHVzaChcbiAgICAgICAgICBgZm9yKHZhciAke3N5bWJvbH06IHUzMiA9IDA7ICR7c3ltYm9sfSA8IHVuaWZvcm1zLiR7YXBwZW5kTWF4KHN5bWJvbCl9OyAke3N5bWJvbH0rKykge2AsXG4gICAgICAgICk7XG4gICAgICAgIHJlZHVjZU9wc0xvb3BGb290ZXJzLnB1c2goJ30nKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCByZWR1Y2VPcHMgPSBpc1JlZHVjZU9wc1dpdGhvdXRMb29wXG4gICAgICA/IFtcbiAgICAgICAgICAuLi5pZHhDb3B5LFxuICAgICAgICAgIGBsZXQgc3VtID0gJHtpbnB1dFZhcnMubWFwKChpbnB1dFZhciwgaSkgPT4gaW5wdXRWYXIuZ2V0QnlJbmRpY2VzKGBpbnB1dCR7aX1JbmRpY2VzYCkpLmpvaW4oJyAqICcpfTtgLFxuICAgICAgICBdXG4gICAgICA6IFtcbiAgICAgICAgICAuLi5pZHhDb3B5LFxuICAgICAgICAgIGluaXRTdW0sXG4gICAgICAgICAgLi4ucmVkdWNlT3BzTG9vcEhlYWRlcnMsXG4gICAgICAgICAgLi4ucmVkdWNlT3BzU2V0SW5kaWNlcyxcbiAgICAgICAgICBpbml0UHJvZCxcbiAgICAgICAgICAuLi5yZWR1Y2VPcENvbXB1dGUsXG4gICAgICAgICAgdXBkYXRlU3VtLFxuICAgICAgICAgIC4uLnJlZHVjZU9wc0xvb3BGb290ZXJzLFxuICAgICAgICBdO1xuICAgIHJldHVybiBgXG4gICAgICAgICAgICAke3NoYWRlckhlbHBlclxuICAgICAgICAgICAgICAucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3Jtc1N5bWJvbHMubWFwKChzeW1ib2wpID0+ICh7IG5hbWU6IGAke2FwcGVuZE1heChzeW1ib2wpfWAsIHR5cGU6ICd1MzInIH0pKSlcbiAgICAgICAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0U2l6ZScsICd1MzInKVxuICAgICAgICAgICAgICAuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcnMsIG91dHB1dCl9XG5cbiAgICAgICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0U2l6ZScpfVxuICAgICAgICAgICAgdmFyIG91dHB1dEluZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAgICAgICAke2lucHV0VmFycy5tYXAoKF92YXIsIGkpID0+IGB2YXIgaW5wdXQke2l9SW5kaWNlczogJHtpbnB1dFZhcnNbaV0udHlwZS5pbmRpY2VzfTtgKS5qb2luKCdcXG4nKX1cbiAgICAgICAgICAgICR7cmVkdWNlT3BzLmpvaW4oJ1xcbicpfTtcbiAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3N1bScpfTtcbiAgICAgICAgICB9YDtcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnRWluc3VtJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBlaW5zdW1FcXVhdGlvbi5lcXVhdGlvbiwgaW5wdXREZXBlbmRlbmNpZXM6IGlucHV0U2hhcGVzLm1hcCgoKSA9PiAncmFuaycpIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4ge1xuICAgICAgLy8gVGhlIHN5bWJvbHMgZnJvbSB1bmlmb3JtU3ltYm9scyBhcnJheSBhcmUgZ3VhcmFudGVlZCB0byBleGlzdCBpbiBlaW5zdW1FcXVhdGlvbnMuc3ltYm9sVG9JbmZvIG1hcC4gVGhlXG4gICAgICAvLyBmaWx0ZXIgaXMgYWRkZWQgdG8gbWFrZSBzdXJlIHRoYXQgZGltVmFsdWUgaXMgbmV2ZXIgMC5cbiAgICAgIGNvbnN0IHByb2dyYW1Vbmlmb3Jtc0luaXQ6IFByb2dyYW1Vbmlmb3JtW10gPSB1bmlmb3Jtc1N5bWJvbHNcbiAgICAgICAgLmZpbHRlcigoc3ltYm9sKSA9PiBlaW5zdW1FcXVhdGlvbi5zeW1ib2xUb0luZm8uaGFzKHN5bWJvbCkpXG4gICAgICAgIC5tYXAoKHN5bWJvbCkgPT4gKHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBlaW5zdW1FcXVhdGlvbi5zeW1ib2xUb0luZm8uZ2V0KHN5bWJvbCk/LmRpbVZhbHVlIHx8IDAgfSkpO1xuICAgICAgcHJvZ3JhbVVuaWZvcm1zSW5pdC5wdXNoKHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0pO1xuICAgICAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gaW5wdXRTaGFwZXNcbiAgICAgICAgLm1hcCgoZGltcywgXykgPT4gWy4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGRpbXMpXSlcbiAgICAgICAgLnJlZHVjZSgoYWNjLCBpbnB1dFByb2dyYW1Vbmlmb3JtcykgPT4gYWNjLmNvbmNhdChpbnB1dFByb2dyYW1Vbmlmb3JtcyksIHByb2dyYW1Vbmlmb3Jtc0luaXQpO1xuICAgICAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMob3V0cHV0U2hhcGUpKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZSB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgICB9O1xuICAgIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGVpbnN1bSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogRWluc3VtQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBlaW5zdW1FcXVhdGlvbiA9IG5ldyBFaW5zdW1FcXVhdGlvbihjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcy5lcXVhdGlvbik7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gZWluc3VtRXF1YXRpb24ub3V0cHV0RGltcztcbiAgY29uc3QgaW5wdXRTaGFwZXMgPSBjb250ZXh0LmlucHV0cy5tYXAoKGlucHV0LCBfKSA9PiBpbnB1dC5kaW1zKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUVpbnN1bVByb2dyYW1JbmZvKGlucHV0U2hhcGVzLCBjb250ZXh0LmlucHV0c1swXS5kYXRhVHlwZSwgZWluc3VtRXF1YXRpb24sIG91dHB1dFNoYXBlKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VFaW5zdW1BdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogRWluc3VtQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGVxdWF0aW9uID0gKGF0dHJpYnV0ZXMuZXF1YXRpb24gYXMgc3RyaW5nKS5yZXBsYWNlKC9cXHMrL2csICcnKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGVxdWF0aW9uIH0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciB9IGZyb20gJy4vY29tbW9uJztcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignRXhwYW5kIHJlcXVpcmVzIDIgaW5wdXQuJyk7XG4gIH1cbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBzaGFwZSA9IEFycmF5LmZyb20oaW5wdXRzWzFdLmdldEJpZ0ludDY0QXJyYXkoKSwgTnVtYmVyKTtcblxuICBsZXQgc2hhcGVJbmRleCA9IHNoYXBlLmxlbmd0aCA8IGlucHV0U2hhcGUubGVuZ3RoID8gMCA6IHNoYXBlLmxlbmd0aCAtIGlucHV0U2hhcGUubGVuZ3RoO1xuICBsZXQgaW5wdXRTaGFwZUluZGV4ID0gaW5wdXRTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGggPyAwIDogaW5wdXRTaGFwZS5sZW5ndGggLSBzaGFwZS5sZW5ndGg7XG4gIGZvciAoOyBzaGFwZUluZGV4IDwgc2hhcGUubGVuZ3RoICYmIGlucHV0U2hhcGVJbmRleCA8IGlucHV0U2hhcGUubGVuZ3RoOyArK3NoYXBlSW5kZXgsICsraW5wdXRTaGFwZUluZGV4KSB7XG4gICAgaWYgKFxuICAgICAgc2hhcGVbc2hhcGVJbmRleF0gIT09IGlucHV0U2hhcGVbaW5wdXRTaGFwZUluZGV4XSAmJlxuICAgICAgc2hhcGVbc2hhcGVJbmRleF0gIT09IDEgJiZcbiAgICAgIGlucHV0U2hhcGVbaW5wdXRTaGFwZUluZGV4XSAhPT0gMVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBhbmQgcmVxdWlyZXMgc2hhcGUgdG8gYmUgYnJvYWRjYXN0YWJsZSB0byBpbnB1dCcpO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRTaGFwZSA9IChzaGFwZTE6IHJlYWRvbmx5IG51bWJlcltdLCBzaGFwZTI6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCBkaWZmID0gc2hhcGUxLmxlbmd0aCAtIHNoYXBlMi5sZW5ndGg7XG4gIGNvbnN0IHNoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpZmY7ICsraSkge1xuICAgIHNoYXBlLnB1c2goc2hhcGUxW2ldKTtcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoYXBlMi5sZW5ndGg7ICsraSkge1xuICAgIHNoYXBlLnB1c2goc2hhcGUyW2ldID09PSAxID8gc2hhcGUxW2kgKyBkaWZmXSA6IHNoYXBlMltpXSk7XG4gIH1cbiAgcmV0dXJuIHNoYXBlO1xufTtcblxuY29uc3QgY2FsY3VsYXRlT3V0cHV0U2hhcGUgPSAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlcltdID0+XG4gIGlucHV0U2hhcGUubGVuZ3RoID4gc2hhcGUubGVuZ3RoID8gZ2V0QWRqdXN0ZWRTaGFwZShpbnB1dFNoYXBlLCBzaGFwZSkgOiBnZXRBZGp1c3RlZFNoYXBlKHNoYXBlLCBpbnB1dFNoYXBlKTtcblxuY29uc3QgY3JlYXRlRXhwYW5kUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgc2hhcGUgPSBBcnJheS5mcm9tKGlucHV0c1sxXS5nZXRCaWdJbnQ2NEFycmF5KCksIE51bWJlcik7XG4gIGNvbnN0IG91dHB1dFNoYXBlOiBudW1iZXJbXSA9IGNhbGN1bGF0ZU91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHNoYXBlKTtcbiAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGlzQm9vbE9yU2NhbGFyID0gZGF0YVR5cGUgPT09IERhdGFUeXBlLmJvb2wgfHwgU2hhcGVVdGlsLnNpemUoaW5wdXRTaGFwZSkgPT09IDE7XG4gIGNvbnN0IGlDb21wb25lbnRzID1cbiAgICBkYXRhVHlwZSA9PT0gRGF0YVR5cGUuYm9vbCA/IDQgOiBpbnB1dFNoYXBlLmxlbmd0aCA+IDAgJiYgaW5wdXRTaGFwZVtpbnB1dFNoYXBlLmxlbmd0aCAtIDFdICUgNCA9PT0gMCA/IDQgOiAxO1xuICBjb25zdCBjb21wb25lbnRzID0gaXNCb29sT3JTY2FsYXJcbiAgICA/IDRcbiAgICA6IG91dHB1dFNoYXBlLmxlbmd0aCA+IDAgJiYgb3V0cHV0U2hhcGVbb3V0cHV0U2hhcGUubGVuZ3RoIC0gMV0gJSA0ID09PSAwXG4gICAgICA/IDRcbiAgICAgIDogMTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IE1hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyBjb21wb25lbnRzKTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgZGF0YVR5cGUsIGlucHV0U2hhcGUubGVuZ3RoLCBpQ29tcG9uZW50cyk7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgsIGNvbXBvbmVudHMpO1xuICAgIGxldCBhc3NpZ25tZW50OiBzdHJpbmc7XG4gICAgaWYgKGRhdGFUeXBlID09PSBEYXRhVHlwZS5ib29sKSB7XG4gICAgICBjb25zdCBzaW5nbGVBc3NpZ25tZW50ID0gKHJlc1N0cjogc3RyaW5nLCB4OiBudW1iZXIsIHR5cGVDYXN0ID0gJycpID0+IGBcbiAgICAgICAgICBsZXQgb3V0cHV0SW5kaWNlcyR7eH0gPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoYG91dHB1dE9mZnNldCArICR7eH11YCl9O1xuICAgICAgICAgIGxldCBvZmZzZXQke3h9ID0gJHtpbnB1dC5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldChgb3V0cHV0SW5kaWNlcyR7eH1gLCBvdXRwdXQpfTtcbiAgICAgICAgICBsZXQgaW5kZXgke3h9ID0gb2Zmc2V0JHt4fSAvIDR1O1xuICAgICAgICAgIGxldCBjb21wb25lbnQke3h9ID0gb2Zmc2V0JHt4fSAlIDR1O1xuICAgICAgICAgICR7cmVzU3RyfVske3h9XSA9ICR7dHlwZUNhc3R9KCR7aW5wdXQuZ2V0QnlPZmZzZXQoYGluZGV4JHt4fWApfVtjb21wb25lbnQke3h9XSk7XG4gICAgICAgIGA7XG4gICAgICBhc3NpZ25tZW50ID0gYFxuICAgICAgICBsZXQgb3V0cHV0T2Zmc2V0ID0gZ2xvYmFsX2lkeCAqICR7Y29tcG9uZW50c307XG4gICAgICAgIHZhciBkYXRhID0gdmVjNDx1MzI+KDApO1xuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAwLCAndTMyJyl9XG4gICAgICAgICR7c2luZ2xlQXNzaWdubWVudCgnZGF0YScsIDEsICd1MzInKX1cbiAgICAgICAgJHtzaW5nbGVBc3NpZ25tZW50KCdkYXRhJywgMiwgJ3UzMicpfVxuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAzLCAndTMyJyl9XG4gICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ2RhdGEnKX1cbiAgICAgIH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NpZ25tZW50ID0gYFxuICAgICAgICBsZXQgb3V0cHV0SW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcyhgZ2xvYmFsX2lkeCAqICR7Y29tcG9uZW50c31gKX07XG4gICAgICAgIGxldCBpbnB1dE9mZnNldCA9ICR7aW5wdXQuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoJ291dHB1dEluZGljZXMnLCBvdXRwdXQpfTtcbiAgICAgICAgbGV0IGRhdGEgPSAke291dHB1dC50eXBlLnZhbHVlfSgke2lucHV0LmdldEJ5T2Zmc2V0KGBpbnB1dE9mZnNldCAvICR7aUNvbXBvbmVudHN9YCl9KTtcbiAgICAgICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAnZGF0YScpfVxuICAgICAgfWA7XG4gICAgfVxuICAgIHJldHVybiBgXG4gICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3JtKCd2ZWNfc2l6ZScsICd1MzInKS5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBvdXRwdXQpfVxuICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLnZlY19zaXplJyl9XG4gICAgJHthc3NpZ25tZW50fWA7XG4gIH07XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRTaGFwZSwgb3V0cHV0U2hhcGUpLFxuICBdO1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdFeHBhbmQnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke291dHB1dFNoYXBlLmxlbmd0aH07JHtpQ29tcG9uZW50c30ke2NvbXBvbmVudHN9YCwgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuayddIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBleHBhbmQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRXhwYW5kUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMpLCB7IGlucHV0czogWzBdIH0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxuICBXT1JLR1JPVVBfU0laRSxcbn0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0ICogYXMgdW5hcnkgZnJvbSAnLi91bmFyeS1vcCc7XG5cbi8vIEdFTFUgaXMgZGVmaW5lZCBhcyBZPTAuNSpYKigxK3RhbmgoMC43OTc4ODUqWCswLjAzNTY3NypYKlgqWCkpLCB3aGVyZSBYIG1heSBwcmUtYWRkIGEgYmlhcy5cblxuY29uc3QgY3JlYXRlRmFzdEdlbHVQcm9ncmFtSW5mbyA9IChpbnB1dFRlbnNvcnM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dFRlbnNvcnNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShpbnB1dFRlbnNvcnNbMF0uZGltcyk7XG4gIGNvbnN0IGJpYXNMZW5ndGggPSBTaGFwZVV0aWwuc2l6ZShpbnB1dFRlbnNvcnNbMV0uZGltcyk7XG4gIC8vIGNhbiBvbmx5IHVzZSB2ZWM0IHdoZW4gYmlhcyBsZW5ndGggaXMgbXVsdGlwbGUgb2YgNFxuICBjb25zdCB1c2VWZWM0ID0gYmlhc0xlbmd0aCAlIDQgPT09IDA7XG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcik6IHN0cmluZyA9PiB7XG4gICAgY29uc3QgeCA9IGlucHV0VmFyaWFibGUoJ3gnLCBkYXRhVHlwZSwgWzFdLCA0KTtcbiAgICBjb25zdCBiaWFzID0gaW5wdXRWYXJpYWJsZSgnYmlhcycsIGRhdGFUeXBlLCBbMV0sIDQpO1xuICAgIGNvbnN0IHkgPSBvdXRwdXRWYXJpYWJsZSgneScsIGRhdGFUeXBlLCBbMV0sIDQpO1xuXG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3ZlY19zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2JpYXNfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcblxuICAgIGNvbnN0IHNpbmdsZUVsZW1lbnRCaWFzID0gKGk6IDAgfCAxIHwgMiB8IDMpID0+IGBcbiAgICAgIGxldCBiaWFzJHtpfV9vZmZzZXQ6IHUzMiA9IChnbG9iYWxfaWR4ICogNCArICR7aX0pICUgdW5pZm9ybXMuYmlhc19zaXplO1xuICAgICAgbGV0IGJpYXMke2l9ID0gJHtiaWFzLmdldEJ5T2Zmc2V0KGBiaWFzJHtpfV9vZmZzZXQgLyA0YCl9W2JpYXMke2l9X29mZnNldCAlIDRdO2A7XG4gICAgY29uc3QgYmlhc0dldEV4cHJlc3Npb24gPSB1c2VWZWM0XG4gICAgICA/IGBcbiAgICAgIGxldCBiaWFzID0gJHtiaWFzLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4ICUgKHVuaWZvcm1zLmJpYXNfc2l6ZSAvIDQpJyl9O2BcbiAgICAgIDogYCR7c2luZ2xlRWxlbWVudEJpYXMoMCl9JHtzaW5nbGVFbGVtZW50QmlhcygxKX0ke3NpbmdsZUVsZW1lbnRCaWFzKDIpfSR7c2luZ2xlRWxlbWVudEJpYXMoMyl9XG4gICAgICBsZXQgYmlhcyA9ICR7eC50eXBlLnZhbHVlfShiaWFzMCwgYmlhczEsIGJpYXMyLCBiaWFzMyk7YDtcblxuICAgIHJldHVybiBgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyh4LCBiaWFzLCB5KX1cblxuICAgICR7dW5hcnkuZmFzdEdlbHVJbXBsKHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUoZGF0YVR5cGUpKX1cblxuICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydChXT1JLR1JPVVBfU0laRSl9XG4gICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfdmVjX3NpemUnKX1cblxuICAgICAgbGV0IHggPSAke3guZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAke2JpYXNHZXRFeHByZXNzaW9ufVxuICAgICAgbGV0IHhfaW4gPSB4ICsgYmlhcztcbiAgICAgICR7eS5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIHVuYXJ5LmZhc3RHZWx1RXhwcmVzc2lvbigneF9pbicpKX1cbiAgICB9YDtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdGYXN0R2VsdVdpdGhCaWFzJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHt1c2VWZWM0fWAsIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3R5cGUnLCAndHlwZSddIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6IChpbnB1dHMpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBpbnB1dHNbMF0uZGltcywgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA0KSB9LFxuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYmlhc0xlbmd0aCB9LFxuICAgICAgXSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyBXT1JLR1JPVVBfU0laRSAvIDQpIH0sXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgZmFzdEdlbHUgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgaWYgKGNvbnRleHQuaW5wdXRzLmxlbmd0aCA8IDIgfHwgU2hhcGVVdGlsLnNpemUoY29udGV4dC5pbnB1dHNbMV0uZGltcykgPT09IDApIHtcbiAgICB1bmFyeS5mYXN0R2VsdShjb250ZXh0KTtcbiAgfSBlbHNlIHtcbiAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRmFzdEdlbHVQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cykpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdhdGhlckF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBheGlzOiBudW1iZXI7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dhdGhlciByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxufTtcblxuY29uc3QgY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IEdhdGhlckF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgaW5kaWNlc1NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG5cbiAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0UmFuayk7XG5cbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDApO1xuICBvdXRwdXRTaGFwZS5zcGxpY2UoYXhpcywgMSwgLi4uaW5kaWNlc1NoYXBlKTtcblxuICBjb25zdCBheGlzRGltTGltaXQgPSBpbnB1dFNoYXBlW2F4aXNdO1xuICBjb25zdCBjb21wb25lbnRzID0gaW5wdXRzWzBdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ib29sID8gNCA6IDE7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBNYXRoLmNlaWwoU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gY29tcG9uZW50cyk7XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5pbnQzMiwgZGF0YTogYXhpc0RpbUxpbWl0IH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGF4aXMgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMsIG91dHB1dFNoYXBlKSxcbiAgXTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBkYXRhID0gaW5wdXRWYXJpYWJsZSgnZGF0YScsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBpbmRpY2VzID0gaW5wdXRWYXJpYWJsZSgnaW5wdXRJbmRpY2VzJywgaW5wdXRzWzFdLmRhdGFUeXBlLCBpbnB1dHNbMV0uZGltcy5sZW5ndGgpO1xuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG5cbiAgICBjb25zdCBjYWxjRGF0YUluZGljZXMgPSAoeDogbnVtYmVyIHwgc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICAgIGNvbnN0IGluZGljZXNSYW5rID0gaW5kaWNlc1NoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBjYWxjU3RyID0gYHZhciBpbmRpY2VzSW5kaWNlcyR7eH0gID0gJHtpbmRpY2VzLnR5cGUuaW5kaWNlc30oMCk7YDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlc1Jhbms7IGkrKykge1xuICAgICAgICBjYWxjU3RyICs9IGAke2luZGljZXNSYW5rID4gMSA/IGBpbmRpY2VzSW5kaWNlcyR7eH1bJHtpfV1gIDogYGluZGljZXNJbmRpY2VzJHt4fWB9ID0gJHtcbiAgICAgICAgICBvdXRwdXRTaGFwZS5sZW5ndGggPiAxID8gYG91dHB1dEluZGljZXMke3h9W3VuaWZvcm1zLmF4aXMgKyAke2l9XWAgOiBgb3V0cHV0SW5kaWNlcyR7eH1gXG4gICAgICAgIH07YDtcbiAgICAgIH1cbiAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgIHZhciBpZHgke3h9ID0gJHtpbmRpY2VzLmdldEJ5SW5kaWNlcyhgaW5kaWNlc0luZGljZXMke3h9YCl9O1xuICAgICAgICAgIGlmIChpZHgke3h9IDwgMCkge1xuICAgICAgICAgICAgaWR4JHt4fSA9IGlkeCR7eH0gKyB1bmlmb3Jtcy5heGlzRGltTGltaXQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBkYXRhSW5kaWNlcyR7eH0gOiAke2RhdGEudHlwZS5pbmRpY2VzfTtcbiAgICAgICAgYDtcbiAgICAgIGZvciAobGV0IGkgPSAwLCBqID0gMDsgaSA8IGlucHV0UmFuazsgaSsrKSB7XG4gICAgICAgIGlmIChpID09PSBheGlzKSB7XG4gICAgICAgICAgY2FsY1N0ciArPSBgJHtpbnB1dFJhbmsgPiAxID8gYGRhdGFJbmRpY2VzJHt4fVske2l9XWAgOiBgZGF0YUluZGljZXMke3h9YH0gPSB1MzIoaWR4JHt4fSk7YDtcbiAgICAgICAgICBqICs9IGluZGljZXNSYW5rO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbGNTdHIgKz0gYCR7aW5wdXRSYW5rID4gMSA/IGBkYXRhSW5kaWNlcyR7eH1bJHtpfV1gIDogYGRhdGFJbmRpY2VzJHt4fWB9ID0gJHtcbiAgICAgICAgICAgIG91dHB1dFNoYXBlLmxlbmd0aCA+IDEgPyBgb3V0cHV0SW5kaWNlcyR7eH1bJHtqfV1gIDogYG91dHB1dEluZGljZXMke3h9YFxuICAgICAgICAgIH07YDtcbiAgICAgICAgICBqKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBjYWxjU3RyO1xuICAgIH07XG4gICAgbGV0IGFzc2lnbm1lbnQ6IHN0cmluZztcbiAgICBpZiAoaW5wdXRzWzBdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ib29sKSB7XG4gICAgICBjb25zdCBzaW5nbGVBc3NpZ25tZW50ID0gKHJlc1N0cjogc3RyaW5nLCB4OiBudW1iZXIsIHR5cGVDYXN0ID0gJycpID0+IGBcbiAgICAgICAgICBsZXQgb3V0cHV0SW5kaWNlcyR7eH0gPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoYG91dHB1dE9mZnNldCArICR7eH11YCl9O1xuICAgICAgICAgICR7Y2FsY0RhdGFJbmRpY2VzKHgpfTtcbiAgICAgICAgICBsZXQgb2Zmc2V0JHt4fSA9ICR7ZGF0YS5pbmRpY2VzVG9PZmZzZXQoYGRhdGFJbmRpY2VzJHt4fWApfTtcbiAgICAgICAgICBsZXQgaW5kZXgke3h9ID0gb2Zmc2V0JHt4fSAvIDR1O1xuICAgICAgICAgIGxldCBjb21wb25lbnQke3h9ID0gb2Zmc2V0JHt4fSAlIDR1O1xuICAgICAgICAgICR7cmVzU3RyfVske3h9XSA9ICR7dHlwZUNhc3R9KCR7ZGF0YS5nZXRCeU9mZnNldChgaW5kZXgke3h9YCl9W2NvbXBvbmVudCR7eH1dKTtcbiAgICAgICAgYDtcbiAgICAgIGFzc2lnbm1lbnQgPSBgXG4gICAgICAgIGxldCBvdXRwdXRPZmZzZXQgPSBnbG9iYWxfaWR4ICogJHtjb21wb25lbnRzfTtcbiAgICAgICAgdmFyIHZhbHVlID0gdmVjNDx1MzI+KDApO1xuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ3ZhbHVlJywgMCwgJ3UzMicpfVxuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ3ZhbHVlJywgMSwgJ3UzMicpfVxuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ3ZhbHVlJywgMiwgJ3UzMicpfVxuICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ3ZhbHVlJywgMywgJ3UzMicpfVxuICAgICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICd2YWx1ZScpfVxuICAgICAgYDtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzaWdubWVudCA9IGBcbiAgICAgIGxldCBvdXRwdXRJbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgICAgJHtjYWxjRGF0YUluZGljZXMoJycpfTtcbiAgICAgIGxldCB2YWx1ZSA9ICR7ZGF0YS5nZXRCeUluZGljZXMoJ2RhdGFJbmRpY2VzJyl9O1xuICAgICAgJHtvdXRwdXQuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAndmFsdWUnKX07XG4gICAgICBgO1xuICAgIH1cbiAgICByZXR1cm4gYFxuICAgICAgJHtzaGFkZXJIZWxwZXJcbiAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0U2l6ZScsICd1MzInKVxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdheGlzRGltTGltaXQnLCAnaTMyJylcbiAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnYXhpcycsICd1MzInKVxuICAgICAgICAuZGVjbGFyZVZhcmlhYmxlcyhkYXRhLCBpbmRpY2VzLCBvdXRwdXQpfVxuICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dFNpemUnKX1cbiAgICAgICAgJHthc3NpZ25tZW50fVxuICAgICAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0dhdGhlcicsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuaycsICdyYW5rJ10gfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2F0aGVyQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEdhdGhlckF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogYXR0cmlidXRlcy5heGlzIGFzIG51bWJlciB9KTtcblxuZXhwb3J0IGNvbnN0IGdhdGhlciA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogR2F0aGVyQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUdhdGhlclByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyLCBVbmlmb3Jtc0FycmF5VHlwZSB9IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBHYXRoZXJOREF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBiYXRjaERpbXM6IG51bWJlcjtcbn1cblxuY29uc3QgY29tcHV0ZVNsaWNlT2Zmc2V0cyA9IChcbiAgY29udGV4dDogQ29tcHV0ZUNvbnRleHQsXG4gIGluZGljZXNEYXRhOiBUZW5zb3JWaWV3LFxuICBzaXplc0Zyb21TbGljZURpbXNEYXRhOiBudW1iZXJbXSxcbiAgYmF0Y2hEaW1zOiBudW1iZXIsXG4gIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIG51bVNsaWNlczogbnVtYmVyLFxuICBudW1TbGljZXNQZXJCYXRjaDogbnVtYmVyLFxuICBpbnB1dEJhdGNoU3RyaWRlOiBudW1iZXIsXG4gIG51bVNsaWNlRGltczogbnVtYmVyLFxuKSA9PiB7XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogbnVtU2xpY2VzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGJhdGNoRGltcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBpbnB1dERpbXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogc2l6ZXNGcm9tU2xpY2VEaW1zRGF0YSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBudW1TbGljZXNQZXJCYXRjaCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBpbnB1dEJhdGNoU3RyaWRlIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG51bVNsaWNlRGltcyB9LFxuICBdO1xuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW251bVNsaWNlc107XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGluZGljZXNEYXRhLmRpbXMsIG91dHB1dFNoYXBlKSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgaW5kaWNlcyA9IGlucHV0VmFyaWFibGUoJ2luZGljZXNfZGF0YScsIGluZGljZXNEYXRhLmRhdGFUeXBlLCBpbmRpY2VzRGF0YS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ2lucHV0X3NsaWNlX29mZnNldHNfZGF0YScsIERhdGFUeXBlLnVpbnQzMiwgMSwgMSk7XG4gICAgY29uc3QgdmFyaWFibGVzID0gW2luZGljZXMsIG91dHB1dF07XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnYmF0Y2hfZGltcycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdpbnB1dF9kaW1zJywgdHlwZTogJ3UzMicsIGxlbmd0aDogaW5wdXREaW1zLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnc2l6ZXNfZnJvbV9zbGljZV9kaW1zX2RhdGEnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBzaXplc0Zyb21TbGljZURpbXNEYXRhLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnbnVtX3NsaWNlc19wZXJfYmF0Y2gnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnaW5wdXRfYmF0Y2hfc3RyaWRlJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ251bV9zbGljZV9kaW1zJywgdHlwZTogJ3UzMicgfSxcbiAgICBdO1xuICAgIHJldHVybiBgXG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4udmFyaWFibGVzKX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cbiAgICBsZXQgYmF0Y2hfaWR4ID0gZ2xvYmFsX2lkeCAvIHVuaWZvcm1zLm51bV9zbGljZXNfcGVyX2JhdGNoO1xuICAgIGxldCBiYXNlX29mZnNldCA9IGJhdGNoX2lkeCAqIHVuaWZvcm1zLmlucHV0X2JhdGNoX3N0cmlkZTtcblxuICAgIGxldCBzbGljZV9pbmRpY2VzX2Jhc2Vfb2Zmc2V0ID0gZ2xvYmFsX2lkeCAqIHVuaWZvcm1zLm51bV9zbGljZV9kaW1zO1xuICAgIHZhciByZWxhdGl2ZV9zbGljZV9vZmZzZXQgPSAwO1xuICAgIGZvciAodmFyIGRpbV9pZHggPSAwdTsgZGltX2lkeCA8IHVuaWZvcm1zLm51bV9zbGljZV9kaW1zOyBkaW1faWR4ICsrKSB7XG4gICAgICB2YXIgaW5kZXggPSBpMzIoaW5kaWNlc19kYXRhW2RpbV9pZHggKyBzbGljZV9pbmRpY2VzX2Jhc2Vfb2Zmc2V0XS54KTtcbiAgICAgIGxldCBpbnB1dF9kaW1faWR4ID0gdW5pZm9ybXMuYmF0Y2hfZGltcyArIGRpbV9pZHg7XG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgICR7XG4gICAgICAgICAgaW5wdXREaW1zLmxlbmd0aCA9PT0gMVxuICAgICAgICAgICAgPyAnaW5kZXggKz0gaTMyKHVuaWZvcm1zLmlucHV0X2RpbXMpOydcbiAgICAgICAgICAgIDogJ2luZGV4ICs9IGkzMih1bmlmb3Jtcy5pbnB1dF9kaW1zW2lucHV0X2RpbV9pZHhdKTsnXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgICR7XG4gICAgICAgIHNpemVzRnJvbVNsaWNlRGltc0RhdGEubGVuZ3RoID09PSAxXG4gICAgICAgICAgPyAncmVsYXRpdmVfc2xpY2Vfb2Zmc2V0ICs9IGluZGV4ICogaTMyKHVuaWZvcm1zLnNpemVzX2Zyb21fc2xpY2VfZGltc19kYXRhKTsnXG4gICAgICAgICAgOiAncmVsYXRpdmVfc2xpY2Vfb2Zmc2V0ICs9IGluZGV4ICogaTMyKHVuaWZvcm1zLnNpemVzX2Zyb21fc2xpY2VfZGltc19kYXRhW2RpbV9pZHhdKTsnXG4gICAgICB9XG4gICAgfVxuXG4gICAgaW5wdXRfc2xpY2Vfb2Zmc2V0c19kYXRhW2dsb2JhbF9pZHhdID0gIGJhc2Vfb2Zmc2V0ICsgdTMyKHJlbGF0aXZlX3NsaWNlX29mZnNldCk7XG4gIH1gO1xuICB9O1xuXG4gIHJldHVybiBjb250ZXh0LmNvbXB1dGUoXG4gICAge1xuICAgICAgbmFtZTogJ2NvbXB1dGVTbGljZU9mZnNldHMnLFxuICAgICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7aW5wdXREaW1zLmxlbmd0aH1fJHtzaXplc0Zyb21TbGljZURpbXNEYXRhLmxlbmd0aH1gLCBpbnB1dERlcGVuZGVuY2llczogWydyYW5rJ10gfSxcbiAgICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogY29udGV4dC5pbnB1dHNbMV0uZGF0YVR5cGUgfV0sXG4gICAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG51bVNsaWNlcyAvIDY0KSB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgICB9KSxcbiAgICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICB9LFxuICAgIHsgaW5wdXRzOiBbaW5kaWNlc0RhdGFdLCBvdXRwdXRzOiBbLTFdIH0sXG4gIClbMF07XG59O1xuXG5leHBvcnQgY29uc3QgZ2F0aGVyTkQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEdhdGhlck5EQXR0cmlidXRlcykgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbnB1dFR5cGUgPSBpbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGluZGljZXNTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCBudW1TbGljZURpbXMgPSBpbmRpY2VzU2hhcGVbaW5kaWNlc1NoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBudW1TbGljZXMgPSBTaGFwZVV0aWwuc2l6ZVRvRGltZW5zaW9uKGluZGljZXNTaGFwZSwgaW5kaWNlc1NoYXBlLmxlbmd0aCAtIDEpO1xuICBjb25zdCBzbGljZVNpemUgPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXRTaGFwZSwgYXR0cmlidXRlcy5iYXRjaERpbXMgKyBudW1TbGljZURpbXMpO1xuICBjb25zdCBudW1CYXRjaGVzID0gU2hhcGVVdGlsLnNpemVUb0RpbWVuc2lvbihpbnB1dFNoYXBlLCBhdHRyaWJ1dGVzLmJhdGNoRGltcyk7XG4gIGNvbnN0IGlucHV0QmF0Y2hTdHJpZGUgPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXRTaGFwZSwgYXR0cmlidXRlcy5iYXRjaERpbXMpO1xuICBjb25zdCBudW1TbGljZXNQZXJCYXRjaCA9IG51bVNsaWNlcyAvIG51bUJhdGNoZXM7XG4gIGNvbnN0IHNpemVzRnJvbVNsaWNlRGltcyA9IG5ldyBBcnJheShudW1TbGljZURpbXMpO1xuICBsZXQgcnVubmluZ1Byb2R1Y3QgPSBzbGljZVNpemU7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtU2xpY2VEaW1zOyArK2kpIHtcbiAgICBzaXplc0Zyb21TbGljZURpbXNbbnVtU2xpY2VEaW1zIC0gMSAtIGldID0gcnVubmluZ1Byb2R1Y3Q7XG4gICAgcnVubmluZ1Byb2R1Y3QgKj0gaW5wdXRTaGFwZVthdHRyaWJ1dGVzLmJhdGNoRGltcyArIG51bVNsaWNlRGltcyAtIDEgLSBpXTtcbiAgfVxuXG4gIGNvbnN0IGlucHV0U2xpY2VPZmZzZXRzID0gY29tcHV0ZVNsaWNlT2Zmc2V0cyhcbiAgICBjb250ZXh0LFxuICAgIGlucHV0c1sxXSxcbiAgICBzaXplc0Zyb21TbGljZURpbXMsXG4gICAgYXR0cmlidXRlcy5iYXRjaERpbXMsXG4gICAgaW5wdXRTaGFwZSxcbiAgICBudW1TbGljZXMsXG4gICAgbnVtU2xpY2VzUGVyQmF0Y2gsXG4gICAgaW5wdXRCYXRjaFN0cmlkZSxcbiAgICBudW1TbGljZURpbXMsXG4gICk7XG5cbiAgY29uc3QgbGFzdEluZGljZXNEaW1lbnNpb24gPSBhdHRyaWJ1dGVzLmJhdGNoRGltcyArIG51bVNsaWNlRGltcztcbiAgaWYgKGxhc3RJbmRpY2VzRGltZW5zaW9uID4gaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2xhc3QgZGltZW5zaW9uIG9mIGluZGljZXMgbXVzdCBub3QgYmUgbGFyZ2VyIHRoYW4gcmFuayBvZiBpbnB1dCB0ZW5zb3InKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5kaWNlc1NoYXBlLnNsaWNlKDAsIC0xKS5jb25jYXQoaW5wdXRTaGFwZS5zbGljZShsYXN0SW5kaWNlc0RpbWVuc2lvbikpO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBzbGljZVNpemUgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgaW5wdXRTbGljZU9mZnNldHMuZGltcywgb3V0cHV0U2hhcGUpLFxuICBdO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnZGF0YScsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBpbmRpY2VzID0gaW5wdXRWYXJpYWJsZSgnc2xpY2Vfb2Zmc2V0cycsIERhdGFUeXBlLnVpbnQzMiwgaW5wdXRTbGljZU9mZnNldHMuZGltcy5sZW5ndGgpO1xuXG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgICByZXR1cm4gYFxuICAgICAgICAgICR7c2hhZGVySGVscGVyXG4gICAgICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdvdXRwdXRfc2l6ZScsICd1MzInKVxuICAgICAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnc2xpY2Vfc2l6ZScsICd1MzInKVxuICAgICAgICAgICAgLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIGluZGljZXMsIG91dHB1dCl9XG4gICAgICAgICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgICAgICAgbGV0IHNsaWNlX29mZnNldCA9IHNsaWNlX29mZnNldHNbZ2xvYmFsX2lkeCAvIHVuaWZvcm1zLnNsaWNlX3NpemVdO1xuICAgICAgICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9IGRhdGFbdTMyKHNsaWNlX29mZnNldCkgKyBnbG9iYWxfaWR4ICUgdW5pZm9ybXMuc2xpY2Vfc2l6ZV07XG4gICAgICAgIH1gO1xuICB9O1xuICBjb250ZXh0LmNvbXB1dGUoXG4gICAge1xuICAgICAgbmFtZTogJ0dhdGhlck5EJyxcbiAgICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnLCAncmFuayddIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0VHlwZSB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgICB9KSxcbiAgICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICB9LFxuICAgIHsgaW5wdXRzOiBbaW5wdXRzWzBdLCBpbnB1dFNsaWNlT2Zmc2V0c10gfSxcbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdhdGhlck5EQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEdhdGhlck5EQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGJhdGNoRGltcyA9IGF0dHJpYnV0ZXMuYmF0Y2hfZGltcyBhcyBudW1iZXI7XG4gIHJldHVybiB7XG4gICAgYmF0Y2hEaW1zLFxuICAgIGNhY2hlS2V5OiAnJyxcbiAgfTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHRlbnNvclR5cGVUb1dzZ2xWYWx1ZVR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2F0aGVyQmxvY2tRdWFudGl6ZWRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgZ2F0aGVyQXhpczogbnVtYmVyO1xuICBxdWFudGl6ZUF4aXM6IG51bWJlcjtcbiAgYmxvY2tTaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogR2F0aGVyQmxvY2tRdWFudGl6ZWRBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoIDwgMyB8fCBpbnB1dHMubGVuZ3RoID4gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignR2F0aGVyQmxvY2tRdWFudGl6ZWQgcmVxdWlyZXMgMyBvciA0IGlucHV0cy4nKTtcbiAgfVxuICBjb25zdCBxdWFudGl6ZUF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLnF1YW50aXplQXhpcywgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgY29uc3QgYmxvY2tTaXplID0gYXR0cmlidXRlcy5ibG9ja1NpemU7XG4gIGNvbnN0IGRhdGEgPSBpbnB1dHNbMF07XG4gIGNvbnN0IHNjYWxlcyA9IGlucHV0c1syXTtcbiAgY29uc3QgemVyb1BvaW50ID0gaW5wdXRzLmxlbmd0aCA9PT0gNCA/IGlucHV0c1szXSA6IHVuZGVmaW5lZDtcbiAgaWYgKFxuICAgIHNjYWxlcy5kaW1zLmxlbmd0aCAhPT0gZGF0YS5kaW1zLmxlbmd0aCB8fFxuICAgICFkYXRhLmRpbXNcbiAgICAgIC5tYXAoKGQsIGkpID0+IChpID09PSBxdWFudGl6ZUF4aXMgPyBNYXRoLmNlaWwoZCAvIGJsb2NrU2l6ZSkgPT09IHNjYWxlcy5kaW1zW2ldIDogZCA9PT0gc2NhbGVzLmRpbXNbaV0pKVxuICAgICAgLnJlZHVjZSgoYSwgYikgPT4gYSAmJiBiLCB0cnVlKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnU2NhbGVzIG11c3QgaGF2ZSB0aGUgc2FtZSByYW5rIGFzIHRoZSBpbnB1dCB0ZW5zb3IgYW5kIHRoZSBkaW1zIHNob3VsZCBtYXRjaCBleGNlcHQgb24gZ2F0aGVyQXhpcy4nLFxuICAgICk7XG4gIH1cbiAgLy8gVE9ETyBVbmNvbW1lbnQgdGhlIGZvbGxvd2luZyBjaGVjayBvbmNlIHRoZSB0ZXN0IGNhc2UgY3JlYXRpb24gY29kZSBpcyBmaXhlZCB0byBjcmVhdGUgZGF0YSBjb3JyZWN0bHkgYWxpZ25lZC5cbiAgLy8gY29uc3QgaW5kaWNlcyA9IGlucHV0c1sxXTtcbiAgLy8gY29uc3QgdmFsaWRJbmRleCA9IChpbmRleDogbnVtYmVyKSA9PiBpbmRleCA+PSAwICYmIGluZGV4IDwgZGF0YS5kaW1zW2F0dHJpYnV0ZXMuZ2F0aGVyQXhpc107XG4gIC8vIGlmIChpbmRpY2VzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5pbnQzMiAmJiBpbmRpY2VzLmdldEludDMyQXJyYXkoKS5zb21lKCh2KSA9PiAhdmFsaWRJbmRleCh2KSkgfHxcbiAgLy8gICAgIGluZGljZXMuZGF0YVR5cGUgPT09IERhdGFUeXBlLmludDY0ICYmIGluZGljZXMuZ2V0QmlnSW50NjRBcnJheSgpLnNvbWUoKHYpID0+ICF2YWxpZEluZGV4KE51bWJlcih2KSkpKSB7XG4gIC8vICAgdGhyb3cgbmV3IEVycm9yKCdJbmRpY2VzIG11c3QgYmUgd2l0aGluIHRoZSBib3VuZHMgb2YgdGhlIGdhdGhlckF4aXMuJyk7XG4gIC8vIH1cbiAgaWYgKHplcm9Qb2ludCkge1xuICAgIGlmICh6ZXJvUG9pbnQuZGF0YVR5cGUgIT09IGRhdGEuZGF0YVR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignWmVybyBwb2ludCBtdXN0IGhhdmUgdGhlIHNhbWUgZGF0YSB0eXBlIGFzIHRoZSBpbnB1dCB0ZW5zb3IuJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHplcm9Qb2ludC5kaW1zLmxlbmd0aCAhPT0gc2NhbGVzLmRpbXMubGVuZ3RoIHx8XG4gICAgICAhemVyb1BvaW50LmRpbXMubWFwKChkLCBpKSA9PiBkID09PSBzY2FsZXMuZGltc1tpXSkucmVkdWNlKChhLCBiKSA9PiBhICYmIGIsIHRydWUpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdaZXJvIHBvaW50IG11c3QgaGF2ZSB0aGUgc2FtZSByYW5rIGFzIHRoZSBpbnB1dCB0ZW5zb3IgYW5kIHRoZSBkaW1zIHNob3VsZCBtYXRjaCBleGNlcHQgb24gcXVhbnRpemVBeGlzLicsXG4gICAgICApO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgY3JlYXRlR2F0aGVyQmxvY2tRdWFudGl6ZWRQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IEdhdGhlckJsb2NrUXVhbnRpemVkQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbmRpY2VzU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGdhdGhlckF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmdhdGhlckF4aXMsIGlucHV0UmFuayk7XG4gIGNvbnN0IHF1YW50aXplQXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMucXVhbnRpemVBeGlzLCBpbnB1dFJhbmspO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoMCk7XG4gIG91dHB1dFNoYXBlLnNwbGljZShnYXRoZXJBeGlzLCAxLCAuLi5pbmRpY2VzU2hhcGUpO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCBvdXRwdXRUeXBlID0gaW5wdXRzWzJdLmRhdGFUeXBlO1xuICBjb25zdCBpbnB1dFR5cGUgPSBpbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGlzU2lnbmVkID0gaW5wdXRUeXBlID09PSBEYXRhVHlwZS5pbnQ0OyAvLyBpbnB1dCBkYXRhIHR5cGUgaXMgZWl0aGVyIGludDQgb3IgdWludDQuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBxdWFudGl6ZUF4aXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogZ2F0aGVyQXhpcyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBhdHRyaWJ1dGVzLmJsb2NrU2l6ZSB9LFxuICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKC4uLmlucHV0cy5tYXAoKGlucHV0LCBfKSA9PiBpbnB1dC5kaW1zKSwgb3V0cHV0U2hhcGUpLFxuICBdO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGRhdGEgPSBpbnB1dFZhcmlhYmxlKCdkYXRhJywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcy5sZW5ndGgpO1xuICAgIGNvbnN0IGluZGljZXMgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dEluZGljZXMnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3Qgc2NhbGVzID0gaW5wdXRWYXJpYWJsZSgnc2NhbGVzJywgaW5wdXRzWzJdLmRhdGFUeXBlLCBpbnB1dHNbMl0uZGltcy5sZW5ndGgpO1xuICAgIGNvbnN0IHplcm9Qb2ludCA9XG4gICAgICBpbnB1dHMubGVuZ3RoID4gMyA/IGlucHV0VmFyaWFibGUoJ3plcm9Qb2ludCcsIGlucHV0c1szXS5kYXRhVHlwZSwgaW5wdXRzWzNdLmRpbXMubGVuZ3RoKSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0Jywgb3V0cHV0VHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgICBjb25zdCBpbnB1dFZhcmlhYmxlcyA9IFtkYXRhLCBpbmRpY2VzLCBzY2FsZXNdO1xuICAgIGlmICh6ZXJvUG9pbnQpIHtcbiAgICAgIGlucHV0VmFyaWFibGVzLnB1c2goemVyb1BvaW50KTtcbiAgICB9XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAncXVhbnRpemVfYXhpcycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdnYXRoZXJfYXhpcycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdibG9ja19zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICBdO1xuICAgIHJldHVybiBgXG4gICAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICBsZXQgb3V0cHV0X2luZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAgIHZhciBpbmRpY2VzX2luZGljZXMgPSAke2luZGljZXMudHlwZS5pbmRpY2VzfSgwKTtcbiAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgIGlmIChpbmRpY2VzU2hhcGUubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICBmb3IgKHZhciBpOiB1MzIgPSAwOyBpIDwgJHtpbmRpY2VzU2hhcGUubGVuZ3RofTsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRfaW5kaWNlcycsICd1bmlmb3Jtcy5nYXRoZXJfYXhpcyArIGknKX07XG4gICAgICAgICAgICAke2luZGljZXMuaW5kaWNlc1NldCgnaW5kaWNlc19pbmRpY2VzJywgJ2knLCAnaW5kZXgnKX07XG4gICAgICAgICAgfWA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgaW5kaWNlc19pbmRpY2VzID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCAndW5pZm9ybXMuZ2F0aGVyX2F4aXMnKX07YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCl9O1xuICAgICAgICB2YXIgZGF0YV9pbmRpY2VzID0gJHtkYXRhLnR5cGUuaW5kaWNlc30oMCk7XG4gICAgICAgIGZvciAodmFyIGk6IHUzMiA9IDA7IGkgPCB1bmlmb3Jtcy5nYXRoZXJfYXhpczsgaSsrKSB7XG4gICAgICAgICAgbGV0IGluZGV4ID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCAnaScpfTtcbiAgICAgICAgICAke2RhdGEuaW5kaWNlc1NldCgnZGF0YV9pbmRpY2VzJywgJ2knLCAnaW5kZXgnKX07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGluZGV4X2Zyb21faW5kaWNlcyA9ICR7aW5kaWNlcy5nZXRCeUluZGljZXMoJ2luZGljZXNfaW5kaWNlcycpfTtcbiAgICAgICAgaWYgKGluZGV4X2Zyb21faW5kaWNlcyA8IDApIHtcbiAgICAgICAgICBpbmRleF9mcm9tX2luZGljZXMgKz0gJHtpbnB1dFNoYXBlW2dhdGhlckF4aXNdfTtcbiAgICAgICAgfVxuICAgICAgICAke2RhdGEuaW5kaWNlc1NldCgnZGF0YV9pbmRpY2VzJywgJ3VuaWZvcm1zLmdhdGhlcl9heGlzJywgJ3UzMihpbmRleF9mcm9tX2luZGljZXMpJyl9O1xuICAgICAgICBmb3IgKHZhciBpID0gdW5pZm9ybXMuZ2F0aGVyX2F4aXMgKyAxOyBpIDwgJHtvdXRwdXRTaGFwZS5sZW5ndGh9OyBpKyspIHtcbiAgICAgICAgICBsZXQgaW5kZXggPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRfaW5kaWNlcycsIGBpICsgJHtpbmRpY2VzU2hhcGUubGVuZ3RofSAtIDFgKX07XG4gICAgICAgICAgJHtkYXRhLmluZGljZXNTZXQoJ2RhdGFfaW5kaWNlcycsICdpJywgJ2luZGV4Jyl9O1xuICAgICAgICB9XG4gICAgICAgIGxldCBkYXRhX29mZnNldCA9ICR7ZGF0YS5pbmRpY2VzVG9PZmZzZXQoJ2RhdGFfaW5kaWNlcycpfTtcbiAgICAgICAgbGV0IGRhdGFfaW5kZXggPSBkYXRhX29mZnNldCAlIDg7XG4gICAgICAgIC8vIENvbnZlcnQgNC1iaXQgcGFja2VkIGRhdGEgdG8gOC1iaXQgcGFja2VkIGRhdGEuXG4gICAgICAgIGxldCBwYWNrZWRfNGJpdF9xdWFudGl6ZWRfZGF0YSA9ICR7ZGF0YS5nZXRCeU9mZnNldCgnZGF0YV9vZmZzZXQgLyA4Jyl9O1xuICAgICAgICBsZXQgcGFja2VkXzhiaXRfcXVhbnRpemVkX2RhdGEgPSAocGFja2VkXzRiaXRfcXVhbnRpemVkX2RhdGEgPj4gKDQgKiAoZGF0YV9pbmRleCAlIDIpKSkgJiAweDBmMGYwZjBmO1xuICAgICAgICBsZXQgcXVhbnRpemVkX2RhdGFfdmVjID0gJHtpc1NpZ25lZCA/ICd1bnBhY2s0eEk4JyA6ICd1bnBhY2s0eFU4J30odTMyKHBhY2tlZF84Yml0X3F1YW50aXplZF9kYXRhKSk7XG4gICAgICAgIGxldCBxdWFudGl6ZWRfZGF0YSA9IHF1YW50aXplZF9kYXRhX3ZlY1tkYXRhX2luZGV4IC8gMl07XG4gICAgICAgIHZhciBzY2FsZV9pbmRpY2VzID0gZGF0YV9pbmRpY2VzO1xuICAgICAgICBsZXQgcXVhbnRpemVfYXhpc19pbmRleCA9ICR7c2NhbGVzLmluZGljZXNHZXQoJ2RhdGFfaW5kaWNlcycsICd1bmlmb3Jtcy5xdWFudGl6ZV9heGlzJyl9IC8gdW5pZm9ybXMuYmxvY2tfc2l6ZTtcbiAgICAgICAgJHtzY2FsZXMuaW5kaWNlc1NldCgnc2NhbGVfaW5kaWNlcycsICd1bmlmb3Jtcy5xdWFudGl6ZV9heGlzJywgJ3F1YW50aXplX2F4aXNfaW5kZXgnKX07XG4gICAgICAgIHZhciBzY2FsZSA9ICR7c2NhbGVzLmdldEJ5SW5kaWNlcygnc2NhbGVfaW5kaWNlcycpfTtcbiAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgIGlmICghemVyb1BvaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gJ3ZhciB6ZXJvX3BvaW50ID0gMCc7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2luZGljZXMgPSBzY2FsZV9pbmRpY2VzO1xuICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF9vZmZzZXQgPSAke3plcm9Qb2ludC5pbmRpY2VzVG9PZmZzZXQoJ3plcm9fcG9pbnRfaW5kaWNlcycpfTtcbiAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfaW5kZXggPSB6ZXJvX3BvaW50X29mZnNldCAlIDg7XG4gICAgICAgICAgICAgIGxldCBwYWNrZWRfNGJpdF96ZXJvX3BvaW50cyA9ICR7emVyb1BvaW50LmdldEJ5T2Zmc2V0KCd6ZXJvX3BvaW50X29mZnNldCAvIDgnKX07XG4gICAgICAgICAgICAgIGxldCBwYWNrZWRfOGJpdF96ZXJvX3BvaW50cyA9IChwYWNrZWRfNGJpdF96ZXJvX3BvaW50cyA+PiAoNCAqICh6ZXJvX3BvaW50X2luZGV4ICUgMikpKSAmIDB4MGYwZjBmMGY7XG4gICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X3ZlYyA9ICR7aXNTaWduZWQgPyAndW5wYWNrNHhJOCcgOiAndW5wYWNrNHhVOCd9KHUzMihwYWNrZWRfOGJpdF96ZXJvX3BvaW50cykpO1xuICAgICAgICAgICAgICBsZXQgemVyb19wb2ludCA9IHplcm9fcG9pbnRfdmVjW3plcm9fcG9pbnRfaW5kZXggLyAyXTtgO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKX07XG4gICAgICAgIGxldCBkZXF1YW50aXplZF9kYXRhID0gJHt0ZW5zb3JUeXBlVG9Xc2dsVmFsdWVUeXBlKG91dHB1dFR5cGUpfShxdWFudGl6ZWRfZGF0YSAtIHplcm9fcG9pbnQpICogc2NhbGU7XG4gICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ2RlcXVhbnRpemVkX2RhdGEnKX07XG4gICAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0dhdGhlckJsb2NrUXVhbnRpemVkJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX07JHtpbnB1dHNcbiAgICAgICAgLmZpbHRlcigoXywgaSkgPT4gaSAhPT0gMSlcbiAgICAgICAgLm1hcCgoaW5wdXQpID0+IGlucHV0LmRpbXMuam9pbignXycpKVxuICAgICAgICAuam9pbignOycpfWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llczogQXJyYXkuZnJvbSh7IGxlbmd0aDogaW5wdXRzLmxlbmd0aCB9LCAoX3YsIF9pKSA9PiAncmFuaycpLFxuICAgIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogb3V0cHV0VHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgZ2F0aGVyQmxvY2tRdWFudGl6ZWQgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEdhdGhlckJsb2NrUXVhbnRpemVkQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUdhdGhlckJsb2NrUXVhbnRpemVkUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdhdGhlckJsb2NrUXVhbnRpemVkQXR0cmlidXRlcyA9IChcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4pOiBHYXRoZXJCbG9ja1F1YW50aXplZEF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBibG9ja1NpemU6IGF0dHJpYnV0ZXMuYmxvY2tTaXplIGFzIG51bWJlcixcbiAgICBnYXRoZXJBeGlzOiBhdHRyaWJ1dGVzLmdhdGhlckF4aXMgYXMgbnVtYmVyLFxuICAgIHF1YW50aXplQXhpczogYXR0cmlidXRlcy5xdWFudGl6ZUF4aXMgYXMgbnVtYmVyLFxuICB9KTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHsgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsIGlucHV0VmFyaWFibGUsIG91dHB1dFZhcmlhYmxlLCBTaGFkZXJIZWxwZXIgfSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2F0aGVyRWxlbWVudHNBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgYXhpczogbnVtYmVyO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHYXRoZXJFbGVtZW50cyByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHYXRoZXJFbGVtZW50cyByZXF1aXJlcyB0aGF0IHRoZSBkYXRhIGlucHV0IGJlIHJhbmsgPj0gMS4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IGlucHV0c1sxXS5kaW1zLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgR2F0aGVyRWxlbWVudHMgcmVxdWlyZXMgdGhhdCB0aGUgZGF0YSBpbnB1dCBhbmRcbiAgICAgICAgICAgICAgICAgICAgIGluZGljZXMgaW5wdXQgdGVuc29ycyBiZSBvZiBzYW1lIHJhbmsuYCk7XG4gIH1cbn07XG5cbmNvbnN0IGNyZWF0ZUdhdGhlckVsZW1lbnRzUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBHYXRoZXJFbGVtZW50c0F0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgaW5wdXRPdXRwdXREYXRhVHlwZSA9IGlucHV0c1swXS5kYXRhVHlwZTtcbiAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3QgaW5kaWNlc1NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IGluZGljZXNEYXRhVHlwZSA9IGlucHV0c1sxXS5kYXRhVHlwZTtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRSYW5rKTtcbiAgY29uc3QgYXhpc0RpbUxpbWl0ID0gaW5wdXRTaGFwZVtheGlzXTtcblxuICBjb25zdCBvdXRwdXRTaGFwZSA9IGluZGljZXNTaGFwZS5zbGljZSgwKTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcblxuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgaW5wdXRPdXRwdXREYXRhVHlwZSwgaW5wdXRSYW5rKTtcbiAgY29uc3QgaW5kaWNlcyA9IGlucHV0VmFyaWFibGUoJ2luZGljZXNJbnB1dCcsIGluZGljZXNEYXRhVHlwZSwgaW5kaWNlc1NoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dE91dHB1dERhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IGF4aXNEaW1MaW1pdCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBheGlzIH0sXG4gIF07XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0U2hhcGUsIGluZGljZXNTaGFwZSwgb3V0cHV0U2hhcGUpKTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3JhbmsnLCAncmFuayddO1xuXG4gIC8vIGludDY0IGluZGljZXMgd291bGQgYmUgdHJlYXRlZCBhcyBsaXR0bGUgZW5kaWFuIGkzMiB3aXRoIGFzc3VtcHRpb24gdGhleSBmYWxsIGluIGkzMiBsaW1pdHNcbiAgLy8gVGhhdCBhc3N1bXB0aW9uIGlzIHNhZmUgYXMgaXQncyBub3QgcG9zc2libGUgdG8gYWxsb2NhdGUgPjJnYiBidWZmZXIgZm9yIGlucHV0IHRlbnNvclxuICAvLyBJbnB1dCBkYXRhIHdpbGwgYmUgdHJlYXRlZCBhcyB1MzIgb3IgdHdvIHUzMiBmb3IgOC1ieXRlIHRlbnNvcnNcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICAgICAke3NoYWRlckhlbHBlclxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdvdXRwdXRTaXplJywgJ3UzMicpXG4gICAgICAgIC5yZWdpc3RlclVuaWZvcm0oJ2F4aXNEaW1MaW1pdCcsICdpMzInKVxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdheGlzJywgJ3UzMicpXG4gICAgICAgIC5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCBpbmRpY2VzLCBvdXRwdXQpfVxuICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRTaXplJyl9XG5cbiAgICAgIGxldCBvdXRwdXRJbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuXG4gICAgICB2YXIgaWR4ID0gJHtpbmRpY2VzLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4Jyl9O1xuICAgICAgaWYgKGlkeCA8IDApIHtcbiAgICAgICAgaWR4ID0gaWR4ICsgdW5pZm9ybXMuYXhpc0RpbUxpbWl0O1xuICAgICAgfVxuICAgICAgdmFyIGlucHV0SW5kaWNlcyA9ICR7aW5wdXQudHlwZS5pbmRpY2VzfShvdXRwdXRJbmRpY2VzKTtcbiAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRJbmRpY2VzJywgJ3VuaWZvcm1zLmF4aXMnLCAndTMyKGlkeCknKX07XG4gICAgICBsZXQgdmFsdWUgPSAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRJbmRpY2VzJyl9O1xuXG4gICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICd2YWx1ZScpfTtcbiAgfWA7XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnR2F0aGVyRWxlbWVudHMnLFxuICAgIHNoYWRlckNhY2hlOiB7IGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdhdGhlckVsZW1lbnRzQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEdhdGhlckVsZW1lbnRzQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBheGlzOiBhdHRyaWJ1dGVzLmF4aXMgYXMgbnVtYmVyIH0pO1xuXG5leHBvcnQgY29uc3QgZ2F0aGVyRWxlbWVudHMgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEdhdGhlckVsZW1lbnRzQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBpbnB1dHMgPSBjb250ZXh0LmlucHV0cztcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUdhdGhlckVsZW1lbnRzUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IEdlbW1VdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIEluZGljZXNIZWxwZXIsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBpcyBtaXNzaW5nJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPCAyIHx8IGlucHV0cy5sZW5ndGggPiAzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhaWQgaW5wdXQgbnVtYmVyLicpO1xuICB9XG5cbiAgLy8gJ0MnIGNhbiBiZSBvZiBkaW1lbnNpb25hbGl0eSAwLCAxIG9yIDIgb25seVxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0uZGltcy5sZW5ndGggPiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlIG9mIEMnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGF0YVR5cGUgIT09IGlucHV0c1sxXS5kYXRhVHlwZSB8fCAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMF0uZGF0YVR5cGUgIT09IGlucHV0c1syXS5kYXRhVHlwZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHR5cGVzIGFyZSBtaXNtYXRjaGVkJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2VtbUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICB0cmFuc0E6IGJvb2xlYW47XG4gIHRyYW5zQjogYm9vbGVhbjtcbiAgYWxwaGE6IG51bWJlcjtcbiAgYmV0YTogbnVtYmVyO1xufVxuXG5jb25zdCBjcmVhdGVHZW1tUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IEdlbW1BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICBjb25zdCBiU2hhcGUgPSBpbnB1dHNbMV0uZGltcy5zbGljZSgpO1xuICBjb25zdCBbTSwgTiwgS10gPSBHZW1tVXRpbC5nZXRTaGFwZU9mR2VtbVJlc3VsdChcbiAgICBhU2hhcGUsXG4gICAgYXR0cmlidXRlcy50cmFuc0EsXG4gICAgYlNoYXBlLFxuICAgIGF0dHJpYnV0ZXMudHJhbnNCLFxuICAgIGlucHV0cy5sZW5ndGggPT09IDMgPyBpbnB1dHNbMl0uZGltcyA6IHVuZGVmaW5lZCxcbiAgKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbTSwgTl07XG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgZ2VtbSBvbiB0aGUgZ2l2ZW4gdGVuc29yc1wiKTtcbiAgfVxuICBjb25zdCB0aWxlU2l6ZSA9IDE2O1xuICBjb25zdCBudW1UaWxlTiA9IE1hdGguY2VpbChOIC8gdGlsZVNpemUpO1xuICBjb25zdCBudW1UaWxlTSA9IE1hdGguY2VpbChNIC8gdGlsZVNpemUpO1xuICAvLyBUT0RPOiBGaW5kIHRoZSBjb25kaXRpb24gd2hlbiB0byB1c2UgdGhlIG5haXZlIG9uZS5cbiAgY29uc3QgdXNlU2hhcmVkID0gdHJ1ZTtcblxuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHVzZVNoYXJlZCA/IG51bVRpbGVOIDogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBNIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IE4gfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogSyB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuZmxvYXQsIGRhdGE6IGF0dHJpYnV0ZXMuYWxwaGEgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBhdHRyaWJ1dGVzLmJldGEgfSxcbiAgXTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3R5cGUnLCAndHlwZSddO1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMykge1xuICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0c1syXS5kaW1zKSk7XG4gICAgaW5wdXREZXBlbmRlbmNpZXMucHVzaCgncmFuaycpO1xuICB9XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dHB1dFNoYXBlKSk7XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgbGV0IGxpbmUgPSAnJztcbiAgICBpZiAoYXR0cmlidXRlcy50cmFuc0EgJiYgYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGxpbmUgPSAndmFsdWUgKz0gYVtrICogdW5pZm9ybXMuTSArIG1dICogYltuICogdW5pZm9ybXMuSyArIGtdOyc7XG4gICAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGxpbmUgPSAndmFsdWUgKz0gYVtrICogdW5pZm9ybXMuTSArIG1dICogYltrICogdW5pZm9ybXMuTiArIG5dOyc7XG4gICAgfSBlbHNlIGlmICghYXR0cmlidXRlcy50cmFuc0EgJiYgYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGxpbmUgPSAndmFsdWUgKz0gYVttICogdW5pZm9ybXMuSyArIGtdICogYltuICogdW5pZm9ybXMuSyArIGtdOyc7XG4gICAgfSBlbHNlIGlmICghYXR0cmlidXRlcy50cmFuc0EgJiYgIWF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICBsaW5lID0gJ3ZhbHVlICs9IGFbbSAqIHVuaWZvcm1zLksgKyBrXSAqIGJbayAqIHVuaWZvcm1zLk4gKyBuXTsnO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbGN1bGF0ZUFscGhhID0gYXR0cmlidXRlcy5hbHBoYSA9PT0gMSA/ICcnIDogJ3ZhbHVlICo9IHVuaWZvcm1zLmFscGhhOyc7XG4gICAgY29uc3QgYSA9IGlucHV0VmFyaWFibGUoJ2EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zKTtcbiAgICBjb25zdCBiID0gaW5wdXRWYXJpYWJsZSgnYicsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMpO1xuICAgIGNvbnN0IGRhdGFUeXBlID0gYS50eXBlLnZhbHVlO1xuICAgIGxldCBjOiBJbmRpY2VzSGVscGVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3QgdmFyaWFibGVzID0gW2EsIGJdO1xuICAgIGlmIChpbnB1dHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBjID0gaW5wdXRWYXJpYWJsZSgnYycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoKTtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKGMpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dCk7XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnTScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdOJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ0snLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnYWxwaGEnLCB0eXBlOiAnZjMyJyB9LFxuICAgICAgeyBuYW1lOiAnYmV0YScsIHR5cGU6ICdmMzInIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKC4uLnZhcmlhYmxlcyl9XG5cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cblxuICAgIGxldCBtID0gZ2xvYmFsX2lkeCAvIHVuaWZvcm1zLk47XG4gICAgbGV0IG4gPSBnbG9iYWxfaWR4ICUgdW5pZm9ybXMuTjtcblxuICAgIHZhciB2YWx1ZSA9ICR7ZGF0YVR5cGV9KDApO1xuICAgIGZvciAodmFyIGs6IHUzMiA9IDB1OyBrIDwgdW5pZm9ybXMuSzsgaysrKSB7XG4gICAgICAke2xpbmV9XG4gICAgfVxuXG4gICAgJHtjYWxjdWxhdGVBbHBoYX1cbiAgICAkeygoKSA9PiB7XG4gICAgICBpZiAoYyAhPSBudWxsKSB7XG4gICAgICAgIHJldHVybiBgbGV0IGNPZmZzZXQgPSAke2MuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoJ3ZlYzIobSwgbiknLCBvdXRwdXQpfTsgdmFsdWUgKz0gJHtcbiAgICAgICAgICBkYXRhVHlwZVxuICAgICAgICB9KHVuaWZvcm1zLmJldGEpICogJHtjLmdldEJ5T2Zmc2V0KCdjT2Zmc2V0Jyl9O2A7XG4gICAgICB9XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSkoKX1cbiAgICBvdXRwdXRbZ2xvYmFsX2lkeF0gPSB2YWx1ZTtcbiAgfWA7XG4gIH07XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlU2hhcmVkID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgYSA9IGlucHV0VmFyaWFibGUoJ2EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zKTtcbiAgICBjb25zdCBiID0gaW5wdXRWYXJpYWJsZSgnYicsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMpO1xuICAgIGxldCBjOiBJbmRpY2VzSGVscGVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3QgdmFyaWFibGVzID0gW2EsIGJdO1xuICAgIGlmIChpbnB1dHMubGVuZ3RoID09PSAzKSB7XG4gICAgICBjID0gaW5wdXRWYXJpYWJsZSgnYycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoKTtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKGMpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dCk7XG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnbnVtX3RpbGVfbicsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdNJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ04nLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnSycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdhbHBoYScsIHR5cGU6ICdmMzInIH0sXG4gICAgICB7IG5hbWU6ICdiZXRhJywgdHlwZTogJ2YzMicgfSxcbiAgICBdO1xuXG4gICAgbGV0IGNhbGNSZXN1bHQgPSAnJztcbiAgICBsZXQgZmlsbFdvcmtncm91cE1lbW9yeSA9ICcnO1xuICAgIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiBhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgICAgZmlsbFdvcmtncm91cE1lbW9yeSA9IGBcbiAgICAgIHZhciBjb2wgPSB0aWxlX3Jvd19zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICB2YXIgcm93ID0ga19zdGFydCArIGxvY2FsX2lkLnk7XG4gICAgICBpZiAoY29sIDwgdW5pZm9ybXMuTSAmJiByb3cgPCB1bmlmb3Jtcy5LKSB7XG4gICAgICAgIHRpbGVfYVtsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9IGFbcm93ICogdW5pZm9ybXMuTSArIGNvbF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aWxlX2FbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSAke2EudHlwZS52YWx1ZX0oMCk7XG4gICAgICB9XG5cbiAgICAgIGNvbCA9IGtfc3RhcnQgKyBsb2NhbF9pZC54O1xuICAgICAgcm93ID0gdGlsZV9jb2xfc3RhcnQgKyBsb2NhbF9pZC55O1xuICAgICAgaWYgKGNvbCA8IHVuaWZvcm1zLksgJiYgcm93IDwgdW5pZm9ybXMuTikge1xuICAgICAgICB0aWxlX2JbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSBiW3JvdyAqIHVuaWZvcm1zLksgKyBjb2xdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGlsZV9iW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gJHtiLnR5cGUudmFsdWV9KDApO1xuICAgICAgfVxuICAgICAgYDtcbiAgICAgIGNhbGNSZXN1bHQgPSBgdmFsdWUgKz0gdGlsZV9hW2tdW2xvY2FsX2lkLnldICogdGlsZV9iW2xvY2FsX2lkLnhdW2tdO2A7XG4gICAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGZpbGxXb3JrZ3JvdXBNZW1vcnkgPSBgXG4gICAgICB2YXIgY29sID0gdGlsZV9yb3dfc3RhcnQgKyBsb2NhbF9pZC54O1xuICAgICAgdmFyIHJvdyA9IGtfc3RhcnQgKyBsb2NhbF9pZC55O1xuICAgICAgaWYgKGNvbCA8IHVuaWZvcm1zLk0gJiYgcm93IDwgdW5pZm9ybXMuSykge1xuICAgICAgICB0aWxlX2FbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSBhW3JvdyAqIHVuaWZvcm1zLk0gKyBjb2xdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGlsZV9hW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gJHthLnR5cGUudmFsdWV9KDApO1xuICAgICAgfVxuXG4gICAgICBjb2wgPSB0aWxlX2NvbF9zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICByb3cgPSBrX3N0YXJ0ICsgbG9jYWxfaWQueTtcbiAgICAgIGlmIChjb2wgPCB1bmlmb3Jtcy5OICYmIHJvdyA8IHVuaWZvcm1zLkspIHtcbiAgICAgICAgdGlsZV9iW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gYltyb3cgKiB1bmlmb3Jtcy5OICsgY29sXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbGVfYltsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9ICR7Yi50eXBlLnZhbHVlfSgwKTtcbiAgICAgIH1cbiAgICAgIGA7XG4gICAgICBjYWxjUmVzdWx0ID0gYHZhbHVlICs9IHRpbGVfYVtrXVtsb2NhbF9pZC55XSAqIHRpbGVfYltrXVtsb2NhbF9pZC54XTtgO1xuICAgIH0gZWxzZSBpZiAoIWF0dHJpYnV0ZXMudHJhbnNBICYmIGF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICBmaWxsV29ya2dyb3VwTWVtb3J5ID0gYFxuICAgICAgdmFyIGNvbCA9IGtfc3RhcnQgKyBsb2NhbF9pZC54O1xuICAgICAgdmFyIHJvdyA9IHRpbGVfcm93X3N0YXJ0ICsgbG9jYWxfaWQueTtcbiAgICAgIGlmIChjb2wgPCB1bmlmb3Jtcy5LICYmIHJvdyA8IHVuaWZvcm1zLk0pIHtcbiAgICAgICAgdGlsZV9hW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gYVtyb3cgKiB1bmlmb3Jtcy5LICsgY29sXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbGVfYVtsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9ICR7YS50eXBlLnZhbHVlfSgwKTtcbiAgICAgIH1cblxuICAgICAgY29sID0ga19zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICByb3cgPSB0aWxlX2NvbF9zdGFydCArIGxvY2FsX2lkLnk7XG4gICAgICBpZiAoY29sIDwgdW5pZm9ybXMuSyAmJiByb3cgPCB1bmlmb3Jtcy5OKSB7XG4gICAgICAgIHRpbGVfYltsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9IGJbcm93ICogdW5pZm9ybXMuSyArIGNvbF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aWxlX2JbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSAke2IudHlwZS52YWx1ZX0oMCk7XG4gICAgICB9XG4gICAgICBgO1xuICAgICAgY2FsY1Jlc3VsdCA9IGB2YWx1ZSArPSB0aWxlX2FbbG9jYWxfaWQueV1ba10gKiB0aWxlX2JbbG9jYWxfaWQueF1ba107YDtcbiAgICB9IGVsc2UgaWYgKCFhdHRyaWJ1dGVzLnRyYW5zQSAmJiAhYXR0cmlidXRlcy50cmFuc0IpIHtcbiAgICAgIGZpbGxXb3JrZ3JvdXBNZW1vcnkgPSBgXG4gICAgICB2YXIgY29sID0ga19zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICB2YXIgcm93ID0gdGlsZV9yb3dfc3RhcnQgKyBsb2NhbF9pZC55O1xuICAgICAgaWYgKGNvbCA8IHVuaWZvcm1zLksgJiYgcm93IDwgdW5pZm9ybXMuTSkge1xuICAgICAgICB0aWxlX2FbbG9jYWxfaWQueV1bbG9jYWxfaWQueF0gPSBhW3JvdyAqIHVuaWZvcm1zLksgKyBjb2xdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGlsZV9hW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gJHthLnR5cGUudmFsdWV9KDApO1xuICAgICAgfVxuXG4gICAgICBjb2wgPSB0aWxlX2NvbF9zdGFydCArIGxvY2FsX2lkLng7XG4gICAgICByb3cgPSBrX3N0YXJ0ICsgbG9jYWxfaWQueTtcbiAgICAgIGlmIChjb2wgPCB1bmlmb3Jtcy5OICYmIHJvdyA8IHVuaWZvcm1zLkspIHtcbiAgICAgICAgdGlsZV9iW2xvY2FsX2lkLnldW2xvY2FsX2lkLnhdID0gYltyb3cgKiB1bmlmb3Jtcy5OICsgY29sXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbGVfYltsb2NhbF9pZC55XVtsb2NhbF9pZC54XSA9ICR7Yi50eXBlLnZhbHVlfSgwKTtcbiAgICAgIH1cbiAgICAgIGA7XG4gICAgICBjYWxjUmVzdWx0ID0gYHZhbHVlICs9IHRpbGVfYVtsb2NhbF9pZC55XVtrXSAqIHRpbGVfYltrXVtsb2NhbF9pZC54XTtgO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbGN1bGF0ZUFscGhhID0gYXR0cmlidXRlcy5hbHBoYSA9PT0gMSA/ICcnIDogJ3ZhbHVlICo9IHVuaWZvcm1zLmFscGhhOyc7XG5cbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKC4uLnZhcmlhYmxlcyl9XG4gIHZhcjx3b3JrZ3JvdXA+IHRpbGVfYTogYXJyYXk8YXJyYXk8JHthLnR5cGUuc3RvcmFnZX0sICR7dGlsZVNpemV9PiwgJHt0aWxlU2l6ZX0+O1xuICB2YXI8d29ya2dyb3VwPiB0aWxlX2I6IGFycmF5PGFycmF5PCR7Yi50eXBlLnN0b3JhZ2V9LCAke3RpbGVTaXplfT4sICR7dGlsZVNpemV9PjtcbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KFt0aWxlU2l6ZSwgdGlsZVNpemUsIDFdKX1cbiAgICBsZXQgdGlsZV9jb2xfc3RhcnQgPSAod29ya2dyb3VwX2luZGV4ICUgdW5pZm9ybXMubnVtX3RpbGVfbikgKiAke3RpbGVTaXplfTtcbiAgICBsZXQgdGlsZV9yb3dfc3RhcnQgPSAod29ya2dyb3VwX2luZGV4IC8gdW5pZm9ybXMubnVtX3RpbGVfbikgKiAke3RpbGVTaXplfTtcbiAgICBsZXQgbnVtX3RpbGVzID0gKHVuaWZvcm1zLksgLSAxKSAvICR7dGlsZVNpemV9ICsgMTtcbiAgICB2YXIga19zdGFydCA9IDB1O1xuICAgIHZhciB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUudmFsdWV9KDApO1xuICAgIGZvciAodmFyIHQ6IHUzMiA9IDB1OyB0IDwgbnVtX3RpbGVzOyB0KyspIHtcbiAgICAgICR7ZmlsbFdvcmtncm91cE1lbW9yeX1cbiAgICAgIGtfc3RhcnQgPSBrX3N0YXJ0ICsgJHt0aWxlU2l6ZX07XG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgIGZvciAodmFyIGs6IHUzMiA9IDB1OyBrIDwgJHt0aWxlU2l6ZX07IGsrKykge1xuICAgICAgICAke2NhbGNSZXN1bHR9XG4gICAgICB9XG4gICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgfVxuXG4gICAgJHtjYWxjdWxhdGVBbHBoYX1cbiAgICBsZXQgbSA9IHRpbGVfcm93X3N0YXJ0ICsgbG9jYWxfaWQueTtcbiAgICBsZXQgbiA9IHRpbGVfY29sX3N0YXJ0ICsgbG9jYWxfaWQueDtcbiAgICAkeygoKSA9PiB7XG4gICAgICBpZiAoYyAhPSBudWxsKSB7XG4gICAgICAgIHJldHVybiBgbGV0IGNPZmZzZXQgPSAke2MuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoJ3ZlYzIobSwgbiknLCBvdXRwdXQpfTsgdmFsdWUgKz0gJHtcbiAgICAgICAgICBvdXRwdXQudHlwZS52YWx1ZVxuICAgICAgICB9KHVuaWZvcm1zLmJldGEpICogJHtjLmdldEJ5T2Zmc2V0KCdjT2Zmc2V0Jyl9O2A7XG4gICAgICB9XG4gICAgICByZXR1cm4gJyc7XG4gICAgfSkoKX1cbiAgICBpZiAobSA8IHVuaWZvcm1zLk0gJiYgbiA8IHVuaWZvcm1zLk4pIHtcbiAgICAgIG91dHB1dFttICogdW5pZm9ybXMuTiArIG5dID0gdmFsdWU7XG4gICAgfVxuICB9YDtcbiAgfTtcblxuICBpZiAodXNlU2hhcmVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6ICdHZW1tU2hhcmVkJyxcbiAgICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9YCwgaW5wdXREZXBlbmRlbmNpZXMgfSxcbiAgICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dLFxuICAgICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IG51bVRpbGVOICogbnVtVGlsZU0gfSxcbiAgICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgICAgfSksXG4gICAgICBnZXRTaGFkZXJTb3VyY2U6IGdldFNoYWRlclNvdXJjZVNoYXJlZCxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnR2VtbScsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX1gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEdlbW1BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgdHJhbnNBID0gYXR0cmlidXRlcy50cmFuc0EgYXMgYm9vbGVhbjtcbiAgY29uc3QgdHJhbnNCID0gYXR0cmlidXRlcy50cmFuc0IgYXMgYm9vbGVhbjtcbiAgY29uc3QgYWxwaGEgPSBhdHRyaWJ1dGVzLmFscGhhIGFzIG51bWJlcjtcbiAgY29uc3QgYmV0YSA9IGF0dHJpYnV0ZXMuYmV0YSBhcyBudW1iZXI7XG4gIHJldHVybiB7XG4gICAgdHJhbnNBLFxuICAgIHRyYW5zQixcbiAgICBhbHBoYSxcbiAgICBiZXRhLFxuICAgIGNhY2hlS2V5OiBgJHthdHRyaWJ1dGVzLnRyYW5zQX07JHthdHRyaWJ1dGVzLnRyYW5zQn07JHthdHRyaWJ1dGVzLmFscGhhID09PSAxfWAsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgZ2VtbSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlR2VtbVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBJbmRpY2VzSGVscGVyLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5sZXQgW2lkeE4sIGlkeEMsIGlkeEgsIGlkeFddID0gWzAsIDEsIDIsIDNdOyAvLyBOQ0hXXG50eXBlIE1vZGUgPSAnYmlsaW5lYXInIHwgJ25lYXJlc3QnIHwgJ2JpY3ViaWMnO1xudHlwZSBQYWRkaW5nTW9kZSA9ICd6ZXJvcycgfCAnYm9yZGVyJyB8ICdyZWZsZWN0aW9uJztcbnR5cGUgRm9ybWF0ID0gJ05IV0MnIHwgJ05DSFcnO1xuZXhwb3J0IGludGVyZmFjZSBHcmlkU2FtcGVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgYWxpZ25Db3JuZXJzOiBudW1iZXI7XG4gIG1vZGU6IE1vZGU7XG4gIHBhZGRpbmdNb2RlOiBQYWRkaW5nTW9kZTtcbiAgZm9ybWF0OiBGb3JtYXQ7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgNC1EIHRlbnNvciBpcyBzdXBwb3J0ZWQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBkaW1lbnNpb25zIG11c3QgYmUgZXF1YWwgdG8gZ3JpZCBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMiAhPT0gaW5wdXRzWzFdLmRpbXNbaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMV0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGxhc3QgZGltZW5zaW9uIG9mIGdyaWQgbXVzdCBiZSBlcXVhbCB0byAke2lucHV0c1swXS5kaW1zLmxlbmd0aCAtIDJ9YCk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXNbMF0gIT09IGlucHV0c1sxXS5kaW1zWzBdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdncmlkIGJhdGNoIHNpemUgbXVzdCBtYXRjaCBpbnB1dCBiYXRjaCBzaXplJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdzR2V0Q3ViaWNDb2VmZnMgPSBgXG4gIGZuIGdzX2dldF9jdWJpY19jb2VmZnMoeDogZjMyKSAtPiB2ZWM0PGYzMj4ge1xuICAgIGxldCBjdWJpY19hbHBoYSA9IC0wLjc1ZjtcbiAgICBsZXQgeF9hYnMgPSBhYnMoeCk7XG4gICAgdmFyIGNvZWZmczogdmVjNDxmMzI+O1xuICAgIGNvZWZmc1swXSA9ICgoKGN1YmljX2FscGhhICogKHhfYWJzICsgMSkgLSA1ICogY3ViaWNfYWxwaGEpICogKHhfYWJzICsgMSkgKyA4ICogY3ViaWNfYWxwaGEpICogKHhfYWJzICsgMSkgLSA0ICogY3ViaWNfYWxwaGEpO1xuICAgIGNvZWZmc1sxXSA9ICgoKGN1YmljX2FscGhhICsgMikgKiB4X2FicyAtIChjdWJpY19hbHBoYSArIDMpKSAqIHhfYWJzICogeF9hYnMgKyAxKTtcbiAgICBjb2VmZnNbMl0gPSAoKChjdWJpY19hbHBoYSArIDIpICogKDEgLSB4X2FicykgLSAoY3ViaWNfYWxwaGEgKyAzKSkgKiAoMSAtIHhfYWJzKSAqICgxIC0geF9hYnMpICsgMSk7XG4gICAgY29lZmZzWzNdID0gKCgoY3ViaWNfYWxwaGEgKiAoMiAtIHhfYWJzKSAtIDUgKiBjdWJpY19hbHBoYSkgKiAoMiAtIHhfYWJzKSArIDggKiBjdWJpY19hbHBoYSkgKiAoMiAtIHhfYWJzKSAtIDQgKiBjdWJpY19hbHBoYSk7XG4gICAgcmV0dXJuIGNvZWZmcztcbiAgfVxuYDtcblxuY29uc3QgZ3NCaWN1YmljSW50ZXJwb2xhdGUgPSAoZGF0YVR5cGU6IHN0cmluZyk6IHN0cmluZyA9PiBgXG4gIGZuIGdzX2JpY3ViaWNfaW50ZXJwb2xhdGUocDogbWF0NHg0PCR7ZGF0YVR5cGV9PiwgeDogZjMyLCB5OiBmMzIpIC0+ICR7ZGF0YVR5cGV9IHtcbiAgICB2YXIgdjogdmVjNDxmMzI+O1xuICAgIHZhciBjb2VmZnMgPSBnc19nZXRfY3ViaWNfY29lZmZzKHgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICB2W2ldID0gY29lZmZzWzBdICogcFtpXVswXSArIGNvZWZmc1sxXSAqIHBbaV1bMV0gKyBjb2VmZnNbMl0gKiBwW2ldWzJdICsgY29lZmZzWzNdICogcFtpXVszXTtcbiAgICB9XG4gICAgY29lZmZzID0gZ3NfZ2V0X2N1YmljX2NvZWZmcyh5KTtcbiAgICBsZXQgcGl4ZWwgPSAke2RhdGFUeXBlfShjb2VmZnNbMF0gKiB2WzBdICsgY29lZmZzWzFdICogdlsxXSArIGNvZWZmc1syXSAqIHZbMl0gKyBjb2VmZnNbM10gKiB2WzNdKTtcbiAgICByZXR1cm4gcGl4ZWw7XG4gIH1cbmA7XG5cbmNvbnN0IGdzRGVub3JtYWxpemUgPSAoYXR0cmlidXRlczogR3JpZFNhbXBlQXR0cmlidXRlcyk6IHN0cmluZyA9PiBgXG4gIGZuIGdzX2Rlbm9ybWFsaXplKG46IGYzMiwgbGVuZ3RoOiBpMzIpIC0+IGYzMiB7XG4gICAgJHtcbiAgICAgIGF0dHJpYnV0ZXMuYWxpZ25Db3JuZXJzID09PSAwXG4gICAgICAgID8gYFxuICAgIC8vIGFsaWduQ29ybmVyczogZmFsc2UgPT4gWy0xLCAxXSB0byBbLTAuNSwgbGVuZ3RoIC0gMC41XVxuICAgIHJldHVybiAoKG4gKyAxLjApICogZjMyKGxlbmd0aCkgLSAxLjApIC8gMi4wO1xuICAgIGBcbiAgICAgICAgOiBgXG4gICAgLy8gYWxpZ25Db3JuZXJzOiB0cnVlID0+IFstMSwgMV0gdG8gWzAsIGxlbmd0aCAtIDFdXG4gICAgcmV0dXJuIChuICsgMS4wKSAvIDIuMCAqIChmMzIobGVuZ3RoIC0gMSkpO1xuICAgIGBcbiAgICB9XG4gIH1cbmA7XG5cbmNvbnN0IGdzUmVmbGVjdCA9IChhdHRyaWJ1dGVzOiBHcmlkU2FtcGVBdHRyaWJ1dGVzKTogc3RyaW5nID0+IGBcbiAgJHtcbiAgICBhdHRyaWJ1dGVzLnBhZGRpbmdNb2RlID09PSAncmVmbGVjdGlvbidcbiAgICAgID8gYFxuICAgICAgZm4gZ3NfcmVmbGVjdCh4OiBpMzIsIHhfbWluOiBmMzIsIHhfbWF4OiBmMzIpIC0+IHUzMiB7XG4gICAgICAgIHZhciBkeCA9IDAuMDtcbiAgICAgICAgdmFyIGZ4ID0gZjMyKHgpO1xuICAgICAgICBsZXQgcmFuZ2UgPSB4X21heCAtIHhfbWluO1xuICAgICAgICBpZiAoZnggPCB4X21pbikge1xuICAgICAgICAgIGR4ID0geF9taW4gLSBmeDtcbiAgICAgICAgICBsZXQgbiA9IHUzMihkeCAvIHJhbmdlKTtcbiAgICAgICAgICBsZXQgciA9IGR4IC0gZjMyKG4pICogcmFuZ2U7XG4gICAgICAgICAgaWYgKG4gJSAyID09IDApIHtcbiAgICAgICAgICAgIGZ4ID0geF9taW4gKyByO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmeCA9IHhfbWF4IC0gcjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZnggPiB4X21heCkge1xuICAgICAgICAgIGR4ID0gZnggLSB4X21heDtcbiAgICAgICAgICBsZXQgbiA9IHUzMihkeCAvIHJhbmdlKTtcbiAgICAgICAgICBsZXQgciA9IGR4IC0gZjMyKG4pICogcmFuZ2U7XG4gICAgICAgICAgaWYgKG4gJSAyID09IDApIHtcbiAgICAgICAgICAgIGZ4ID0geF9tYXggLSByO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmeCA9IHhfbWluICsgcjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHUzMihmeCk7XG4gICAgICB9YFxuICAgICAgOiAnJ1xuICB9XG5gO1xuXG5jb25zdCBwaXhlbEF0R3JpZCA9IChpbnB1dDogSW5kaWNlc0hlbHBlciwgZGF0YVR5cGU6IHN0cmluZywgYXR0cmlidXRlczogR3JpZFNhbXBlQXR0cmlidXRlcyk6IHN0cmluZyA9PlxuICBgXG4gIGZuIHBpeGVsX2F0X2dyaWQocjogaTMyLCBjOiBpMzIsIEg6IGkzMiwgVzogaTMyLCBiYXRjaDogdTMyLCBjaGFubmVsOiB1MzIsIGJvcmRlcjogdmVjNDxmMzI+KSAtPiAke2RhdGFUeXBlfSB7XG4gICAgIHZhciBwaXhlbCA9ICR7ZGF0YVR5cGV9KDApO1xuICAgICB2YXIgaW5kaWNlcyA9IHZlYzQ8dTMyPigwKTtcbiAgICAgaW5kaWNlc1ske2lkeE59XSA9IGJhdGNoO1xuICAgICBpbmRpY2VzWyR7aWR4Q31dID0gY2hhbm5lbDtgICtcbiAgKCgpID0+IHtcbiAgICBzd2l0Y2ggKGF0dHJpYnV0ZXMucGFkZGluZ01vZGUpIHtcbiAgICAgIGNhc2UgJ3plcm9zJzpcbiAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICBpZiAociA+PSAwICYmIHIgPCBIICYmIGMgPj0wICYmIGMgPCBXKSB7XG4gICAgICAgICAgICBpbmRpY2VzWyR7aWR4SH1dID0gdTMyKHIpO1xuICAgICAgICAgICAgaW5kaWNlc1ske2lkeFd9XSA9IHUzMihjKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuICR7ZGF0YVR5cGV9KDApO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIGNhc2UgJ2JvcmRlcic6XG4gICAgICAgIHJldHVybiBgXG4gICAgICAgICAgaW5kaWNlc1ske2lkeEh9XSA9IHUzMihjbGFtcChyLCAwLCBIIC0gMSkpO1xuICAgICAgICAgIGluZGljZXNbJHtpZHhXfV0gPSB1MzIoY2xhbXAoYywgMCwgVyAtIDEpKTtcbiAgICAgICAgYDtcbiAgICAgIGNhc2UgJ3JlZmxlY3Rpb24nOlxuICAgICAgICByZXR1cm4gYFxuICAgICAgICAgIGluZGljZXNbJHtpZHhIfV0gPSBnc19yZWZsZWN0KHIsIGJvcmRlclsxXSwgYm9yZGVyWzNdKTtcbiAgICAgICAgICBpbmRpY2VzWyR7aWR4V31dID0gZ3NfcmVmbGVjdChjLCBib3JkZXJbMF0sIGJvcmRlclsyXSk7XG4gICAgICAgIGA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHBhZGRpbmcgbW9kZSAke2F0dHJpYnV0ZXMucGFkZGluZ01vZGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH0pKCkgK1xuICBgXG4gICAgcmV0dXJuICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbmRpY2VzJyl9O1xuICB9XG5gO1xuXG5jb25zdCBjb21wdXRlUGl4ZWwgPSAob3V0cHV0OiBJbmRpY2VzSGVscGVyLCBkYXRhVHlwZTogc3RyaW5nLCBhdHRyaWJ1dGVzOiBHcmlkU2FtcGVBdHRyaWJ1dGVzKTogc3RyaW5nID0+XG4gICgoKSA9PiB7XG4gICAgc3dpdGNoIChhdHRyaWJ1dGVzLm1vZGUpIHtcbiAgICAgIGNhc2UgJ25lYXJlc3QnOlxuICAgICAgICByZXR1cm4gYFxuICAgICAgICAgIGxldCByZXN1bHQgPSBwaXhlbF9hdF9ncmlkKGkzMihyb3VuZCh5KSksIGkzMihyb3VuZCh4KSksIEhfaW4sIFdfaW4sIGluZGljZXNbJHtpZHhOfV0sIGluZGljZXNbJHtpZHhDfV0sIGJvcmRlcik7XG4gICAgICAgIGA7XG4gICAgICBjYXNlICdiaWxpbmVhcic6XG4gICAgICAgIHJldHVybiBgXG4gICAgICAgICAgbGV0IHgxID0gaTMyKGZsb29yKHgpKTtcbiAgICAgICAgICBsZXQgeTEgPSBpMzIoZmxvb3IoeSkpO1xuICAgICAgICAgIGxldCB4MiA9IHgxICsgMTtcbiAgICAgICAgICBsZXQgeTIgPSB5MSArIDE7XG5cbiAgICAgICAgICBsZXQgcDExID0gcGl4ZWxfYXRfZ3JpZCh5MSwgeDEsIEhfaW4sIFdfaW4sIGluZGljZXNbJHtpZHhOfV0sIGluZGljZXNbJHtpZHhDfV0sIGJvcmRlcik7XG4gICAgICAgICAgbGV0IHAxMiA9IHBpeGVsX2F0X2dyaWQoeTEsIHgyLCBIX2luLCBXX2luLCBpbmRpY2VzWyR7aWR4Tn1dLCBpbmRpY2VzWyR7aWR4Q31dLCBib3JkZXIpO1xuICAgICAgICAgIGxldCBwMjEgPSBwaXhlbF9hdF9ncmlkKHkyLCB4MSwgSF9pbiwgV19pbiwgaW5kaWNlc1ske2lkeE59XSwgaW5kaWNlc1ske2lkeEN9XSwgYm9yZGVyKTtcbiAgICAgICAgICBsZXQgcDIyID0gcGl4ZWxfYXRfZ3JpZCh5MiwgeDIsIEhfaW4sIFdfaW4sIGluZGljZXNbJHtpZHhOfV0sIGluZGljZXNbJHtpZHhDfV0sIGJvcmRlcik7XG5cbiAgICAgICAgICBsZXQgZHgyID0gJHtkYXRhVHlwZX0oZjMyKHgyKSAtIHgpO1xuICAgICAgICAgIGxldCBkeDEgPSAke2RhdGFUeXBlfSh4IC0gZjMyKHgxKSk7XG4gICAgICAgICAgbGV0IGR5MiA9ICR7ZGF0YVR5cGV9KGYzMih5MikgLSB5KTtcbiAgICAgICAgICBsZXQgZHkxID0gJHtkYXRhVHlwZX0oeSAtIGYzMih5MSkpO1xuICAgICAgICAgIGxldCByZXN1bHQgPSBkeTIgKiAoZHgyICogcDExICsgZHgxICogcDEyKSArIGR5MSAqIChkeDIgKiBwMjEgKyBkeDEgKiBwMjIpO1xuICAgICAgICBgO1xuICAgICAgY2FzZSAnYmljdWJpYyc6XG4gICAgICAgIHJldHVybiBgXG4gICAgICAgICAgbGV0IHgwID0gaTMyKGZsb29yKHgpKSAtIDE7XG4gICAgICAgICAgbGV0IHkwID0gaTMyKGZsb29yKHkpKSAtIDE7XG4gICAgICAgICAgdmFyIHA6IG1hdDR4NDwke2RhdGFUeXBlfT47XG4gICAgICAgICAgZm9yICh2YXIgaCA9IDA7IGggPCA0OyBoKyspIHtcbiAgICAgICAgICAgIGZvciAodmFyIHcgPSAwOyB3IDwgNDsgdysrKSB7XG4gICAgICAgICAgICAgIHBbaF1bd10gPSBwaXhlbF9hdF9ncmlkKGggKyB5MCwgdyArIHgwLCBIX2luLCBXX2luLCBpbmRpY2VzWyR7aWR4Tn1dLCBpbmRpY2VzWyR7aWR4Q31dLCBib3JkZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGxldCBkeCA9IHggLSBmMzIoeDAgKyAxKTtcbiAgICAgICAgICBsZXQgZHkgPSB5IC0gZjMyKHkwICsgMSk7XG4gICAgICAgICAgbGV0IHJlc3VsdCA9IGdzX2JpY3ViaWNfaW50ZXJwb2xhdGUocCwgZHgsIGR5KTtcbiAgICAgICAgYDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbW9kZSAke2F0dHJpYnV0ZXMubW9kZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIH1cbiAgfSkoKSArIGAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICdyZXN1bHQnKX1gO1xuXG5jb25zdCBjcmVhdGVHcmlkU2FtcGxlUHJvZ3JhbUluZm8gPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IEdyaWRTYW1wZUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHggPSBpbnB1dFZhcmlhYmxlKCd4JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcy5sZW5ndGgpO1xuICAvLyBkaXNjYXJkIGxhc3QgZGltZW5zaW9uIGZvciB1c2luZyB2ZWMyIHRvIGFjY2VzcyBncmlkIGRhdGFcbiAgY29uc3QgZ3JpZFNoYXBlID0gW2lucHV0c1sxXS5kaW1zWzBdLCBpbnB1dHNbMV0uZGltc1sxXSwgaW5wdXRzWzFdLmRpbXNbMl1dO1xuICBjb25zdCBncmlkID0gaW5wdXRWYXJpYWJsZSgnZ3JpZCcsIGlucHV0c1sxXS5kYXRhVHlwZSwgZ3JpZFNoYXBlLmxlbmd0aCwgMik7XG4gIGxldCBvdXRwdXRTaGFwZSA9IFtpbnB1dHNbMF0uZGltc1swXSwgaW5wdXRzWzBdLmRpbXNbMV0sIGlucHV0c1sxXS5kaW1zWzFdLCBpbnB1dHNbMV0uZGltc1syXV07XG4gIGlmIChhdHRyaWJ1dGVzLmZvcm1hdCA9PT0gJ05IV0MnKSB7XG4gICAgb3V0cHV0U2hhcGUgPSBbaW5wdXRzWzBdLmRpbXNbMF0sIGlucHV0c1sxXS5kaW1zWzFdLCBpbnB1dHNbMV0uZGltc1syXSwgaW5wdXRzWzBdLmRpbXNbM11dO1xuICAgIFtpZHhOLCBpZHhDLCBpZHhILCBpZHhXXSA9IFswLCAzLCAxLCAyXTtcbiAgfVxuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBkYXRhVHlwZSA9IHgudHlwZS52YWx1ZTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcblxuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgZ3JpZFNoYXBlLCBvdXRwdXRTaGFwZSksXG4gIF07XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0X3NpemUnLCAndTMyJykuZGVjbGFyZVZhcmlhYmxlcyh4LCBncmlkLCBvdXRwdXQpfVxuICAke2dzR2V0Q3ViaWNDb2VmZnN9XG4gICR7Z3NCaWN1YmljSW50ZXJwb2xhdGUoZGF0YVR5cGUpfVxuICAke2dzRGVub3JtYWxpemUoYXR0cmlidXRlcyl9XG4gICR7Z3NSZWZsZWN0KGF0dHJpYnV0ZXMpfVxuICAke3BpeGVsQXRHcmlkKHgsIGRhdGFUeXBlLCBhdHRyaWJ1dGVzKX1cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuICAgICAgbGV0IEhfaW4gPSBpMzIodW5pZm9ybXMueF9zaGFwZVske2lkeEh9XSk7XG4gICAgICBsZXQgV19pbiA9IGkzMih1bmlmb3Jtcy54X3NoYXBlWyR7aWR4V31dKTtcblxuICAgICAgJHtcbiAgICAgICAgYXR0cmlidXRlcy5hbGlnbkNvcm5lcnMgPT09IDBcbiAgICAgICAgICA/IGBcbiAgICAgIGxldCB4X21pbiA9IC0wLjU7XG4gICAgICBsZXQgeF9tYXggPSBmMzIoV19pbikgLSAwLjU7XG4gICAgICBsZXQgeV9taW4gPSAtMC41O1xuICAgICAgbGV0IHlfbWF4ID0gZjMyKEhfaW4pIC0gMC41O1xuICAgICAgYFxuICAgICAgICAgIDogYFxuICAgICAgbGV0IHhfbWluID0gMC4wO1xuICAgICAgbGV0IHhfbWF4ID0gZjMyKFdfaW4pIC0gMS4wO1xuICAgICAgbGV0IHlfbWluID0gMC4wO1xuICAgICAgbGV0IHlfbWF4ID0gZjMyKEhfaW4pIC0gMS4wO1xuICAgICAgYFxuICAgICAgfTtcbiAgICAgIGxldCBib3JkZXIgPSB2ZWM0PGYzMj4oeF9taW4sIHlfbWluLCB4X21heCwgeV9tYXgpO1xuXG4gICAgICBsZXQgaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcbiAgICAgIHZhciBncmlkX2luZGljZXMgPSB2ZWMzPHUzMj4oaW5kaWNlc1ske2lkeE59XSwgaW5kaWNlc1ske2lkeEh9XSwgaW5kaWNlc1ske2lkeFd9XSk7XG4gICAgICBsZXQgbnh5ID0gJHtncmlkLmdldEJ5SW5kaWNlcygnZ3JpZF9pbmRpY2VzJyl9O1xuICAgICAgdmFyIHggPSBnc19kZW5vcm1hbGl6ZShmMzIobnh5WzBdKSwgV19pbik7XG4gICAgICB2YXIgeSA9IGdzX2Rlbm9ybWFsaXplKGYzMihueHlbMV0pLCBIX2luKTtcblxuICAgICAgJHtjb21wdXRlUGl4ZWwob3V0cHV0LCBkYXRhVHlwZSwgYXR0cmlidXRlcyl9XG4gIH1gO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0dyaWRTYW1wbGUnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9YCwgaW5wdXREZXBlbmRlbmNpZXM6IFsndHlwZScsICd0eXBlJ10gfSxcbiAgICBnZXRSdW5EYXRhOiAoaW5wdXRzKSA9PiB7XG4gICAgICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV0sXG4gICAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgICAgfTtcbiAgICB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBncmlkU2FtcGxlID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBHcmlkU2FtcGVBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZUdyaWRTYW1wbGVQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcykpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR3JpZFNhbXBsZUF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBHcmlkU2FtcGVBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYWxpZ25Db3JuZXJzOiBhdHRyaWJ1dGVzLmFsaWduX2Nvcm5lcnMgYXMgbnVtYmVyLFxuICAgIG1vZGU6IGF0dHJpYnV0ZXMubW9kZSBhcyBNb2RlLFxuICAgIHBhZGRpbmdNb2RlOiBhdHRyaWJ1dGVzLnBhZGRpbmdfbW9kZSBhcyBQYWRkaW5nTW9kZSxcbiAgICBmb3JtYXQ6IGF0dHJpYnV0ZXMuZm9ybWF0IGFzIEZvcm1hdCxcbiAgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBHcHVEYXRhVHlwZSwgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGFwcGx5QXR0ZW50aW9uLFxuICBBdHRlbnRpb25BdHRycyxcbiAgQXR0ZW50aW9uTWFza1R5cGUsXG4gIEF0dGVudGlvblBhcmFtZXRlcnMsXG4gIEF0dGVudGlvblFrdkZvcm1hdCxcbn0gZnJvbSAnLi9hdHRlbnRpb24nO1xuaW1wb3J0IHsgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciwgVW5pZm9ybXNBcnJheVR5cGUgfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbywgVHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuY29uc3QgZ2V0SW5wdXQgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGk6IG51bWJlcikgPT5cbiAgaW5wdXRzLmxlbmd0aCA+IGkgJiYgaW5wdXRzW2ldLmRpbXMubGVuZ3RoID4gMCA/IGlucHV0c1tpXSA6IHVuZGVmaW5lZDtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGF0dHJpYnV0ZXM6IEF0dGVudGlvbkF0dHJzKTogQXR0ZW50aW9uUGFyYW1ldGVycyA9PiB7XG4gIGNvbnN0IHF1ZXJ5ID0gaW5wdXRzWzBdO1xuICBjb25zdCBrZXkgPSBnZXRJbnB1dChpbnB1dHMsIDEpO1xuICBjb25zdCB2YWx1ZSA9IGdldElucHV0KGlucHV0cywgMik7XG4gIGNvbnN0IGJpYXMgPSBnZXRJbnB1dChpbnB1dHMsIDMpO1xuICBjb25zdCBrZXlQYWRkaW5nTWFzayA9IGdldElucHV0KGlucHV0cywgNCk7XG4gIGNvbnN0IGF0dGVudGlvbkJpYXMgPSBnZXRJbnB1dChpbnB1dHMsIDUpO1xuICBjb25zdCBwYXN0S2V5ID0gZ2V0SW5wdXQoaW5wdXRzLCA2KTtcbiAgY29uc3QgcGFzdFZhbHVlID0gZ2V0SW5wdXQoaW5wdXRzLCA3KTtcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gTm90YXRpb25zOlxuICAvLyAgICBCOiBiYXRjaF9zaXplXG4gIC8vICAgIE46IG51bV9oZWFkc1xuICAvLyAgICBIOiBoZWFkX3NpemUgb2YgUSBhbmQgS1xuICAvLyAgICBIX3Y6IGhlYWRfc2l6ZSBvZiBWXG4gIC8vICAgIEQ6IGhpZGRlbl9zaXplIGZvciBRIGFuZCBLLCB3aGVyZSBEID0gTiAqIEhcbiAgLy8gICAgRF92OiBoaWRkZW5fc2l6ZSBvZiBWLCB3aGVyZSBEX3YgPSBOICogSF92XG4gIC8vICAgIFM6IHFfc2VxdWVuY2VfbGVuZ3RoXG4gIC8vICAgIFA6IHBhc3Rfc2VxdWVuY2VfbGVuZ3RoIG9mIGt2IGNhY2hlXG4gIC8vICAgIEw6IGt2X3NlcXVlbmNlX2xlbmd0aFxuICAvLyAgICBUOiB0b3RhbF9zZXF1ZW5jZV9sZW5ndGggPSBQICsgTFxuICAvLyAgICBNOiBtYXhfc2VxdWVuY2VfbGVuZ3RoIG9mIGt2IGNhY2hlIHdoZW4gcGFzdCBhbmQgcHJlc2VudCBzaGFyZSBidWZmZXJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIE11bHRpSGVhZEF0dGVudGlvbiBpbnB1dHM6XG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyAgUV9LX1ZfQlNOSCAtIG5vIHBhY2tpbmc6XG4gIC8vICAgICBxdWVyeSAgICAgICAgICAgIChRKSAgICAgICA6IChCLCBTLCBEKVxuICAvLyAgICAga2V5ICAgICAgICAgICAgICAoSykgICAgICAgOiAoQiwgTCwgRClcbiAgLy8gICAgIHZhbHVlICAgICAgICAgICAgKFYpICAgICAgIDogKEIsIEwsIERfdilcbiAgLy8gIFFfS19WX0JTTkhfQk5TSF9CTlNIIC0gY3Jvc3MgYXR0ZW50aW9uIChrdiBjYWNoZSBpcyBub3QgdXNlZCwgTCA9PSBULCBEID09IERfdik6XG4gIC8vICAgICBxdWVyeSAgICAgICAgICAgIChRKSAgICAgICA6IChCLCBTLCBEKVxuICAvLyAgICAga2V5ICAgICAgICAgICAgICAoSykgICAgICAgOiAoQiwgTiwgTCwgSClcbiAgLy8gICAgIHZhbHVlICAgICAgICAgICAgKFYpICAgICAgIDogKEIsIE4sIEwsIEhfdilcbiAgLy8gIFFfS1ZfQlNOSF9CU04ySCAtIHBhY2tlZCBrdiAoa3YgY2FjaGUgaXMgbm90IHVzZWQsIGJpYXMgaXMgbm90IGFsbG93ZWQgZm9yIHBhY2tlZCBrdik6XG4gIC8vICAgICBxdWVyeSAgICAgICAgICAgIChRKSAgICAgICA6IChCLCBTLCBEKVxuICAvLyAgICAga2V5ICAgICAgICAgICAgICAoSy9WKSAgICAgOiAoQiwgTCwgTiwgMiwgSClcbiAgLy8gICAgIHZhbHVlICAgICAgICAgICAgICAgICAgICAgIDogTm9uZVxuICAvLyAgUUtWX0JTTjNIIC0gcGFja2VkIHFrdiAoa3YgY2FjaGUgaXMgbm90IHVzZWQsIFMgPT0gTCwgRCA9PSBEX3YpOlxuICAvLyAgICAgcXVlcnkgICAgICAgICAgICAoUS9LL1YpICAgOiAoQiwgUywgTiwgMywgSClcbiAgLy8gICAgIGtleSAgICAgICAgICAgICAgICAgICAgICAgIDogTm9uZVxuICAvLyAgICAgdmFsdWUgICAgICAgICAgICAgICAgICAgICAgOiBOb25lXG4gIC8vXG4gIC8vICBPdGhlciBpbnB1dHM6XG4gIC8vICAgICBiaWFzICAgICAgICAgICAgIChRL0svVikgICA6IE5vbmUgb3IgKEQgKyBEICsgRF92KVxuICAvLyAgICAga2V5X3BhZGRpbmdfbWFzayAoSy9WKSAgICAgOiAoQikgb3IgKDMgKiBCICsgMikgb3IgKEIsIFQpIG9yIChCLCBTLCBUKVxuICAvLyAgICAgYXR0ZW50aW9uX2JpYXMgICAgICAgICAgICAgOiBOb25lIG9yIChCLCBOLCBTLCBUKSwgKDEsIE4sIFMsIFQpLCAoQiwgMSwgUywgVCkgb3IgKDEsIDEsIFMsIFQpXG4gIC8vICAgICBwYXN0X2tleSAgICAgICAgICAgICAgICAgICA6IChCLCBOLCBQLCBIKSBvciBOb25lLiBQYXN0IHN0YXRlIGlzIG9ubHkgYWxsb3dlZCBmb3IgUV9LX1ZfQlNOSC5cbiAgLy8gICAgIHBhc3RfdmFsdWUgICAgICAgICAgICAgICAgIDogKEIsIE4sIFAsIEgpIG9yIE5vbmUuIFBhc3Qgc3RhdGUgaXMgb25seSBhbGxvd2VkIGZvciBRX0tfVl9CU05ILlxuICAvL1xuICAvLyAgTm90IFN1cHBvcnRlZDpcbiAgLy8gICAgIGtleV9wYWRkaW5nX21hc2ssIHBhY2tlZCBrdiwgcGFja2VkIHFrdiwgYW5kIGJyb2FkY2FzdCBmb3IgYXR0ZW50aW9uX2JpYXMuXG5cbiAgaWYgKHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSAzICYmIHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBxdWVyeSBpcyBleHBlY3RlZCB0byBoYXZlIDMgb3IgNSBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBjb25zdCBiYXRjaFNpemUgPSBxdWVyeS5kaW1zWzBdO1xuICBjb25zdCBzZXF1ZW5jZUxlbmd0aCA9IHF1ZXJ5LmRpbXNbMV07XG4gIGNvbnN0IGhpZGRlblNpemUgPSBxdWVyeS5kaW1zLmxlbmd0aCA9PT0gMyA/IHF1ZXJ5LmRpbXNbMl0gOiBhdHRyaWJ1dGVzLm51bUhlYWRzICogcXVlcnkuZGltc1s0XTtcbiAgbGV0IGt2U2VxdWVuY2VMZW5ndGggPSBzZXF1ZW5jZUxlbmd0aDtcblxuICBsZXQgcGFzdFNlcXVlbmNlTGVuZ3RoID0gMDtcbiAgbGV0IG1heFNlcXVlbmNlTGVuZ3RoID0gMDtcbiAgY29uc3QgaGVhZFNpemUgPSBNYXRoLmZsb29yKGhpZGRlblNpemUgLyBhdHRyaWJ1dGVzLm51bUhlYWRzKTtcbiAgaWYgKHBhc3RLZXkgJiYgcGFzdFZhbHVlICYmIFNoYXBlVXRpbC5zaXplKHBhc3RLZXkuZGltcykgJiYgU2hhcGVVdGlsLnNpemUocGFzdFZhbHVlLmRpbXMpKSB7XG4gICAgaWYgKHBhc3RLZXkuZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X2tleVwiIGlzIGV4cGVjdGVkIHRvIGhhdmUgNCBkaW1lbnNpb25zJyk7XG4gICAgfVxuICAgIGlmIChwYXN0S2V5LmRpbXNbMF0gIT09IGJhdGNoU2l6ZSB8fCBwYXN0S2V5LmRpbXNbMV0gIT09IGF0dHJpYnV0ZXMubnVtSGVhZHMgfHwgcGFzdEtleS5kaW1zWzNdICE9PSBoZWFkU2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInBhc3Rfa2V5XCIgc2hhcGUgKGJhdGNoX3NpemUsIG51bV9oZWFkcywgcGFzdF9zZXF1ZW5jZV9sZW5ndGgsIGhlYWRfc2l6ZSknKTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgcGFzdFZhbHVlLmRpbXNbMF0gIT09IGJhdGNoU2l6ZSB8fFxuICAgICAgcGFzdFZhbHVlLmRpbXNbMV0gIT09IGF0dHJpYnV0ZXMubnVtSGVhZHMgfHxcbiAgICAgIHBhc3RWYWx1ZS5kaW1zWzNdICE9PSBoZWFkU2l6ZVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInBhc3RfdmFsdWVcIiBzaGFwZSAoYmF0Y2hfc2l6ZSwgbnVtX2hlYWRzLCBwYXN0X3NlcXVlbmNlX2xlbmd0aCwgaGVhZF9zaXplKScpO1xuICAgIH1cbiAgICBpZiAocGFzdEtleS5kaW1zWzJdICE9PSBwYXN0VmFsdWUuZGltc1syXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInBhc3Rfa2V5XCIgYW5kIFwicGFzdF92YWx1ZVwiIHNoYWxsIGhhdmUgc2FtZSBkaW0gMiAocGFzdF9zZXF1ZW5jZV9sZW5ndGgpJyk7XG4gICAgfVxuICAgIGlmIChwYXN0VmFsdWUuZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X3ZhbHVlXCIgaXMgZXhwZWN0ZWQgdG8gaGF2ZSA0IGRpbWVuc2lvbnMnKTtcbiAgICB9XG4gICAgcGFzdFNlcXVlbmNlTGVuZ3RoID0gcGFzdEtleS5kaW1zWzJdO1xuICAgIG1heFNlcXVlbmNlTGVuZ3RoID0gcGFzdEtleS5kaW1zWzJdO1xuICB9IGVsc2UgaWYgKChwYXN0S2V5ICYmIFNoYXBlVXRpbC5zaXplKHBhc3RLZXkuZGltcykpIHx8IChwYXN0VmFsdWUgJiYgU2hhcGVVdGlsLnNpemUocGFzdFZhbHVlLmRpbXMpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X2tleVwiIGFuZCBcInBhc3RfdmFsdWVcIiBzaGFsbCBiZSBib3RoIHByZXNlbnQgb3IgYm90aCBhYnNlbnQnKTtcbiAgfVxuXG4gIGxldCBxa3ZGb3JtYXQ6IEF0dGVudGlvblFrdkZvcm1hdDtcbiAgaWYgKGtleSAmJiBTaGFwZVV0aWwuc2l6ZShrZXkuZGltcykgPiAwKSB7XG4gICAgaWYgKHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDMgZGltZW5zaW9ucyB3aGVuIGtleSBpcyBnaXZlbicpO1xuICAgIH1cbiAgICBpZiAoa2V5LmRpbXMubGVuZ3RoIDwgMyB8fCBrZXkuZGltcy5sZW5ndGggPiA1KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwia2V5XCIgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAzLCA0LCBvciA1IGRpbWVuc2lvbnMnKTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5LmRpbXNbMF0gIT09IGtleS5kaW1zWzBdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBhbmQgXCJrZXlcIiBzaGFsbCBoYXZlIHNhbWUgZGltIDAgKGJhdGNoIHNpemUpJyk7XG4gICAgfVxuXG4gICAgaWYgKGtleS5kaW1zLmxlbmd0aCA9PT0gMykge1xuICAgICAgaWYgKGtleS5kaW1zWzJdICE9PSBxdWVyeS5kaW1zWzJdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJxdWVyeVwiIGFuZCBcImtleVwiIHNoYWxsIGhhdmUgc2FtZSBkaW0gMiAoaGlkZGVuX3NpemUpJyk7XG4gICAgICB9XG4gICAgICBxa3ZGb3JtYXQgPSBBdHRlbnRpb25Ra3ZGb3JtYXQucWt2QlNOSDtcbiAgICAgIGt2U2VxdWVuY2VMZW5ndGggPSBrZXkuZGltc1sxXTtcbiAgICB9IGVsc2UgaWYgKGtleS5kaW1zLmxlbmd0aCA9PT0gNSkge1xuICAgICAgaWYgKGtleS5kaW1zWzJdICE9PSBhdHRyaWJ1dGVzLm51bUhlYWRzIHx8IGtleS5kaW1zWzNdICE9PSAyIHx8IGtleS5kaW1zWzRdICE9PSBoZWFkU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdCBcImtleVwiIHNoYXBlIChiYXRjaF9zaXplLCBrdl9zZXF1ZW5jZV9sZW5ndGgsIG51bV9oZWFkcywgMiwgaGVhZF9zaXplKSBmb3IgcGFja2VkIGt2Jyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3QgXCJ2YWx1ZVwiIGJlIG5vbmUgd2hlbiBcImtleVwiIGhhcyBwYWNrZWQga3YgZm9ybWF0LicpO1xuICAgICAgfVxuICAgICAgcWt2Rm9ybWF0ID0gQXR0ZW50aW9uUWt2Rm9ybWF0LnFLdkJTTkh4QlNOMkg7XG4gICAgICBrdlNlcXVlbmNlTGVuZ3RoID0ga2V5LmRpbXNbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGtleV9kaW1zLnNpemUoKSA9PSA0IChjcm9zcy1hdHRlbnRpb24gd2l0aCBwYXN0X2tleSlcbiAgICAgIGlmIChrZXkuZGltc1sxXSAhPT0gYXR0cmlidXRlcy5udW1IZWFkcyB8fCBrZXkuZGltc1szXSAhPT0gaGVhZFNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3QgXCJrZXlcIiBzaGFwZSAoYmF0Y2hfc2l6ZSwgbnVtX2hlYWRzLCBrdl9zZXF1ZW5jZV9sZW5ndGgsIGhlYWRfc2l6ZSkgZm9yIHBhc3Rfa2V5Jyk7XG4gICAgICB9XG5cbiAgICAgIHFrdkZvcm1hdCA9IEF0dGVudGlvblFrdkZvcm1hdC51bmtub3duOyAvLyBRX0tfVl9CU05IX0JOU0hfQk5TSFxuICAgICAga3ZTZXF1ZW5jZUxlbmd0aCA9IGtleS5kaW1zWzJdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBwYWNrZWQgUUtWXG4gICAgaWYgKHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSA1KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDUgZGltZW5zaW9ucyB3aGVuIGtleSBpcyBlbXB0eScpO1xuICAgIH1cbiAgICBpZiAocXVlcnkuZGltc1syXSAhPT0gYXR0cmlidXRlcy5udW1IZWFkcyB8fCBxdWVyeS5kaW1zWzNdICE9PSAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdCBcInF1ZXJ5XCIgc2hhcGUgKGJhdGNoX3NpemUsIGt2X3NlcXVlbmNlX2xlbmd0aCwgbnVtX2hlYWRzLCAzLCBoZWFkX3NpemUpIGZvciBwYWNrZWQga3YnKTtcbiAgICB9XG5cbiAgICBxa3ZGb3JtYXQgPSBBdHRlbnRpb25Ra3ZGb3JtYXQucWt2QlNOM0g7XG4gIH1cblxuICBpZiAoYmlhcyAmJiBTaGFwZVV0aWwuc2l6ZShiaWFzLmRpbXMpID4gMCkge1xuICAgIGlmIChiaWFzLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwiYmlhc1wiIGlzIGV4cGVjdGVkIHRvIGhhdmUgMSBkaW1lbnNpb24nKTtcbiAgICB9XG5cbiAgICBpZiAoa2V5KSB7XG4gICAgICBpZiAoa2V5LmRpbXMubGVuZ3RoID09PSA1ICYmIGtleS5kaW1zWzNdID09PSAyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYmlhcyBpcyBub3QgYWxsb3dlZCBmb3IgcGFja2VkIGt2LicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHRvdGFsU2VxdWVuY2VMZW5ndGggPSBwYXN0U2VxdWVuY2VMZW5ndGggKyBrdlNlcXVlbmNlTGVuZ3RoO1xuXG4gIGxldCBtYXNrVHlwZTogQXR0ZW50aW9uTWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5ub25lO1xuICBpZiAoa2V5UGFkZGluZ01hc2sgJiYgU2hhcGVVdGlsLnNpemUoa2V5UGFkZGluZ01hc2suZGltcykgPiAwKSB7XG4gICAgbWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5tYXNrVW5rbm93bjtcbiAgICBjb25zdCBtYXNrRGltcyA9IGtleVBhZGRpbmdNYXNrLmRpbXM7XG4gICAgaWYgKG1hc2tEaW1zLmxlbmd0aCA9PT0gMSkge1xuICAgICAgaWYgKG1hc2tEaW1zWzBdID09PSBiYXRjaFNpemUpIHtcbiAgICAgICAgbWFza1R5cGUgPSBBdHRlbnRpb25NYXNrVHlwZS5tYXNrMWRLZXlTZXFMZW47XG4gICAgICB9IGVsc2UgaWYgKG1hc2tEaW1zWzBdID09PSAzICogYmF0Y2hTaXplICsgMikge1xuICAgICAgICBtYXNrVHlwZSA9IEF0dGVudGlvbk1hc2tUeXBlLm1hc2sxREtleVNlcUxlblN0YXJ0O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobWFza0RpbXMubGVuZ3RoID09PSAyICYmIG1hc2tEaW1zWzBdID09PSBiYXRjaFNpemUgJiYgbWFza0RpbXNbMV0gPT09IHRvdGFsU2VxdWVuY2VMZW5ndGgpIHtcbiAgICAgIG1hc2tUeXBlID0gQXR0ZW50aW9uTWFza1R5cGUubWFzazJkS2V5UGFkZGluZztcbiAgICB9XG4gICAgaWYgKG1hc2tUeXBlID09PSBBdHRlbnRpb25NYXNrVHlwZS5tYXNrVW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcImtleV9wYWRkaW5nX21hc2tcIiBzaGFwZSBzaGFsbCBiZSAoYmF0Y2hfc2l6ZSkgb3IgKGJhdGNoX3NpemUsIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNYXNrIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuXG4gIGxldCBwYXNzUGFzdEluS3YgPSBmYWxzZTtcbiAgbGV0IHZIaWRkZW5TaXplID0gaGlkZGVuU2l6ZTtcbiAgaWYgKHZhbHVlICYmIFNoYXBlVXRpbC5zaXplKHZhbHVlLmRpbXMpID4gMCkge1xuICAgIGlmICh2YWx1ZS5kaW1zLmxlbmd0aCAhPT0gMyAmJiB2YWx1ZS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInZhbHVlXCIgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAzIG9yIDQgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChxdWVyeS5kaW1zWzBdICE9PSB2YWx1ZS5kaW1zWzBdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBhbmQgXCJ2YWx1ZVwiIHNoYWxsIGhhdmUgc2FtZSBkaW0gMCAoYmF0Y2hfc2l6ZSknKTtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUuZGltcy5sZW5ndGggPT09IDMpIHtcbiAgICAgIGlmIChrdlNlcXVlbmNlTGVuZ3RoICE9PSB2YWx1ZS5kaW1zWzFdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJrZXlcIiBhbmQgXCJ2YWx1ZVwiIHNoYWxsIGhhdmUgdGhlIHNhbWUgZGltIDEgKGt2X3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICAgIH1cbiAgICAgIHZIaWRkZW5TaXplID0gdmFsdWUuZGltc1syXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUV9LX1ZfQlNOSF9CTlNIX0JOU0hcbiAgICAgIGlmIChrdlNlcXVlbmNlTGVuZ3RoICE9PSB2YWx1ZS5kaW1zWzJdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJrZXlcIiBhbmQgXCJ2YWx1ZVwiIHNoYWxsIGhhdmUgdGhlIHNhbWUgZGltIDIgKGt2X3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICAgIH1cbiAgICAgIHZIaWRkZW5TaXplID0gdmFsdWUuZGltc1sxXSAqIHZhbHVlLmRpbXNbM107XG4gICAgICBwYXNzUGFzdEluS3YgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGJyb2FkY2FzdFJlc1Bvc0JpYXMgPSBmYWxzZTtcblxuICBpZiAoa2V5UGFkZGluZ01hc2sgJiYgU2hhcGVVdGlsLnNpemUoa2V5UGFkZGluZ01hc2suZGltcykgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdLZXkgcGFkZGluZyBtYXNrIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuXG4gIGlmIChhdHRlbnRpb25CaWFzICYmIFNoYXBlVXRpbC5zaXplKGF0dGVudGlvbkJpYXMuZGltcykgPiAwKSB7XG4gICAgaWYgKGF0dGVudGlvbkJpYXMuZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJhdHRlbnRpb25fYmlhc1wiIGlzIGV4cGVjdGVkIHRvIGhhdmUgNCBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogc3VwcG9ydCBicm9hZGNhc3RpbmcgdGhlIGZpcnN0IGFuZCBzZWNvbmQgZGltZW5zaW9ucyBvZiBhdHRlbnRpb25fYmlhcy5cbiAgICBpZiAoXG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbMF0gIT09IGJhdGNoU2l6ZSB8fFxuICAgICAgYXR0ZW50aW9uQmlhcy5kaW1zWzFdICE9PSBhdHRyaWJ1dGVzLm51bUhlYWRzIHx8XG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbMl0gIT09IHNlcXVlbmNlTGVuZ3RoIHx8XG4gICAgICBhdHRlbnRpb25CaWFzLmRpbXNbM10gIT09IHRvdGFsU2VxdWVuY2VMZW5ndGhcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0IFwiYXR0ZW50aW9uX2JpYXNcIiBzaGFwZSAoYmF0Y2hfc2l6ZSwgbnVtX2hlYWRzLCBzZXF1ZW5jZV9sZW5ndGgsIHRvdGFsX3NlcXVlbmNlX2xlbmd0aCknKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJhdGNoU2l6ZSxcbiAgICBzZXF1ZW5jZUxlbmd0aCxcbiAgICBwYXN0U2VxdWVuY2VMZW5ndGgsXG4gICAga3ZTZXF1ZW5jZUxlbmd0aCxcbiAgICB0b3RhbFNlcXVlbmNlTGVuZ3RoLFxuICAgIG1heFNlcXVlbmNlTGVuZ3RoLFxuICAgIGlucHV0SGlkZGVuU2l6ZTogMCxcbiAgICBoaWRkZW5TaXplLFxuICAgIHZIaWRkZW5TaXplLFxuICAgIGhlYWRTaXplLFxuICAgIHZIZWFkU2l6ZTogTWF0aC5mbG9vcih2SGlkZGVuU2l6ZSAvIGF0dHJpYnV0ZXMubnVtSGVhZHMpLFxuICAgIG51bUhlYWRzOiBhdHRyaWJ1dGVzLm51bUhlYWRzLFxuICAgIGlzVW5pZGlyZWN0aW9uYWw6IGZhbHNlLFxuICAgIHBhc3RQcmVzZW50U2hhcmVCdWZmZXI6IGZhbHNlLFxuICAgIG1hc2tGaWx0ZXJWYWx1ZTogYXR0cmlidXRlcy5tYXNrRmlsdGVyVmFsdWUsXG4gICAgbWFza1R5cGUsXG4gICAgc2NhbGU6IGF0dHJpYnV0ZXMuc2NhbGUsXG4gICAgYnJvYWRjYXN0UmVzUG9zQmlhcyxcbiAgICBwYXNzUGFzdEluS3YsXG4gICAgcWt2Rm9ybWF0LFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTXVsdGlIZWFkQXR0ZW50aW9uQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBBdHRlbnRpb25BdHRycyk6IEF0dGVudGlvbkF0dHJzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IC4uLmF0dHJpYnV0ZXMgfSk7XG5cbmNvbnN0IHdlaWdodFRyYW5zcG9zZUF0dHJpYnV0ZTogVHJhbnNwb3NlQXR0cmlidXRlcyA9IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IHBlcm06IFswLCAyLCAxLCAzXSB9KTtcblxuY29uc3QgYWRkQmlhc1RyYW5zcG9zZSA9IChcbiAgY29udGV4dDogQ29tcHV0ZUNvbnRleHQsXG4gIHFrdjogVGVuc29yVmlldyxcbiAgYmlhczogVGVuc29yVmlldyxcbiAgYmF0Y2hTaXplOiBudW1iZXIsXG4gIHNlcXVlbmNlTGVuZ3RoOiBudW1iZXIsXG4gIGhpZGRlblNpemU6IG51bWJlcixcbiAgYmlhc09mZnNldDogbnVtYmVyLFxuKSA9PiB7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW2JhdGNoU2l6ZSwgc2VxdWVuY2VMZW5ndGgsIGhpZGRlblNpemVdO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYmlhc09mZnNldCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBoaWRkZW5TaXplIH0sXG4gIF07XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ3Frdl93aXRoX2JpYXMnLCBxa3YuZGF0YVR5cGUsIG91dHB1dFNoYXBlKTtcbiAgICBjb25zdCBxa3ZJbnB1dCA9IGlucHV0VmFyaWFibGUoJ3FrdicsIHFrdi5kYXRhVHlwZSwgb3V0cHV0U2hhcGUpO1xuICAgIGNvbnN0IGJpYXNJbnB1dCA9IGlucHV0VmFyaWFibGUoJ2JpYXMnLCBiaWFzLmRhdGFUeXBlLCBvdXRwdXRTaGFwZSk7XG5cbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdiaWFzX29mZnNldCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdoaWRkZW5fc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKHFrdklucHV0LCBiaWFzSW5wdXQsIG91dHB1dCl9XG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgbGV0IGJpYXNfb2Zmc2V0X2lkeCA9IChnbG9iYWxfaWR4ICUgdW5pZm9ybXMuaGlkZGVuX3NpemUpICsgdW5pZm9ybXMuYmlhc19vZmZzZXQ7XG5cbiAgICBxa3Zfd2l0aF9iaWFzW2dsb2JhbF9pZHhdID0gcWt2W2dsb2JhbF9pZHhdICsgYmlhc1tiaWFzX29mZnNldF9pZHhdO1xuICB9YDtcbiAgfTtcblxuICByZXR1cm4gY29udGV4dC5jb21wdXRlKFxuICAgIHtcbiAgICAgIG5hbWU6ICdNdWx0aUhlYWRBdHRlbnRpb25BZGRCaWFzJyxcbiAgICAgIHNoYWRlckNhY2hlOiB7IGlucHV0RGVwZW5kZW5jaWVzOiBbJ3R5cGUnLCAndHlwZSddIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IHFrdi5kYXRhVHlwZSwgZ3B1RGF0YVR5cGU6IEdwdURhdGFUeXBlLmRlZmF1bHQgfV0sXG4gICAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgICAgfSksXG4gICAgICBnZXRTaGFkZXJTb3VyY2UsXG4gICAgfSxcbiAgICB7IGlucHV0czogW3FrdiwgYmlhc10sIG91dHB1dHM6IFstMV0gfSxcbiAgKVswXTtcbn07XG5cbmV4cG9ydCBjb25zdCBtYXliZVRyYW5zcG9zZVRvQk5TSEFuZEFkZEJpYXMgPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBiYXRjaFNpemU6IG51bWJlcixcbiAgbnVtSGVhZHM6IG51bWJlcixcbiAgc2VxdWVuY2VMZW5ndGg6IG51bWJlcixcbiAgaGVhZFNpemU6IG51bWJlcixcbiAgaW5wdXQ6IFRlbnNvclZpZXcsXG4gIGJpYXM/OiBUZW5zb3JWaWV3LFxuICBiaWFzT2Zmc2V0PzogbnVtYmVyLFxuKSA9PiB7XG4gIC8vIGNvbnN0IG5ld0RpbXMgPSBbXTtcblxuICBsZXQgcmVzaGFwZWRJbnB1dCA9IGlucHV0O1xuICBpZiAoIShiaWFzICYmIFNoYXBlVXRpbC5zaXplKGJpYXMuZGltcykgPiAwKSkge1xuICAgIGlmIChpbnB1dC5kaW1zLmxlbmd0aCA9PT0gMykge1xuICAgICAgcmVzaGFwZWRJbnB1dCA9IGlucHV0LnJlc2hhcGUoW2JhdGNoU2l6ZSwgc2VxdWVuY2VMZW5ndGgsIG51bUhlYWRzLCBoZWFkU2l6ZV0pO1xuICAgIH1cbiAgICBpZiAobnVtSGVhZHMgPT09IDEgfHwgc2VxdWVuY2VMZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiByZXNoYXBlZElucHV0O1xuICAgIH1cbiAgICByZXR1cm4gY29udGV4dC5jb21wdXRlKGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvKHJlc2hhcGVkSW5wdXQsIHdlaWdodFRyYW5zcG9zZUF0dHJpYnV0ZS5wZXJtKSwge1xuICAgICAgaW5wdXRzOiBbcmVzaGFwZWRJbnB1dF0sXG4gICAgICBvdXRwdXRzOiBbLTFdLFxuICAgIH0pWzBdO1xuICB9IGVsc2Uge1xuICAgIGlmIChzZXF1ZW5jZUxlbmd0aCA9PT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBZGRCaWFzUmVzaGFwZSBpcyBub3QgaW1wbGVtZW50ZWQuIFBsZWFzZSBleHBvcnQgeW91ciBtb2RlbCB3aXRoIHBhY2tlZCBRS1Ygb3IgS1YnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzaGFwZWRJbnB1dCA9IGFkZEJpYXNUcmFuc3Bvc2UoXG4gICAgICAgIGNvbnRleHQsXG4gICAgICAgIGlucHV0LFxuICAgICAgICBiaWFzLFxuICAgICAgICBiYXRjaFNpemUsXG4gICAgICAgIHNlcXVlbmNlTGVuZ3RoLFxuICAgICAgICBudW1IZWFkcyAqIGhlYWRTaXplLFxuICAgICAgICBiaWFzT2Zmc2V0ISxcbiAgICAgICk7XG4gICAgICByZXNoYXBlZElucHV0ID0gcmVzaGFwZWRJbnB1dC5yZXNoYXBlKFtiYXRjaFNpemUsIHNlcXVlbmNlTGVuZ3RoLCBudW1IZWFkcywgaGVhZFNpemVdKTtcbiAgICAgIGlmIChudW1IZWFkcyA9PT0gMSB8fCBzZXF1ZW5jZUxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gcmVzaGFwZWRJbnB1dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8ocmVzaGFwZWRJbnB1dCwgd2VpZ2h0VHJhbnNwb3NlQXR0cmlidXRlLnBlcm0pLCB7XG4gICAgICAgIGlucHV0czogW3Jlc2hhcGVkSW5wdXRdLFxuICAgICAgICBvdXRwdXRzOiBbLTFdLFxuICAgICAgfSlbMF07XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgY29uc3QgbXVsdGlIZWFkQXR0ZW50aW9uID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBBdHRlbnRpb25BdHRycyk6IHZvaWQgPT4ge1xuICBjb25zdCBwYXJhbXMgPSB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IHF1ZXJ5ID0gY29udGV4dC5pbnB1dHNbMF07XG4gIGNvbnN0IGtleSA9IGdldElucHV0KGNvbnRleHQuaW5wdXRzLCAxKTtcbiAgY29uc3QgdmFsdWUgPSBnZXRJbnB1dChjb250ZXh0LmlucHV0cywgMik7XG4gIGNvbnN0IGJpYXMgPSBnZXRJbnB1dChjb250ZXh0LmlucHV0cywgMyk7XG4gIGNvbnN0IGtleVBhZGRpbmdNYXNrID0gZ2V0SW5wdXQoY29udGV4dC5pbnB1dHMsIDQpO1xuICBjb25zdCBhdHRlbnRpb25CaWFzID0gZ2V0SW5wdXQoY29udGV4dC5pbnB1dHMsIDUpO1xuICBjb25zdCBwYXN0S2V5ID0gZ2V0SW5wdXQoY29udGV4dC5pbnB1dHMsIDYpO1xuICBjb25zdCBwYXN0VmFsdWUgPSBnZXRJbnB1dChjb250ZXh0LmlucHV0cywgNyk7XG4gIGlmIChxdWVyeS5kaW1zLmxlbmd0aCA9PT0gNSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGFja2VkIFFLViBpcyBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIGlmIChrZXk/LmRpbXMubGVuZ3RoID09PSA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQYWNrZWQgS1YgaXMgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICAvLyBhcHBseUF0dGVudGlvbiBleHBlY3RzIEJOU0ggaW5wdXRzXG4gIGNvbnN0IGt2Qk5TSCA9IGtleSAmJiB2YWx1ZSAmJiBrZXkuZGltcy5sZW5ndGggPT09IDQgJiYgdmFsdWUuZGltcy5sZW5ndGggPT09IDQ7XG5cbiAgY29uc3QgUSA9IG1heWJlVHJhbnNwb3NlVG9CTlNIQW5kQWRkQmlhcyhcbiAgICBjb250ZXh0LFxuICAgIHBhcmFtcy5iYXRjaFNpemUsXG4gICAgcGFyYW1zLm51bUhlYWRzLFxuICAgIHBhcmFtcy5zZXF1ZW5jZUxlbmd0aCxcbiAgICBwYXJhbXMuaGVhZFNpemUsXG4gICAgcXVlcnksXG4gICAgYmlhcyxcbiAgICAwLFxuICApO1xuXG4gIGlmIChrdkJOU0gpIHtcbiAgICByZXR1cm4gYXBwbHlBdHRlbnRpb24oY29udGV4dCwgUSwga2V5LCB2YWx1ZSwga2V5UGFkZGluZ01hc2ssIHVuZGVmaW5lZCwgcGFzdEtleSwgcGFzdFZhbHVlLCBhdHRlbnRpb25CaWFzLCBwYXJhbXMpO1xuICB9XG4gIGlmICgha2V5IHx8ICF2YWx1ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigna2V5IGFuZCB2YWx1ZSBtdXN0IGJlIHByb3ZpZGVkJyk7XG4gIH1cbiAgY29uc3QgSyA9IG1heWJlVHJhbnNwb3NlVG9CTlNIQW5kQWRkQmlhcyhcbiAgICBjb250ZXh0LFxuICAgIHBhcmFtcy5iYXRjaFNpemUsXG4gICAgcGFyYW1zLm51bUhlYWRzLFxuICAgIHBhcmFtcy5rdlNlcXVlbmNlTGVuZ3RoLFxuICAgIHBhcmFtcy5oZWFkU2l6ZSxcbiAgICBrZXksXG4gICAgYmlhcyxcbiAgICBwYXJhbXMuaGlkZGVuU2l6ZSxcbiAgKTtcblxuICBjb25zdCBWID0gbWF5YmVUcmFuc3Bvc2VUb0JOU0hBbmRBZGRCaWFzKFxuICAgIGNvbnRleHQsXG4gICAgcGFyYW1zLmJhdGNoU2l6ZSxcbiAgICBwYXJhbXMubnVtSGVhZHMsXG4gICAgcGFyYW1zLmt2U2VxdWVuY2VMZW5ndGgsXG4gICAgcGFyYW1zLnZIZWFkU2l6ZSxcbiAgICB2YWx1ZSxcbiAgICBiaWFzLFxuICAgIDIgKiBwYXJhbXMuaGlkZGVuU2l6ZSxcbiAgKTtcblxuICBhcHBseUF0dGVudGlvbihjb250ZXh0LCBRLCBLLCBWLCBrZXlQYWRkaW5nTWFzaywgdW5kZWZpbmVkLCBwYXN0S2V5LCBwYXN0VmFsdWUsIGF0dGVudGlvbkJpYXMsIHBhcmFtcyk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0sIFRlbnNvckluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLFxuICBnZXRFbGVtZW50QXQsXG4gIEluZGljZXNIZWxwZXIsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG59IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBTcGxpdEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG4gIHJlYWRvbmx5IG51bU91dHB1dHM6IG51bWJlcjtcbiAgcmVhZG9ubHkgc3BsaXRTaXplczogbnVtYmVyW107XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0b28gZmV3IGlucHV0cycpO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVTcGxpdEF0dHJpYnV0ZXNGcm9tSW5wdXRzID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzLFxuKTogU3BsaXRBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3Qgc3BsaXRTaXplczogbnVtYmVyW10gPSBbXTtcbiAgbGV0IG51bU91dHB1dHM6IG51bWJlciA9IGF0dHJpYnV0ZXMubnVtT3V0cHV0cztcbiAgaWYgKGlucHV0c1sxXS5kaW1zWzBdID4gMCkge1xuICAgIGlucHV0c1sxXS5nZXRCaWdJbnQ2NEFycmF5KCkuZm9yRWFjaCgodikgPT4gc3BsaXRTaXplcy5wdXNoKE51bWJlcih2KSkpO1xuICAgIG51bU91dHB1dHMgPSBzcGxpdFNpemVzLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgbnVtT3V0cHV0cywgYXhpczogYXR0cmlidXRlcy5heGlzLCBzcGxpdFNpemVzIH0pO1xufTtcblxuY29uc3QgY2FsY3VsYXRlT3V0cHV0SW5kZXhJbXBsID0gKG51bWJlck9mVGVuc29yczogbnVtYmVyKTogc3RyaW5nID0+IGBcbmZuIGNhbGN1bGF0ZU91dHB1dEluZGV4KGluZGV4OiB1MzIpIC0+IHUzMiB7XG4gICAgZm9yICh2YXIgaTogdTMyID0gMHU7IGkgPCAke251bWJlck9mVGVuc29yc311OyBpICs9IDF1ICkge1xuICAgIGlmIChpbmRleCA8ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5zaXplX2luX3NwbGl0X2F4aXMnLCAnaScsIG51bWJlck9mVGVuc29ycyl9KSB7XG4gICAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICR7bnVtYmVyT2ZUZW5zb3JzfXU7XG59YDtcbmNvbnN0IHdyaXRlQnVmZmVyRGF0YUltcGwgPSAob3V0cHV0czogcmVhZG9ubHkgSW5kaWNlc0hlbHBlcltdKSA9PiB7XG4gIGNvbnN0IG51bWJlck9mVGVuc29ycyA9IG91dHB1dHMubGVuZ3RoO1xuICBjb25zdCBjb2RlTGluZXM6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZUZW5zb3JzOyArK2kpIHtcbiAgICBjb25zdCByZXR1cm5TbmlwcGV0ID0gb3V0cHV0c1tpXS5zZXRCeUluZGljZXMoJ2luZGljZXMnLCAnaW5wdXRbZ2xvYmFsX2lkeF0nKTtcbiAgICBpZiAobnVtYmVyT2ZUZW5zb3JzID09PSAxKSB7XG4gICAgICBjb2RlTGluZXMucHVzaChyZXR1cm5TbmlwcGV0KTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKGBpZiAob3V0cHV0X251bWJlciA9PSAke2l9dSkgeyAke3JldHVyblNuaXBwZXR9IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IG51bWJlck9mVGVuc29ycyAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKGBlbHNlIHsgJHtyZXR1cm5TbmlwcGV0fSB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKGBlbHNlIGlmIChvdXRwdXRfbnVtYmVyID09ICR7aX0pIHsgJHtyZXR1cm5TbmlwcGV0fSB9YCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBgXG4gICAgICBmbiB3cml0ZUJ1ZmZlckRhdGEob3V0cHV0X251bWJlcjogdTMyLCBpbmRpY2VzOiAke291dHB1dHNbMF0udHlwZS5pbmRpY2VzfSwgZ2xvYmFsX2lkeDogdTMyKSB7XG4gICAgICAgICR7Y29kZUxpbmVzLmpvaW4oJ1xcbicpfVxuICAgICAgfWA7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlU3BsaXRQcm9ncmFtSW5mbyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGlucHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKGlucHV0U2hhcGUpO1xuICBjb25zdCBkYXRhVHlwZSA9IGlucHV0c1swXS5kYXRhVHlwZTtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBvdXRwdXRzID0gbmV3IEFycmF5PEluZGljZXNIZWxwZXI+KGF0dHJpYnV0ZXMubnVtT3V0cHV0cyk7XG4gIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBkYXRhVHlwZSwgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBzaXplSW5TcGxpdEF4aXMgPSBuZXcgQXJyYXk8bnVtYmVyPihhdHRyaWJ1dGVzLm51bU91dHB1dHMpO1xuICBjb25zdCBvdXRwdXRzVGVuc29ySW5mbzogVGVuc29ySW5mb1tdID0gW107XG4gIGNvbnN0IG91dHB1dFNoYXBlczogbnVtYmVyW11bXSA9IFtdO1xuICBsZXQgcHJldmlvdXNTdW0gPSAwO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGlucHV0U2l6ZSB9XTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLm51bU91dHB1dHM7IGkrKykge1xuICAgIHByZXZpb3VzU3VtICs9IGF0dHJpYnV0ZXMuc3BsaXRTaXplc1tpXTtcbiAgICBzaXplSW5TcGxpdEF4aXNbaV0gPSBwcmV2aW91c1N1bTtcbiAgICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoKTtcbiAgICBvdXRwdXRTaGFwZVtheGlzXSA9IGF0dHJpYnV0ZXMuc3BsaXRTaXplc1tpXTtcbiAgICBvdXRwdXRTaGFwZXMucHVzaChvdXRwdXRTaGFwZSk7XG4gICAgb3V0cHV0c1tpXSA9IG91dHB1dFZhcmlhYmxlKGBvdXRwdXQke2l9YCwgZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgb3V0cHV0c1RlbnNvckluZm8ucHVzaCh7IGRpbXM6IG91dHB1dFNoYXBlc1tpXSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9KTtcbiAgfVxuICBwcm9ncmFtVW5pZm9ybXMucHVzaChcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogc2l6ZUluU3BsaXRBeGlzIH0sXG4gICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRTaGFwZSwgLi4ub3V0cHV0U2hhcGVzKSxcbiAgKTtcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICR7c2hhZGVySGVscGVyXG4gICAgLnJlZ2lzdGVyVW5pZm9ybSgnaW5wdXRfc2l6ZScsICd1MzInKVxuICAgIC5yZWdpc3RlclVuaWZvcm0oJ3NpemVfaW5fc3BsaXRfYXhpcycsICd1MzInLCBzaXplSW5TcGxpdEF4aXMubGVuZ3RoKVxuICAgIC5kZWNsYXJlVmFyaWFibGVzKGlucHV0LCAuLi5vdXRwdXRzKX1cbiAgJHtjYWxjdWxhdGVPdXRwdXRJbmRleEltcGwoc2l6ZUluU3BsaXRBeGlzLmxlbmd0aCl9XG4gICR7d3JpdGVCdWZmZXJEYXRhSW1wbChvdXRwdXRzKX1cblxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5pbnB1dF9zaXplJyl9XG5cbiAgICB2YXIgaW5kaWNlcyA9ICR7aW5wdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgIHZhciBpbmRleCA9ICR7aW5wdXQuaW5kaWNlc0dldCgnaW5kaWNlcycsIGF4aXMpfTtcbiAgICBsZXQgb3V0cHV0X251bWJlciA9IGNhbGN1bGF0ZU91dHB1dEluZGV4KGluZGV4KTtcbiAgICBpZiAob3V0cHV0X251bWJlciAhPSAwKSB7XG4gICAgICBpbmRleCAtPSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuc2l6ZV9pbl9zcGxpdF9heGlzJywgJ291dHB1dF9udW1iZXIgLSAxdScsIHNpemVJblNwbGl0QXhpcy5sZW5ndGgpfTtcbiAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5kaWNlcycsIGF4aXMsICdpbmRleCcpfTtcbiAgICB9XG4gICAgd3JpdGVCdWZmZXJEYXRhKG91dHB1dF9udW1iZXIsIGluZGljZXMsIGdsb2JhbF9pZHgpO1xuICB9YDtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnU3BsaXQnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogb3V0cHV0c1RlbnNvckluZm8sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChpbnB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBzcGxpdCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgdXBkYXRlZEF0dHJpYnV0ZXMgPVxuICAgIGNvbnRleHQuaW5wdXRzLmxlbmd0aCA9PT0gMSA/IGF0dHJpYnV0ZXMgOiBjcmVhdGVTcGxpdEF0dHJpYnV0ZXNGcm9tSW5wdXRzKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZVNwbGl0UHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIHVwZGF0ZWRBdHRyaWJ1dGVzKSwgeyBpbnB1dHM6IFswXSB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNwbGl0QXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFNwbGl0QXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF4aXMgPSBhdHRyaWJ1dGVzLmF4aXMgYXMgbnVtYmVyO1xuICBjb25zdCBzcGxpdFNpemVzOiBudW1iZXJbXSA9IGF0dHJpYnV0ZXMuc3BsaXRTaXplcyBhcyBudW1iZXJbXTtcbiAgY29uc3QgbnVtT3V0cHV0cyA9IChhdHRyaWJ1dGVzLm51bU91dHB1dHMgYXMgbnVtYmVyKSA8IDAgPyBzcGxpdFNpemVzLmxlbmd0aCA6IChhdHRyaWJ1dGVzLm51bU91dHB1dHMgYXMgbnVtYmVyKTtcbiAgaWYgKG51bU91dHB1dHMgIT09IHNwbGl0U2l6ZXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdudW1PdXRwdXRzIGFuZCBzcGxpdFNpemVzIGxlbmdoIG11c3QgYmUgZXF1YWwnKTtcbiAgfVxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpcywgbnVtT3V0cHV0cywgc3BsaXRTaXplcyB9KTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyLCBXT1JLR1JPVVBfU0laRSB9IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBSb3RhcnlFbWJlZGRpbmdBdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgaW50ZXJsZWF2ZWQ6IGJvb2xlYW47XG4gIHJlYWRvbmx5IG51bUhlYWRzOiBudW1iZXI7XG4gIHJlYWRvbmx5IHJvdGFyeUVtYmVkZGluZ0RpbTogbnVtYmVyO1xuICByZWFkb25seSBzY2FsZTogbnVtYmVyO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBbaW5wdXQsIHBvc2l0aW9uSWRzLCBjb3NDYWNoZSwgc2luQ2FjaGVdID0gaW5wdXRzO1xuICBjb25zdCB7IG51bUhlYWRzLCByb3RhcnlFbWJlZGRpbmdEaW0gfSA9IGF0dHJpYnV0ZXM7XG5cbiAgaWYgKGlucHV0LmRpbXMubGVuZ3RoICE9PSAzICYmIGlucHV0LmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnB1dCAneCcgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAzIG9yIDQgZGltZW5zaW9ucywgZ290ICR7aW5wdXQuZGltcy5sZW5ndGh9YCk7XG4gIH1cbiAgaWYgKFxuICAgICFTaGFwZVV0aWwuYXJlRXF1YWwocG9zaXRpb25JZHMuZGltcywgW10pICYmXG4gICAgIVNoYXBlVXRpbC5hcmVFcXVhbChwb3NpdGlvbklkcy5kaW1zLCBbMV0pICYmXG4gICAgcG9zaXRpb25JZHMuZGltcy5sZW5ndGggIT09IDJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnB1dCAncG9zaXRpb25faWRzJyBpcyBleHBlY3RlZCB0byBoYXZlIDAsIDEsIG9yIDIgZGltZW5zaW9ucywgZ290ICR7cG9zaXRpb25JZHMuZGltcy5sZW5ndGh9YCk7XG4gIH1cbiAgaWYgKGNvc0NhY2hlLmRpbXMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnB1dCAnY29zX2NhY2hlJyBpcyBleHBlY3RlZCB0byBoYXZlIDIgZGltZW5zaW9ucywgZ290ICR7Y29zQ2FjaGUuZGltcy5sZW5ndGh9YCk7XG4gIH1cbiAgaWYgKHNpbkNhY2hlLmRpbXMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnB1dCAnc2luX2NhY2hlJyBpcyBleHBlY3RlZCB0byBoYXZlIDIgZGltZW5zaW9ucywgZ290ICR7c2luQ2FjaGUuZGltcy5sZW5ndGh9YCk7XG4gIH1cbiAgaWYgKCFTaGFwZVV0aWwuYXJlRXF1YWwoY29zQ2FjaGUuZGltcywgc2luQ2FjaGUuZGltcykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnB1dHMgJ2Nvc19jYWNoZScgYW5kICdzaW5fY2FjaGUnIGFyZSBleHBlY3RlZCB0byBoYXZlIHRoZSBzYW1lIHNoYXBlXCIpO1xuICB9XG5cbiAgaWYgKHJvdGFyeUVtYmVkZGluZ0RpbSA+IDAgJiYgbnVtSGVhZHMgPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ251bV9oZWFkcyBtdXN0IGJlIHByb3ZpZGVkIGlmIHJvdGFyeV9lbWJlZGRpbmdfZGltIGlzIHNwZWNpZmllZCcpO1xuICB9XG5cbiAgY29uc3QgYmF0Y2hTaXplID0gaW5wdXQuZGltc1swXTtcbiAgY29uc3Qgc2VxdWVuY2VMZW5ndGggPSBpbnB1dC5kaW1zW2lucHV0LmRpbXMubGVuZ3RoIC0gMl07XG4gIGNvbnN0IG1heFNlcXVlbmNlTGVuZ3RoID0gY29zQ2FjaGUuZGltc1swXTtcbiAgY29uc3QgaGlkZGVuU2l6ZSA9IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbihpbnB1dC5kaW1zLCAxKSAvIHNlcXVlbmNlTGVuZ3RoO1xuICBjb25zdCBoZWFkU2l6ZSA9IHJvdGFyeUVtYmVkZGluZ0RpbSA9PT0gMCA/IGNvc0NhY2hlLmRpbXNbMV0gKiAyIDogaGlkZGVuU2l6ZSAvIG51bUhlYWRzO1xuICBpZiAocm90YXJ5RW1iZWRkaW5nRGltID4gaGVhZFNpemUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3JvdGFyeV9lbWJlZGRpbmdfZGltIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGhlYWRfc2l6ZScpO1xuICB9XG5cbiAgaWYgKHBvc2l0aW9uSWRzLmRpbXMubGVuZ3RoID09PSAyKSB7XG4gICAgaWYgKGJhdGNoU2l6ZSAhPT0gcG9zaXRpb25JZHMuZGltc1swXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnB1dCAncG9zaXRpb25faWRzJyBkaW1lbnNpb24gMCBzaG91bGQgYmUgb2Ygc2l6ZSBiYXRjaF9zaXplLCBnb3QgJHtwb3NpdGlvbklkcy5kaW1zWzBdfWApO1xuICAgIH1cbiAgICBpZiAoc2VxdWVuY2VMZW5ndGggIT09IHBvc2l0aW9uSWRzLmRpbXNbMV0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJ3Bvc2l0aW9uX2lkcycgZGltZW5zaW9uIDEgc2hvdWxkIGJlIG9mIHNpemUgc2VxdWVuY2VfbGVuZ3RoLCBnb3QgJHtwb3NpdGlvbklkcy5kaW1zWzFdfWApO1xuICAgIH1cbiAgfVxuXG4gIGlmIChoZWFkU2l6ZSAvIDIgIT09IGNvc0NhY2hlLmRpbXNbMV0gJiYgcm90YXJ5RW1iZWRkaW5nRGltIC8gMiAhPT0gY29zQ2FjaGUuZGltc1sxXSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBJbnB1dCAnY29zX2NhY2hlJyBkaW1lbnNpb24gMSBzaG91bGQgYmUgc2FtZSBhcyBoZWFkX3NpemUgLyAyIG9yIHJvdGFyeV9lbWJlZGRpbmdfZGltIC8gMiwgZ290ICR7XG4gICAgICAgIGNvc0NhY2hlLmRpbXNbMV1cbiAgICAgIH1gLFxuICAgICk7XG4gIH1cblxuICBpZiAoc2VxdWVuY2VMZW5ndGggPiBtYXhTZXF1ZW5jZUxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignVXBkYXRpbmcgY29zX2NhY2hlIGFuZCBzaW5fY2FjaGUgaW4gUm90YXJ5RW1iZWRkaW5nIGlzIG5vdCBjdXJyZW50bHkgc3VwcG9ydGVkJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVSb3RhcnlFbWJlZGRpbmdQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IFJvdGFyeUVtYmVkZGluZ0F0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHsgaW50ZXJsZWF2ZWQsIG51bUhlYWRzLCByb3RhcnlFbWJlZGRpbmdEaW0sIHNjYWxlIH0gPSBhdHRyaWJ1dGVzO1xuICBjb25zdCBiYXRjaFNpemUgPSBpbnB1dHNbMF0uZGltc1swXTtcbiAgY29uc3QgYmF0Y2hTdHJpZGUgPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXRzWzBdLmRpbXMsIDEpO1xuICBjb25zdCBzZXF1ZW5jZUxlbmd0aCA9IGlucHV0c1swXS5kaW1zW2lucHV0c1swXS5kaW1zLmxlbmd0aCAtIDJdO1xuICBjb25zdCBoaWRkZW5TaXplID0gYmF0Y2hTdHJpZGUgLyBzZXF1ZW5jZUxlbmd0aDtcbiAgY29uc3QgaGFsZlJvdGFyeUVtYmVkZGluZ0RpbSA9IGlucHV0c1syXS5kaW1zWzFdO1xuICBjb25zdCBoZWFkU2l6ZSA9IHJvdGFyeUVtYmVkZGluZ0RpbSA9PT0gMCA/IGhhbGZSb3RhcnlFbWJlZGRpbmdEaW0gKiAyIDogaGlkZGVuU2l6ZSAvIG51bUhlYWRzO1xuXG4gIC8vIFJvdGFyeSBlbWJlZGRpbmdzIHdpbGwgYmUgY2FsY3VsYXRlZCBpbiBhIHBhaXItd2lzZSBmYXNoaW9uLiBJbiBhY2NvcmRhbmNlLCB1c2UgdGhlIHNoYXBlXG4gIC8vIFtiYXRjaCBzaXplLCBzZXF1ZW5jZSBsZW5ndGgsIG51bSBvZiBoZWFkcywgbnVtIG9mIHBhaXJzIHRvIHJvdGF0ZSArIG51bSBvZiBkaW1zIHRvIGNvcHldXG4gIC8vIHRvIHVuZm9sZCB0aGUgZ2xvYmFsIGluZGV4IGluIHNoYWRlci5cbiAgY29uc3QgZ2xvYmFsU2hhcGUgPSBuZXcgQXJyYXk8bnVtYmVyPihcbiAgICBiYXRjaFNpemUsXG4gICAgc2VxdWVuY2VMZW5ndGgsXG4gICAgaGlkZGVuU2l6ZSAvIGhlYWRTaXplLFxuICAgIGhlYWRTaXplIC0gaGFsZlJvdGFyeUVtYmVkZGluZ0RpbSxcbiAgKTtcbiAgY29uc3QgZ2xvYmFsU3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhnbG9iYWxTaGFwZSk7XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUuZmxvYXQsIGRhdGE6IHNjYWxlIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGdsb2JhbFNoYXBlIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGdsb2JhbFN0cmlkZXMgfSxcblxuICAgIC8vIHN0cmlkZXMgZm9yIGFkZHJlc3NpbmcgdGhlIGlucHV0L291dHB1dCB0ZW5zb3IsIGluIHBlcm11dGF0ZWQgb3JkZXIgdG8gYWxpZ24gd2l0aCB0aGUgdW5mb2xkZWQgZ2xvYmFsIGluZGV4LFxuICAgIC8vIGkuZS4gQlNOSFxuICAgIC4uLihpbnB1dHNbMF0uZGltcy5sZW5ndGggPT09IDNcbiAgICAgID8gbmV3IEFycmF5PFByb2dyYW1Vbmlmb3JtPih7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogW2JhdGNoU3RyaWRlLCBoaWRkZW5TaXplLCBoZWFkU2l6ZSwgMV0gfSlcbiAgICAgIDogW10pLFxuICAgIC4uLihpbnB1dHNbMF0uZGltcy5sZW5ndGggPT09IDRcbiAgICAgID8gbmV3IEFycmF5PFByb2dyYW1Vbmlmb3JtPih7XG4gICAgICAgICAgdHlwZTogRGF0YVR5cGUudWludDMyLFxuICAgICAgICAgIGRhdGE6IFtiYXRjaFN0cmlkZSwgaGVhZFNpemUsIHNlcXVlbmNlTGVuZ3RoICogaGVhZFNpemUsIDFdLFxuICAgICAgICB9KVxuICAgICAgOiBbXSksXG5cbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMsIGlucHV0c1syXS5kaW1zLCBpbnB1dHNbM10uZGltcywgaW5wdXRzWzBdLmRpbXMpLFxuICBdO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYXJpYWJsZSgnaW5wdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgcG9zaXRpb25JZHMgPSBpbnB1dFZhcmlhYmxlKCdwb3NpdGlvbl9pZHMnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgY29zQ2FjaGUgPSBpbnB1dFZhcmlhYmxlKCdjb3NfY2FjaGUnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3Qgc2luQ2FjaGUgPSBpbnB1dFZhcmlhYmxlKCdzaW5fY2FjaGUnLCBpbnB1dHNbM10uZGF0YVR5cGUsIGlucHV0c1szXS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcblxuICAgIHNoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKFtcbiAgICAgIHsgbmFtZTogJ3NjYWxlJywgdHlwZTogJ2YzMicgfSxcbiAgICAgIHsgbmFtZTogJ2dsb2JhbF9zaGFwZScsIHR5cGU6ICd1MzInLCBsZW5ndGg6IGdsb2JhbFNoYXBlLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnZ2xvYmFsX3N0cmlkZXMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBnbG9iYWxTdHJpZGVzLmxlbmd0aCB9LFxuICAgICAgeyBuYW1lOiAnaW5wdXRfb3V0cHV0X3N0cmlkZXMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBnbG9iYWxTdHJpZGVzLmxlbmd0aCB9LFxuICAgIF0pO1xuXG4gICAgcmV0dXJuIGBcbiAgICAgICAgJHtzaGFkZXJIZWxwZXIuZGVjbGFyZVZhcmlhYmxlcyhpbnB1dCwgcG9zaXRpb25JZHMsIGNvc0NhY2hlLCBzaW5DYWNoZSwgb3V0cHV0KX1cblxuICAgICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoV09SS0dST1VQX1NJWkUpfVxuICAgICAgICAgIGxldCBoYWxmX3JvdGFyeV9lbWJfZGltID0gdW5pZm9ybXMuJHtjb3NDYWNoZS5uYW1lfV9zaGFwZVsxXTtcbiAgICAgICAgICBsZXQgYnNuaCA9IGdsb2JhbF9pZHggLyB1bmlmb3Jtcy5nbG9iYWxfc3RyaWRlcyAlIHVuaWZvcm1zLmdsb2JhbF9zaGFwZTtcbiAgICAgICAgICBsZXQgc2l6ZSA9IHVuaWZvcm1zLmdsb2JhbF9zaGFwZVswXSAqIHVuaWZvcm1zLmdsb2JhbF9zdHJpZGVzWzBdO1xuICAgICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3NpemUnKX1cblxuICAgICAgICAgIGlmIChic25oWzNdIDwgaGFsZl9yb3RhcnlfZW1iX2RpbSkge1xuICAgICAgICAgICAgbGV0IHBvc2l0aW9uX2lkc19pZHggPVxuICAgICAgICAgICAgICAgICR7cG9zaXRpb25JZHMuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoJ2JzbmgueHknLCBvdXRwdXRWYXJpYWJsZSgnJywgcG9zaXRpb25JZHMudHlwZS50ZW5zb3IsIDIpKX07XG4gICAgICAgICAgICBsZXQgcG9zaXRpb25faWQgPVxuICAgICAgICAgICAgICAgIHUzMigke3Bvc2l0aW9uSWRzLmdldEJ5T2Zmc2V0KCdwb3NpdGlvbl9pZHNfaWR4Jyl9KSArIHNlbGVjdCgwLCBic25oWzFdLCBwb3NpdGlvbl9pZHNfaWR4ID09IDApO1xuICAgICAgICAgICAgbGV0IGkgPSBkb3QoYnNuaCwgdW5pZm9ybXMuaW5wdXRfb3V0cHV0X3N0cmlkZXMpICsgc2VsZWN0KDAsIGJzbmhbM10sICR7aW50ZXJsZWF2ZWR9KTtcbiAgICAgICAgICAgIGxldCBqID0gaSArIHNlbGVjdChoYWxmX3JvdGFyeV9lbWJfZGltLCAxLCAke2ludGVybGVhdmVkfSk7XG4gICAgICAgICAgICBsZXQgcmUgPSAke2lucHV0LmdldEJ5T2Zmc2V0KCdpJyl9ICogJHtjb3NDYWNoZS5nZXQoJ3Bvc2l0aW9uX2lkJywgJ2JzbmhbM10nKX0gLVxuICAgICAgICAgICAgICAgICR7aW5wdXQuZ2V0QnlPZmZzZXQoJ2onKX0gKiAke3NpbkNhY2hlLmdldCgncG9zaXRpb25faWQnLCAnYnNuaFszXScpfTtcbiAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdpJywgJ3JlJyl9XG4gICAgICAgICAgICBsZXQgaW0gPSAke2lucHV0LmdldEJ5T2Zmc2V0KCdpJyl9ICogJHtzaW5DYWNoZS5nZXQoJ3Bvc2l0aW9uX2lkJywgJ2JzbmhbM10nKX0gK1xuICAgICAgICAgICAgICAgICR7aW5wdXQuZ2V0QnlPZmZzZXQoJ2onKX0gKiAke2Nvc0NhY2hlLmdldCgncG9zaXRpb25faWQnLCAnYnNuaFszXScpfTtcbiAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdqJywgJ2ltJyl9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBrID0gZG90KGJzbmgsIHVuaWZvcm1zLmlucHV0X291dHB1dF9zdHJpZGVzKSArIGhhbGZfcm90YXJ5X2VtYl9kaW07XG4gICAgICAgICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnaycsIGlucHV0LmdldEJ5T2Zmc2V0KCdrJykpfVxuICAgICAgICAgIH1cbiAgICAgICAgfWA7XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnUm90YXJ5RW1iZWRkaW5nJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICAgICAgaW50ZXJsZWF2ZWQsXG4gICAgICB9KS5jYWNoZUtleSxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnLCAncmFuaycsICdyYW5rJywgJ3JhbmsnXSxcbiAgICB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogaW5wdXRzWzBdLmRpbXMsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShnbG9iYWxTaGFwZSkgLyBXT1JLR1JPVVBfU0laRSkgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCByb3RhcnlFbWJlZGRpbmcgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFJvdGFyeUVtYmVkZGluZ0F0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlUm90YXJ5RW1iZWRkaW5nUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuXG5pbXBvcnQgeyBhcHBseUF0dGVudGlvbiwgQXR0ZW50aW9uTWFza1R5cGUsIEF0dGVudGlvblBhcmFtZXRlcnMsIEF0dGVudGlvblFrdkZvcm1hdCB9IGZyb20gJy4vYXR0ZW50aW9uJztcbmltcG9ydCB7IG1heWJlVHJhbnNwb3NlVG9CTlNIQW5kQWRkQmlhcyB9IGZyb20gJy4vbXVsdGloZWFkLWF0dGVudGlvbic7XG5pbXBvcnQgeyBjcmVhdGVTcGxpdFByb2dyYW1JbmZvLCBTcGxpdEF0dHJpYnV0ZXMgfSBmcm9tICcuL3NwbGl0JztcbmltcG9ydCB7IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvLCBUcmFuc3Bvc2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi90cmFuc3Bvc2UnO1xuaW1wb3J0IHsgUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlcywgY3JlYXRlUm90YXJ5RW1iZWRkaW5nUHJvZ3JhbUluZm8gfSBmcm9tICcuL3JvdGFyeS1lbWJlZGRpbmcnO1xuaW1wb3J0IHsgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciwgVW5pZm9ybXNBcnJheVR5cGUgfSBmcm9tICcuL2NvbW1vbic7XG5leHBvcnQgaW50ZXJmYWNlIEdyb3VwUXVlcnlBdHRlbnRpb25BdHRyaWJ1dGVzIHtcbiAgbnVtSGVhZHM6IG51bWJlcjtcbiAga3ZOdW1IZWFkczogbnVtYmVyO1xuICBzY2FsZTogbnVtYmVyO1xuICBzb2Z0Y2FwOiBudW1iZXI7XG4gIGRvUm90YXJ5OiBudW1iZXI7XG4gIHJvdGFyeUludGVybGVhdmVkOiBudW1iZXI7XG4gIHNtb290aFNvZnRtYXg6IGJvb2xlYW47XG4gIGxvY2FsV2luZG93U2l6ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBHcm91cFF1ZXJ5QXR0ZW50aW9uQXR0cmlidXRlcyxcbik6IEF0dGVudGlvblBhcmFtZXRlcnMgPT4ge1xuICBpZiAoYXR0cmlidXRlcy5kb1JvdGFyeSAmJiBpbnB1dHMubGVuZ3RoIDw9IDcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nvc19jYWNoZSBhbmQgc2luX2NhY2hlIGlucHV0cyBhcmUgcmVxdWlyZWQgaWYgZG9fcm90YXJ5IGlzIHNwZWNpZmllZCcpO1xuICB9XG4gIGNvbnN0IHF1ZXJ5ID0gaW5wdXRzWzBdO1xuICBjb25zdCBrZXkgPSBpbnB1dHNbMV07XG4gIGNvbnN0IHZhbHVlID0gaW5wdXRzWzJdO1xuICBjb25zdCBwYXN0S2V5ID0gaW5wdXRzWzNdO1xuICBjb25zdCBwYXN0VmFsdWUgPSBpbnB1dHNbNF07XG4gIGlmIChhdHRyaWJ1dGVzLmRvUm90YXJ5ICE9PSAwICYmIGlucHV0cy5sZW5ndGggPD0gNykge1xuICAgIHRocm93IG5ldyBFcnJvcignY29zX2Nhc3QgYW5kIHNpbl9jYWNoZSBhcmUgZXhwZWN0ZWQgaWYgZG9fcm90YXJ5IGF0dHJpYnV0ZSBpcyBub24temVybycpO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLmxvY2FsV2luZG93U2l6ZSAhPT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvY2FsIGF0dGVudGlvbiBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbiAgaWYgKGF0dHJpYnV0ZXMuc29mdGNhcCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU29mdGNhcCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbiAgaWYgKGF0dHJpYnV0ZXMucm90YXJ5SW50ZXJsZWF2ZWQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1JvdGFyeSBpbnRlcmxlYXZlZCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cbiAgaWYgKGF0dHJpYnV0ZXMuc21vb3RoU29mdG1heCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU21vb3RoIHNvZnRtYXggaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG4gIC8vIEFiYnJldmlhdGlvbiBhbmQgTWVhbmluZ3M6XG4gIC8vICAgQjogICAgYmF0Y2hfc2l6ZVxuICAvLyAgIFM6ICAgIHNlcXVlbmNlX2xlbmd0aCAoaW5wdXQgc2VxdWVuY2UgbGVuZ3RoIG9mIHF1ZXJ5KVxuICAvLyAgIFA6ICAgIHBhc3Rfc2VxdWVuY2VfbGVuZ3RoIChwYXN0IHNlcXVlbmNlIGxlbmd0aCBvZiBrZXkgb3IgdmFsdWUpXG4gIC8vICAgTDogICAga3Zfc2VxdWVuY2VfbGVuZ3RoIChpbnB1dCBzZXF1ZW5jZSBsZW5ndGggb2Yga2V5IG9yIHZhbHVlKVxuICAvLyAgIE06ICAgIG1heF9zZXF1ZW5jZV9sZW5ndGhcbiAgLy8gICBUOiAgICB0b3RhbF9zZXF1ZW5jZV9sZW5ndGggPSBwYXN0X3NlcXVlbmNlX2xlbmd0aCArIGt2X3NlcXVlbmNlX2xlbmd0aFxuICAvLyAgIE46ICAgIG51bV9oZWFkc1xuICAvLyAgIEg6ICAgIGhlYWQgc2l6ZSBmb3IgUSBhbmQgSywgYWthIHFfaGVhZF9zaXplIG9yIGtfaGVhZF9zaXplIG9yIHFrX2hlYWRfc2l6ZVxuICAvLyAgIEhfdjogIHZfaGVhZF9zaXplXG4gIC8vICAgRF9pOiAgaW5wdXQgaGlkZGVuIHNpemVcbiAgLy8gICBEOiAgICBoaWRkZW4gc2l6ZSBmb3IgUSBhbmQgSyAoRCA9IE4gKiBIKSwgYWthIHFfaGlkZGVuX3NpemUgb3Iga19oaWRkZW5fc2l6ZSBvciBxa19oaWRkZW5fc2l6ZVxuICAvLyAgIERfdjogIHZfaGlkZGVuX3NpemUgPSBudW1faGVhZHMgKiB2X2hlYWRfc2l6ZVxuXG4gIC8vICAgICBwYXN0X2tleSAgICAgICAgICAgICAgICAgICA6IChCLCBOLCBTKiwgSClcbiAgLy8gICAgIHBhc3RfdmFsdWUgICAgICAgICAgICAgICAgIDogKEIsIE4sIFMqLCBIKVxuICAvLyBXaGVuIG5vIHBhY2tpbmcgZm9yIHEvay92OlxuICAvLyAgICAgcXVlcnkgICAgICAgICAgICAoUSkgICAgICAgOiAoQiwgUywgRClcbiAgLy8gICAgIGtleSAgICAgICAgICAgICAgKEspICAgICAgIDogKEIsIEwsIEQpIG9yIChCLCBOLCBTKiwgSClcbiAgLy8gICAgIHZhbHVlICAgICAgICAgICAgKFYpICAgICAgIDogKEIsIEwsIERfdikgb3IgKEIsIE4sIFMqLCBIKVxuICAvLyBXaGVuIHBhY2tlZCBrdiBpcyB1c2VkOlxuICAvLyAgICAgcXVlcnkgICAgICAgICAgICAoUSkgICAgICAgOiAoQiwgUywgRClcbiAgLy8gICAgIGtleSAgICAgICAgICAgICAgKEspICAgICAgIDogKEIsIEwsIE4sIDIsIEgpXG4gIC8vICAgICB2YWx1ZSAgICAgICAgICAgIChWKSAgICAgICA6IE5vbmVcbiAgLy8gV2hlbiBwYWNrZWQgcWt2IGlzIHVzZWQ6XG4gIC8vICAgICBxdWVyeSAgICAgICAgICAgIChRKSAgICAgICA6IChCLCBMLCBOLCAzLCBIKSBvciAoQiwgUywgMypEKVxuICAvLyAgICAga2V5ICAgICAgICAgICAgICAoSykgICAgICAgOiBOb25lXG4gIC8vICAgICB2YWx1ZSAgICAgICAgICAgIChWKSAgICAgICA6IE5vbmVcblxuICBpZiAocXVlcnkuZGltcy5sZW5ndGggIT09IDMgJiYgcXVlcnkuZGltcy5sZW5ndGggIT09IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHF1ZXJ5IGlzIGV4cGVjdGVkIHRvIGhhdmUgMyBvciA1IGRpbWVuc2lvbnMnKTtcbiAgfVxuXG4gIGNvbnN0IGRtbWhhUGFja2luZyA9IGZhbHNlO1xuICBjb25zdCBiYXRjaFNpemUgPSBxdWVyeS5kaW1zWzBdO1xuICBjb25zdCBzZXF1ZW5jZUxlbmd0aCA9IHF1ZXJ5LmRpbXNbMV07XG4gIGxldCBoaWRkZW5TaXplID1cbiAgICBxdWVyeS5kaW1zLmxlbmd0aCA9PT0gMyA/IChkbW1oYVBhY2tpbmcgPyBxdWVyeS5kaW1zWzJdIC8gMyA6IHF1ZXJ5LmRpbXNbMl0pIDogYXR0cmlidXRlcy5udW1IZWFkcyAqIHF1ZXJ5LmRpbXNbNF07XG4gIGxldCBrdlNlcXVlbmNlTGVuZ3RoID0gc2VxdWVuY2VMZW5ndGg7XG5cbiAgbGV0IHBhc3RTZXF1ZW5jZUxlbmd0aCA9IDA7XG4gIGNvbnN0IHBhY2tlZFFLViA9ICFrZXkgfHwga2V5LmRpbXMubGVuZ3RoID09PSAwO1xuICBjb25zdCBoZWFkU2l6ZSA9ICFwYWNrZWRRS1ZcbiAgICA/IE1hdGguZmxvb3IoaGlkZGVuU2l6ZSAvIGF0dHJpYnV0ZXMubnVtSGVhZHMpXG4gICAgOiBNYXRoLmZsb29yKGhpZGRlblNpemUgLyAoYXR0cmlidXRlcy5udW1IZWFkcyArIDIgKiBhdHRyaWJ1dGVzLmt2TnVtSGVhZHMpKTtcbiAgaWYgKHBhY2tlZFFLVikge1xuICAgIGhpZGRlblNpemUgPSBoZWFkU2l6ZSAqIGF0dHJpYnV0ZXMubnVtSGVhZHM7XG4gIH1cbiAgY29uc3QgaGFzUGFzdEtleSA9IHBhc3RLZXkgJiYgcGFzdEtleS5kaW1zLmxlbmd0aCAhPT0gMDtcbiAgY29uc3QgaGFzUGFzdFZhbHVlID0gcGFzdFZhbHVlICYmIHBhc3RWYWx1ZS5kaW1zLmxlbmd0aCAhPT0gMDtcbiAgLy8gQ3VycmVubHkgdGhlIG9ubnhydW50aW1lIEdRQSBzcGVjaWZpY2F0aW9uIG9ubHkgc3VwcG9ydCBrZXkvdmFsdWUgQk5TSCBmb3JtYXQuXG4gIGNvbnN0IGlzUGFzdGt2QlNOSCA9XG4gICAgaGFzUGFzdEtleSAmJlxuICAgIHBhc3RLZXkuZGltcy5sZW5ndGggPT09IDQgJiZcbiAgICBwYXN0S2V5LmRpbXNbMF0gPT09IGJhdGNoU2l6ZSAmJlxuICAgIHBhc3RLZXkuZGltc1sxXSAhPT0gYXR0cmlidXRlcy5rdk51bUhlYWRzICYmXG4gICAgcGFzdEtleS5kaW1zWzJdID09PSBhdHRyaWJ1dGVzLmt2TnVtSGVhZHMgJiZcbiAgICBwYXN0S2V5LmRpbXNbM10gPT09IGhlYWRTaXplO1xuXG4gIGlmIChpc1Bhc3RrdkJTTkgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0JTTkggcGFzdEtleS9wYXN0VmFsdWUgaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG4gIGlmIChoYXNQYXN0S2V5ICYmIGhhc1Bhc3RWYWx1ZSkge1xuICAgIGlmIChwYXN0S2V5LmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdF9rZXlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDQgZGltZW5zaW9ucycpO1xuICAgIH1cbiAgICBpZiAocGFzdFZhbHVlLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicGFzdF92YWx1ZVwiIGlzIGV4cGVjdGVkIHRvIGhhdmUgNCBkaW1lbnNpb25zJyk7XG4gICAgfVxuICAgIHBhc3RTZXF1ZW5jZUxlbmd0aCA9IHBhc3RLZXkuZGltc1syXTtcbiAgfSBlbHNlIGlmIChoYXNQYXN0S2V5IHx8IGhhc1Bhc3RWYWx1ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X2tleVwiIGFuZCBcInBhc3RfdmFsdWVcIiBzaGFsbCBiZSBib3RoIHByZXNlbnQgb3IgYm90aCBhYnNlbnQnKTtcbiAgfVxuXG4gIGxldCBxa3ZGb3JtYXQ6IEF0dGVudGlvblFrdkZvcm1hdCA9IEF0dGVudGlvblFrdkZvcm1hdC5xa3ZCTlNIO1xuICBpZiAoa2V5ICYmIGtleS5kaW1zLmxlbmd0aCA+IDApIHtcbiAgICBpZiAocXVlcnkuZGltcy5sZW5ndGggIT09IDMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJxdWVyeVwiIGlzIGV4cGVjdGVkIHRvIGhhdmUgMyBkaW1lbnNpb25zIHdoZW4ga2V5IGlzIGdpdmVuJyk7XG4gICAgfVxuICAgIGlmIChrZXkuZGltcy5sZW5ndGggPCAzIHx8IGtleS5kaW1zLmxlbmd0aCA+IDUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJrZXlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDMsIDQsIG9yIDUgZGltZW5zaW9ucycpO1xuICAgIH1cbiAgICBpZiAocXVlcnkuZGltc1swXSAhPT0ga2V5LmRpbXNbMF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJxdWVyeVwiIGFuZCBcImtleVwiIHNoYWxsIGhhdmUgc2FtZSBkaW0gMCAoYmF0Y2ggc2l6ZSknKTtcbiAgICB9XG5cbiAgICBpZiAoa2V5LmRpbXMubGVuZ3RoID09PSAzKSB7XG4gICAgICBpZiAocXVlcnkuZGltc1syXSAlIGtleS5kaW1zWzJdICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uIDIgb2YgXCJxdWVyeVwiIHNob3VsZCBiZSBhIG11bHRpcGxlIG9mIFwia2V5XCInKTtcbiAgICAgIH1cbiAgICAgIGt2U2VxdWVuY2VMZW5ndGggPSBrZXkuZGltc1sxXTtcbiAgICB9IGVsc2UgaWYgKGtleS5kaW1zLmxlbmd0aCA9PT0gNSkge1xuICAgICAgaWYgKGtleS5kaW1zWzJdICE9PSBhdHRyaWJ1dGVzLm51bUhlYWRzIHx8IGtleS5kaW1zWzNdICE9PSAyIHx8IGtleS5kaW1zWzRdICE9PSBoZWFkU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdCBcImtleVwiIHNoYXBlIChiYXRjaF9zaXplLCBrdl9zZXF1ZW5jZV9sZW5ndGgsIG51bV9oZWFkcywgMiwgaGVhZF9zaXplKSBmb3IgcGFja2VkIGt2Jyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3QgXCJ2YWx1ZVwiIGJlIG5vbmUgd2hlbiBcImtleVwiIGhhcyBwYWNrZWQga3YgZm9ybWF0LicpO1xuICAgICAgfVxuICAgICAga3ZTZXF1ZW5jZUxlbmd0aCA9IGtleS5kaW1zWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBrZXlfZGltcy5zaXplKCkgPT0gNCAoY3Jvc3MtYXR0ZW50aW9uIHdpdGggcGFzdF9rZXkpXG4gICAgICBpZiAoa2V5LmRpbXNbMV0gIT09IGF0dHJpYnV0ZXMubnVtSGVhZHMgfHwga2V5LmRpbXNbM10gIT09IGhlYWRTaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0IFwia2V5XCIgc2hhcGUgKGJhdGNoX3NpemUsIG51bV9oZWFkcywga3Zfc2VxdWVuY2VfbGVuZ3RoLCBoZWFkX3NpemUpIGZvciBwYXN0X2tleScpO1xuICAgICAgfVxuICAgICAga3ZTZXF1ZW5jZUxlbmd0aCA9IGtleS5kaW1zWzJdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBwYWNrZWQgUUtWXG4gICAgaWYgKHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSAzICYmIHF1ZXJ5LmRpbXMubGVuZ3RoICE9PSA1KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwicXVlcnlcIiBpcyBleHBlY3RlZCB0byBoYXZlIDMgb3IgNSBkaW1lbnNpb25zIHdoZW4ga2V5IGlzIGVtcHR5Jyk7XG4gICAgfVxuICAgIGlmIChxdWVyeS5kaW1zLmxlbmd0aCA9PT0gNSAmJiAocXVlcnkuZGltc1syXSAhPT0gYXR0cmlidXRlcy5udW1IZWFkcyB8fCBxdWVyeS5kaW1zWzNdICE9PSAzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3QgXCJxdWVyeVwiIHNoYXBlIChiYXRjaF9zaXplLCBrdl9zZXF1ZW5jZV9sZW5ndGgsIG51bV9oZWFkcywgMywgaGVhZF9zaXplKSBmb3IgcGFja2VkIGt2Jyk7XG4gICAgfVxuXG4gICAgcWt2Rm9ybWF0ID0gQXR0ZW50aW9uUWt2Rm9ybWF0LnFrdkJTTjNIO1xuICB9XG5cbiAgY29uc3QgbWFza1R5cGU6IEF0dGVudGlvbk1hc2tUeXBlID0gQXR0ZW50aW9uTWFza1R5cGUubm9uZTtcbiAgbGV0IHBhc3NQYXN0SW5LdiA9IGZhbHNlO1xuICBsZXQgdkhpZGRlblNpemUgPSBhdHRyaWJ1dGVzLmt2TnVtSGVhZHMgPyBoZWFkU2l6ZSAqIGF0dHJpYnV0ZXMua3ZOdW1IZWFkcyA6IGhpZGRlblNpemU7XG4gIGlmICh2YWx1ZSAmJiB2YWx1ZS5kaW1zLmxlbmd0aCA+IDApIHtcbiAgICBpZiAodmFsdWUuZGltcy5sZW5ndGggIT09IDMgJiYgdmFsdWUuZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJ2YWx1ZVwiIGlzIGV4cGVjdGVkIHRvIGhhdmUgMyBvciA0IGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAocXVlcnkuZGltc1swXSAhPT0gdmFsdWUuZGltc1swXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBcInF1ZXJ5XCIgYW5kIFwidmFsdWVcIiBzaGFsbCBoYXZlIHNhbWUgZGltIDAgKGJhdGNoX3NpemUpJyk7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLmRpbXMubGVuZ3RoID09PSAzKSB7XG4gICAgICBpZiAoa3ZTZXF1ZW5jZUxlbmd0aCAhPT0gdmFsdWUuZGltc1sxXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IFwia2V5XCIgYW5kIFwidmFsdWVcIiBzaGFsbCBoYXZlIHRoZSBzYW1lIGRpbSAxIChrdl9zZXF1ZW5jZV9sZW5ndGgpJyk7XG4gICAgICB9XG4gICAgICB2SGlkZGVuU2l6ZSA9IHZhbHVlLmRpbXNbMl07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChrdlNlcXVlbmNlTGVuZ3RoICE9PSB2YWx1ZS5kaW1zWzJdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJwYXN0X2tleVwiIGFuZCBcInBhc3RfdmFsdWVcIiBzaGFsbCBoYXZlIHRoZSBzYW1lIGRpbSAyIChrdl9zZXF1ZW5jZV9sZW5ndGgpJyk7XG4gICAgICB9XG4gICAgICB2SGlkZGVuU2l6ZSA9IHZhbHVlLmRpbXNbMV0gKiB2YWx1ZS5kaW1zWzNdO1xuICAgICAgcGFzc1Bhc3RJbkt2ID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgY29uc3Qgc2VxbExlbnMgPSBpbnB1dHMubGVuZ3RoID4gNCA/IGlucHV0c1s1XSA6IHVuZGVmaW5lZDtcbiAgaWYgKHNlcWxMZW5zICYmIHNlcWxMZW5zLmRpbXMubGVuZ3RoICE9PSAxICYmIHNlcWxMZW5zLmRpbXNbMF0gIT09IGJhdGNoU2l6ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgXCJzZXFsZW5zXCIgaXMgZXhwZWN0ZWQgdG8gaGF2ZSAxIGRpbWVuc2lvbiBhbmQgdGhlIHNhbWUgZGltIDAgYXMgYmF0Y2hfc2l6ZScpO1xuICB9XG4gIGNvbnN0IHRvdGFsU2VxdWVuY2VMZW5ndGggPSAtMTtcbiAgY29uc3QgbWF4U2VxdWVuY2VMZW5ndGggPSAtMTtcbiAgY29uc3QgYnJvYWRjYXN0UmVzUG9zQmlhcyA9IGZhbHNlO1xuXG4gIHJldHVybiB7XG4gICAgYmF0Y2hTaXplLFxuICAgIHNlcXVlbmNlTGVuZ3RoLFxuICAgIHBhc3RTZXF1ZW5jZUxlbmd0aCxcbiAgICBrdlNlcXVlbmNlTGVuZ3RoLFxuICAgIHRvdGFsU2VxdWVuY2VMZW5ndGgsXG4gICAgbWF4U2VxdWVuY2VMZW5ndGgsXG4gICAgaW5wdXRIaWRkZW5TaXplOiAwLFxuICAgIGhpZGRlblNpemUsXG4gICAgdkhpZGRlblNpemUsXG4gICAgaGVhZFNpemUsXG4gICAgdkhlYWRTaXplOiBNYXRoLmZsb29yKHZIaWRkZW5TaXplIC8gYXR0cmlidXRlcy5rdk51bUhlYWRzKSxcbiAgICBudW1IZWFkczogYXR0cmlidXRlcy5udW1IZWFkcyxcbiAgICBrdk51bUhlYWRzOiBhdHRyaWJ1dGVzLmt2TnVtSGVhZHMsXG4gICAgblJlcHM6IGF0dHJpYnV0ZXMubnVtSGVhZHMgLyBhdHRyaWJ1dGVzLmt2TnVtSGVhZHMsXG4gICAgcGFzdFByZXNlbnRTaGFyZUJ1ZmZlcjogZmFsc2UsXG4gICAgbWFza1R5cGUsXG4gICAgc2NhbGU6IGF0dHJpYnV0ZXMuc2NhbGUsXG4gICAgYnJvYWRjYXN0UmVzUG9zQmlhcyxcbiAgICBwYXNzUGFzdEluS3YsXG4gICAgcWt2Rm9ybWF0LFxuICB9O1xufTtcblxuY29uc3Qgd2VpZ2h0VHJhbnNwb3NlQXR0cmlidXRlOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzID0gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgcGVybTogWzAsIDIsIDEsIDNdIH0pO1xuXG5jb25zdCBtYXliZVRyYW5zcG9zZVRvQk5TSCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgaW5wdXQ6IFRlbnNvclZpZXcsIHBhcmFtczogQXR0ZW50aW9uUGFyYW1ldGVycykgPT4ge1xuICBsZXQgcmVzaGFwZWRJbnB1dCA9IGlucHV0O1xuICBjb25zdCBudW1IZWFkcyA9IHBhcmFtcy5rdk51bUhlYWRzITtcbiAgaWYgKGlucHV0LmRpbXMubGVuZ3RoID09PSAzICYmIHBhcmFtcy5rdlNlcXVlbmNlTGVuZ3RoICE9PSAwKSB7XG4gICAgcmVzaGFwZWRJbnB1dCA9IGlucHV0LnJlc2hhcGUoW3BhcmFtcy5iYXRjaFNpemUsIHBhcmFtcy5rdlNlcXVlbmNlTGVuZ3RoLCBudW1IZWFkcywgcGFyYW1zLmhlYWRTaXplXSk7XG4gICAgcmVzaGFwZWRJbnB1dCA9IGNvbnRleHQuY29tcHV0ZShjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhyZXNoYXBlZElucHV0LCB3ZWlnaHRUcmFuc3Bvc2VBdHRyaWJ1dGUucGVybSksIHtcbiAgICAgIGlucHV0czogW3Jlc2hhcGVkSW5wdXRdLFxuICAgICAgb3V0cHV0czogWy0xXSxcbiAgICB9KVswXTtcbiAgfVxuXG4gIHJldHVybiByZXNoYXBlZElucHV0O1xufTtcblxuY29uc3QgZ2VuZXJhdGVQb3NpdGlvbklkc1Byb2dyYW1JbmZvID0gKFxuICBiYXRjaFNpemU6IG51bWJlcixcbiAgc2VxdWVuY2VMZW5ndGg6IG51bWJlcixcbiAgc2VxTGVuczogVGVuc29yVmlldyxcbiAgdG90YWxTZXFMZW46IFRlbnNvclZpZXcsXG4pID0+IHtcbiAgY29uc3Qgb3V0cHV0RGF0YVR5cGUgPSBEYXRhVHlwZS5pbnQ2NDtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3R5cGUnLCAndHlwZSddO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFtiYXRjaFNpemUgKiBzZXF1ZW5jZUxlbmd0aF07XG4gIGNvbnN0IG91dHB1dFNpemUgPSBiYXRjaFNpemUgKiBzZXF1ZW5jZUxlbmd0aDtcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHNlcXVlbmNlTGVuZ3RoIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGJhdGNoU2l6ZSB9LFxuICBdO1xuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBzZXFMZW5zSW5wdXRIZWxwZXIgPSBpbnB1dFZhcmlhYmxlKCdzZXFfbGVucycsIHNlcUxlbnMuZGF0YVR5cGUsIHNlcUxlbnMuZGltcyk7XG4gICAgY29uc3QgdG90YWxTZXFMZW5JbnB1dEhlbHBlciA9IGlucHV0VmFyaWFibGUoJ3RvdGFsX3NlcV9sZW5zJywgdG90YWxTZXFMZW4uZGF0YVR5cGUsIHRvdGFsU2VxTGVuLmRpbXMpO1xuICAgIGNvbnN0IHBvc2l0aW9uSWRzSGVscGVyID0gb3V0cHV0VmFyaWFibGUoJ3Bvc19pZHMnLCBvdXRwdXREYXRhVHlwZSwgb3V0cHV0U2hhcGUpO1xuXG4gICAgY29uc3QgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlID0gW1xuICAgICAgeyBuYW1lOiAnb3V0cHV0X3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgeyBuYW1lOiAnc2VxdWVuY2VfbGVuZ3RoJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2JhdGNoX3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgIF07XG5cbiAgICByZXR1cm4gYFxuICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKHNlcUxlbnNJbnB1dEhlbHBlciwgdG90YWxTZXFMZW5JbnB1dEhlbHBlciwgcG9zaXRpb25JZHNIZWxwZXIpfVxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuICAgIGxldCB0b3RhbF9zZXF1ZW5jZV9sZW5ndGggPSB1MzIoJHt0b3RhbFNlcUxlbklucHV0SGVscGVyLmdldEJ5T2Zmc2V0KCcwJyl9KTtcbiAgICBsZXQgaXNfc3Vic2VxdWVudF9wcm9tcHQgPSB1bmlmb3Jtcy5zZXF1ZW5jZV9sZW5ndGggPiAxICYmIHVuaWZvcm1zLnNlcXVlbmNlX2xlbmd0aCAhPSB0b3RhbF9zZXF1ZW5jZV9sZW5ndGg7XG4gICAgbGV0IGlzX2ZpcnN0X3Byb21wdCA9ICFpc19zdWJzZXF1ZW50X3Byb21wdCAmJiB1bmlmb3Jtcy5zZXF1ZW5jZV9sZW5ndGggPT0gdG90YWxfc2VxdWVuY2VfbGVuZ3RoO1xuICAgIGxldCBiYXRjaF9pZHggPSBnbG9iYWxfaWR4IC8gdW5pZm9ybXMuc2VxdWVuY2VfbGVuZ3RoO1xuICAgIGxldCBzZXF1ZW5jZV9pZHggPSBpMzIoZ2xvYmFsX2lkeCAlIHVuaWZvcm1zLnNlcXVlbmNlX2xlbmd0aCk7XG4gICAgdmFyIHBvc19pZDogaTMyID0gMDtcbiAgICBsZXQgc2VxbGVuID0gJHtzZXFMZW5zSW5wdXRIZWxwZXIuZ2V0QnlPZmZzZXQoJ2JhdGNoX2lkeCcpfTtcbiAgICBsZXQgdG90YWxfc2VxbGVuID0gc2VxbGVuICsgMTtcbiAgICBpZiAoaXNfZmlyc3RfcHJvbXB0KSB7XG4gICAgICBpZiAoc2VxdWVuY2VfaWR4IDwgdG90YWxfc2VxbGVuKSB7XG4gICAgICAgIHBvc19pZCA9IHNlcXVlbmNlX2lkeDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvc19pZCA9IDE7XG4gICAgICB9XG4gICAgICAke3Bvc2l0aW9uSWRzSGVscGVyLnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3Bvc19pZCcpfVxuICAgIH0gZWxzZSBpZiAoaXNfc3Vic2VxdWVudF9wcm9tcHQpIHtcbiAgICAgIGxldCBwYXN0X3NlcWxlbiA9IHRvdGFsX3NlcWxlbiAtIGkzMih1bmlmb3Jtcy5zZXF1ZW5jZV9sZW5ndGgpO1xuICAgICAgaWYgKHBhc3Rfc2VxbGVuICsgc2VxdWVuY2VfaWR4IDwgdG90YWxfc2VxbGVuKSB7XG4gICAgICAgIHBvc19pZCA9IHBhc3Rfc2VxbGVuICsgc2VxdWVuY2VfaWR4O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcG9zX2lkID0gMTtcbiAgICAgIH1cbiAgICAgICR7cG9zaXRpb25JZHNIZWxwZXIuc2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnLCAncG9zX2lkJyl9XG4gICAgfSBlbHNlIGlmIChnbG9iYWxfaWR4IDwgdW5pZm9ybXMuYmF0Y2hfc2l6ZSkge1xuICAgICAgJHtwb3NpdGlvbklkc0hlbHBlci5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsICdzZXFsZW4nKX1cbiAgICB9O1xuICB9XG4gIGA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0dlbmVyYXRlUG9zaXRpb25JZHMnLFxuICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2JhdGNoU2l6ZX07JHtzZXF1ZW5jZUxlbmd0aH1gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IG91dHB1dERhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBncm91cFF1ZXJ5QXR0ZW50aW9uID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBHcm91cFF1ZXJ5QXR0ZW50aW9uQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBwYXJhbXMgPSB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGlmIChjb250ZXh0LmlucHV0c1swXS5kaW1zLmxlbmd0aCA9PT0gNSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGFja2VkIFFLViBpcyBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIGlmIChjb250ZXh0LmlucHV0c1sxXT8uZGltcy5sZW5ndGggPT09IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhY2tlZCBLViBpcyBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIGNvbnN0IHEgPSBjb250ZXh0LmlucHV0c1swXTtcbiAgY29uc3QgayA9IGNvbnRleHQuaW5wdXRzWzFdICYmIGNvbnRleHQuaW5wdXRzWzFdLmRpbXMubGVuZ3RoID4gMCA/IGNvbnRleHQuaW5wdXRzWzFdIDogdW5kZWZpbmVkO1xuICBjb25zdCB2ID0gY29udGV4dC5pbnB1dHNbMl0gJiYgY29udGV4dC5pbnB1dHNbMl0uZGltcy5sZW5ndGggPiAwID8gY29udGV4dC5pbnB1dHNbMl0gOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHBhc3RLZXkgPSBjb250ZXh0LmlucHV0c1szXSAmJiBjb250ZXh0LmlucHV0c1szXS5kaW1zLmxlbmd0aCAhPT0gMCA/IGNvbnRleHQuaW5wdXRzWzNdIDogdW5kZWZpbmVkO1xuICBjb25zdCBwYXN0VmFsdWUgPSBjb250ZXh0LmlucHV0c1s0XSAmJiBjb250ZXh0LmlucHV0c1s0XS5kaW1zLmxlbmd0aCAhPT0gMCA/IGNvbnRleHQuaW5wdXRzWzRdIDogdW5kZWZpbmVkO1xuICBjb25zdCBzZXFMZW5zID0gY29udGV4dC5pbnB1dHMubGVuZ3RoID4gNCA/IGNvbnRleHQuaW5wdXRzWzVdIDogdW5kZWZpbmVkO1xuICBjb25zdCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQgPSBjb250ZXh0LmlucHV0cy5sZW5ndGggPiA1ID8gY29udGV4dC5pbnB1dHNbNl0gOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGt2TnVtSGVhZHMgPSBwYXJhbXMua3ZOdW1IZWFkcyA/IHBhcmFtcy5rdk51bUhlYWRzIDogcGFyYW1zLm51bUhlYWRzO1xuXG4gIC8vIFRPRE8gUmVtb3ZlIGV4cGxpY2l0IHNwbGl0IG9wZXJhdGlvbiBhbmQgdXNlIGluZGV4aW5nIGluIEF0dGVudGlvbiBpbXBsZW1lbnRhdGlvbiB0byBhdm9pZCBvdmVyaGVhZC5cblxuICBjb25zdCBzcGxpdEF0dHJpYnV0ZXM6IFNwbGl0QXR0cmlidXRlcyA9IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgYXhpczogMixcbiAgICBudW1PdXRwdXRzOiAzLFxuICAgIHNwbGl0U2l6ZXM6IFtwYXJhbXMubnVtSGVhZHMgKiBwYXJhbXMuaGVhZFNpemUsIGt2TnVtSGVhZHMgKiBwYXJhbXMuaGVhZFNpemUsIGt2TnVtSGVhZHMgKiBwYXJhbXMuaGVhZFNpemVdLFxuICB9KTtcbiAgY29uc3QgW3F1ZXJ5LCBrZXksIHZhbHVlXSA9XG4gICAgIWsgJiYgIXZcbiAgICAgID8gY29udGV4dC5jb21wdXRlKGNyZWF0ZVNwbGl0UHJvZ3JhbUluZm8oW3FdLCBzcGxpdEF0dHJpYnV0ZXMpLCB7IGlucHV0czogW3FdLCBvdXRwdXRzOiBbLTEsIC0xLCAtMV0gfSlcbiAgICAgIDogW3EsIGshLCB2IV07XG4gIGxldCBxUm90YXJ5OiBUZW5zb3JWaWV3IHwgdW5kZWZpbmVkO1xuICBsZXQga1JvdGFyeTogVGVuc29yVmlldyB8IHVuZGVmaW5lZDtcbiAgaWYgKGF0dHJpYnV0ZXMuZG9Sb3RhcnkpIHtcbiAgICBjb25zdCBwb3NJZHMgPSBjb250ZXh0LmNvbXB1dGUoXG4gICAgICBnZW5lcmF0ZVBvc2l0aW9uSWRzUHJvZ3JhbUluZm8ocGFyYW1zLmJhdGNoU2l6ZSwgcGFyYW1zLnNlcXVlbmNlTGVuZ3RoLCBzZXFMZW5zISwgdG90YWxTZXF1ZW5jZUxlbmd0aElucHV0ISksXG4gICAgICB7IGlucHV0czogW3NlcUxlbnMhLCB0b3RhbFNlcXVlbmNlTGVuZ3RoSW5wdXQhXSwgb3V0cHV0czogWy0xXSB9LFxuICAgIClbMF07XG4gICAgY29uc3QgY29zQ2FjaGUgPSBjb250ZXh0LmlucHV0c1s3XTtcbiAgICBjb25zdCBzaW5DYWNoZSA9IGNvbnRleHQuaW5wdXRzWzhdO1xuICAgIGNvbnN0IHFSb3RhcnlFbWJlZGRpbmdBdHRyaWJ1dGVzOiBSb3RhcnlFbWJlZGRpbmdBdHRyaWJ1dGVzID0gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICAgIGludGVybGVhdmVkOiBhdHRyaWJ1dGVzLnJvdGFyeUludGVybGVhdmVkICE9PSAwLFxuICAgICAgbnVtSGVhZHM6IHBhcmFtcy5udW1IZWFkcyxcbiAgICAgIHJvdGFyeUVtYmVkZGluZ0RpbTogMCxcbiAgICAgIHNjYWxlOiBhdHRyaWJ1dGVzLnNjYWxlLFxuICAgIH0pO1xuICAgIGNvbnN0IGlucHV0cyA9IFtxdWVyeSwgcG9zSWRzLCBjb3NDYWNoZSwgc2luQ2FjaGVdO1xuICAgIGNvbnN0IG91dHB1dHMgPSBbLTFdO1xuICAgIHFSb3RhcnkgPSBjb250ZXh0LmNvbXB1dGUoY3JlYXRlUm90YXJ5RW1iZWRkaW5nUHJvZ3JhbUluZm8oaW5wdXRzLCBxUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlcyksIHtcbiAgICAgIGlucHV0cyxcbiAgICAgIG91dHB1dHMsXG4gICAgfSlbMF07XG4gICAgaW5wdXRzLnNwbGljZSgwLCAxLCBrZXkpO1xuICAgIGNvbnN0IGtSb3RhcnlFbWJlZGRpbmdBdHRyaWJ1dGVzOiBSb3RhcnlFbWJlZGRpbmdBdHRyaWJ1dGVzID0gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICAgIGludGVybGVhdmVkOiBhdHRyaWJ1dGVzLnJvdGFyeUludGVybGVhdmVkICE9PSAwLFxuICAgICAgbnVtSGVhZHM6IHBhcmFtcy5rdk51bUhlYWRzISxcbiAgICAgIHJvdGFyeUVtYmVkZGluZ0RpbTogMCxcbiAgICAgIHNjYWxlOiBhdHRyaWJ1dGVzLnNjYWxlLFxuICAgIH0pO1xuICAgIGtSb3RhcnkgPSBjb250ZXh0LmNvbXB1dGUoY3JlYXRlUm90YXJ5RW1iZWRkaW5nUHJvZ3JhbUluZm8oaW5wdXRzLCBrUm90YXJ5RW1iZWRkaW5nQXR0cmlidXRlcyksIHtcbiAgICAgIGlucHV0cyxcbiAgICAgIG91dHB1dHMsXG4gICAgfSlbMF07XG4gIH1cbiAgY29uc3QgUSA9IG1heWJlVHJhbnNwb3NlVG9CTlNIQW5kQWRkQmlhcyhcbiAgICBjb250ZXh0LFxuICAgIHBhcmFtcy5iYXRjaFNpemUsXG4gICAgcGFyYW1zLm51bUhlYWRzLFxuICAgIHBhcmFtcy5zZXF1ZW5jZUxlbmd0aCxcbiAgICBwYXJhbXMuaGVhZFNpemUsXG4gICAgYXR0cmlidXRlcy5kb1JvdGFyeSA/IHFSb3RhcnkhIDogcXVlcnksXG4gICAgdW5kZWZpbmVkLFxuICAgIDAsXG4gICk7XG4gIGNvbnN0IEsgPSBtYXliZVRyYW5zcG9zZVRvQk5TSChjb250ZXh0LCBhdHRyaWJ1dGVzLmRvUm90YXJ5ID8ga1JvdGFyeSEgOiBrZXksIHBhcmFtcyk7XG4gIGNvbnN0IFYgPSBtYXliZVRyYW5zcG9zZVRvQk5TSChjb250ZXh0LCB2YWx1ZSwgcGFyYW1zKTtcblxuICBhcHBseUF0dGVudGlvbihcbiAgICBjb250ZXh0LFxuICAgIFEsXG4gICAgSyxcbiAgICBWLFxuICAgIHVuZGVmaW5lZCxcbiAgICB1bmRlZmluZWQsXG4gICAgcGFzdEtleSxcbiAgICBwYXN0VmFsdWUsXG4gICAgdW5kZWZpbmVkLFxuICAgIHBhcmFtcyxcbiAgICBzZXFMZW5zLFxuICAgIHRvdGFsU2VxdWVuY2VMZW5ndGhJbnB1dCxcbiAgKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvIH0gZnJvbSAnLi90cmFuc3Bvc2UnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgZ2V0TWF4Q29tcG9uZW50cyxcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgc3VtVmVjdG9yLFxuICB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUsXG59IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBJbnN0YW5jZU5vcm1BdHRyaWJ1dGVzIHtcbiAgZXBzaWxvbjogbnVtYmVyO1xuICBmb3JtYXQ6ICdOSFdDJyB8ICdOQ0hXJztcbn1cblxuY29uc3QgY29tcHV0ZUNoYW5uZWxTY2FsZVNoaWZ0ID0gKFxuICBjb250ZXh0OiBDb21wdXRlQ29udGV4dCxcbiAgaW5wdXQ6IFRlbnNvclZpZXcsXG4gIHNjYWxlOiBUZW5zb3JWaWV3LFxuICBiaWFzOiBUZW5zb3JWaWV3LFxuICBuOiBudW1iZXIsXG4gIGg6IG51bWJlcixcbiAgYzogbnVtYmVyLFxuICBlcHNpbG9uOiBudW1iZXIsXG4pID0+IHtcbiAgY29uc3QgY29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMoaCk7XG4gIGNvbnN0IGYzMlR5cGUgPSBjb21wb25lbnRzID09PSAxID8gJ2YzMicgOiBgdmVjJHtjb21wb25lbnRzfWZgO1xuICBjb25zdCB3Z1R5cGUgPSBjb21wb25lbnRzID09PSAxID8gJ3ZlYzJmJyA6IGBtYXQyeCR7Y29tcG9uZW50c31mYDtcbiAgY29uc3QgdW5pdHNPZldvcmsgPSBuICogYztcbiAgbGV0IHdvcmtncm91cFNpemUgPSA2NDtcbiAgaWYgKHVuaXRzT2ZXb3JrID09PSAxKSB7XG4gICAgd29ya2dyb3VwU2l6ZSA9IDI1NjtcbiAgfVxuICBjb25zdCBpbnB1dFNoYXBlID0gW24sIGMsIGggLyBjb21wb25lbnRzXTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbbiwgYywgMl07XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWydyYW5rJywgJ3R5cGUnLCAndHlwZSddO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRTaGFwZSwgb3V0cHV0U2hhcGUpKTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCB4ID0gaW5wdXRWYXJpYWJsZSgneCcsIGlucHV0LmRhdGFUeXBlLCAzLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBzID0gaW5wdXRWYXJpYWJsZSgnc2NhbGUnLCBzY2FsZS5kYXRhVHlwZSwgc2NhbGUuZGltcyk7XG4gICAgY29uc3QgYiA9IGlucHV0VmFyaWFibGUoJ2JpYXMnLCBiaWFzLmRhdGFUeXBlLCBiaWFzLmRpbXMpO1xuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBEYXRhVHlwZS5mbG9hdCwgMywgMik7XG4gICAgY29uc3QgdmFyaWFibGVzID0gW3gsIHMsIGIsIG91dHB1dF07XG4gICAgcmV0dXJuIGBcbiAgdmFyPHdvcmtncm91cD4gd29ya2dyb3VwX3NoYXJlZCA6IGFycmF5PCR7d2dUeXBlfSwgJHt3b3JrZ3JvdXBTaXplfT47XG4gIGNvbnN0IHdvcmtncm91cF9zaXplID0gJHt3b3JrZ3JvdXBTaXplfXU7XG4gICR7c2hhZGVySGVscGVyLmRlY2xhcmVWYXJpYWJsZXMoLi4udmFyaWFibGVzKX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KHdvcmtncm91cFNpemUpfVxuICAgIGxldCBiYXRjaCA9IHdvcmtncm91cF9pbmRleCAvIHVuaWZvcm1zLnhfc2hhcGVbMV07XG4gICAgbGV0IGNoYW5uZWwgPSB3b3JrZ3JvdXBfaW5kZXggJSB1bmlmb3Jtcy54X3NoYXBlWzFdO1xuICAgIGxldCBoaWdodCA9IHVuaWZvcm1zLnhfc2hhcGVbMl07XG4gICAgLy8gaW5pdGlhbGl6ZSB3b3JrZ3JvdXAgbWVtb3J5XG4gICAgdmFyIHN1bSA9ICR7ZjMyVHlwZX0oMCk7XG4gICAgdmFyIHNxdWFyZWRfc3VtID0gJHtmMzJUeXBlfSgwKTtcbiAgICBmb3IgKHZhciBoID0gbG9jYWxfaWR4OyBoIDwgaGlnaHQ7IGggKz0gd29ya2dyb3VwX3NpemUpIHtcbiAgICAgIGxldCB2YWx1ZSA9ICR7ZjMyVHlwZX0oJHt4LmdldCgnYmF0Y2gnLCAnY2hhbm5lbCcsICdoJyl9KTtcbiAgICAgIHN1bSArPSB2YWx1ZTtcbiAgICAgIHNxdWFyZWRfc3VtICs9IHZhbHVlICogdmFsdWU7XG4gICAgfVxuICAgIHdvcmtncm91cF9zaGFyZWRbbG9jYWxfaWR4XSA9ICR7d2dUeXBlfShzdW0sIHNxdWFyZWRfc3VtKTtcbiAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICBmb3IgKHZhciBjdXJyU2l6ZSA9IHdvcmtncm91cF9zaXplID4+IDE7ICBjdXJyU2l6ZSA+IDA7IGN1cnJTaXplID0gY3VyclNpemUgPj4gMSkge1xuICAgICAgaWYgKGxvY2FsX2lkeCA8IGN1cnJTaXplKSB7XG4gICAgICAgIHdvcmtncm91cF9zaGFyZWRbbG9jYWxfaWR4XSA9IHdvcmtncm91cF9zaGFyZWRbbG9jYWxfaWR4XSArIHdvcmtncm91cF9zaGFyZWRbbG9jYWxfaWR4ICsgY3VyclNpemVdO1xuICAgICAgfVxuICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuICAgIH1cbiAgICBpZiAobG9jYWxfaWR4ID09IDApIHtcbiAgICAgIGxldCBzdW1fZmluYWwgPSAke3N1bVZlY3Rvcignd29ya2dyb3VwX3NoYXJlZFswXVswXScsIGNvbXBvbmVudHMpfSAvIGYzMihoaWdodCAqICR7Y29tcG9uZW50c30pO1xuICAgICAgbGV0IHNxdWFyZWRfc3VtX2ZpbmFsID0gJHtzdW1WZWN0b3IoJ3dvcmtncm91cF9zaGFyZWRbMF1bMV0nLCBjb21wb25lbnRzKX0gLyBmMzIoaGlnaHQgKiAke2NvbXBvbmVudHN9KTtcblxuICAgICAgbGV0IGludl9zdGRfZGV2ID0gaW52ZXJzZVNxcnQoc3F1YXJlZF9zdW1fZmluYWwgLSBzdW1fZmluYWwgKiBzdW1fZmluYWwgKyBmMzIoJHtlcHNpbG9ufSkpO1xuICAgICAgbGV0IGNoYW5uZWxfc2NhbGUgPSBpbnZfc3RkX2RldiAqIGYzMihzY2FsZVtjaGFubmVsXSk7XG4gICAgICBsZXQgY2hhbm5lbF9zaGlmdCA9IGYzMihiaWFzW2NoYW5uZWxdKSAtIHN1bV9maW5hbCAqIGNoYW5uZWxfc2NhbGU7XG4gICAgICBvdXRwdXRbd29ya2dyb3VwX2luZGV4XSA9IHZlYzJmKGNoYW5uZWxfc2NhbGUsIGNoYW5uZWxfc2hpZnQpO1xuICAgIH1cbiAgfWA7XG4gIH07XG5cbiAgcmV0dXJuIGNvbnRleHQuY29tcHV0ZShcbiAgICB7XG4gICAgICBuYW1lOiAnSW5zdGFuY2VOb3JtQ29tcHV0ZUNoYW5uZWxTY2FsZVNoaWZ0JyxcbiAgICAgIC8vIFRPRE86IHVzZSBlcHNpbG9uIGFzIHVuaWZvcm0uIEN1cnJlbnRseSBlcHNpbG9uIGFzIHVuaWZvcm0gZmFpbHMgdGVzdF9pbnN0YW5jZW5vcm1fZXBzaWxvbi5cbiAgICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2NvbXBvbmVudHN9OyR7ZXBzaWxvbn07JHt3b3JrZ3JvdXBTaXplfWAsIGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IERhdGFUeXBlLmZsb2F0IH1dLFxuICAgICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IHVuaXRzT2ZXb3JrIH0sXG4gICAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICAgIH0pLFxuICAgICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIH0sXG4gICAgeyBpbnB1dHM6IFtpbnB1dCwgc2NhbGUsIGJpYXNdLCBvdXRwdXRzOiBbLTFdIH0sXG4gIClbMF07XG59O1xuXG5jb25zdCBjcmVhdGVJbnN0YW5jZU5vcm1Qcm9ncmFtSW5mbyA9IChcbiAgY29udGV4dDogQ29tcHV0ZUNvbnRleHQsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBJbnN0YW5jZU5vcm1BdHRyaWJ1dGVzLFxuKSA9PiB7XG4gIGNvbnN0IHhTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IHhTaGFwZTtcbiAgY29uc3QgYXhpcyA9IDI7XG4gIGNvbnN0IE4gPSB4U2hhcGVbMF07XG4gIGNvbnN0IEMgPSB4U2hhcGVbMV07XG4gIGNvbnN0IEggPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oeFNoYXBlLCBheGlzKTtcbiAgY29uc3QgY29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMoSCk7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyBjb21wb25lbnRzO1xuICAvLyBjb21wdXRlIGNoYW5uZWwgc2NhbGUgYW5kIGNoYW5uZWwgc2hpZnQuXG4gIGNvbnN0IGNoYW5uZWxTY2FsZVNoaWZ0ID0gY29tcHV0ZUNoYW5uZWxTY2FsZVNoaWZ0KFxuICAgIGNvbnRleHQsXG4gICAgaW5wdXRzWzBdLFxuICAgIGlucHV0c1sxXSxcbiAgICBpbnB1dHNbMl0sXG4gICAgTixcbiAgICBILFxuICAgIEMsXG4gICAgYXR0cmlidXRlcy5lcHNpbG9uLFxuICApO1xuXG4gIGNvbnN0IGlucHV0U2hhcGUgPSBbTiwgQywgSCAvIGNvbXBvbmVudHNdO1xuICBjb25zdCBzY2FsZVNoYXBlID0gW04sIENdO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFsndHlwZScsICdub25lJ107XG5cbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgeCA9IGlucHV0VmFyaWFibGUoJ3gnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0U2hhcGUubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBzY2FsZSA9IGlucHV0VmFyaWFibGUoJ3NjYWxlX3NoaWZ0JywgRGF0YVR5cGUuZmxvYXQsIHNjYWxlU2hhcGUubGVuZ3RoLCAyKTtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gICAgY29uc3QgdmFyaWFibGVzID0gW3gsIHNjYWxlLCBvdXRwdXRdO1xuICAgIHJldHVybiBgXG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0X3NpemUnLCAndTMyJykuZGVjbGFyZVZhcmlhYmxlcyguLi52YXJpYWJsZXMpfVxuICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cbiAgICAgIGxldCBvdXRwdXRJbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgICAgbGV0IGJhdGNoID0gb3V0cHV0SW5kaWNlc1swXTtcbiAgICAgIGxldCBjaGFubmVsID0gb3V0cHV0SW5kaWNlc1sxXTtcbiAgICAgIGxldCBzY2FsZV9zaGlmdCA9ICR7c2NhbGUuZ2V0QnlJbmRpY2VzKCd2ZWMyPHUzMj4oYmF0Y2gsIGNoYW5uZWwpJyl9O1xuICAgICAgbGV0IHZhbHVlID0gJHt4LmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4Jyl9ICogJHtvdXRwdXQudHlwZS52YWx1ZX0oc2NhbGVfc2hpZnQueCkgKyAke291dHB1dC50eXBlLnZhbHVlfShzY2FsZV9zaGlmdC55KTtcbiAgICAgICR7b3V0cHV0LnNldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JywgJ3ZhbHVlJyl9O1xuICB9YDtcbiAgfTtcblxuICBjb250ZXh0LmNvbXB1dGUoXG4gICAge1xuICAgICAgbmFtZTogJ0luc3RhbmNlTm9ybWFsaXphdGlvbicsXG4gICAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtjb21wb25lbnRzfWAsIGlucHV0RGVwZW5kZW5jaWVzIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwob3V0cHV0U2l6ZSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgICBwcm9ncmFtVW5pZm9ybXM6IFtcbiAgICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgICAgICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0U2hhcGUsIHNjYWxlU2hhcGUsIGlucHV0U2hhcGUpLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgICBnZXRTaGFkZXJTb3VyY2UsXG4gICAgfSxcbiAgICB7IGlucHV0czogW2lucHV0c1swXSwgY2hhbm5lbFNjYWxlU2hpZnRdIH0sXG4gICk7XG59O1xuXG5jb25zdCBjcmVhdGVJbnN0YW5jZU5vcm1OSFdDUHJvZ3JhbUluZm8gPSAoXG4gIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogSW5zdGFuY2VOb3JtQXR0cmlidXRlcyxcbikgPT4ge1xuICBjb25zdCB4U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSB4U2hhcGU7XG4gIGNvbnN0IE4gPSB4U2hhcGVbMF07XG4gIGNvbnN0IEMgPSB4U2hhcGVbeFNoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBIID0gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKHhTaGFwZSwgMSkgLyBDO1xuICBjb25zdCBjb21wb25lbnRzID0gZ2V0TWF4Q29tcG9uZW50cyhDKTtcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIGNvbXBvbmVudHM7XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogSCB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBNYXRoLmZsb29yKEMgLyBjb21wb25lbnRzKSB9LFxuICBdO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFsndHlwZScsICd0eXBlJ107XG5cbiAgLy8gMS4gdHJhbnNwb3NlIHggZnJvbSBOSFdDIHRvIE5DSFdcbiAgbGV0IG5lZWRUcmFuc3Bvc2UgPSBmYWxzZTtcbiAgY29uc3QgdHJhbnNwb3NlZFhQZXJtID0gWzAsIHhTaGFwZS5sZW5ndGggLSAxXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4U2hhcGUubGVuZ3RoIC0gMjsgaSsrKSB7XG4gICAgbmVlZFRyYW5zcG9zZSA9IG5lZWRUcmFuc3Bvc2UgfHwgeFNoYXBlW2kgKyAxXSAhPT0gMTtcbiAgICB0cmFuc3Bvc2VkWFBlcm0ucHVzaChpICsgMSk7XG4gIH1cblxuICBuZWVkVHJhbnNwb3NlID0gbmVlZFRyYW5zcG9zZSAmJiB4U2hhcGVbeFNoYXBlLmxlbmd0aCAtIDFdICE9PSAxO1xuXG4gIGNvbnN0IHRyYW5zcG9zZWRYID0gbmVlZFRyYW5zcG9zZVxuICAgID8gY29udGV4dC5jb21wdXRlKGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzWzBdLCB0cmFuc3Bvc2VkWFBlcm0pLCB7XG4gICAgICAgIGlucHV0czogW2NvbnRleHQuaW5wdXRzWzBdXSxcbiAgICAgICAgb3V0cHV0czogWy0xXSxcbiAgICAgIH0pWzBdXG4gICAgOiBjb250ZXh0LmlucHV0c1swXS5yZXNoYXBlKEFycmF5LmZyb20oeyBsZW5ndGg6IHhTaGFwZS5sZW5ndGggfSwgKF8sIGkpID0+IHhTaGFwZVt0cmFuc3Bvc2VkWFBlcm1baV1dKSk7XG4gIC8vIDIuIGNvbXB1dGUgY2hhbm5lbCBzY2FsZSBhbmQgY2hhbm5lbCBzaGlmdC5cbiAgY29uc3QgY2hhbm5lbFNjYWxlU2hpZnQgPSBjb21wdXRlQ2hhbm5lbFNjYWxlU2hpZnQoXG4gICAgY29udGV4dCxcbiAgICB0cmFuc3Bvc2VkWCxcbiAgICBpbnB1dHNbMV0sXG4gICAgaW5wdXRzWzJdLFxuICAgIE4sXG4gICAgSCxcbiAgICBDLFxuICAgIGF0dHJpYnV0ZXMuZXBzaWxvbixcbiAgKTtcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUoaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgICBjb25zdCBzY2FsZVR5cGUgPSBjb21wb25lbnRzID09PSAxID8gJ3ZlYzJmJyA6IGBtYXQke2NvbXBvbmVudHN9eDJmYDtcbiAgICBjb25zdCBzY2FsZURhdGEgPSAobnVtOiBudW1iZXIpID0+IHtcbiAgICAgIGNvbnN0IGluZGV4ID0gbnVtID09PSAwID8gJ3gnIDogJ3knO1xuICAgICAgY29uc3QgZjMyVHlwZSA9IGNvbXBvbmVudHMgPT09IDEgPyAnZjMyJyA6IGB2ZWMke2NvbXBvbmVudHN9ZmA7XG4gICAgICBzd2l0Y2ggKGNvbXBvbmVudHMpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIHJldHVybiBgJHtkYXRhVHlwZX0oJHtmMzJUeXBlfShzY2FsZS4ke2luZGV4fSkpYDtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHJldHVybiBgdmVjMjwke2RhdGFUeXBlfT4oJHtmMzJUeXBlfShzY2FsZVswXS4ke2luZGV4fSwgc2NhbGVbMV0uJHtpbmRleH0pKWA7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICByZXR1cm4gYHZlYzQ8JHtkYXRhVHlwZX0+KCR7ZjMyVHlwZX0oc2NhbGVbMF0uJHtpbmRleH0sIHNjYWxlWzFdLiR7aW5kZXh9LCBzY2FsZVsyXS4ke2luZGV4fSwgc2NhbGVbM10uJHtpbmRleH0pKWA7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBOb3Qgc3VwcG9ydGVkIGNvbXBvZW50cyAke2NvbXBvbmVudHN9YCk7XG4gICAgICB9XG4gICAgfTtcbiAgICBjb25zdCBpbnB1dEhlbHBlciA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcywgY29tcG9uZW50cyk7XG4gICAgY29uc3Qgb3V0cHV0SGVscGVyID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUsIGNvbXBvbmVudHMpO1xuXG4gICAgcmV0dXJuIGBcbiAgQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjxzdG9yYWdlLCByZWFkPiBpbnB1dCA6IGFycmF5PCR7aW5wdXRIZWxwZXIudHlwZS5zdG9yYWdlfT47XG4gIEBncm91cCgwKSBAYmluZGluZygxKSB2YXI8c3RvcmFnZSwgcmVhZD4gc2NhbGVfaW5wdXQgOiBhcnJheTwke3NjYWxlVHlwZX0+O1xuICBAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyPHN0b3JhZ2UsIHJlYWRfd3JpdGU+IG91dHB1dCA6IGFycmF5PCR7b3V0cHV0SGVscGVyLnR5cGUuc3RvcmFnZX0+O1xuICBzdHJ1Y3QgVW5pZm9ybXMge0g6IHUzMiwgQyA6IHUzMn07XG4gIEBncm91cCgwKSBAYmluZGluZygzKSB2YXI8dW5pZm9ybT4gdW5pZm9ybXM6IFVuaWZvcm1zO1xuXG4gICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgIGxldCBjdXJyZW50X2ltYWdlX251bWJlciA9IGdsb2JhbF9pZHggLyAodW5pZm9ybXMuQyAqIHVuaWZvcm1zLkgpO1xuICAgIGxldCBjdXJyZW50X2NoYW5uZWxfbnVtYmVyID0gZ2xvYmFsX2lkeCAlIHVuaWZvcm1zLkM7XG5cbiAgICBsZXQgc2NhbGVfb2Zmc2V0ID0gY3VycmVudF9pbWFnZV9udW1iZXIgKiB1bmlmb3Jtcy5DICsgY3VycmVudF9jaGFubmVsX251bWJlcjtcbiAgICBsZXQgc2NhbGUgPSBzY2FsZV9pbnB1dFtzY2FsZV9vZmZzZXRdO1xuICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9IGZtYShpbnB1dFtnbG9iYWxfaWR4XSwgJHtzY2FsZURhdGEoMCl9LCAke3NjYWxlRGF0YSgxKX0pO1xuICB9YDtcbiAgfTtcbiAgY29udGV4dC5jb21wdXRlKFxuICAgIHtcbiAgICAgIG5hbWU6ICdJbnN0YW5jZU5vcm1hbGl6YXRpb25OSFdDJyxcbiAgICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2NvbXBvbmVudHN9YCwgaW5wdXREZXBlbmRlbmNpZXMgfSxcbiAgICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH1dLFxuICAgICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICAgIH0pLFxuICAgICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIH0sXG4gICAgeyBpbnB1dHM6IFtpbnB1dHNbMF0sIGNoYW5uZWxTY2FsZVNoaWZ0XSB9LFxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGluc3RhbmNlTm9ybSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogSW5zdGFuY2VOb3JtQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJykge1xuICAgIGNyZWF0ZUluc3RhbmNlTm9ybU5IV0NQcm9ncmFtSW5mbyhjb250ZXh0LCBjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIH0gZWxzZSB7XG4gICAgY3JlYXRlSW5zdGFuY2VOb3JtUHJvZ3JhbUluZm8oY29udGV4dCwgY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3ksIFByb2dyYW1Vbmlmb3JtIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge1xuICBjYXN0VG9GMzIsXG4gIGZpbGxWZWN0b3IsXG4gIGdldE1heENvbXBvbmVudHMsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHN1bVZlY3RvcixcbiAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlLFxuICBVbmlmb3Jtc0FycmF5VHlwZSxcbn0gZnJvbSAnLi9jb21tb24nO1xuXG5pbnRlcmZhY2UgTGF5ZXJOb3JtQXR0cmlidXRlcyB7XG4gIHNpbXBsaWZpZWQ6IGJvb2xlYW47XG4gIGF4aXM6IG51bWJlcjtcbiAgZXBzaWxvbjogbnVtYmVyO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoIDwgMikge1xuICAgIHRocm93IG5ldyBFcnJvcignbGF5ZXJOb3JtIHJlcXVpcmVzIGF0IGxlYXN0IDIgaW5wdXRzLicpO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVMYXllck5vcm1Qcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IExheWVyTm9ybUF0dHJpYnV0ZXMsXG4gIG91dHB1dENvdW50OiBudW1iZXIsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHNpbXBsaWZpZWQgPSBhdHRyaWJ1dGVzLnNpbXBsaWZpZWQ7XG5cbiAgY29uc3QgeFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IHNjYWxlID0gaW5wdXRzWzFdO1xuICBjb25zdCBiaWFzID0gIXNpbXBsaWZpZWQgJiYgaW5wdXRzWzJdO1xuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0geFNoYXBlO1xuICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXR0cmlidXRlcy5heGlzLCB4U2hhcGUubGVuZ3RoKTtcbiAgY29uc3Qgbm9ybUNvdW50ID0gU2hhcGVVdGlsLnNpemVUb0RpbWVuc2lvbih4U2hhcGUsIGF4aXMpO1xuICBjb25zdCBub3JtU2l6ZSA9IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbih4U2hhcGUsIGF4aXMpO1xuXG4gIGNvbnN0IHNjYWxlU2l6ZSA9IFNoYXBlVXRpbC5zaXplKHNjYWxlLmRpbXMpO1xuICBjb25zdCBiaWFzU2l6ZSA9IGJpYXMgPyBTaGFwZVV0aWwuc2l6ZShiaWFzLmRpbXMpIDogMDtcbiAgaWYgKHNjYWxlU2l6ZSAhPT0gbm9ybVNpemUgfHwgKGJpYXMgJiYgYmlhc1NpemUgIT09IG5vcm1TaXplKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgU2l6ZSBvZiBYLnNoYXBlKClbYXhpczpdID09ICR7bm9ybVNpemV9LlxuICAgICAgIFNpemUgb2Ygc2NhbGUgYW5kIGJpYXMgKGlmIHByb3ZpZGVkKSBtdXN0IG1hdGNoIHRoaXMuXG4gICAgICAgR290IHNjYWxlIHNpemUgb2YgJHtzY2FsZVNpemV9IGFuZCBiaWFzIHNpemUgb2YgJHtiaWFzU2l6ZX1gKTtcbiAgfVxuXG4gIGNvbnN0IG1lYW5JbnZTdGREZXZEaW06IG51bWJlcltdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeFNoYXBlLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGkgPCBheGlzKSB7XG4gICAgICBtZWFuSW52U3RkRGV2RGltLnB1c2goeFNoYXBlW2ldKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWVhbkludlN0ZERldkRpbS5wdXNoKDEpO1xuICAgIH1cbiAgfVxuICBjb25zdCBjb21wb25lbnRzID0gZ2V0TWF4Q29tcG9uZW50cyhub3JtU2l6ZSk7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWyd0eXBlJywgJ3R5cGUnXTtcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBub3JtQ291bnQgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBub3JtU2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBNYXRoLmZsb29yKG5vcm1TaXplIC8gY29tcG9uZW50cykgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBhdHRyaWJ1dGVzLmVwc2lsb24gfSxcbiAgXTtcbiAgaWYgKGJpYXMpIHtcbiAgICBpbnB1dERlcGVuZGVuY2llcy5wdXNoKCd0eXBlJyk7XG4gIH1cbiAgY29uc3QgaGFzTWVhbkRhdGFPdXRwdXQgPSBvdXRwdXRDb3VudCA+IDE7XG4gIGNvbnN0IGhhc0ludlN0ZE91dHB1dCA9IG91dHB1dENvdW50ID4gMjtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBkYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShpbnB1dHNbMF0uZGF0YVR5cGUpO1xuICAgIGNvbnN0IHZhcmlhYmxlcyA9IFtcbiAgICAgIGlucHV0VmFyaWFibGUoJ3gnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zLCBjb21wb25lbnRzKSxcbiAgICAgIGlucHV0VmFyaWFibGUoJ3NjYWxlJywgc2NhbGUuZGF0YVR5cGUsIHNjYWxlLmRpbXMsIGNvbXBvbmVudHMpLFxuICAgIF07XG4gICAgaWYgKGJpYXMpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKGlucHV0VmFyaWFibGUoJ2JpYXMnLCBiaWFzLmRhdGFUeXBlLCBiaWFzLmRpbXMsIGNvbXBvbmVudHMpKTtcbiAgICB9XG4gICAgdmFyaWFibGVzLnB1c2gob3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUsIGNvbXBvbmVudHMpKTtcbiAgICBpZiAoaGFzTWVhbkRhdGFPdXRwdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dFZhcmlhYmxlKCdtZWFuX2RhdGFfb3V0cHV0JywgRGF0YVR5cGUuZmxvYXQsIG1lYW5JbnZTdGREZXZEaW0pKTtcbiAgICB9XG4gICAgaWYgKGhhc0ludlN0ZE91dHB1dCkge1xuICAgICAgdmFyaWFibGVzLnB1c2gob3V0cHV0VmFyaWFibGUoJ2ludl9zdGRfb3V0cHV0JywgRGF0YVR5cGUuZmxvYXQsIG1lYW5JbnZTdGREZXZEaW0pKTtcbiAgICB9XG5cbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdub3JtX2NvdW50JywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ25vcm1fc2l6ZScsIHR5cGU6ICdmMzInIH0sXG4gICAgICB7IG5hbWU6ICdub3JtX3NpemVfdmVjdG9yaXplZCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdlcHNpbG9uJywgdHlwZTogJ2YzMicgfSxcbiAgICBdO1xuICAgIHJldHVybiBgXG4gICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4udmFyaWFibGVzKX1cbiAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMubm9ybV9jb3VudCcpfVxuICAgIGxldCBvZmZzZXQgPSBnbG9iYWxfaWR4ICogdW5pZm9ybXMubm9ybV9zaXplX3ZlY3Rvcml6ZWQ7XG4gICAgdmFyIG1lYW5fdmVjdG9yID0gJHtmaWxsVmVjdG9yKCdmMzInLCBjb21wb25lbnRzKX07XG4gICAgdmFyIG1lYW5fc3F1YXJlX3ZlY3RvciA9ICR7ZmlsbFZlY3RvcignZjMyJywgY29tcG9uZW50cyl9O1xuXG4gICAgZm9yICh2YXIgaDogdTMyID0gMHU7IGggPCB1bmlmb3Jtcy5ub3JtX3NpemVfdmVjdG9yaXplZDsgaCsrKSB7XG4gICAgICBsZXQgdmFsdWUgPSAke2Nhc3RUb0YzMihkYXRhVHlwZSwgY29tcG9uZW50cywgJ3hbaCArIG9mZnNldF0nKX07XG4gICAgICBtZWFuX3ZlY3RvciArPSB2YWx1ZTtcbiAgICAgIG1lYW5fc3F1YXJlX3ZlY3RvciArPSB2YWx1ZSAqIHZhbHVlO1xuICAgIH1cbiAgICBsZXQgbWVhbiA9ICR7c3VtVmVjdG9yKCdtZWFuX3ZlY3RvcicsIGNvbXBvbmVudHMpfSAvIHVuaWZvcm1zLm5vcm1fc2l6ZTtcbiAgICBsZXQgaW52X3N0ZF9kZXYgPSBpbnZlcnNlU3FydCgke3N1bVZlY3RvcignbWVhbl9zcXVhcmVfdmVjdG9yJywgY29tcG9uZW50cyl9IC8gdW5pZm9ybXMubm9ybV9zaXplICR7XG4gICAgICBzaW1wbGlmaWVkID8gJycgOiAnLSBtZWFuICogbWVhbidcbiAgICB9ICsgdW5pZm9ybXMuZXBzaWxvbik7XG5cbiAgICBmb3IgKHZhciBqOiB1MzIgPSAwOyBqIDwgdW5pZm9ybXMubm9ybV9zaXplX3ZlY3Rvcml6ZWQ7IGorKykge1xuICAgICAgbGV0IGYzMmlucHV0ID0gJHtjYXN0VG9GMzIoZGF0YVR5cGUsIGNvbXBvbmVudHMsICd4W2ogKyBvZmZzZXRdJyl9O1xuICAgICAgbGV0IGYzMnNjYWxlID0gJHtjYXN0VG9GMzIoZGF0YVR5cGUsIGNvbXBvbmVudHMsICdzY2FsZVtqXScpfTtcbiAgICAgIG91dHB1dFtqICsgb2Zmc2V0XSA9ICR7dmFyaWFibGVzWzBdLnR5cGUudmFsdWV9KChmMzJpbnB1dCAke3NpbXBsaWZpZWQgPyAnJyA6ICctIG1lYW4nfSkgKiBpbnZfc3RkX2RldiAqIGYzMnNjYWxlXG4gICAgICAgICR7YmlhcyA/IGArICR7Y2FzdFRvRjMyKGRhdGFUeXBlLCBjb21wb25lbnRzLCAnYmlhc1tqXScpfWAgOiAnJ31cbiAgICAgICk7XG4gICAgfVxuXG4gICAgJHtoYXNNZWFuRGF0YU91dHB1dCA/ICdtZWFuX2RhdGFfb3V0cHV0W2dsb2JhbF9pZHhdID0gbWVhbicgOiAnJ307XG4gICAgJHtoYXNJbnZTdGRPdXRwdXQgPyAnaW52X3N0ZF9vdXRwdXRbZ2xvYmFsX2lkeF0gPSBpbnZfc3RkX2RldicgOiAnJ307XG4gIH1gO1xuICB9O1xuICBjb25zdCBvdXRwdXRzID0gW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfV07XG4gIGlmIChoYXNNZWFuRGF0YU91dHB1dCkge1xuICAgIG91dHB1dHMucHVzaCh7IGRpbXM6IG1lYW5JbnZTdGREZXZEaW0sIGRhdGFUeXBlOiBEYXRhVHlwZS5mbG9hdCB9KTtcbiAgfVxuICBpZiAoaGFzSW52U3RkT3V0cHV0KSB7XG4gICAgb3V0cHV0cy5wdXNoKHsgZGltczogbWVhbkludlN0ZERldkRpbSwgZGF0YVR5cGU6IERhdGFUeXBlLmZsb2F0IH0pO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnTGF5ZXJOb3JtYWxpemF0aW9uJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtjb21wb25lbnRzfTske291dHB1dENvdW50fTske3NpbXBsaWZpZWR9YCwgaW5wdXREZXBlbmRlbmNpZXMgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0cyxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG5vcm1Db3VudCAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBsYXllck5vcm0gPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IExheWVyTm9ybUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlTGF5ZXJOb3JtUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMsIGNvbnRleHQub3V0cHV0Q291bnQpKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0IH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVOYWl2ZU1hdG11bFByb2dyYW1JbmZvIH0gZnJvbSAnLi9tYXRtdWwtc2hhZGVycyc7XG5pbXBvcnQgeyBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyB9IGZyb20gJy4vM3JkLXBhcnR5L21hdG11bF9wYWNrZWRfd2ViZ3B1JztcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignTWF0TXVsIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS5kaW1zW2lucHV0c1swXS5kaW1zLmxlbmd0aCAtIDFdICE9PSBpbnB1dHNbMV0uZGltc1tpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyXSkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2hhcmVkIGRpbWVuc2lvbiBkb2VzIG5vdCBtYXRjaC4nKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IG1hdE11bCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoY29udGV4dC5pbnB1dHNbMF0uZGltcywgY29udGV4dC5pbnB1dHNbMV0uZGltcywgdHJ1ZSk7XG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCB1c2UgbWF0bXVsIG9uIHRoZSBnaXZlbiB0ZW5zb3JzXCIpO1xuICB9XG4gIGNvbnN0IE4gPSBvdXRwdXRTaGFwZVtvdXRwdXRTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3QgSyA9IGNvbnRleHQuaW5wdXRzWzBdLmRpbXNbY29udGV4dC5pbnB1dHNbMF0uZGltcy5sZW5ndGggLSAxXTtcbiAgaWYgKE4gPCA4ICYmIEsgPCA4KSB7XG4gICAgY29udGV4dC5jb21wdXRlKGNyZWF0ZU5haXZlTWF0bXVsUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIHsgYWN0aXZhdGlvbjogJycgfSwgb3V0cHV0U2hhcGUpKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBNID0gb3V0cHV0U2hhcGVbb3V0cHV0U2hhcGUubGVuZ3RoIC0gMl07XG4gICAgY29uc3QgYmF0Y2hBID0gU2hhcGVVdGlsLnNpemUoY29udGV4dC5pbnB1dHNbMF0uZGltcy5zbGljZSgwLCAtMikpO1xuICAgIGNvbnN0IGJhdGNoQiA9IFNoYXBlVXRpbC5zaXplKGNvbnRleHQuaW5wdXRzWzFdLmRpbXMuc2xpY2UoMCwgLTIpKTtcbiAgICBpZiAoYmF0Y2hBICE9PSAxICYmIE0gPT09IDEgJiYgYmF0Y2hCID09PSAxKSB7XG4gICAgICAvLyBPcHRpbWl6YXRpb24gZm9yIGJhdGNoZWQgdmVjLW1hdC1tdWxcbiAgICAgIGNvbnN0IHJlc2hhcGVkQSA9IGNvbnRleHQuaW5wdXRzWzBdLnJlc2hhcGUoWzEsIGJhdGNoQSwgS10pO1xuICAgICAgY29uc3QgcmVzaGFwZWRCID0gY29udGV4dC5pbnB1dHNbMV0ucmVzaGFwZShbMSwgSywgTl0pO1xuICAgICAgY29uc3QgbWF0bXVsT3V0cHV0U2hhcGUgPSBbMSwgYmF0Y2hBLCBOXTtcbiAgICAgIGNvbnN0IG1hdG11bElucHV0cyA9IFtyZXNoYXBlZEEsIHJlc2hhcGVkQl07XG4gICAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8obWF0bXVsSW5wdXRzLCB7IGFjdGl2YXRpb246ICcnIH0sIG91dHB1dFNoYXBlLCBtYXRtdWxPdXRwdXRTaGFwZSksIHtcbiAgICAgICAgaW5wdXRzOiBtYXRtdWxJbnB1dHMsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dC5jb21wdXRlKGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCB7IGFjdGl2YXRpb246ICcnIH0sIG91dHB1dFNoYXBlKSk7XG4gICAgfVxuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLFxuICBnZXRNYXhDb21wb25lbnRzLFxuICBpbnB1dFZhcmlhYmxlLFxuICBvdXRwdXRWYXJpYWJsZSxcbiAgU2hhZGVySGVscGVyLFxuICB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUsXG59IGZyb20gJy4vY29tbW9uJztcblxuLy8gIFRPRE8gc3VwcG9ydCBxdWFudGl6YXRpb24gYml0cyBub3QgZXF1YWwgdG8gNFxuZXhwb3J0IGludGVyZmFjZSBNYXRNdWxOQml0c0F0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBrOiBudW1iZXI7XG4gIG46IG51bWJlcjtcbiAgYWNjdXJhY3lMZXZlbDogbnVtYmVyO1xuICBiaXRzOiBudW1iZXI7XG4gIGJsb2NrU2l6ZTogbnVtYmVyO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogTWF0TXVsTkJpdHNBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoIDwgMyB8fCBpbnB1dHMubGVuZ3RoID4gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignTWF0TXVsTkJpdHMgcmVxdWlyZXMgMyBvciA0IGlucHV0cycpO1xuICB9XG4gIGNvbnN0IGEgPSBpbnB1dHNbMF07XG4gIGNvbnN0IGFSYW5rID0gYS5kaW1zLmxlbmd0aDtcbiAgaWYgKGEuZGltc1thUmFuayAtIDFdICE9PSBhdHRyaWJ1dGVzLmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBsYXN0IGRpbSBvZiBpbnB1dCBzaGFwZSBkb2VzIG5vdCBtYXRjaCB0aGUgayB2YWx1ZScpO1xuICB9XG4gIGNvbnN0IG5CbG9ja3NQZXJDb2wgPSBNYXRoLmZsb29yKChhdHRyaWJ1dGVzLmsgKyBhdHRyaWJ1dGVzLmJsb2NrU2l6ZSAtIDEpIC8gYXR0cmlidXRlcy5ibG9ja1NpemUpO1xuICBjb25zdCBibG9iU2l6ZSA9IChhdHRyaWJ1dGVzLmJsb2NrU2l6ZSAvIDgpICogYXR0cmlidXRlcy5iaXRzO1xuICBjb25zdCBiID0gaW5wdXRzWzFdO1xuICBpZiAoIVNoYXBlVXRpbC5hcmVFcXVhbChiLmRpbXMsIFthdHRyaWJ1dGVzLm4sIG5CbG9ja3NQZXJDb2wsIGJsb2JTaXplXSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBzZWNvbmQgaW5wdXRzIG11c3QgYmUgM0QgdGVuc29yIHdpdGggc2hhcGUgTiBYIG5CbG9ja3NQZXJDb2wgWCBibG9iU2l6ZScpO1xuICB9XG4gIGNvbnN0IHNjYWxlcyA9IGlucHV0c1syXTtcbiAgY29uc3Qgc2NhbGVzU2hhcGUgPSBzY2FsZXMuZGltcztcbiAgaWYgKFNoYXBlVXRpbC5zaXplKHNjYWxlc1NoYXBlKSAhPT0gYXR0cmlidXRlcy5uICogbkJsb2Nrc1BlckNvbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2NhbGVzIGlucHV0IHNpemUgZXJyb3IuJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDQpIHtcbiAgICBjb25zdCB6ZXJvUG9pbnRzID0gaW5wdXRzWzNdO1xuICAgIGNvbnN0IHplcm9Qb2ludHNTaGFwZSA9IHplcm9Qb2ludHMuZGltcztcbiAgICBjb25zdCBleHBlY3RlZFplcm9Qb2ludHNTaXplID1cbiAgICAgIGF0dHJpYnV0ZXMuYml0cyA+IDQgPyBhdHRyaWJ1dGVzLm4gKiBuQmxvY2tzUGVyQ29sIDogYXR0cmlidXRlcy5uICogTWF0aC5mbG9vcigobkJsb2Nrc1BlckNvbCArIDEpIC8gMik7XG4gICAgaWYgKFNoYXBlVXRpbC5zaXplKHplcm9Qb2ludHNTaGFwZSkgIT09IGV4cGVjdGVkWmVyb1BvaW50c1NpemUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignemVyb1BvaW50cyBpbnB1dCBzaXplIGVycm9yLicpO1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU1hdE11bE5CaXRzUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBhdHRyaWJ1dGVzOiBNYXRNdWxOQml0c0F0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgYVJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgZGltQU91dGVyID0gaW5wdXRTaGFwZVthUmFuayAtIDJdO1xuICBjb25zdCBkaW1Jbm5lciA9IGF0dHJpYnV0ZXMuaztcbiAgY29uc3QgZGltQk91dGVyID0gYXR0cmlidXRlcy5uO1xuICBjb25zdCBiYXRjaERpbXMgPSBpbnB1dFNoYXBlLnNsaWNlKDAsIGFSYW5rIC0gMik7XG4gIGNvbnN0IGJhdGNoU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGJhdGNoRGltcyk7XG4gIGNvbnN0IGJsb2JTaXplID0gaW5wdXRzWzFdLmRpbXNbMl07XG4gIGNvbnN0IGJsb2JTaXplSW5Xb3JkcyA9IGJsb2JTaXplIC8gNDtcbiAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dHNbMF0uZGF0YVR5cGU7XG4gIGNvbnN0IGFDb21wb25lbnRzID0gZ2V0TWF4Q29tcG9uZW50cyhhdHRyaWJ1dGVzLmspO1xuICBjb25zdCBiQ29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMoYmxvYlNpemVJbldvcmRzKTtcbiAgY29uc3QgY29tcG9uZW50cyA9IGdldE1heENvbXBvbmVudHMoZGltQk91dGVyKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBiYXRjaERpbXMuY29uY2F0KFtkaW1BT3V0ZXIsIGRpbUJPdXRlcl0pO1xuICBjb25zdCBvdXRwdXROdW1iZXIgPSBkaW1BT3V0ZXIgPiAxICYmIChkaW1CT3V0ZXIgLyBjb21wb25lbnRzKSAlIDIgPT09IDAgPyAyIDogMTtcbiAgY29uc3QgZGlzcGF0Y2hTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gY29tcG9uZW50cyAvIG91dHB1dE51bWJlcjtcblxuICBjb25zdCB3b3JrZ3JvdXBTaXplID0gNjQ7XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW107XG4gIGNvbnN0IGlucHV0U2hhcGVUZW1wID0gW2JhdGNoU2l6ZSwgZGltQU91dGVyLCBkaW1Jbm5lciAvIGFDb21wb25lbnRzXTtcbiAgY29uc3QgYlNoYXBlID0gU2hhcGVVdGlsLmNvbnZlcnRTaGFwZShpbnB1dHNbMV0uZGltcykuc2xpY2UoKTtcbiAgYlNoYXBlLnNwbGljZSgtMSwgMSwgYmxvYlNpemVJbldvcmRzIC8gYkNvbXBvbmVudHMpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dFNoYXBlVGVtcCkpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhiU2hhcGUpKTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXRzWzJdLmRpbXMpKTtcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDQpIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhTaGFwZVV0aWwuY29udmVydFNoYXBlKGlucHV0c1szXS5kaW1zKSkpO1xuICB9XG4gIGNvbnN0IG91dHB1dFNoYXBlVGVtcCA9IFtiYXRjaFNpemUsIGRpbUFPdXRlciwgZGltQk91dGVyIC8gY29tcG9uZW50c107XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dHB1dFNoYXBlVGVtcCkpO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IGlucHV0UmFuayA9IGlucHV0U2hhcGVUZW1wLmxlbmd0aDtcbiAgICBjb25zdCBhID0gaW5wdXRWYXJpYWJsZSgnYScsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRSYW5rLCBhQ29tcG9uZW50cyk7XG4gICAgY29uc3QgYiA9IGlucHV0VmFyaWFibGUoJ2InLCBEYXRhVHlwZS51aW50MzIsIGJTaGFwZS5sZW5ndGgsIGJDb21wb25lbnRzKTtcbiAgICBjb25zdCBzY2FsZXMgPSBpbnB1dFZhcmlhYmxlKCdzY2FsZXMnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgaW5wdXRWYXJpYWJsZXMgPSBbYSwgYiwgc2NhbGVzXTtcbiAgICBjb25zdCB6ZXJvUG9pbnRzID1cbiAgICAgIGlucHV0cy5sZW5ndGggPT09IDQgPyBpbnB1dFZhcmlhYmxlKCd6ZXJvX3BvaW50cycsIERhdGFUeXBlLnVpbnQzMiwgaW5wdXRzWzNdLmRpbXMubGVuZ3RoKSA6IHVuZGVmaW5lZDtcbiAgICBpZiAoemVyb1BvaW50cykge1xuICAgICAgaW5wdXRWYXJpYWJsZXMucHVzaCh6ZXJvUG9pbnRzKTtcbiAgICB9XG4gICAgY29uc3Qgb3V0cHV0UmFuayA9IG91dHB1dFNoYXBlVGVtcC5sZW5ndGg7XG4gICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0UmFuaywgY29tcG9uZW50cyk7XG4gICAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUoaW5wdXRzWzBdLmRhdGFUeXBlKTtcblxuICAgIGNvbnN0IHFEcURhdGFUeXBlID0gKCgpID0+IHtcbiAgICAgIHN3aXRjaCAoYUNvbXBvbmVudHMpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIHJldHVybiBgYXJyYXk8JHtkYXRhVHlwZX0sIDg+YDtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHJldHVybiBgbWF0NHgyPCR7ZGF0YVR5cGV9PmA7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICByZXR1cm4gYG1hdDJ4NDwke2RhdGFUeXBlfT5gO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHthQ29tcG9uZW50c30tY29tcG9uZW50IGlzIG5vdCBzdXBwb3J0ZWQuYCk7XG4gICAgICB9XG4gICAgfSkoKTtcblxuICAgIGNvbnN0IHByb2Nlc3NPbmVXb3JkID0gKCk6IHN0cmluZyA9PiB7XG4gICAgICBsZXQgY2FsY1N0ciA9IGBcbiAgICAgICAgICAvLyByZXVzZSBhIGRhdGFcbiAgICAgICAgICAgIHZhciBpbnB1dF9vZmZzZXQgPSAke2EuaW5kaWNlc1RvT2Zmc2V0KGAke2EudHlwZS5pbmRpY2VzfShiYXRjaCwgcm93LCB3b3JkX29mZnNldClgKX07XG4gICAgICAgICAgICB2YXIgYV9kYXRhOiAke3FEcURhdGFUeXBlfTtcbiAgICAgICAgICAgIGZvciAodmFyIGo6IHUzMiA9IDA7IGogPCAkezggLyBhQ29tcG9uZW50c307IGorKykge1xuICAgICAgICAgICAgICBhX2RhdGFbal0gPSAke2EuZ2V0QnlPZmZzZXQoJ2lucHV0X29mZnNldCcpfTtcbiAgICAgICAgICAgICAgaW5wdXRfb2Zmc2V0Kys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgYDtcbiAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgY29tcG9uZW50cyAqIG91dHB1dE51bWJlcjsgYysrKSB7XG4gICAgICAgIGNhbGNTdHIgKz0gYFxuICAgICAgICAgICAgYl92YWx1ZSA9ICR7YkNvbXBvbmVudHMgPT09IDEgPyBgYiR7Y31fZGF0YWAgOiBgYiR7Y31fZGF0YVtpXWB9O1xuICAgICAgICAgICAgYl92YWx1ZV9sb3dlciA9IHVucGFjazR4VTgoYl92YWx1ZSAmIGJfbWFzayk7XG4gICAgICAgICAgICBiX3ZhbHVlX3VwcGVyID0gdW5wYWNrNHhVOCgoYl92YWx1ZSA+PiA0KSAmIGJfbWFzayk7XG4gICAgICAgICAgICBiX3F1YW50aXplZF92YWx1ZXMgPSAke3FEcURhdGFUeXBlfSgke0FycmF5LmZyb20oXG4gICAgICAgICAgICAgIHsgbGVuZ3RoOiA0IH0sXG4gICAgICAgICAgICAgIChfLCBpKSA9PiBgJHtkYXRhVHlwZX0oYl92YWx1ZV9sb3dlclske2l9XSksICR7ZGF0YVR5cGV9KGJfdmFsdWVfdXBwZXJbJHtpfV0pYCxcbiAgICAgICAgICAgICkuam9pbignLCAnKX0pO1xuICAgICAgICAgICAgYl9kZXF1YW50aXplZF92YWx1ZXMgPSAkeygoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChhQ29tcG9uZW50cyA9PT0gMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBgJHtxRHFEYXRhVHlwZX0oJHtBcnJheS5mcm9tKFxuICAgICAgICAgICAgICAgICAgeyBsZW5ndGg6IDggfSxcbiAgICAgICAgICAgICAgICAgIChfLCBpKSA9PiBgKGJfcXVhbnRpemVkX3ZhbHVlc1ske2l9XSAtICR7emVyb1BvaW50cyA/IGB6ZXJvX3BvaW50JHtjfWAgOiAnemVyb19wb2ludCd9KSAqIHNjYWxlJHtjfWAsXG4gICAgICAgICAgICAgICAgKS5qb2luKCcsICcpfSk7YDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYChiX3F1YW50aXplZF92YWx1ZXMgLSAke3FEcURhdGFUeXBlfSgke0FycmF5KDgpXG4gICAgICAgICAgICAgICAgICAuZmlsbChgJHt6ZXJvUG9pbnRzID8gYHplcm9fcG9pbnQke2N9YCA6ICd6ZXJvX3BvaW50J31gKVxuICAgICAgICAgICAgICAgICAgLmpvaW4oJywnKX0pKSAqIHNjYWxlJHtjfTtgO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSgpfTtcbiAgICAgICAgICAgIHdvcmtncm91cF9zaGFyZWRbbG9jYWxfaWQueCAqICR7b3V0cHV0TnVtYmVyfSArICR7TWF0aC5mbG9vcihjIC8gY29tcG9uZW50cyl9XSR7Y29tcG9uZW50cyA+IDEgPyBgWyR7YyAlIGNvbXBvbmVudHN9XWAgOiAnJ30gKz0gJHtBcnJheS5mcm9tKFxuICAgICAgICAgICAgICB7IGxlbmd0aDogOCAvIGFDb21wb25lbnRzIH0sXG4gICAgICAgICAgICAgIChfLCBpKSA9PlxuICAgICAgICAgICAgICAgIGAke1xuICAgICAgICAgICAgICAgICAgYUNvbXBvbmVudHMgPT09IDFcbiAgICAgICAgICAgICAgICAgICAgPyBgYV9kYXRhWyR7aX1dICogYl9kZXF1YW50aXplZF92YWx1ZXNbJHtpfV1gXG4gICAgICAgICAgICAgICAgICAgIDogYGRvdChhX2RhdGFbJHtpfV0sIGJfZGVxdWFudGl6ZWRfdmFsdWVzWyR7aX1dKWBcbiAgICAgICAgICAgICAgICB9YCxcbiAgICAgICAgICAgICkuam9pbignICsgJyl9O1xuICAgICAgICAgIGA7XG4gICAgICB9XG4gICAgICByZXR1cm4gY2FsY1N0cjtcbiAgICB9O1xuICAgIGNvbnN0IHByZXBhcmVTY2FsZUFuZFplcm9Qb2ludCA9ICgpOiBzdHJpbmcgPT4ge1xuICAgICAgbGV0IGNhbGNTdHIgPSBgXG4gICAgICAgICAgICB2YXIgY29sX2luZGV4ID0gY29sICogJHtjb21wb25lbnRzfTtcbiAgICAgICAgICAgICR7XG4gICAgICAgICAgICAgIHplcm9Qb2ludHNcbiAgICAgICAgICAgICAgICA/IGBcbiAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2J5dGVzX3Blcl9jb2wgPSAobkJsb2Nrc1BlckNvbCArIDEpIC8gMjtcbiAgICAgICAgICAgIHZhciB6ZXJvX3BvaW50X2J5dGVfY291bnQ6IHUzMjtcbiAgICAgICAgICAgIHZhciB6ZXJvX3BvaW50X3dvcmRfaW5kZXg6IHUzMjtcbiAgICAgICAgICAgIHZhciB6ZXJvX3BvaW50X2J5dGVfb2Zmc2V0OiB1MzI7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9uaWJibGVfb2Zmc2V0OiB1MzIgPSBibG9jayAmIDB4MXU7XG4gICAgICAgICAgICB2YXIgemVyb19wb2ludF9iaXRzX29mZnNldDogdTMyO1xuICAgICAgICAgICAgdmFyIHplcm9fcG9pbnRfd29yZDogdTMyO2BcbiAgICAgICAgICAgICAgICA6IGBcbiAgICAgICAgICAgIC8vIFRoZSBkZWZhdWx0IHplcm8gcG9pbnQgaXMgOCBmb3IgdW5zaWduZWQgNC1iaXQgcXVhbnRpemF0aW9uLlxuICAgICAgICAgICAgbGV0IHplcm9fcG9pbnQgPSAke2RhdGFUeXBlfSgkezguMH0pO2BcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGA7XG4gICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGNvbXBvbmVudHMgKiBvdXRwdXROdW1iZXI7IGMrKykge1xuICAgICAgICBjYWxjU3RyICs9IGBcbiAgICAgICAgICAgIGxldCBzY2FsZSR7Y30gPSAke3NjYWxlcy5nZXRCeU9mZnNldChgY29sX2luZGV4ICogbkJsb2Nrc1BlckNvbCArIGJsb2NrYCl9O1xuICAgICAgICAgICAgJHtcbiAgICAgICAgICAgICAgemVyb1BvaW50c1xuICAgICAgICAgICAgICAgID8gYFxuICAgICAgICAgICAgemVyb19wb2ludF9ieXRlX2NvdW50ID0gY29sX2luZGV4ICogemVyb19wb2ludF9ieXRlc19wZXJfY29sICsgKGJsb2NrID4+IDB4MXUpO1xuICAgICAgICAgICAgemVyb19wb2ludF93b3JkX2luZGV4ID0gemVyb19wb2ludF9ieXRlX2NvdW50ID4+IDB4MnU7XG4gICAgICAgICAgICB6ZXJvX3BvaW50X2J5dGVfb2Zmc2V0ID0gemVyb19wb2ludF9ieXRlX2NvdW50ICYgMHgzdTtcbiAgICAgICAgICAgIHplcm9fcG9pbnRfYml0c19vZmZzZXQgPSAoemVyb19wb2ludF9ieXRlX29mZnNldCA8PCAzKSArICh6ZXJvX3BvaW50X25pYmJsZV9vZmZzZXQgPDwgMik7XG4gICAgICAgICAgICB6ZXJvX3BvaW50X3dvcmQgPSAke3plcm9Qb2ludHMuZ2V0QnlPZmZzZXQoJ3plcm9fcG9pbnRfd29yZF9pbmRleCcpfSA+PiB6ZXJvX3BvaW50X2JpdHNfb2Zmc2V0O1xuICAgICAgICAgICAgbGV0IHplcm9fcG9pbnQke2N9ID0gJHtkYXRhVHlwZX0oKHplcm9fcG9pbnRfd29yZCkgJiAweEZ1KTtgXG4gICAgICAgICAgICAgICAgOiAnJ1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29sX2luZGV4ICs9IDE7YDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjYWxjU3RyO1xuICAgIH07XG4gICAgY29uc3QgcHJlcGFyZUJEYXRhID0gKCk6IHN0cmluZyA9PiB7XG4gICAgICBsZXQgY2FsY1N0ciA9IGBjb2xfaW5kZXggPSBjb2wgKiAke2NvbXBvbmVudHN9O2A7XG4gICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGNvbXBvbmVudHMgKiBvdXRwdXROdW1iZXI7IGMrKykge1xuICAgICAgICBjYWxjU3RyICs9IGBcbiAgICAgICAgICAgIGxldCBiJHtjfV9kYXRhID0gJHtiLmdldEJ5SW5kaWNlcyhgJHtiLnR5cGUuaW5kaWNlc30oY29sX2luZGV4LCBibG9jaywgd29yZClgKX07XG4gICAgICAgICAgICBjb2xfaW5kZXggKz0gMTtgO1xuICAgICAgfVxuICAgICAgY2FsY1N0ciArPSBgXG4gICAgICAgICAgICB2YXIgYl92YWx1ZTogdTMyO1xuICAgICAgICAgICAgbGV0IGJfbWFzazogdTMyID0gMHgwRjBGMEYwRnU7XG4gICAgICAgICAgICB2YXIgYl92YWx1ZV9sb3dlcjogdmVjNDx1MzI+O1xuICAgICAgICAgICAgdmFyIGJfdmFsdWVfdXBwZXI6IHZlYzQ8dTMyPjtcbiAgICAgICAgICAgIHZhciBiX3F1YW50aXplZF92YWx1ZXM6ICR7cURxRGF0YVR5cGV9O1xuICAgICAgICAgICAgdmFyIGJfZGVxdWFudGl6ZWRfdmFsdWVzOiAke3FEcURhdGFUeXBlfTtgO1xuICAgICAgcmV0dXJuIGNhbGNTdHI7XG4gICAgfTtcbiAgICByZXR1cm4gYFxuICAgICAgICB2YXI8d29ya2dyb3VwPiB3b3JrZ3JvdXBfc2hhcmVkOiBhcnJheTwke291dHB1dC50eXBlLnZhbHVlfSwgJHtvdXRwdXROdW1iZXIgKiB3b3JrZ3JvdXBTaXplfT47XG4gICAgICAgICR7c2hhZGVySGVscGVyLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydChbd29ya2dyb3VwU2l6ZSwgMSwgMV0pfVxuICAgICAgICAgIGxldCBvdXRwdXRfaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcyhgKGdsb2JhbF9pZHggLyAke3dvcmtncm91cFNpemV9KSAqICR7b3V0cHV0TnVtYmVyfWApfTtcbiAgICAgICAgICBsZXQgY29sID0gb3V0cHV0X2luZGljZXNbMl07XG4gICAgICAgICAgbGV0IHJvdyA9IG91dHB1dF9pbmRpY2VzWzFdO1xuICAgICAgICAgIGxldCBiYXRjaCA9IG91dHB1dF9pbmRpY2VzWzBdO1xuICAgICAgICAgIGxldCBuQmxvY2tzUGVyQ29sID0gdW5pZm9ybXMuYl9zaGFwZVsxXTtcblxuICAgICAgICAgIGZvciAodmFyIGJsb2NrID0gbG9jYWxfaWQueDsgYmxvY2sgPCBuQmxvY2tzUGVyQ29sOyBibG9jayArPSAke3dvcmtncm91cFNpemV9KSB7XG4gICAgICAgICAgICAvL3Byb2Nlc3Mgb25lIGJsb2NrXG4gICAgICAgICAgICB2YXIgd29yZF9vZmZzZXQ6IHUzMiA9IGJsb2NrICogJHthdHRyaWJ1dGVzLmJsb2NrU2l6ZSAvIGFDb21wb25lbnRzfTtcbiAgICAgICAgICAgICR7cHJlcGFyZVNjYWxlQW5kWmVyb1BvaW50KCl9XG4gICAgICAgICAgICBmb3IgKHZhciB3b3JkOiB1MzIgPSAwOyB3b3JkIDwgJHtibG9iU2l6ZUluV29yZHN9OyB3b3JkICs9ICR7YkNvbXBvbmVudHN9KSB7XG4gICAgICAgICAgICAgICR7cHJlcGFyZUJEYXRhKCl9XG4gICAgICAgICAgICAgIGZvciAodmFyIGk6IHUzMiA9IDA7IGkgPCAke2JDb21wb25lbnRzfTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgJHtwcm9jZXNzT25lV29yZCgpfVxuICAgICAgICAgICAgICAgIHdvcmRfb2Zmc2V0ICs9ICR7OCAvIGFDb21wb25lbnRzfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgICAgICBpZiAobG9jYWxfaWQueCA8ICR7b3V0cHV0TnVtYmVyfSkge1xuICAgICAgICAgICAgdmFyIG91dHB1dF92YWx1ZTogJHtvdXRwdXQudHlwZS52YWx1ZX0gPSAke291dHB1dC50eXBlLnZhbHVlfSgwKTtcbiAgICAgICAgICAgIHZhciB3b3JrZ3JvdXBfc2hhcmVkX29mZnNldDogdTMyID0gbG9jYWxfaWQueDtcbiAgICAgICAgICAgIGZvciAodmFyIGI6IHUzMiA9IDB1OyBiIDwgJHt3b3JrZ3JvdXBTaXplfXU7IGIrKykge1xuICAgICAgICAgICAgICBvdXRwdXRfdmFsdWUgKz0gd29ya2dyb3VwX3NoYXJlZFt3b3JrZ3JvdXBfc2hhcmVkX29mZnNldF07XG4gICAgICAgICAgICAgIHdvcmtncm91cF9zaGFyZWRfb2Zmc2V0ICs9ICR7b3V0cHV0TnVtYmVyfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5SW5kaWNlcyhgJHtvdXRwdXQudHlwZS5pbmRpY2VzfShiYXRjaCwgcm93LCBjb2wgKyBsb2NhbF9pZC54KWAsICdvdXRwdXRfdmFsdWUnKX07XG4gICAgICAgICAgfVxuICAgICAgICB9YDtcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnTWF0TXVsTkJpdHMnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmJsb2NrU2l6ZX07JHthdHRyaWJ1dGVzLmJpdHN9OyR7YUNvbXBvbmVudHN9OyR7YkNvbXBvbmVudHN9OyR7Y29tcG9uZW50c307JHtvdXRwdXROdW1iZXJ9OyR7d29ya2dyb3VwU2l6ZX1gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXM6IEFycmF5KGlucHV0cy5sZW5ndGgpLmZpbGwoJ3JhbmsnKSxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IGRpc3BhdGNoU2l6ZSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbi8vIEN1cnJlbnRseSwgb25seSBzdXBwb3J0IGJsb2NrU2l6ZSA9IDMyLlxuZXhwb3J0IGNvbnN0IGNyZWF0ZU1hdE11bE5CaXRzQmxvY2tTaXplMzJQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IE1hdE11bE5CaXRzQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBhUmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBkaW1BT3V0ZXIgPSBpbnB1dFNoYXBlW2FSYW5rIC0gMl07XG4gIGNvbnN0IGRpbUlubmVyID0gYXR0cmlidXRlcy5rO1xuICBjb25zdCBkaW1CT3V0ZXIgPSBhdHRyaWJ1dGVzLm47XG4gIGNvbnN0IGJhdGNoRGltcyA9IGlucHV0U2hhcGUuc2xpY2UoMCwgYVJhbmsgLSAyKTtcbiAgY29uc3QgYmF0Y2hTaXplID0gU2hhcGVVdGlsLnNpemUoYmF0Y2hEaW1zKTtcbiAgY29uc3QgYmxvYlNpemUgPSBpbnB1dHNbMV0uZGltc1syXTtcbiAgY29uc3QgYmxvYlNpemVJbldvcmRzID0gYmxvYlNpemUgLyA0O1xuICBjb25zdCBkYXRhVHlwZSA9IGlucHV0c1swXS5kYXRhVHlwZTtcbiAgY29uc3QgYUNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKGF0dHJpYnV0ZXMuayk7XG4gIGNvbnN0IGJDb21wb25lbnRzID0gZ2V0TWF4Q29tcG9uZW50cyhibG9iU2l6ZUluV29yZHMpO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGJhdGNoRGltcy5jb25jYXQoW2RpbUFPdXRlciwgZGltQk91dGVyXSk7XG5cbiAgY29uc3Qgd29ya2dyb3VwU2l6ZSA9IDEyODtcbiAgY29uc3Qgd29ya2dyb3VwWSA9IGRpbUJPdXRlciAlIDggPT09IDAgPyA4IDogZGltQk91dGVyICUgNCA9PT0gMCA/IDQgOiAxO1xuICBjb25zdCB3b3JrZ3JvdXBYID0gd29ya2dyb3VwU2l6ZSAvIHdvcmtncm91cFk7XG4gIGNvbnN0IHRpbGVTaXplID0gd29ya2dyb3VwWCAqIGJDb21wb25lbnRzICogODsgLy8gZWFjaCB1aW50MzIgaGFzIDggZGF0YS5cbiAgY29uc3QgYUxlbmd0aFBlclRpbGUgPSB0aWxlU2l6ZSAvIGFDb21wb25lbnRzO1xuICBjb25zdCBibG9ja3NQZXJUaWxlID0gdGlsZVNpemUgLyBhdHRyaWJ1dGVzLmJsb2NrU2l6ZTtcbiAgY29uc3QgZGlzcGF0Y2hTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpIC8gd29ya2dyb3VwWTtcblxuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXTtcbiAgY29uc3QgaW5wdXRTaGFwZVRlbXAgPSBbYmF0Y2hTaXplLCBkaW1BT3V0ZXIsIGRpbUlubmVyIC8gYUNvbXBvbmVudHNdO1xuICBjb25zdCBiU2hhcGUgPSBTaGFwZVV0aWwuY29udmVydFNoYXBlKGlucHV0c1sxXS5kaW1zKS5zbGljZSgpO1xuICBiU2hhcGUuc3BsaWNlKC0xLCAxLCBibG9iU2l6ZUluV29yZHMgLyBiQ29tcG9uZW50cyk7XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0U2hhcGVUZW1wKSk7XG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGJTaGFwZSkpO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMl0uZGltcykpO1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gNCkge1xuICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKFNoYXBlVXRpbC5jb252ZXJ0U2hhcGUoaW5wdXRzWzNdLmRpbXMpKSk7XG4gIH1cbiAgY29uc3Qgb3V0cHV0U2hhcGVUZW1wID0gW2JhdGNoU2l6ZSwgZGltQU91dGVyLCBkaW1CT3V0ZXJdO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhvdXRwdXRTaGFwZVRlbXApKTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBpbnB1dFJhbmsgPSBpbnB1dFNoYXBlVGVtcC5sZW5ndGg7XG4gICAgY29uc3QgYSA9IGlucHV0VmFyaWFibGUoJ2EnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0UmFuaywgYUNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGIgPSBpbnB1dFZhcmlhYmxlKCdiJywgRGF0YVR5cGUudWludDMyLCBiU2hhcGUubGVuZ3RoLCBiQ29tcG9uZW50cyk7XG4gICAgY29uc3Qgc2NhbGVzID0gaW5wdXRWYXJpYWJsZSgnc2NhbGVzJywgaW5wdXRzWzJdLmRhdGFUeXBlLCBpbnB1dHNbMl0uZGltcy5sZW5ndGgpO1xuICAgIGNvbnN0IGlucHV0VmFyaWFibGVzID0gW2EsIGIsIHNjYWxlc107XG4gICAgY29uc3QgemVyb1BvaW50cyA9XG4gICAgICBpbnB1dHMubGVuZ3RoID09PSA0ID8gaW5wdXRWYXJpYWJsZSgnemVyb19wb2ludHMnLCBEYXRhVHlwZS51aW50MzIsIGlucHV0c1szXS5kaW1zLmxlbmd0aCkgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHplcm9Qb2ludHMpIHtcbiAgICAgIGlucHV0VmFyaWFibGVzLnB1c2goemVyb1BvaW50cyk7XG4gICAgfVxuICAgIGNvbnN0IG91dHB1dFJhbmsgPSBvdXRwdXRTaGFwZVRlbXAubGVuZ3RoO1xuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFJhbmspO1xuICAgIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKGlucHV0c1swXS5kYXRhVHlwZSk7XG4gICAgY29uc3QgcmVhZEEgPSAoKSA9PiB7XG4gICAgICBzd2l0Y2ggKGFDb21wb25lbnRzKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgIGxldCBhX2RhdGEwID0gdmVjNDwke2RhdGFUeXBlfT4oc3ViX2Fbd29yZF9vZmZzZXRdLCBzdWJfYVt3b3JkX29mZnNldCArIDFdLCBzdWJfYVt3b3JkX29mZnNldCArIDJdLCBzdWJfYVt3b3JkX29mZnNldCArIDNdKTtcbiAgICAgICAgICBsZXQgYV9kYXRhMSA9IHZlYzQ8JHtkYXRhVHlwZX0+KHN1Yl9hW3dvcmRfb2Zmc2V0ICsgNF0sIHN1Yl9hW3dvcmRfb2Zmc2V0ICsgNV0sIHN1Yl9hW3dvcmRfb2Zmc2V0ICsgNl0sIHN1Yl9hW3dvcmRfb2Zmc2V0ICsgN10pO2A7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgIGxldCBhX2RhdGEwID0gdmVjNDwke2RhdGFUeXBlfT4oc3ViX2Fbd29yZF9vZmZzZXRdLCBzdWJfYVt3b3JkX29mZnNldCArIDFdKTtcbiAgICAgICAgICBsZXQgYV9kYXRhMSA9IHZlYzQ8JHtkYXRhVHlwZX0+KHN1Yl9hW3dvcmRfb2Zmc2V0ICsgMl0sIHN1Yl9hW3dvcmRfb2Zmc2V0ICsgM10pO2A7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgIGxldCBhX2RhdGEwID0gc3ViX2Fbd29yZF9vZmZzZXRdO1xuICAgICAgICAgIGxldCBhX2RhdGExID0gc3ViX2Fbd29yZF9vZmZzZXQgKyAxXTtgO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHthQ29tcG9uZW50c30tY29tcG9uZW50IGlzIG5vdCBzdXBwb3J0ZWQuYCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBgXG4gICAgICAgIHZhcjx3b3JrZ3JvdXA+IHN1Yl9hOiBhcnJheTwke2EudHlwZS52YWx1ZX0sICR7YUxlbmd0aFBlclRpbGV9PjtcbiAgICAgICAgdmFyPHdvcmtncm91cD4gaW50ZXJfcmVzdWx0czogYXJyYXk8YXJyYXk8JHtvdXRwdXQudHlwZS52YWx1ZX0sICR7d29ya2dyb3VwWH0+LCAke3dvcmtncm91cFl9PjtcbiAgICAgICAgJHtzaGFkZXJIZWxwZXIuZGVjbGFyZVZhcmlhYmxlcyguLi5pbnB1dFZhcmlhYmxlcywgb3V0cHV0KX1cbiAgICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KFt3b3JrZ3JvdXBYLCB3b3JrZ3JvdXBZLCAxXSl9XG4gICAgICAgICAgbGV0IG91dHB1dF9pbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKGB3b3JrZ3JvdXBfaW5kZXggKiAke3dvcmtncm91cFl9YCl9O1xuICAgICAgICAgIGxldCBjb2wgPSBvdXRwdXRfaW5kaWNlc1syXTtcbiAgICAgICAgICBsZXQgcm93ID0gb3V0cHV0X2luZGljZXNbMV07XG4gICAgICAgICAgbGV0IGJhdGNoID0gb3V0cHV0X2luZGljZXNbMF07XG4gICAgICAgICAgbGV0IG5fYmxvY2tzX3Blcl9jb2wgPSB1bmlmb3Jtcy5iX3NoYXBlWzFdO1xuICAgICAgICAgIGxldCBudW1fdGlsZXMgPSAgKG5fYmxvY2tzX3Blcl9jb2wgLSAxKSAvICR7YmxvY2tzUGVyVGlsZX0gKyAxO1xuXG4gICAgICAgICAgLy8gTG9vcCBvdmVyIHNoYXJlZCBkaW1lbnNpb24uXG4gICAgICAgICAgZm9yICh2YXIgdGlsZTogdTMyID0gMDsgdGlsZSA8IG51bV90aWxlczsgdGlsZSArPSAxKSB7XG4gICAgICAgICAgICBsZXQgYV9jb2xfc3RhcnQgPSB0aWxlICogJHthTGVuZ3RoUGVyVGlsZX07XG4gICAgICAgICAgICAvLyBsb2FkIG9uZSB0aWxlIEEgZGF0YSBpbnRvIHNoYXJlZCBtZW1vcnkuXG4gICAgICAgICAgICBmb3IgKHZhciBhX29mZnNldCA9IGxvY2FsX2lkeDsgYV9vZmZzZXQgPCAke2FMZW5ndGhQZXJUaWxlfTsgYV9vZmZzZXQgKz0gJHt3b3JrZ3JvdXBTaXplfSlcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbGV0IGFfY29sID0gYV9jb2xfc3RhcnQgKyBhX29mZnNldDtcbiAgICAgICAgICAgICAgaWYgKGFfY29sIDwgdW5pZm9ybXMuYV9zaGFwZVsyXSlcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHN1Yl9hW2Ffb2Zmc2V0XSA9ICR7YS5nZXRCeUluZGljZXMoYCR7YS50eXBlLmluZGljZXN9KGJhdGNoLCByb3csIGFfY29sKWApfTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdWJfYVthX29mZnNldF0gPSAke2EudHlwZS52YWx1ZX0oMCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgICAgICAgICAgLy8gZWFjaCB0aHJlYWQgcHJvY2VzcyBvbmUgYmxvY2tcbiAgICAgICAgICAgIGxldCBiX3JvdyA9IGNvbCArIGxvY2FsX2lkLnk7XG4gICAgICAgICAgICBsZXQgYmxvY2sgPSB0aWxlICogJHtibG9ja3NQZXJUaWxlfSArIGxvY2FsX2lkLng7XG4gICAgICAgICAgICAke1xuICAgICAgICAgICAgICB6ZXJvUG9pbnRzXG4gICAgICAgICAgICAgICAgPyBgXG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9ieXRlc19wZXJfY29sID0gKG5fYmxvY2tzX3Blcl9jb2wgKyAxKSAvIDI7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9ieXRlX2NvdW50ID0gYl9yb3cgKiB6ZXJvX3BvaW50X2J5dGVzX3Blcl9jb2wgKyAoYmxvY2sgPj4gMHgxdSk7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF93b3JkX2luZGV4ID0gemVyb19wb2ludF9ieXRlX2NvdW50ID4+IDB4MnU7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9ieXRlX29mZnNldCA9IHplcm9fcG9pbnRfYnl0ZV9jb3VudCAmIDB4M3U7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9uaWJibGVfb2Zmc2V0OiB1MzIgPSBibG9jayAmIDB4MXU7XG4gICAgICAgICAgICBsZXQgemVyb19wb2ludF9iaXRzX29mZnNldCA9ICh6ZXJvX3BvaW50X2J5dGVfb2Zmc2V0IDw8IDMpICsgKHplcm9fcG9pbnRfbmliYmxlX29mZnNldCA8PCAyKTtcbiAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X3dvcmQgPSAke3plcm9Qb2ludHMuZ2V0QnlPZmZzZXQoJ3plcm9fcG9pbnRfd29yZF9pbmRleCcpfSA+PiB6ZXJvX3BvaW50X2JpdHNfb2Zmc2V0O1xuICAgICAgICAgICAgbGV0IHplcm9fcG9pbnQgPSAke2RhdGFUeXBlfSgoemVyb19wb2ludF93b3JkKSAmIDB4RnUpO2BcbiAgICAgICAgICAgICAgICA6IGBcbiAgICAgICAgICAgIC8vIFRoZSBkZWZhdWx0IHplcm8gcG9pbnQgaXMgOCBmb3IgdW5zaWduZWQgNC1iaXQgcXVhbnRpemF0aW9uLlxuICAgICAgICAgICAgbGV0IHplcm9fcG9pbnQgPSAke2RhdGFUeXBlfSgkezguMH0pO2BcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBzY2FsZSA9ICR7c2NhbGVzLmdldEJ5T2Zmc2V0KGBiX3JvdyAqIG5fYmxvY2tzX3Blcl9jb2wgKyBibG9ja2ApfTtcbiAgICAgICAgICAgIGxldCBiX2RhdGEgPSAke2IuZ2V0QnlJbmRpY2VzKGAke2IudHlwZS5pbmRpY2VzfShiX3JvdywgYmxvY2ssIDApYCl9O1xuICAgICAgICAgICAgdmFyIHdvcmRfb2Zmc2V0ID0gbG9jYWxfaWQueCAqICR7YXR0cmlidXRlcy5ibG9ja1NpemUgLyBhQ29tcG9uZW50c307XG4gICAgICAgICAgICBmb3IgKHZhciBpOiB1MzIgPSAwOyBpIDwgJHtiQ29tcG9uZW50c307IGkrKykge1xuICAgICAgICAgICAgICAke3JlYWRBKCl9XG4gICAgICAgICAgICAgIGxldCBiX3ZhbHVlID0gJHtiQ29tcG9uZW50cyA9PT0gMSA/IGBiX2RhdGFgIDogYGJfZGF0YVtpXWB9O1xuICAgICAgICAgICAgICBsZXQgYl92YWx1ZV9sb3dlciA9IHVucGFjazR4VTgoYl92YWx1ZSAmIDB4MEYwRjBGMEZ1KTtcbiAgICAgICAgICAgICAgbGV0IGJfdmFsdWVfdXBwZXIgPSB1bnBhY2s0eFU4KChiX3ZhbHVlID4+IDQpICYgMHgwRjBGMEYwRnUpO1xuICAgICAgICAgICAgICBsZXQgYl9xdWFudGl6ZWRfdmFsdWVzID0gbWF0Mng0PCR7ZGF0YVR5cGV9Pigke0FycmF5LmZyb20oXG4gICAgICAgICAgICAgICAgeyBsZW5ndGg6IDQgfSxcbiAgICAgICAgICAgICAgICAoXywgaSkgPT4gYCR7ZGF0YVR5cGV9KGJfdmFsdWVfbG93ZXJbJHtpfV0pLCAke2RhdGFUeXBlfShiX3ZhbHVlX3VwcGVyWyR7aX1dKWAsXG4gICAgICAgICAgICAgICkuam9pbignLCAnKX0pO1xuICAgICAgICAgICAgICBsZXQgYl9kZXF1YW50aXplZF92YWx1ZXMgPSAoYl9xdWFudGl6ZWRfdmFsdWVzIC0gbWF0Mng0PCR7ZGF0YVR5cGV9Pigke0FycmF5KDgpLmZpbGwoJ3plcm9fcG9pbnQnKS5qb2luKCcsJyl9KSkgKiBzY2FsZTtcbiAgICAgICAgICAgICAgaW50ZXJfcmVzdWx0c1tsb2NhbF9pZC55XVtsb2NhbF9pZC54XSArPSAke0FycmF5LmZyb20oXG4gICAgICAgICAgICAgICAgeyBsZW5ndGg6IDIgfSxcbiAgICAgICAgICAgICAgICAoXywgaSkgPT4gYCR7YGRvdChhX2RhdGEke2l9LCBiX2RlcXVhbnRpemVkX3ZhbHVlc1ske2l9XSlgfWAsXG4gICAgICAgICAgICAgICkuam9pbignICsgJyl9O1xuICAgICAgICAgICAgICB3b3JkX29mZnNldCArPSAkezggLyBhQ29tcG9uZW50c307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGxvY2FsX2lkeCA8ICR7d29ya2dyb3VwWX0pIHtcbiAgICAgICAgICAgIHZhciBvdXRwdXRfdmFsdWU6ICR7b3V0cHV0LnR5cGUudmFsdWV9ID0gJHtvdXRwdXQudHlwZS52YWx1ZX0oMCk7XG4gICAgICAgICAgICBmb3IgKHZhciBiID0gMHU7IGIgPCAke3dvcmtncm91cFh9OyBiKyspIHtcbiAgICAgICAgICAgICAgb3V0cHV0X3ZhbHVlICs9IGludGVyX3Jlc3VsdHNbbG9jYWxfaWR4XVtiXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjb2wgKyBsb2NhbF9pZHggPCB1bmlmb3Jtcy5vdXRwdXRfc2hhcGVbMl0pXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICR7b3V0cHV0LnNldEJ5SW5kaWNlcyhgJHtvdXRwdXQudHlwZS5pbmRpY2VzfShiYXRjaCwgcm93LCBjb2wgKyBsb2NhbF9pZHgpYCwgJ291dHB1dF92YWx1ZScpfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfWA7XG4gIH07XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ0Jsb2Nrd2lzZU1hdE11bE5CaXRzMzInLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmJsb2NrU2l6ZX07JHthQ29tcG9uZW50c307JHtiQ29tcG9uZW50c307JHt3b3JrZ3JvdXBYfTske3dvcmtncm91cFl9YCxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiBBcnJheShpbnB1dHMubGVuZ3RoKS5maWxsKCdyYW5rJyksXG4gICAgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlIH1dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBkaXNwYXRjaFNpemUgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgbWF0TXVsTkJpdHMgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IE1hdE11bE5CaXRzQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGlmIChcbiAgICBhdHRyaWJ1dGVzLmJsb2NrU2l6ZSA9PT0gMzIgJiZcbiAgICBjb250ZXh0LmFkYXB0ZXJJbmZvLmlzVmVuZG9yKCdpbnRlbCcpICYmXG4gICAgY29udGV4dC5hZGFwdGVySW5mby5pc0FyY2hpdGVjdHVyZSgnZ2VuLTEybHAnKVxuICApIHtcbiAgICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlTWF0TXVsTkJpdHNCbG9ja1NpemUzMlByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKSk7XG4gIH0gZWxzZSB7XG4gICAgY29udGV4dC5jb21wdXRlKGNyZWF0ZU1hdE11bE5CaXRzUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTWF0TXVsTkJpdHNBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogTWF0TXVsTkJpdHNBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleShhdHRyaWJ1dGVzIGFzIE9taXQ8TWF0TXVsTkJpdHNBdHRyaWJ1dGVzLCBrZXlvZiBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXk+KTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGdldEVsZW1lbnRBdCxcbiAgSW5kaWNlc0hlbHBlcixcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgVW5pZm9ybURhdGFFbGVtZW50VHlwZSxcbiAgVW5pZm9ybXNBcnJheVR5cGUsXG59IGZyb20gJy4vY29tbW9uJztcblxuaW50ZXJmYWNlIFBhZEF0dHJpYnV0ZXMge1xuICAvLyAwLWNvbnN0YW50LCAxLXJlZmxlY3QsIDItZWRnZSwgMy13cmFwXG4gIHJlYWRvbmx5IG1vZGU6IG51bWJlcjtcbiAgcmVhZG9ubHkgdmFsdWU6IG51bWJlcjtcbiAgcmVhZG9ubHkgcGFkczogbnVtYmVyW107XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUb28gZmV3IGlucHV0cycpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0uZGF0YVR5cGUgIT09IERhdGFUeXBlLmZsb2F0ICYmIGlucHV0c1swXS5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuZmxvYXQxNikge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgdHlwZSBtdXN0IGJlIGZsb2F0IG9yIGZsb2F0MTYuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSAyKSB7XG4gICAgbGV0IHZhbGlkUGFkcyA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAqIDIgPT09IGlucHV0c1sxXS5kaW1zWzBdO1xuICAgIGlmIChpbnB1dHMubGVuZ3RoID09PSA0KSB7XG4gICAgICB2YWxpZFBhZHMgPSBpbnB1dHNbM10uZGltc1swXSAqIDIgPT09IGlucHV0c1sxXS5kaW1zWzBdO1xuICAgIH1cbiAgICBpZiAoIXZhbGlkUGFkcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgcGFkcyBzaG91bGQgYmUgYSAxRCB0ZW5zb3Igb2Ygc2hhcGUgWzIgKiBpbnB1dF9yYW5rXSBvciBbMiAqIG51bV9heGVzXS4nKTtcbiAgICB9XG4gIH1cbn07XG5cbmNvbnN0IGdldFBhZENvbnN0YW50ID0gKG91dHB1dDogSW5kaWNlc0hlbHBlciwgaW5wdXRSYW5rOiBudW1iZXIsIHBhZHNMZW5ndGg6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gaW5wdXRSYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBibG9jayArPSBgXG4gICAgICAgICAgICBrID0gaTMyKCR7b3V0cHV0LmluZGljZXNHZXQoJ2luZGljZXMnLCBpKX0pIC0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnBhZHMnLCBpLCBwYWRzTGVuZ3RoKX07XG4gICAgICAgICAgICBpZiAoayA8IDApIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoayA+PSBpMzIoJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCBpLCBpbnB1dFJhbmspfSkpIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvZmZzZXQgKz0gayAqIGkzMigke2dldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zdHJpZGVzJywgaSwgaW5wdXRSYW5rKX0pO1xuICAgICAgICBgO1xuICB9XG5cbiAgcmV0dXJuIGBcbiAgICAgICAgICB2YWx1ZSA9ICR7b3V0cHV0LnR5cGUudmFsdWV9KHVuaWZvcm1zLmNvbnN0YW50X3ZhbHVlKTtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE7IGkrKykge1xuICAgICAgICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICAgICAgICB2YXIgayA9IDA7XG4gICAgICAgICAgICAke2Jsb2NrfVxuICAgICAgICAgICAgdmFsdWUgPSB4W29mZnNldF07XG4gICAgICAgICAgfVxuICAgICAgYDtcbn07XG5cbmNvbnN0IGdldFBhZFJlZmxlY3QgPSAob3V0cHV0OiBJbmRpY2VzSGVscGVyLCBpbnB1dFJhbms6IG51bWJlciwgcGFkc0xlbmd0aDogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSBpbnB1dFJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgIGJsb2NrICs9IGBcbiAgICAgICAgICAgICAgICBrID0gaTMyKCR7b3V0cHV0LmluZGljZXNHZXQoJ2luZGljZXMnLCBpKX0pIC0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnBhZHMnLCBpLCBwYWRzTGVuZ3RoKX07XG4gICAgICAgICAgICAgICAgaWYgKGsgPCAwKSB7XG4gICAgICAgICAgICAgICAgICBrID0gLWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGxldCBfMm5fMSA9IDIgKiAoaTMyKCR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgaSwgaW5wdXRSYW5rKX0pIC0gMSk7XG4gICAgICAgICAgICAgICAgICBrID0gayAlIF8ybl8xO1xuICAgICAgICAgICAgICAgICAgaWYoayA+PSBpMzIoJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCBpLCBpbnB1dFJhbmspfSkpIHtcbiAgICAgICAgICAgICAgICAgICAgayA9IF8ybl8xIC0gaztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IGsgKiBpMzIoJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc3RyaWRlcycsIGksIGlucHV0UmFuayl9KTtcbiAgICAgICAgICAgIGA7XG4gIH1cblxuICByZXR1cm4gYFxuICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICAgICAgICAgICAgdmFyIGsgPSAwO1xuICAgICAgICAgICAgICAke2Jsb2NrfVxuICAgICAgICAgICAgICB2YWx1ZSA9IHhbb2Zmc2V0XTtcbiAgICAgICAgICBgO1xufTtcblxuY29uc3QgZ2V0UGFkRWRnZSA9IChvdXRwdXQ6IEluZGljZXNIZWxwZXIsIGlucHV0UmFuazogbnVtYmVyLCBwYWRzTGVuZ3RoOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBsZXQgYmxvY2sgPSAnJztcbiAgZm9yIChsZXQgaSA9IGlucHV0UmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgICAgICAgICAgIGsgPSBpMzIoJHtvdXRwdXQuaW5kaWNlc0dldCgnaW5kaWNlcycsIGkpfSkgLSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMucGFkcycsIGksIHBhZHNMZW5ndGgpfTtcbiAgICAgICAgICAgICAgICBpZiAoayA8IDApIHtcbiAgICAgICAgICAgICAgICAgIGsgPSAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoayA+PSBpMzIoJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCBpLCBpbnB1dFJhbmspfSkpIHtcbiAgICAgICAgICAgICAgICAgIGsgPSBpMzIoJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc2hhcGUnLCBpLCBpbnB1dFJhbmspfSkgLSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gayAqIGkzMigke2dldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zdHJpZGVzJywgaSwgaW5wdXRSYW5rKX0pO1xuICAgICAgICAgICAgYDtcbiAgfVxuXG4gIHJldHVybiBgXG4gICAgICAgICAgICAgIHZhciBvZmZzZXQgPSAwO1xuICAgICAgICAgICAgICB2YXIgayA9IDA7XG4gICAgICAgICAgICAgICR7YmxvY2t9XG4gICAgICAgICAgICAgIHZhbHVlID0geFtvZmZzZXRdO1xuICAgICAgICAgIGA7XG59O1xuXG5jb25zdCBnZXRQYWRXcmFwID0gKG91dHB1dDogSW5kaWNlc0hlbHBlciwgaW5wdXRSYW5rOiBudW1iZXIsIHBhZHNMZW5ndGg6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gaW5wdXRSYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBibG9jayArPSBgXG4gICAgICAgICAgICAgICAgayA9IGkzMigke291dHB1dC5pbmRpY2VzR2V0KCdpbmRpY2VzJywgaSl9KSAtICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5wYWRzJywgaSwgcGFkc0xlbmd0aCl9O1xuICAgICAgICAgICAgICAgIGlmIChrIDwgMCkgIHtcbiAgICAgICAgICAgICAgICAgIGsgKz0gaTMyKCR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgaSwgaW5wdXRSYW5rKX1dKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGsgPj0gaTMyKCR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy54X3NoYXBlJywgaSwgaW5wdXRSYW5rKX0pKSB7XG4gICAgICAgICAgICAgICAgICBrIC09IGkzMigke2dldEVsZW1lbnRBdCgndW5pZm9ybXMueF9zaGFwZScsIGksIGlucHV0UmFuayl9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IGsgKiBpMzIoJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnhfc3RyaWRlcycsIGksIGlucHV0UmFuayl9KTtcbiAgICAgICAgICAgIGA7XG4gIH1cblxuICByZXR1cm4gYFxuICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICAgICAgICAgICAgdmFyIGsgPSAwO1xuICAgICAgICAgICAgICAke2Jsb2NrfVxuICAgICAgICAgICAgICB2YWx1ZSA9IHhbb2Zmc2V0XTtcbiAgICAgICAgICBgO1xufTtcblxuY29uc3QgZ2V0UGFkU25pcHBldCA9IChvdXRwdXQ6IEluZGljZXNIZWxwZXIsIGlucHV0UmFuazogbnVtYmVyLCBhdHRyaWJ1dGVzOiBQYWRBdHRyaWJ1dGVzKTogc3RyaW5nID0+IHtcbiAgc3dpdGNoIChhdHRyaWJ1dGVzLm1vZGUpIHtcbiAgICBjYXNlIDA6XG4gICAgICByZXR1cm4gZ2V0UGFkQ29uc3RhbnQob3V0cHV0LCBpbnB1dFJhbmssIGF0dHJpYnV0ZXMucGFkcy5sZW5ndGgpO1xuICAgIGNhc2UgMTpcbiAgICAgIHJldHVybiBnZXRQYWRSZWZsZWN0KG91dHB1dCwgaW5wdXRSYW5rLCBhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoKTtcbiAgICBjYXNlIDI6XG4gICAgICByZXR1cm4gZ2V0UGFkRWRnZShvdXRwdXQsIGlucHV0UmFuaywgYXR0cmlidXRlcy5wYWRzLmxlbmd0aCk7XG4gICAgY2FzZSAzOlxuICAgICAgcmV0dXJuIGdldFBhZFdyYXAob3V0cHV0LCBpbnB1dFJhbmssIGF0dHJpYnV0ZXMucGFkcy5sZW5ndGgpO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbW9kZScpO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVQYWRQcm9ncmFtSW5mbyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwucGFkU2hhcGUoaW5wdXRzWzBdLmRpbXMuc2xpY2UoKSwgYXR0cmlidXRlcy5wYWRzKTtcbiAgY29uc3QgaW5wdXREaW1zID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IGF0dHJpYnV0ZXMucGFkcyB9LFxuICBdO1xuXG4gIGNvbnN0IGlzVmFsdWVGcm9tSW5wdXQgPSBpbnB1dHMubGVuZ3RoID49IDMgJiYgaW5wdXRzWzJdLmRhdGE7XG4gIGlmIChhdHRyaWJ1dGVzLm1vZGUgPT09IDApIHtcbiAgICBwcm9ncmFtVW5pZm9ybXMucHVzaCh7IHR5cGU6IGlzVmFsdWVGcm9tSW5wdXQgPyBpbnB1dHNbMl0uZGF0YVR5cGUgOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogYXR0cmlidXRlcy52YWx1ZSB9KTtcbiAgfVxuXG4gIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKGlucHV0c1swXS5kaW1zLCBvdXRwdXRTaGFwZSkpO1xuICBjb25zdCBpbnB1dERlcGVuZGVuY2llczogUHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3lbXSA9IFsncmFuayddO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4ge1xuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCd4JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dERpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBkYXRhVHlwZSA9IGlucHV0LnR5cGUudmFsdWU7XG4gICAgY29uc3QgcGFkU25pcHBldCA9IGdldFBhZFNuaXBwZXQob3V0cHV0LCBpbnB1dERpbXMubGVuZ3RoLCBhdHRyaWJ1dGVzKTtcbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdwYWRzJywgdHlwZTogJ2kzMicsIGxlbmd0aDogYXR0cmlidXRlcy5wYWRzLmxlbmd0aCB9LFxuICAgIF07XG4gICAgaWYgKGF0dHJpYnV0ZXMubW9kZSA9PT0gMCkge1xuICAgICAgdW5pZm9ybXMucHVzaCh7IG5hbWU6ICdjb25zdGFudF92YWx1ZScsIHR5cGU6IChpc1ZhbHVlRnJvbUlucHV0ID8gZGF0YVR5cGUgOiAnZjMyJykgYXMgVW5pZm9ybURhdGFFbGVtZW50VHlwZSB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYFxuICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyhpbnB1dCwgb3V0cHV0KX1cbiAgICAgICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0X3NpemUnKX1cblxuICAgICAgICAgICAgbGV0IGluZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG5cbiAgICAgICAgICAgIHZhciB2YWx1ZSA9ICR7ZGF0YVR5cGV9KDApO1xuICAgICAgICAgICAgJHtwYWRTbmlwcGV0fVxuICAgICAgICAgICAgb3V0cHV0W2dsb2JhbF9pZHhdID0gdmFsdWU7XG4gICAgICAgIH1gO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ1BhZCcsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7YXR0cmlidXRlcy5tb2RlfSR7aXNWYWx1ZUZyb21JbnB1dH1gLCBpbnB1dERlcGVuZGVuY2llcyB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgfTtcbn07XG5cbmNvbnN0IGNyZWF0ZVBhZEF0dHJpYnV0ZXNGcm9tSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLCBhdHRyaWJ1dGVzOiBQYWRBdHRyaWJ1dGVzKTogUGFkQXR0cmlidXRlcyA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoID4gMSkge1xuICAgIGNvbnN0IGJpZ0ludDY0UGFkcyA9IGlucHV0c1sxXS5nZXRCaWdJbnQ2NEFycmF5KCk7XG4gICAgY29uc3QgdmFsdWUgPVxuICAgICAgaW5wdXRzLmxlbmd0aCA+PSAzICYmIGlucHV0c1syXS5kYXRhXG4gICAgICAgID8gaW5wdXRzWzJdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5mbG9hdDE2XG4gICAgICAgICAgPyBpbnB1dHNbMl0uZ2V0VWludDE2QXJyYXkoKVswXVxuICAgICAgICAgIDogaW5wdXRzWzJdLmdldEZsb2F0MzJBcnJheSgpWzBdXG4gICAgICAgIDogMC4wO1xuXG4gICAgY29uc3QgaW5wdXRSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICAgIGNvbnN0IHVwZGF0ZVBhZHMgPSBuZXcgSW50MzJBcnJheSgyICogaW5wdXRSYW5rKS5maWxsKDApO1xuICAgIGlmIChpbnB1dHMubGVuZ3RoID49IDQpIHtcbiAgICAgIGNvbnN0IGF4ZXMgPSBpbnB1dHNbM10uZ2V0QmlnSW50NjRBcnJheSgpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBheGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHVwZGF0ZVBhZHNbTnVtYmVyKGF4ZXNbaV0pXSA9IE51bWJlcihiaWdJbnQ2NFBhZHNbaV0pO1xuICAgICAgICB1cGRhdGVQYWRzW051bWJlcihheGVzW2ldKSArIGlucHV0UmFua10gPSBOdW1iZXIoYmlnSW50NjRQYWRzW2kgKyBheGVzLmxlbmd0aF0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBiaWdJbnQ2NFBhZHMuZm9yRWFjaCgodiwgaSkgPT4gKHVwZGF0ZVBhZHNbTnVtYmVyKGkpXSA9IE51bWJlcih2KSkpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhZHM6IG51bWJlcltdID0gW107XG4gICAgdXBkYXRlUGFkcy5mb3JFYWNoKCh2KSA9PiBwYWRzLnB1c2godikpO1xuXG4gICAgcmV0dXJuIHsgbW9kZTogYXR0cmlidXRlcy5tb2RlLCB2YWx1ZSwgcGFkcyB9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcGFkID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBQYWRBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGNvbnRleHQuaW5wdXRzKTtcbiAgY29uc3QgdXBkYXRlZEF0dHJpYnV0ZXMgPSBjcmVhdGVQYWRBdHRyaWJ1dGVzRnJvbUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVQYWRQcm9ncmFtSW5mbyhjb250ZXh0LmlucHV0cywgdXBkYXRlZEF0dHJpYnV0ZXMpLCB7IGlucHV0czogWzBdIH0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgZW52IH0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgUG9vbENvbnZVdGlsLCBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB9IGZyb20gJy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGdldEVsZW1lbnRBdCxcbiAgSW5kaWNlc0hlbHBlcixcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgVW5pZm9ybXNBcnJheVR5cGUsXG59IGZyb20gJy4vY29tbW9uJztcblxuLy8gVE9ETzogc3VwcG9ydDpcbi8vIC0gY2VpbF9tb2RlICAgICAgICAgICAgICAgICBcInRlc3RfbWF4cG9vbF8yZF9jZWlsXCJcbi8vIC0gc3RvcmFnZV9vcmRlciAgICAgICAgICAgICBcInRlc3RfbWF4cG9vbF93aXRoX2FyZ21heF8yZF9wcmVjb21wdXRlZF9zdHJpZGVzXCJcbi8vIC0gW01heFBvb2xdIGRpbGF0aW9ucyAgICAgICBcInRlc3RfbWF4cG9vbF8yZF9kaWxhdGlvbnNcIlxuLy8gLSBbTWF4UG9vbF0gb3V0cHV0WzFdICAgICAgIFwidGVzdF9tYXhwb29sX3dpdGhfYXJnbWF4XzJkX3ByZWNvbXB1dGVkX3BhZHNcIlxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoZW52LndlYmdwdS52YWxpZGF0ZUlucHV0Q29udGVudCAmJiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUG9vbCBvcHMgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlID0gPEF0dHJpYnV0ZVR5cGUgZXh0ZW5kcyBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgfCBNYXhQb29sQXR0cmlidXRlcz4oXG4gIGlucHV0OiBUZW5zb3JWaWV3LFxuICBhdHRyaWJ1dGVzOiBBdHRyaWJ1dGVUeXBlLFxuICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLFxuKTogW0F0dHJpYnV0ZVR5cGUsIG51bWJlcltdXSA9PiB7XG4gIGNvbnN0IGlzQ2hhbm5lbHNMYXN0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJztcbiAgY29uc3QgaW5wdXRTaGFwZUFzQ2hhbm5lbEZpcnN0ID0gaW5wdXQuZGltcy5zbGljZSgpO1xuICBpZiAoaXNDaGFubmVsc0xhc3QpIHtcbiAgICBpbnB1dFNoYXBlQXNDaGFubmVsRmlyc3Quc3BsaWNlKDEsIDAsIGlucHV0U2hhcGVBc0NoYW5uZWxGaXJzdC5wb3AoKSEpOyAvLyBNb3ZlIGNoYW5uZWwgdG8gdGhlIHNlY29uZCBwb3NpdGlvbi5cbiAgfVxuICBjb25zdCBoYXNEaWxhdGlvbnMgPSBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChhdHRyaWJ1dGVzLCAnZGlsYXRpb25zJyk7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5zdHJpZGVzLnNsaWNlKCk7XG4gIGNvbnN0IGRpbGF0aW9uczogbnVtYmVyW10gPSBoYXNEaWxhdGlvbnMgPyAoYXR0cmlidXRlcyBhcyBNYXhQb29sQXR0cmlidXRlcykuZGlsYXRpb25zLnNsaWNlKCkgOiBbXTtcbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5zbGljZSgpO1xuICBQb29sQ29udlV0aWwuYWRqdXN0UG9vbEF0dHJpYnV0ZXMoaXNHbG9iYWxPcGVyYXRvciwgaW5wdXRTaGFwZUFzQ2hhbm5lbEZpcnN0LCBrZXJuZWxTaGFwZSwgc3RyaWRlcywgZGlsYXRpb25zLCBwYWRzKTtcblxuICBjb25zdCBvdXRwdXRTaGFwZUFzQ2hhbm5lbEZpcnN0ID0gUG9vbENvbnZVdGlsLmNvbXB1dGVQb29sT3V0cHV0U2hhcGUoXG4gICAgaXNHbG9iYWxPcGVyYXRvcixcbiAgICBpbnB1dFNoYXBlQXNDaGFubmVsRmlyc3QsXG4gICAgc3RyaWRlcyxcbiAgICBkaWxhdGlvbnMsXG4gICAga2VybmVsU2hhcGUsXG4gICAgcGFkcyxcbiAgICBhdHRyaWJ1dGVzLmF1dG9QYWQsXG4gICk7XG5cbiAgY29uc3QgbmV3QXR0cmlidXRlcyA9IE9iamVjdC5hc3NpZ24oe30sIGF0dHJpYnV0ZXMpO1xuICBpZiAoaGFzRGlsYXRpb25zKSB7XG4gICAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7IGtlcm5lbFNoYXBlLCBzdHJpZGVzLCBwYWRzLCBkaWxhdGlvbnMsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5IH0pO1xuICB9IGVsc2Uge1xuICAgIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywgeyBrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkcywgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXkgfSk7XG4gIH1cbiAgY29uc3Qgb3V0cHV0U2hhcGVBc0NoYW5uZWxMYXN0ID0gb3V0cHV0U2hhcGVBc0NoYW5uZWxGaXJzdC5zbGljZSgpO1xuICBvdXRwdXRTaGFwZUFzQ2hhbm5lbExhc3QucHVzaChvdXRwdXRTaGFwZUFzQ2hhbm5lbExhc3Quc3BsaWNlKDEsIDEpWzBdKTtcbiAgcmV0dXJuIFtuZXdBdHRyaWJ1dGVzLCBpc0NoYW5uZWxzTGFzdCA/IG91dHB1dFNoYXBlQXNDaGFubmVsTGFzdCA6IG91dHB1dFNoYXBlQXNDaGFubmVsRmlyc3RdO1xufTtcblxuY29uc3QgZ2V0VW5pZm9ybUFuZFBhZEluZm8gPSA8QXR0cmlidXRlVHlwZSBleHRlbmRzIEF2ZXJhZ2VQb29sQXR0cmlidXRlcyB8IE1heFBvb2xBdHRyaWJ1dGVzPihcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBhdHRyaWJ1dGVzOiBBdHRyaWJ1dGVUeXBlLFxuKTogW1Byb2dyYW1Vbmlmb3JtW10sIFVuaWZvcm1zQXJyYXlUeXBlLCBib29sZWFuLCBib29sZWFuLCBib29sZWFuXSA9PiB7XG4gIGNvbnN0IGlzQ2hhbm5lbHNMYXN0ID0gYXR0cmlidXRlcy5mb3JtYXQgPT09ICdOSFdDJztcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgY29uc3Qga2VybmVsU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUpO1xuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YToga2VybmVsU2l6ZSB9LFxuICBdO1xuICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgeyBuYW1lOiAnb3V0cHV0U2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgeyBuYW1lOiAna2VybmVsU2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gIF07XG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA8PSAyKSB7XG4gICAgY29uc3Qga3cgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2F0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIC0gMV07XG4gICAgY29uc3Qgc3cgPSBhdHRyaWJ1dGVzLnN0cmlkZXNbYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IHB3U3RhcnQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAvIDIgLSAxXTtcbiAgICBjb25zdCBwd0VuZCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC0gMV07XG4gICAgY29uc3QgcHdTdGFydEVuZE5vdFplcm8gPSAhIShwd1N0YXJ0ICsgcHdFbmQpO1xuICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKFxuICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGt3IH0sXG4gICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogc3cgfSxcbiAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwd1N0YXJ0IH0sXG4gICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogcHdFbmQgfSxcbiAgICApO1xuICAgIHVuaWZvcm1zLnB1c2goXG4gICAgICB7IG5hbWU6ICdrdycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdzdycsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdwd1N0YXJ0JywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3B3RW5kJywgdHlwZTogJ3UzMicgfSxcbiAgICApO1xuXG4gICAgbGV0IHBoU3RhcnRFbmROb3RaZXJvID0gZmFsc2U7XG4gICAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoID09PSAyKSB7XG4gICAgICBjb25zdCBraCA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGVbYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggLSAyXTtcbiAgICAgIGNvbnN0IHNoID0gYXR0cmlidXRlcy5zdHJpZGVzW2F0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggLSAyXTtcbiAgICAgIGNvbnN0IHBoU3RhcnQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAvIDIgLSAyXTtcbiAgICAgIGNvbnN0IHBoRW5kID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLSAyXTtcbiAgICAgIHBoU3RhcnRFbmROb3RaZXJvID0gISEocGhTdGFydCArIHBoRW5kKTtcbiAgICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKFxuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YToga2ggfSxcbiAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHNoIH0sXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwaFN0YXJ0IH0sXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBwaEVuZCB9LFxuICAgICAgKTtcblxuICAgICAgdW5pZm9ybXMucHVzaChcbiAgICAgICAgeyBuYW1lOiAna2gnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgICB7IG5hbWU6ICdzaCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICAgIHsgbmFtZTogJ3BoU3RhcnQnLCB0eXBlOiAndTMyJyB9LFxuICAgICAgICB7IG5hbWU6ICdwaEVuZCcsIHR5cGU6ICd1MzInIH0sXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gW3Byb2dyYW1Vbmlmb3JtcywgdW5pZm9ybXMsIHRydWUsIHB3U3RhcnRFbmROb3RaZXJvLCBwaFN0YXJ0RW5kTm90WmVyb107XG4gIH0gZWxzZSB7XG4gICAgaWYgKGlzQ2hhbm5lbHNMYXN0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bvb2xpbmcgd2l0aCBrZXJuZWxTaGFwZS5sZW5ndGggPiAyIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIE5IV0MgZm9ybWF0LicpO1xuICAgIH1cbiAgICBjb25zdCBrZXJuZWxTdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUpO1xuICAgIHByb2dyYW1Vbmlmb3Jtcy5wdXNoKFxuICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGtlcm5lbFN0cmlkZXMgfSxcbiAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBhdHRyaWJ1dGVzLnBhZHMgfSxcbiAgICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBhdHRyaWJ1dGVzLnN0cmlkZXMgfSxcbiAgICApO1xuICAgIHVuaWZvcm1zLnB1c2goXG4gICAgICB7IG5hbWU6ICdrZXJuZWxTdHJpZGVzJywgdHlwZTogJ3UzMicsIGxlbmd0aDoga2VybmVsU3RyaWRlcy5sZW5ndGggfSxcbiAgICAgIHsgbmFtZTogJ3BhZHMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIH0sXG4gICAgICB7IG5hbWU6ICdzdHJpZGVzJywgdHlwZTogJ3UzMicsIGxlbmd0aDogYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCB9LFxuICAgICk7XG5cbiAgICBjb25zdCBoYXNQYWRzID0gYXR0cmlidXRlcy5wYWRzLnJlZHVjZSgoc3VtLCBjdXIpID0+IHN1bSArIGN1cik7XG4gICAgcmV0dXJuIFtwcm9ncmFtVW5pZm9ybXMsIHVuaWZvcm1zLCAhIWhhc1BhZHMsIGZhbHNlLCBmYWxzZV07XG4gIH1cbn07XG5cbmNvbnN0IGdlbmVyYXRlUG9vbGluZ0NvZGUgPSA8QXR0cmlidXRlVHlwZSBleHRlbmRzIEF2ZXJhZ2VQb29sQXR0cmlidXRlcyB8IE1heFBvb2xBdHRyaWJ1dGVzPihcbiAgc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIsXG4gIHg6IEluZGljZXNIZWxwZXIsXG4gIHJhbms6IG51bWJlcixcbiAgb3V0cHV0U2hhcGVSYW5rOiBudW1iZXIsXG4gIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZVR5cGUsXG4gIG9wMTogc3RyaW5nLFxuICBvcDI6IHN0cmluZyxcbiAgc3RhcnQ6IG51bWJlcixcbiAgdW5pZm9ybXM6IFVuaWZvcm1zQXJyYXlUeXBlLFxuICBoYXNQYWRzOiBib29sZWFuLFxuICBwd1N0YXJ0RW5kTm90WmVybzogYm9vbGVhbixcbiAgcGhTdGFydEVuZE5vdFplcm86IGJvb2xlYW4sXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBpc0NoYW5uZWxzTGFzdCA9IGF0dHJpYnV0ZXMuZm9ybWF0ID09PSAnTkhXQyc7XG4gIGNvbnN0IGRhdGFUeXBlID0geC50eXBlLnZhbHVlO1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgeC50eXBlLnRlbnNvciwgb3V0cHV0U2hhcGVSYW5rKTtcblxuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPD0gMikge1xuICAgIGxldCBjb2RlVyA9ICcnO1xuICAgIGxldCBjb2RlSCA9ICcnO1xuICAgIGxldCBjb2RlSEVuZCA9ICcnO1xuICAgIGNvbnN0IGRpbUlkeFcgPSByYW5rIC0gKGlzQ2hhbm5lbHNMYXN0ID8gMiA6IDEpO1xuICAgIGlmIChwd1N0YXJ0RW5kTm90WmVybykge1xuICAgICAgY29kZVcgPSBgXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaTogdTMyID0gMHU7IGkgPCB1bmlmb3Jtcy5rdzsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICB4SW5kaWNlc1ske2RpbUlkeFd9XSA9IGluZGljZXNbJHtkaW1JZHhXfV0gKiB1bmlmb3Jtcy5zdyAtIHVuaWZvcm1zLnB3U3RhcnQgKyBpO1xuICAgICAgICAgICAgICAgICAgaWYgKHhJbmRpY2VzWyR7ZGltSWR4V31dIDwgMCB8fCB4SW5kaWNlc1ske2RpbUlkeFd9XVxuICAgICAgICAgICAgICAgICAgICAgID49IHVuaWZvcm1zLnhfc2hhcGVbJHtkaW1JZHhXfV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcGFkKys7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgbGV0IHhfdmFsID0geFske3guaW5kaWNlc1RvT2Zmc2V0KCd4SW5kaWNlcycpfV07XG4gICAgICAgICAgICAgICAgICAke29wMX1cbiAgICAgICAgICAgICAgICB9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZVcgPSBgXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaTogdTMyID0gMHU7IGkgPCB1bmlmb3Jtcy5rdzsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICB4SW5kaWNlc1ske2RpbUlkeFd9XSA9IGluZGljZXNbJHtkaW1JZHhXfV0gKiB1bmlmb3Jtcy5zdyAtIHVuaWZvcm1zLnB3U3RhcnQgKyBpO1xuICAgICAgICAgICAgICAgICAgbGV0IHhfdmFsID0geFske3guaW5kaWNlc1RvT2Zmc2V0KCd4SW5kaWNlcycpfV07XG4gICAgICAgICAgICAgICAgICAke29wMX1cbiAgICAgICAgICAgICAgICB9YDtcbiAgICB9XG5cbiAgICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPT09IDIpIHtcbiAgICAgIGNvbnN0IGRpbUlkeEggPSByYW5rIC0gKGlzQ2hhbm5lbHNMYXN0ID8gMyA6IDIpO1xuICAgICAgaWYgKHBoU3RhcnRFbmROb3RaZXJvKSB7XG4gICAgICAgIGNvZGVIID0gYFxuICAgICAgICAgICAgICAgIGZvciAodmFyIGo6IHUzMiA9IDB1OyBqIDwgdW5pZm9ybXMua2g7IGorKykge1xuICAgICAgICAgICAgICAgICAgeEluZGljZXNbJHtkaW1JZHhIfV0gPSBpbmRpY2VzWyR7ZGltSWR4SH1dICogdW5pZm9ybXMuc2ggLSB1bmlmb3Jtcy5waFN0YXJ0ICsgajtcbiAgICAgICAgICAgICAgICAgIGlmICh4SW5kaWNlc1ske2RpbUlkeEh9XSA8IDAgfHwgeEluZGljZXNbJHtkaW1JZHhIfV0gPj0gdW5pZm9ybXMueF9zaGFwZVske2RpbUlkeEh9XSkge1xuICAgICAgICAgICAgICAgICAgICBwYWQgKz0gaTMyKHVuaWZvcm1zLmt3KTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb2RlSCA9IGBcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqOiB1MzIgPSAwdTsgaiA8IHVuaWZvcm1zLmtoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgIHhJbmRpY2VzWyR7ZGltSWR4SH1dID0gaW5kaWNlc1ske2RpbUlkeEh9XSAqIHVuaWZvcm1zLnNoIC0gdW5pZm9ybXMucGhTdGFydCArIGo7XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgIH1cbiAgICAgIGNvZGVIRW5kID0gYFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBgO1xuICAgIH1cblxuICAgIGNvbnN0IHBvb2xpbmdDb2RlID0gYFxuICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyh4LCBvdXRwdXQpfVxuXG4gICAgICAgICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0U2l6ZScpfVxuXG4gICAgICAgICAgICAgIGxldCBpbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgICAgICAgICAgICB2YXIgeEluZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG5cbiAgICAgICAgICAgICAgdmFyIHZhbHVlID0gJHtkYXRhVHlwZX0oJHtzdGFydH0pO1xuICAgICAgICAgICAgICB2YXIgcGFkID0gMDtcbiAgICAgICAgICAgICAgJHtjb2RlSH1cbiAgICAgICAgICAgICAgJHtjb2RlV31cbiAgICAgICAgICAgICAgJHtjb2RlSEVuZH1cbiAgICAgICAgICAgICAgJHtvcDJ9XG5cbiAgICAgICAgICAgICAgb3V0cHV0W2dsb2JhbF9pZHhdID0gdmFsdWU7XG4gICAgICAgICAgICB9YDtcbiAgICByZXR1cm4gcG9vbGluZ0NvZGU7XG4gIH0gZWxzZSB7XG4gICAgaWYgKGlzQ2hhbm5lbHNMYXN0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bvb2xpbmcgd2l0aCBrZXJuZWxTaGFwZS5sZW5ndGggPiAyIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIE5IV0MgZm9ybWF0LicpO1xuICAgIH1cbiAgICBjb25zdCBzdHJpZGVzUmFuayA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHBhZHNSYW5rID0gYXR0cmlidXRlcy5wYWRzLmxlbmd0aDtcbiAgICBsZXQgcGFkQ29kZSA9ICcnO1xuICAgIGlmIChoYXNQYWRzKSB7XG4gICAgICBwYWRDb2RlID0gYFxuICAgICAgICAgICAgICAgIGlmICh4SW5kaWNlc1tqXSA+PSB1bmlmb3Jtcy54X3NoYXBlW2pdKSB7XG4gICAgICAgICAgICAgICAgICBwYWQrKztcbiAgICAgICAgICAgICAgICAgIGlzUGFkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoIWlzUGFkKSB7XG4gICAgICAgICAgICAgICAgbGV0IHhfdmFsID0geFske3guaW5kaWNlc1RvT2Zmc2V0KCd4SW5kaWNlcycpfV07XG4gICAgICAgICAgICAgICAgJHtvcDF9XG4gICAgICAgICAgICAgIH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYWRDb2RlID0gYFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGxldCB4X3ZhbCA9IHhbJHt4LmluZGljZXNUb09mZnNldCgneEluZGljZXMnKX1dO1xuICAgICAgICAgICAgICAke29wMX1cbiAgICAgICAgICAgIGA7XG4gICAgfVxuICAgIGNvbnN0IHBvb2xpbmdDb2RlID0gYFxuICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyh4LCBvdXRwdXQpfVxuXG4gICAgICAgICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICAgICAgICAgJHtzaGFkZXJIZWxwZXIuZ3VhcmRBZ2FpbnN0T3V0T2ZCb3VuZHNXb3JrZ3JvdXBTaXplcygndW5pZm9ybXMub3V0cHV0U2l6ZScpfVxuICAgICAgICAgICAgICBsZXQgaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcbiAgICAgICAgICAgICAgdmFyIHhJbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuXG4gICAgICAgICAgICAgIHZhciBvZmZzZXRzOiBhcnJheTx1MzIsICR7c3RyaWRlc1Jhbmt9PjtcblxuICAgICAgICAgICAgICB2YXIgdmFsdWUgPSAke2RhdGFUeXBlfSgke3N0YXJ0fSk7XG4gICAgICAgICAgICAgIHZhciBwYWQgPSAwO1xuICAgICAgICAgICAgICB2YXIgaXNQYWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgICBmb3IgKHZhciBpOiB1MzIgPSAwdTsgaSA8IHVuaWZvcm1zLmtlcm5lbFNpemU7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBvZmZzZXQgPSBpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwdTsgaiA8ICR7c3RyaWRlc1JhbmsgLSAxfXU7IGorKykge1xuICAgICAgICAgICAgICAgICAgb2Zmc2V0c1tqXSA9IG9mZnNldCAvICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5rZXJuZWxTdHJpZGVzJywgJ2onLCBzdHJpZGVzUmFuayl9O1xuICAgICAgICAgICAgICAgICAgb2Zmc2V0IC09IG9mZnNldHNbal0gKiAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMua2VybmVsU3RyaWRlcycsICdqJywgc3RyaWRlc1JhbmspfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb2Zmc2V0c1ske3N0cmlkZXNSYW5rIC0gMX1dID0gb2Zmc2V0O1xuXG4gICAgICAgICAgICAgICAgaXNQYWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gJHtyYW5rIC0gc3RyaWRlc1Jhbmt9dTsgaiA8ICR7cmFua311OyBqKyspIHtcbiAgICAgICAgICAgICAgICAgIHhJbmRpY2VzW2pdID0gaW5kaWNlc1tqXSAqICR7Z2V0RWxlbWVudEF0KFxuICAgICAgICAgICAgICAgICAgICAndW5pZm9ybXMuc3RyaWRlcycsXG4gICAgICAgICAgICAgICAgICAgIGBqIC0gJHtyYW5rIC0gc3RyaWRlc1Jhbmt9dWAsXG4gICAgICAgICAgICAgICAgICAgIHN0cmlkZXNSYW5rLFxuICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICAgICAgKyBvZmZzZXRzW2ogLSAke3JhbmsgLSBzdHJpZGVzUmFua311XSAtICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5wYWRzJywgJ2ogLSAydScsIHBhZHNSYW5rKX07XG4gICAgICAgICAgICAgICAgICAke3BhZENvZGV9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgJHtvcDJ9XG5cbiAgICAgICAgICAgICAgb3V0cHV0W2dsb2JhbF9pZHhdID0gdmFsdWU7XG4gICAgICAgICAgICB9YDtcbiAgICByZXR1cm4gcG9vbGluZ0NvZGU7XG4gIH1cbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgRm9ybWF0QXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IGZvcm1hdDogJ05IV0MnIHwgJ05DSFcnO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBvb2xDb21tb25BdHRyaWJ1dGVzIGV4dGVuZHMgRm9ybWF0QXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IGF1dG9QYWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgY2VpbE1vZGU6IG51bWJlcjtcbiAgcmVhZG9ubHkga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgcGFkczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmNvbnN0IGNyZWF0ZVNoYWRlcktleUZyb21BdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFBvb2xDb21tb25BdHRyaWJ1dGVzKTogc3RyaW5nID0+XG4gIGAke2F0dHJpYnV0ZXMuZm9ybWF0fTske2F0dHJpYnV0ZXMuY2VpbE1vZGV9OyR7YXR0cmlidXRlcy5hdXRvUGFkfTske2F0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RofWA7XG5cbmNvbnN0IGNyZWF0ZUF2ZXJhZ2VQb29sU2hhZGVyS2V5RnJvbUF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzKTogc3RyaW5nID0+XG4gIGAke2NyZWF0ZVNoYWRlcktleUZyb21BdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpfTske2F0dHJpYnV0ZXMuY291bnRJbmNsdWRlUGFkfWA7XG5cbmNvbnN0IGNyZWF0ZU1heFBvb2xTaGFkZXJLZXlGcm9tQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBNYXhQb29sQXR0cmlidXRlcyk6IHN0cmluZyA9PlxuICBgJHtjcmVhdGVTaGFkZXJLZXlGcm9tQXR0cmlidXRlcyhhdHRyaWJ1dGVzKX07JHthdHRyaWJ1dGVzLnN0b3JhZ2VPcmRlcn07JHthdHRyaWJ1dGVzLmRpbGF0aW9uc31gO1xuXG5jb25zdCBwYXJzZVBvb2xDb21tb25BdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUG9vbENvbW1vbkF0dHJpYnV0ZXMgPT4gKHtcbiAgZm9ybWF0OiBhdHRyaWJ1dGVzLmZvcm1hdCBhcyBGb3JtYXRBdHRyaWJ1dGVzWydmb3JtYXQnXSxcbiAgYXV0b1BhZDogWydOT1RTRVQnLCAnVkFMSUQnLCAnU0FNRV9VUFBFUicsICdTQU1FX0xPV0VSJ11bYXR0cmlidXRlcy5hdXRvX3BhZCBhcyBudW1iZXJdLFxuICBjZWlsTW9kZTogYXR0cmlidXRlcy5jZWlsX21vZGUgYXMgbnVtYmVyLFxuICBrZXJuZWxTaGFwZTogYXR0cmlidXRlcy5rZXJuZWxfc2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSxcbiAgc3RyaWRlczogYXR0cmlidXRlcy5zdHJpZGVzIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gIHBhZHM6IGF0dHJpYnV0ZXMucGFkcyBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbn0pO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF2ZXJhZ2VQb29sQXR0cmlidXRlcyBleHRlbmRzIFBvb2xDb21tb25BdHRyaWJ1dGVzLCBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBjb3VudEluY2x1ZGVQYWQ6IGJvb2xlYW47XG59XG5cbmNvbnN0IGNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8gPSAoXG4gIG5hbWU6IHN0cmluZyxcbiAgaW5wdXQ6IFRlbnNvclZpZXcsXG4gIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgW2FkanVzdGVkQXR0cmlidXRlcywgb3V0cHV0U2hhcGVdID0gZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlKFxuICAgIGlucHV0LFxuICAgIGF0dHJpYnV0ZXMsXG4gICAgaXNHbG9iYWxPcGVyYXRvcixcbiAgKTtcbiAgY29uc3QgeCA9IGlucHV0VmFyaWFibGUoJ3gnLCBpbnB1dC5kYXRhVHlwZSwgaW5wdXQuZGltcy5sZW5ndGgpO1xuICBjb25zdCBkYXRhVHlwZSA9IHgudHlwZS52YWx1ZTtcblxuICBjb25zdCBvcDEgPSAndmFsdWUgKz0geF92YWw7JztcbiAgbGV0IG9wMiA9ICcnO1xuICBpZiAoYWRqdXN0ZWRBdHRyaWJ1dGVzLmNvdW50SW5jbHVkZVBhZCkge1xuICAgIG9wMiArPSBgdmFsdWUgLz0gJHtkYXRhVHlwZX0odW5pZm9ybXMua2VybmVsU2l6ZSk7YDtcbiAgfSBlbHNlIHtcbiAgICBvcDIgKz0gYHZhbHVlIC89ICR7ZGF0YVR5cGV9KGkzMih1bmlmb3Jtcy5rZXJuZWxTaXplKSAtIHBhZCk7YDtcbiAgfVxuICBjb25zdCBbcHJvZ3JhbVVuaWZvcm1zLCB1bmlmb3JtcywgaGFzUGFkcywgcHdTdGFydEVuZE5vdFplcm8sIHBoU3RhcnRFbmROb3RaZXJvXSA9IGdldFVuaWZvcm1BbmRQYWRJbmZvKFxuICAgIG91dHB1dFNoYXBlLFxuICAgIGFkanVzdGVkQXR0cmlidXRlcyxcbiAgKTtcbiAgcHJvZ3JhbVVuaWZvcm1zLnB1c2goLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoaW5wdXQuZGltcywgb3V0cHV0U2hhcGUpKTtcbiAgY29uc3QgaW5wdXREZXBlbmRlbmNpZXM6IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10gPSBbJ3JhbmsnXTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2hhc1BhZHN9OyR7cHdTdGFydEVuZE5vdFplcm99OyR7cGhTdGFydEVuZE5vdFplcm99YCxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzLFxuICAgIH0sXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXQuZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSkgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2U6IChzaGFkZXJIZWxwZXIpID0+XG4gICAgICBnZW5lcmF0ZVBvb2xpbmdDb2RlKFxuICAgICAgICBzaGFkZXJIZWxwZXIsXG4gICAgICAgIHgsXG4gICAgICAgIGlucHV0LmRpbXMubGVuZ3RoLFxuICAgICAgICBvdXRwdXRTaGFwZS5sZW5ndGgsXG4gICAgICAgIGFkanVzdGVkQXR0cmlidXRlcyxcbiAgICAgICAgb3AxLFxuICAgICAgICBvcDIsXG4gICAgICAgIDAuMCxcbiAgICAgICAgdW5pZm9ybXMsXG4gICAgICAgIGhhc1BhZHMsXG4gICAgICAgIHB3U3RhcnRFbmROb3RaZXJvLFxuICAgICAgICBwaFN0YXJ0RW5kTm90WmVybyxcbiAgICAgICksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBjb3VudEluY2x1ZGVQYWQgPSAoYXR0cmlidXRlcy5jb3VudF9pbmNsdWRlX3BhZCBhcyBudW1iZXIpID09PSAwID8gZmFsc2UgOiB0cnVlO1xuXG4gIGNvbnN0IGF0dHIgPSBwYXJzZVBvb2xDb21tb25BdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpO1xuICAvLyBUT0RPOiBzdXBwb3J0IGF0dHJpYnV0ZSAnY2VpbF9tb2RlJ1xuICBpZiAoYXR0ci5jZWlsTW9kZSAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndXNpbmcgY2VpbCgpIGluIHNoYXBlIGNvbXB1dGF0aW9uIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciBBdmVyYWdlUG9vbCcpO1xuICB9XG4gIGNvbnN0IGF2ZXJhZ2VQb29sQXR0cmlidXRlcyA9IHsgY291bnRJbmNsdWRlUGFkLCAuLi5hdHRyLCBjYWNoZUtleTogJycgfTtcbiAgcmV0dXJuIHsgLi4uYXZlcmFnZVBvb2xBdHRyaWJ1dGVzLCBjYWNoZUtleTogY3JlYXRlQXZlcmFnZVBvb2xTaGFkZXJLZXlGcm9tQXR0cmlidXRlcyhhdmVyYWdlUG9vbEF0dHJpYnV0ZXMpIH07XG59O1xuXG5leHBvcnQgY29uc3QgYXZlcmFnZVBvb2wgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvKCdBdmVyYWdlUG9vbCcsIGNvbnRleHQuaW5wdXRzWzBdLCBmYWxzZSwgYXR0cmlidXRlcykpO1xufTtcblxuY29uc3QgZ2xvYmFsUG9vbEF0dHJpYnV0ZXMgPSB7XG4gIGF1dG9QYWQ6ICcnLFxuICBjZWlsTW9kZTogMCxcbiAgY291bnRJbmNsdWRlUGFkOiBmYWxzZSxcbiAga2VybmVsU2hhcGU6IFtdLFxuICBzdHJpZGVzOiBbXSxcbiAgcGFkczogW10sXG4gIHN0b3JhZ2VPcmRlcjogMCxcbiAgZGlsYXRpb25zOiBbXSxcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGZvcm1hdCA9IGF0dHJpYnV0ZXMuZm9ybWF0IGFzIEZvcm1hdEF0dHJpYnV0ZXNbJ2Zvcm1hdCddO1xuICByZXR1cm4geyBmb3JtYXQsIC4uLmdsb2JhbFBvb2xBdHRyaWJ1dGVzLCBjYWNoZUtleTogZm9ybWF0IH07XG59O1xuXG5leHBvcnQgY29uc3QgZ2xvYmFsQXZlcmFnZVBvb2wgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvKCdHbG9iYWxBdmVyYWdlUG9vbCcsIGNvbnRleHQuaW5wdXRzWzBdLCB0cnVlLCBhdHRyaWJ1dGVzKSk7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIE1heFBvb2xBdHRyaWJ1dGVzIGV4dGVuZHMgUG9vbENvbW1vbkF0dHJpYnV0ZXMsIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IHN0b3JhZ2VPcmRlcjogbnVtYmVyO1xuICByZWFkb25seSBkaWxhdGlvbnM6IG51bWJlcltdO1xufVxuXG5jb25zdCBjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8gPSAoXG4gIG5hbWU6IHN0cmluZyxcbiAgaW5wdXQ6IFRlbnNvclZpZXcsXG4gIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sXG4gIGF0dHJpYnV0ZXM6IE1heFBvb2xBdHRyaWJ1dGVzLFxuKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBbYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvdXRwdXRTaGFwZV0gPSBnZXRBZGp1c3RlZFBvb2xBdHRyaWJ1dGVzQW5kT3V0cHV0U2hhcGUoXG4gICAgaW5wdXQsXG4gICAgYXR0cmlidXRlcyxcbiAgICBpc0dsb2JhbE9wZXJhdG9yLFxuICApO1xuICBjb25zdCBvcDEgPSBgXG4gICAgICB2YWx1ZSA9IG1heCh4X3ZhbCwgdmFsdWUpO1xuICAgIGA7XG4gIGNvbnN0IG9wMiA9ICcnO1xuICBjb25zdCB4ID0gaW5wdXRWYXJpYWJsZSgneCcsIGlucHV0LmRhdGFUeXBlLCBpbnB1dC5kaW1zLmxlbmd0aCk7XG4gIGNvbnN0IGlucHV0RGVwZW5kZW5jaWVzOiBQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeVtdID0gWydyYW5rJ107XG4gIGNvbnN0IFtwcm9ncmFtVW5pZm9ybXMsIHVuaWZvcm1zLCBoYXNQYWRzLCBwd1N0YXJ0RW5kTm90WmVybywgcGhTdGFydEVuZE5vdFplcm9dID0gZ2V0VW5pZm9ybUFuZFBhZEluZm8oXG4gICAgb3V0cHV0U2hhcGUsXG4gICAgYWRqdXN0ZWRBdHRyaWJ1dGVzLFxuICApO1xuICBwcm9ncmFtVW5pZm9ybXMucHVzaCguLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dC5kaW1zLCBvdXRwdXRTaGFwZSkpO1xuICByZXR1cm4ge1xuICAgIG5hbWUsXG4gICAgc2hhZGVyQ2FjaGU6IHtcbiAgICAgIGhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9OyR7aGFzUGFkc307JHtwd1N0YXJ0RW5kTm90WmVyb307JHtwaFN0YXJ0RW5kTm90WmVyb31gLFxuICAgICAgaW5wdXREZXBlbmRlbmNpZXMsXG4gICAgfSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dC5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKSAvIDY0IC8qIHdvcmtncm91cCBzaXplICovKSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICAgIGdldFNoYWRlclNvdXJjZTogKHNoYWRlckhlbHBlcikgPT5cbiAgICAgIGdlbmVyYXRlUG9vbGluZ0NvZGUoXG4gICAgICAgIHNoYWRlckhlbHBlcixcbiAgICAgICAgeCxcbiAgICAgICAgaW5wdXQuZGltcy5sZW5ndGgsXG4gICAgICAgIG91dHB1dFNoYXBlLmxlbmd0aCxcbiAgICAgICAgYWRqdXN0ZWRBdHRyaWJ1dGVzLFxuICAgICAgICBvcDEsXG4gICAgICAgIG9wMixcbiAgICAgICAgaW5wdXQuZGF0YVR5cGUgPT09IERhdGFUeXBlLmZsb2F0MTYgPyAtNjU1MDQgOiAtMWU1LFxuICAgICAgICB1bmlmb3JtcyxcbiAgICAgICAgaGFzUGFkcyxcbiAgICAgICAgcHdTdGFydEVuZE5vdFplcm8sXG4gICAgICAgIHBoU3RhcnRFbmROb3RaZXJvLFxuICAgICAgKSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBtYXhQb29sID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBNYXhQb29sQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8oJ01heFBvb2wnLCBjb250ZXh0LmlucHV0c1swXSwgZmFsc2UsIGF0dHJpYnV0ZXMpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZU1heFBvb2xBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogTWF4UG9vbEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBzdG9yYWdlT3JkZXIgPSBhdHRyaWJ1dGVzLnN0b3JhZ2Vfb3JkZXIgYXMgbnVtYmVyO1xuICBjb25zdCBkaWxhdGlvbnMgPSBhdHRyaWJ1dGVzLmRpbGF0aW9ucyBhcyBbbnVtYmVyLCBudW1iZXJdO1xuXG4gIGNvbnN0IGF0dHIgPSBwYXJzZVBvb2xDb21tb25BdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpO1xuICAvLyBUT0RPOiBzdXBwb3J0IGF0dHJpYnV0ZSAnY2VpbF9tb2RlJyBhbmQgJ3N0b3JhZ2Vfb3JkZXInXG4gIGlmIChzdG9yYWdlT3JkZXIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbHVtbiBtYWpvciBzdG9yYWdlIG9yZGVyIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciBNYXhQb29sJyk7XG4gIH1cbiAgaWYgKGF0dHIuY2VpbE1vZGUgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzaW5nIGNlaWwoKSBpbiBzaGFwZSBjb21wdXRhdGlvbiBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgTWF4UG9vbCcpO1xuICB9XG4gIGNvbnN0IG1heFBvb2xBdHRyaWJ1dGVzID0geyBzdG9yYWdlT3JkZXIsIGRpbGF0aW9ucywgLi4uYXR0ciwgY2FjaGVLZXk6ICcnIH07XG4gIHJldHVybiB7IC4uLm1heFBvb2xBdHRyaWJ1dGVzLCBjYWNoZUtleTogY3JlYXRlTWF4UG9vbFNoYWRlcktleUZyb21BdHRyaWJ1dGVzKG1heFBvb2xBdHRyaWJ1dGVzKSB9O1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2xvYmFsTWF4UG9vbEF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBNYXhQb29sQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGZvcm1hdCA9IGF0dHJpYnV0ZXMuZm9ybWF0IGFzIEZvcm1hdEF0dHJpYnV0ZXNbJ2Zvcm1hdCddO1xuICByZXR1cm4geyBmb3JtYXQsIC4uLmdsb2JhbFBvb2xBdHRyaWJ1dGVzLCBjYWNoZUtleTogZm9ybWF0IH07XG59O1xuXG5leHBvcnQgY29uc3QgZ2xvYmFsTWF4UG9vbCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogTWF4UG9vbEF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvKCdHbG9iYWxNYXhQb29sJywgY29udGV4dC5pbnB1dHNbMF0sIHRydWUsIGF0dHJpYnV0ZXMpKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgfSBmcm9tICcuLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGdldE1heENvbXBvbmVudHMsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVxdWFudGl6ZUxpbmVyQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGF4aXM6IG51bWJlcjtcbiAgYmxvY2tTaXplOiBudW1iZXI7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLCBhdHRyaWJ1dGVzOiBEZXF1YW50aXplTGluZXJBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoIDwgMiB8fCBpbnB1dHMubGVuZ3RoID4gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignRGVxdWFudGl6ZUxpbmVhciByZXF1aXJlcyAyIG9yIDMgaW5wdXRzLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1sxXS5kaW1zID09PSBpbnB1dHNbMl0uZGltcykge1xuICAgIHRocm93IG5ldyBFcnJvcigneC1zY2FsZSBhbmQgeC16ZXJvLXBvaW50IG11c3QgaGF2ZSB0aGUgc2FtZSBzaGFwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMF0uZGF0YVR5cGUgIT09IGlucHV0c1syXS5kYXRhVHlwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigneCBhbmQgeC16ZXJvLXBvaW50IG11c3QgaGF2ZSB0aGUgc2FtZSBkYXRhIHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuaW50MzIgJiYgaW5wdXRzLmxlbmd0aCA+IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0luIHRoZSBjYXNlIG9mIGRlcXVhbnRpemluZyBpbnQzMiB0aGVyZSBpcyBubyB6ZXJvIHBvaW50LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDAgJiYgaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAxICYmIGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzY2FsZSBpbnB1dCBtdXN0IGJlIGEgc2NhbGFyLCBhIDFEIHRlbnNvciwgb3IgaGF2ZSB0aGUgc2FtZSByYW5rIGFzIHRoZSBpbnB1dCB0ZW5zb3IuJyk7XG4gIH1cbiAgLy8gdmFsaWRhdGUgc2NhbGUgYW5kIHplcm8tcG9pbnQgaW5wdXQgc2hhcGVzXG4gIGlmIChpbnB1dHMubGVuZ3RoID4gMikge1xuICAgIC8vIHplcm8tcG9pbnQgaW5wdXQgdHlwZSBzaG91bGQgYmUgdGhlIHNhbWUgYXMgaW5wdXQgZGF0YSB0eXBlLlxuICAgIGlmIChpbnB1dHNbMF0uZGF0YVR5cGUgIT09IGlucHV0c1syXS5kYXRhVHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd4IGFuZCB4LXplcm8tcG9pbnQgbXVzdCBoYXZlIHRoZSBzYW1lIGRhdGEgdHlwZS4nKTtcbiAgICB9XG4gICAgLy8gU2NhbGUgYW5kIHplcm8tcG9pbnQgaW5wdXRzIG11c3QgaGF2ZSB0aGUgc2FtZSBzaGFwZVxuICAgIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IGlucHV0c1syXS5kaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzY2FsZSBhbmQgemVyby1wb2ludCBpbnB1dHMgbXVzdCBoYXZlIHRoZSBzYW1lIHJhbmsuJyk7XG4gICAgfVxuICAgIGlmICghaW5wdXRzWzFdLmRpbXMubWFwKChkLCBpKSA9PiBkID09PSBpbnB1dHNbMl0uZGltc1tpXSkucmVkdWNlKChhLCBiKSA9PiBhICYmIGIsIHRydWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NjYWxlIGFuZCB6ZXJvLXBvaW50IGlucHV0cyBtdXN0IGhhdmUgdGhlIHNhbWUgc2hhcGUuJyk7XG4gICAgfVxuICB9XG4gIC8vIFZhbGlkYXRlIGJsb2NrU2l6ZVxuICBpZiAoYXR0cmlidXRlcy5ibG9ja1NpemUgPiAwKSB7XG4gICAgLy8gQmxvY2sgcXVuYXRpemF0aW9uXG4gICAgaWYgKGlucHV0c1sxXS5kaW1zLmxlbmd0aCA9PT0gMCB8fCAoaW5wdXRzWzFdLmRpbXMubGVuZ3RoID09PSAxICYmIGlucHV0c1sxXS5kaW1zWzBdID09PSAxKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdibG9ja1NpemUgbXVzdCBiZSBzZXQgb25seSBmb3IgYmxvY2sgcXVhbnRpemF0aW9uLicpO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICAhaW5wdXRzWzFdLmRpbXMubWFwKChkLCBpKSA9PiBpID09PSBhdHRyaWJ1dGVzLmF4aXMgfHwgZCA9PT0gaW5wdXRzWzBdLmRpbXNbaV0pLnJlZHVjZSgoYSwgYikgPT4gYSAmJiBiLCB0cnVlKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGb3IgYmxvY2sgcXVuYXRpemF0aW9uLCBzY2FsZSBpbnB1dCBzaGFwZSB0byBtYXRjaCB0aGUgaW5wdXQgc2hhcGUgZXhjZXB0IGZvciB0aGUgYXhpcycpO1xuICAgIH1cbiAgICAvLyBTY2FsZSBpbnB1dCByYW5rIHNob3VsZCBiZSBzYW1lIGFzIHRoZSBpbnB1dCByYW5rXG4gICAgaWYgKGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvciBibG9jayBxdW5hdGl6YXRpb24gdGhlIHNjYWxlIGlucHV0IHJhbmsgbXVzdCBiZSB0aGUgc2FtZSBhcyB0aGUgeCByYW5rLicpO1xuICAgIH1cbiAgICBjb25zdCBkSSA9IGlucHV0c1swXS5kaW1zW2F0dHJpYnV0ZXMuYXhpc107XG4gICAgY29uc3Qgc2kgPSBpbnB1dHNbMV0uZGltc1thdHRyaWJ1dGVzLmF4aXNdO1xuICAgIGlmIChhdHRyaWJ1dGVzLmJsb2NrU2l6ZSA8IE1hdGguY2VpbChkSSAvIHNpKSB8fCBhdHRyaWJ1dGVzLmJsb2NrU2l6ZSA+IE1hdGguY2VpbChkSSAvIChzaSAtIDEpIC0gMSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYmxvY2tTaXplIG11c3QgYmUgd2l0aCBpbiB0aGUgcmFuZ2UgW2NlaWwoZEkgLyBTaSksIGNlaWwoZEkgLyAoU2kgLSAxKSAtIDEpXS4nKTtcbiAgICB9XG4gIH1cbn07XG5cbmNvbnN0IGNyZWF0ZURlcXVhbnRpemVMaW5lYXJQcm9ncmFtSW5mbyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IERlcXVhbnRpemVMaW5lckF0dHJpYnV0ZXMsXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG4gIGNvbnN0IGlucHV0VHlwZSA9IGlucHV0c1swXS5kYXRhVHlwZTtcbiAgY29uc3QgaXNTaWduZWQgPSBpbnB1dFR5cGUgPT09IERhdGFUeXBlLmludDg7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7IC8vIG91dHB1dCBzaGFwZSBpcyBzYW1lIGFzIHRoZSBpbnB1dCBzaGFwZVxuICBjb25zdCBkYXRhVHlwZSA9IGlucHV0c1sxXS5kYXRhVHlwZTsgLy8gb3V0cHV0IHR5cGUgaXMgc2FtZSBhcyB0aGUgdGhlIHNjYWxlIGlucHV0IHR5cGVcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgY29uc3QgaXNQYWNrZWQgPSBpbnB1dFR5cGUgPT09IERhdGFUeXBlLmludDggfHwgaW5wdXRUeXBlID09PSBEYXRhVHlwZS51aW50ODtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlzUGFja2VkID8gW01hdGguY2VpbChTaGFwZVV0aWwuc2l6ZShpbnB1dHNbMF0uZGltcykgLyA0KV0gOiBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgc2NhbGVTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICBjb25zdCB6ZXJvUG9pbnRJbnB1dCA9IGlucHV0cy5sZW5ndGggPiAyID8gaW5wdXRzWzJdIDogdW5kZWZpbmVkO1xuICBjb25zdCB6ZXJvUG9pbnRTaGFwZSA9IHplcm9Qb2ludElucHV0XG4gICAgPyBpc1BhY2tlZFxuICAgICAgPyBbTWF0aC5jZWlsKFNoYXBlVXRpbC5zaXplKHplcm9Qb2ludElucHV0LmRpbXMpIC8gNCldXG4gICAgICA6IHplcm9Qb2ludElucHV0LmRpbXNcbiAgICA6IHVuZGVmaW5lZDtcbiAgLy8gU2NhbGVzIGlucHV0IGlzIGEgc2NhbGVyIGZvciBwZXItdGVuc29yL3Blci1sYXllciBxdWFudGl6YXRpb24sIDEtRCB0ZW5zb3IgZm9yIHBlci1heGlzIHF1YW50aXphdGlvblxuICAvLyBvciB0ZW5zb3Igd2l0aCBzYW1lIHJhbmsgYXMgaW5wdXQgZm9yIGJsb2NrZWQgcXVhbnRpemF0aW9uLlxuICBjb25zdCBwZXJMYXllclF1YW50aXphdGlvbiA9IHNjYWxlU2hhcGUubGVuZ3RoID09PSAwIHx8IChzY2FsZVNoYXBlLmxlbmd0aCA9PT0gMSAmJiBzY2FsZVNoYXBlWzBdID09PSAxKTtcbiAgY29uc3QgcGVyQXhpc1F1YW50aXphdGlvbiA9IHBlckxheWVyUXVhbnRpemF0aW9uID09PSBmYWxzZSAmJiBzY2FsZVNoYXBlLmxlbmd0aCA9PT0gMTtcbiAgLy8gTGVmdCB1bm5lY2Vzc2FyeSBjb21tZW50ZWQtb3V0IGFzc2lnbm1lbnQgZm9yIGRvY3VtZW50YXRpb25cbiAgLy8gY29uc3QgYmxvY2tRdWFudGl6YXRpb24gPSBwZXJMYXllclF1YW50aXphdGlvbiA9PT0gZmFsc2UgJiYgcGVyQXhpc1F1YW50aXphdGlvbiA9PT0gZmFsc2U7XG4gIGNvbnN0IG1heENvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKG91dHB1dFNpemUpO1xuICBjb25zdCB1c2VDb21wb25lbnRzID0gcGVyTGF5ZXJRdWFudGl6YXRpb24gJiYgKCFpc1BhY2tlZCB8fCBtYXhDb21wb25lbnRzID09PSA0KTtcbiAgY29uc3QgY29tcG9uZW50cyA9IHVzZUNvbXBvbmVudHMgPyBtYXhDb21wb25lbnRzIDogMTtcbiAgY29uc3QgaW5wdXRDb21wb25lbnQgPSB1c2VDb21wb25lbnRzICYmICFpc1BhY2tlZCA/IG1heENvbXBvbmVudHMgOiAxO1xuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgaXNQYWNrZWQgPyBEYXRhVHlwZS51aW50MzIgOiBpbnB1dFR5cGUsIGlucHV0U2hhcGUubGVuZ3RoLCBpbnB1dENvbXBvbmVudCk7XG4gIGNvbnN0IHNjYWxlID0gaW5wdXRWYXJpYWJsZSgnc2NhbGUnLCBkYXRhVHlwZSwgc2NhbGVTaGFwZS5sZW5ndGgpO1xuICBjb25zdCB6ZXJvUG9pbnQgPSB6ZXJvUG9pbnRJbnB1dFxuICAgID8gaW5wdXRWYXJpYWJsZSgnemVyb19wb2ludCcsIGlzUGFja2VkID8gRGF0YVR5cGUudWludDMyIDogaW5wdXRUeXBlLCB6ZXJvUG9pbnRTaGFwZSEubGVuZ3RoKVxuICAgIDogdW5kZWZpbmVkO1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCwgY29tcG9uZW50cyk7XG4gIGNvbnN0IGlucHV0VmFyaWFibGVzID0gW2lucHV0LCBzY2FsZV07XG4gIGlmICh6ZXJvUG9pbnQpIHtcbiAgICBpbnB1dFZhcmlhYmxlcy5wdXNoKHplcm9Qb2ludCk7XG4gIH1cbiAgY29uc3QgaW5wdXRTaGFwZXMgPSBbaW5wdXRTaGFwZSwgc2NhbGVTaGFwZV07XG4gIGlmICh6ZXJvUG9pbnRJbnB1dCkge1xuICAgIGlucHV0U2hhcGVzLnB1c2goemVyb1BvaW50U2hhcGUhKTtcbiAgfVxuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgLyBjb21wb25lbnRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGF4aXMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogYXR0cmlidXRlcy5ibG9ja1NpemUgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyguLi5pbnB1dFNoYXBlcywgb3V0cHV0U2hhcGUpLFxuICBdO1xuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdheGlzJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2Jsb2NrX3NpemUnLCB0eXBlOiAndTMyJyB9LFxuICAgIF07XG4gICAgcmV0dXJuIGBcbiAgICAgICR7c2hhZGVySGVscGVyLnJlZ2lzdGVyVW5pZm9ybXModW5pZm9ybXMpLmRlY2xhcmVWYXJpYWJsZXMoLi4uaW5wdXRWYXJpYWJsZXMsIG91dHB1dCl9XG4gICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuICAgICAgICAgIGxldCBvdXRwdXRfaW5kaWNlcyA9ICR7b3V0cHV0Lm9mZnNldFRvSW5kaWNlcygnZ2xvYmFsX2lkeCcpfTtcblxuICAgICAgICAgIC8vIFNldCBpbnB1dCB4XG4gICAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICBsZXQgaW5wdXQgPSAke2lucHV0LmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4IC8gNCcpfTtcbiAgICAgICAgICAgIGxldCB4X3ZlYyA9ICR7aXNTaWduZWQgPyAndW5wYWNrNHhJOChpbnB1dCknIDogJ3VucGFjazR4VTgoaW5wdXQpJ307XG4gICAgICAgICAgICBsZXQgeF92YWx1ZSA9ICR7Y29tcG9uZW50cyA9PT0gMSA/ICd4X3ZlY1tnbG9iYWxfaWR4ICUgNF0nIDogJ3hfdmVjJ307YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBgbGV0IHhfdmFsdWUgPSAke2lucHV0LmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4Jyl9O2A7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkoKX07XG5cbiAgICAgICAgICAvLyBTZXQgc2NhbGUgaW5wdXRcbiAgICAgICAgICAkeygoKSA9PiB7XG4gICAgICAgICAgICBpZiAocGVyTGF5ZXJRdWFudGl6YXRpb24pIHtcbiAgICAgICAgICAgICAgLy8gc2NhbGUgaW5wdXQgaXMgYSBzY2FsYXIgKClcbiAgICAgICAgICAgICAgcmV0dXJuIGBsZXQgc2NhbGVfdmFsdWU9ICR7c2NhbGUuZ2V0QnlPZmZzZXQoJzAnKX1gO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwZXJBeGlzUXVhbnRpemF0aW9uKSB7XG4gICAgICAgICAgICAgIC8vIHNjYWxlIGlucHV0IGlzIGEgMUQgdGVuc29yXG4gICAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICBsZXQgc2NhbGVfaW5kZXggPSAke291dHB1dC5pbmRpY2VzR2V0KCdvdXRwdXRfaW5kaWNlcycsICd1bmlmb3Jtcy5heGlzJyl9O1xuICAgICAgICAgICAgbGV0IHNjYWxlX3ZhbHVlPSAke3NjYWxlLmdldEJ5T2Zmc2V0KCdzY2FsZV9pbmRleCcpfTtgO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gQmxvY2sgcXVhbnRpemF0aW9uLiBTY2FsZSBpbnB1dCByYW5rIGlzIHNhbWUgYXMgaW5wdXQvb3V0cHV0IHJhbmsuXG4gICAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICB2YXIgc2NhbGVfaW5kaWNlczogJHtzY2FsZS50eXBlLmluZGljZXN9ID0gb3V0cHV0X2luZGljZXM7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAke3NjYWxlLmluZGljZXNHZXQoJ3NjYWxlX2luZGljZXMnLCAndW5pZm9ybXMuYXhpcycpfSAvIHVuaWZvcm1zLmJsb2NrX3NpemU7XG4gICAgICAgICAgICAke3NjYWxlLmluZGljZXNTZXQoJ3NjYWxlX2luZGljZXMnLCAndW5pZm9ybXMuYXhpcycsICdpbmRleCcpfTtcbiAgICAgICAgICAgIGxldCBzY2FsZV92YWx1ZT0gJHtzY2FsZS5nZXRCeUluZGljZXMoJ3NjYWxlX2luZGljZXMnKX07YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSgpfTtcblxuICAgICAgICAgIC8vIFNldCB6ZXJvLXBvaW50IGlucHV0XG4gICAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHplcm9Qb2ludCkge1xuICAgICAgICAgICAgICBpZiAocGVyTGF5ZXJRdWFudGl6YXRpb24pIHtcbiAgICAgICAgICAgICAgICAvLyB6ZXJvLXBvaW50IGlucHV0IGlzIGEgc2NhbGFyXG4gICAgICAgICAgICAgICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2lucHV0ID0gJHt6ZXJvUG9pbnQuZ2V0QnlPZmZzZXQoJzAnKX07XG4gICAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfdmVjID0gICR7aXNTaWduZWQgPyAndW5wYWNrNHhJOCh6ZXJvX3BvaW50X2lucHV0KScgOiAndW5wYWNrNHhVOCh6ZXJvX3BvaW50X2lucHV0KSd9O1xuICAgICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X3ZhbHVlPSB6ZXJvX3BvaW50X3ZlY1swXWA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSAke3plcm9Qb2ludC5nZXRCeU9mZnNldCgnMCcpfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBlckF4aXNRdWFudGl6YXRpb24pIHtcbiAgICAgICAgICAgICAgICAvLyB6ZXJvLXBvaW50IGlucHV0IGlzIGEgMUQgdGVuc29yXG4gICAgICAgICAgICAgICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2luZGV4ID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCAndW5pZm9ybXMuYXhpcycpfTtcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF9pbnB1dCA9ICR7emVyb1BvaW50LmdldEJ5T2Zmc2V0KCd6ZXJvX3BvaW50X2luZGV4IC8gNCcpfTtcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF92ZWMgPSAgJHtpc1NpZ25lZCA/ICd1bnBhY2s0eEk4KHplcm9fcG9pbnRfaW5wdXQpJyA6ICd1bnBhY2s0eFU4KHplcm9fcG9pbnRfaW5wdXQpJ307XG4gICAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSB6ZXJvX3BvaW50X3ZlY1t6ZXJvX3BvaW50X2luZGV4ICUgNF1gO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgIGxldCB6ZXJvX3BvaW50X2luZGV4ID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCAndW5pZm9ybXMuYXhpcycpfTtcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF92YWx1ZSA9ICR7emVyb1BvaW50LmdldEJ5T2Zmc2V0KCd6ZXJvX3BvaW50X2luZGV4Jyl9O2A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEJsb2NrZWRRdWFudGl6YXRpb24uIFRoZSB6ZXJvLXBvaW50IGlucHV0IHNoYXBlIGlzIHNhbWUgYXMgdGhlIGlucHV0IHNoYXBlIGV4Y2VwdCBhbG9uZyBheGlzLlxuICAgICAgICAgICAgICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF9vZmZzZXQgPSAke3NjYWxlLmluZGljZXNUb09mZnNldCgnc2NhbGVfaW5kaWNlcycpfTtcbiAgICAgICAgICAgICAgICBsZXQgemVyb19wb2ludF9pbnB1dCA9ICR7emVyb1BvaW50LmdldEJ5T2Zmc2V0KCd6ZXJvX3BvaW50X29mZnNldCAvIDQnKX07XG4gICAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfdmVjID0gJHtpc1NpZ25lZCA/ICd1bnBhY2s0eEk4KHplcm9fcG9pbnRfaW5wdXQpJyA6ICd1bnBhY2s0eFU4KHplcm9fcG9pbnRfaW5wdXQpJ307XG4gICAgICAgICAgICAgICAgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSB6ZXJvX3BvaW50X3ZlY1t6ZXJvX3BvaW50X29mZnNldCAlIDRdO2A7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSAke3plcm9Qb2ludC5nZXRCeUluZGljZXMoJ3NjYWxlX2luZGljZXMnKX07YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBgbGV0IHplcm9fcG9pbnRfdmFsdWUgPSAke2lzUGFja2VkID8gKGlzU2lnbmVkID8gJ2kzMicgOiAndTMyJykgOiBpbnB1dC50eXBlLnZhbHVlfSgwKTtgO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pKCl9O1xuICAgICAgLy8gQ29tcHV0ZSBhbmQgd3JpdGUgb3V0cHV0XG4gICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIGAke291dHB1dC50eXBlLnZhbHVlfSh4X3ZhbHVlIC0gemVyb19wb2ludF92YWx1ZSkgKiBzY2FsZV92YWx1ZWApfTtcbiAgICAgIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdEZXF1YW50aXplTGluZWFyJyxcbiAgICBzaGFkZXJDYWNoZToge1xuICAgICAgaGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiB6ZXJvUG9pbnQgPyBbJ3JhbmsnLCAncmFuaycsICdyYW5rJ10gOiBbJ3JhbmsnLCAncmFuayddLFxuICAgIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gY29tcG9uZW50cyAvIDY0KSwgeTogMSwgejogMSB9LFxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLFxuICAgIH0pLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGRlcXVhbnRpemVMaW5lYXIgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IERlcXVhbnRpemVMaW5lckF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlRGVxdWFudGl6ZUxpbmVhclByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCBhdHRyaWJ1dGVzKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VEZXF1YW50aXplTGluZWFyQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IERlcXVhbnRpemVMaW5lckF0dHJpYnV0ZXMgPT5cbiAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHsgYXhpczogYXR0cmlidXRlcy5heGlzIGFzIG51bWJlciwgYmxvY2tTaXplOiBhdHRyaWJ1dGVzLmJsb2NrU2l6ZSBhcyBudW1iZXIgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IGVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvLCBQcm9ncmFtVW5pZm9ybSB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIFVuaWZvcm1EYXRhRWxlbWVudFR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzQ29udGVudCA9IChzdGFydDogbnVtYmVyLCBsaW1pdDogbnVtYmVyLCBkZWx0YTogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGNvbnN0IHNhbWVTdGFydExpbWl0ID0gc3RhcnQgPT09IGxpbWl0O1xuICBjb25zdCBpbmNyZWFzaW5nUmFuZ2VOZWdhdGl2ZVN0ZXAgPSBzdGFydCA8IGxpbWl0ICYmIGRlbHRhIDwgMDtcbiAgY29uc3QgZGVjcmVhc2luZ1JhbmdlUG9zaXRpdmVTdGVwID0gc3RhcnQgPiBsaW1pdCAmJiBkZWx0YSA+IDA7XG5cbiAgaWYgKHNhbWVTdGFydExpbWl0IHx8IGluY3JlYXNpbmdSYW5nZU5lZ2F0aXZlU3RlcCB8fCBkZWNyZWFzaW5nUmFuZ2VQb3NpdGl2ZVN0ZXApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJSYW5nZSB0aGVzZSBpbnB1dHMnIGNvbnRlbnRzIGFyZSBpbnZhbGlkLlwiKTtcbiAgfVxufTtcblxuY29uc3QgY3JlYXRlUmFuZ2VQcm9ncmFtSW5mbyA9IChzdGFydDogbnVtYmVyLCBsaW1pdDogbnVtYmVyLCBkZWx0YTogbnVtYmVyLCBkYXRhVHlwZTogRGF0YVR5cGUpOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IG51bUVsZW1lbnRzID0gTWF0aC5hYnMoTWF0aC5jZWlsKChsaW1pdCAtIHN0YXJ0KSAvIGRlbHRhKSk7XG4gIGNvbnN0IG91dHB1dFNoYXBlOiBudW1iZXJbXSA9IFtudW1FbGVtZW50c107XG4gIGNvbnN0IG91dHB1dFNpemUgPSBudW1FbGVtZW50cztcbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBkYXRhVHlwZSwgZGF0YTogc3RhcnQgfSxcbiAgICB7IHR5cGU6IGRhdGFUeXBlLCBkYXRhOiBkZWx0YSB9LFxuICAgIC4uLmNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzKG91dHB1dFNoYXBlKSxcbiAgXTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgZGF0YVR5cGUsIG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgY29uc3Qgd2dzbFR5cGUgPSBvdXRwdXQudHlwZS52YWx1ZTtcbiAgICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRTaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ3N0YXJ0JywgdHlwZTogd2dzbFR5cGUgYXMgVW5pZm9ybURhdGFFbGVtZW50VHlwZSB9LFxuICAgICAgeyBuYW1lOiAnZGVsdGEnLCB0eXBlOiB3Z3NsVHlwZSBhcyBVbmlmb3JtRGF0YUVsZW1lbnRUeXBlIH0sXG4gICAgXTtcbiAgICByZXR1cm4gYFxuICAgICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm1zKHVuaWZvcm1zKS5kZWNsYXJlVmFyaWFibGVzKG91dHB1dCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRTaXplJyl9XG4gICAgICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9IHVuaWZvcm1zLnN0YXJ0ICsgJHt3Z3NsVHlwZX0oZ2xvYmFsX2lkeCkgKiB1bmlmb3Jtcy5kZWx0YTtcbiAgICAgIH1gO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ1JhbmdlJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtkYXRhVHlwZX1gIH0sXG4gICAgZ2V0U2hhZGVyU291cmNlLFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcmFuZ2UgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiB2b2lkID0+IHtcbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGxpbWl0ID0gMDtcbiAgbGV0IGRlbHRhID0gMDtcbiAgaWYgKGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5pbnQzMikge1xuICAgIHN0YXJ0ID0gY29udGV4dC5pbnB1dHNbMF0uZ2V0SW50MzJBcnJheSgpWzBdO1xuICAgIGxpbWl0ID0gY29udGV4dC5pbnB1dHNbMV0uZ2V0SW50MzJBcnJheSgpWzBdO1xuICAgIGRlbHRhID0gY29udGV4dC5pbnB1dHNbMl0uZ2V0SW50MzJBcnJheSgpWzBdO1xuICB9IGVsc2UgaWYgKGNvbnRleHQuaW5wdXRzWzBdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5mbG9hdCkge1xuICAgIHN0YXJ0ID0gY29udGV4dC5pbnB1dHNbMF0uZ2V0RmxvYXQzMkFycmF5KClbMF07XG4gICAgbGltaXQgPSBjb250ZXh0LmlucHV0c1sxXS5nZXRGbG9hdDMyQXJyYXkoKVswXTtcbiAgICBkZWx0YSA9IGNvbnRleHQuaW5wdXRzWzJdLmdldEZsb2F0MzJBcnJheSgpWzBdO1xuICB9XG4gIGlmIChlbnYud2ViZ3B1LnZhbGlkYXRlSW5wdXRDb250ZW50KSB7XG4gICAgdmFsaWRhdGVJbnB1dHNDb250ZW50KHN0YXJ0LCBsaW1pdCwgZGVsdGEpO1xuICB9XG5cbiAgY29udGV4dC5jb21wdXRlKGNyZWF0ZVJhbmdlUHJvZ3JhbUluZm8oc3RhcnQsIGxpbWl0LCBkZWx0YSwgY29udGV4dC5pbnB1dHNbMF0uZGF0YVR5cGUpLCB7IGlucHV0czogW10gfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGF0b21pY091dHB1dFZhcmlhYmxlLFxuICBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyxcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbn0gZnJvbSAnLi9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNjYXR0ZXJOREF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWR1Y3Rpb246IHN0cmluZztcbn1cblxudHlwZSBSZWR1Y3Rpb25UeXBlID0gJ2kzMicgfCAndTMyJyB8ICdmMzInO1xuXG5jb25zdCBhdG9taWNSZWR1Y3Rpb25TbmlwcGV0ID0gKHJlZHVjdGlvbjogc3RyaW5nLCBwdHI6IHN0cmluZywgdjogc3RyaW5nLCB0eXBlOiBSZWR1Y3Rpb25UeXBlKSA9PiB7XG4gIGlmIChyZWR1Y3Rpb24gIT09ICdub25lJyAmJiB0eXBlICE9PSAnaTMyJyAmJiB0eXBlICE9PSAndTMyJyAmJiB0eXBlICE9PSAnZjMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJHt0eXBlfSBpcyBub3Qgc3VwcG9ydGVkIHdpdGggcmVkdWN0aW9uICR7cmVkdWN0aW9ufS5gKTtcbiAgfVxuXG4gIGNvbnN0IGZsb2F0U3RhcnQgPSBge1xuICAgICAgICAgICAgICAgIHZhciBvbGRWYWx1ZSA9IDA7XG4gICAgICAgICAgICAgICAgbG9vcCB7XG4gICAgICAgICAgICAgICAgICBsZXQgbmV3VmFsdWVGMzIgPWA7XG4gIGNvbnN0IGZsb2F0RW5kID0gYDtcbiAgICAgICAgICAgICAgICAgIGxldCBuZXdWYWx1ZSA9IGJpdGNhc3Q8aTMyPihuZXdWYWx1ZUYzMik7XG4gICAgICAgICAgICAgICAgICBsZXQgcmVzID0gYXRvbWljQ29tcGFyZUV4Y2hhbmdlV2VhaygmJHtwdHJ9LCBvbGRWYWx1ZSwgbmV3VmFsdWUpO1xuICAgICAgICAgICAgICAgICAgaWYgcmVzLmV4Y2hhbmdlZCB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSByZXMub2xkX3ZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfWA7XG5cbiAgc3dpdGNoIChyZWR1Y3Rpb24pIHtcbiAgICBjYXNlICdub25lJzpcbiAgICAgIHJldHVybiBgJHtwdHJ9PSR7dn07YDtcbiAgICBjYXNlICdhZGQnOlxuICAgICAgaWYgKHR5cGUgPT09ICdpMzInIHx8IHR5cGUgPT09ICd1MzInKSB7XG4gICAgICAgIHJldHVybiBgYXRvbWljQWRkKCYke3B0cn0sIGJpdGNhc3Q8JHt0eXBlfT4oJHt2fSkpO2A7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhdG9taWNBZGQgb25seSBzdXBwb3J0cyB1aW50L2ludCB0eXBlLiBGb3IgZmxvYXQsIHdlIHVzZVxuICAgICAgICAvLyBhdG9taWNDb21wYXJlRXhjaGFuZ2VXZWFrIHRvIHNpbXVsYXRlLlxuICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAke2Zsb2F0U3RhcnR9Yml0Y2FzdDwke3R5cGV9PihvbGRWYWx1ZSkgKyAoJHt2fSkke2Zsb2F0RW5kfWA7XG4gICAgICB9XG4gICAgY2FzZSAnbWF4JzpcbiAgICAgIGlmICh0eXBlID09PSAnaTMyJyB8fCB0eXBlID09PSAndTMyJykge1xuICAgICAgICByZXR1cm4gYGF0b21pY01heCgmJHtwdHJ9LCBiaXRjYXN0PCR7dHlwZX0+KCR7dn0pKTtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gYXRvbWljTWF4IG9ubHkgc3VwcG9ydHMgdWludC9pbnQgdHlwZS4gRm9yIGZsb2F0LCB3ZSB1c2VcbiAgICAgICAgLy8gYXRvbWljQ29tcGFyZUV4Y2hhbmdlV2VhayB0byBzaW11bGF0ZS5cbiAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgICAke2Zsb2F0U3RhcnR9bWF4KGJpdGNhc3Q8ZjMyPihvbGRWYWx1ZSksICgke3Z9KSkke2Zsb2F0RW5kfWA7XG4gICAgICB9XG4gICAgY2FzZSAnbWluJzpcbiAgICAgIGlmICh0eXBlID09PSAnaTMyJyB8fCB0eXBlID09PSAndTMyJykge1xuICAgICAgICByZXR1cm4gYGF0b21pY01pbigmJHtwdHJ9LCBiaXRjYXN0PCR7dHlwZX0+KCR7dn0pKTtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gYXRvbWljTWluIG9ubHkgc3VwcG9ydHMgdWludC9pbnQgdHlwZS4gRm9yIGZsb2F0LCB3ZSB1c2VcbiAgICAgICAgLy8gYXRvbWljQ29tcGFyZUV4Y2hhbmdlV2VhayB0byBzaW11bGF0ZS5cbiAgICAgICAgcmV0dXJuIGAke2Zsb2F0U3RhcnR9bWluKGJpdGNhc3Q8JHt0eXBlfT4ob2xkVmFsdWUpLCAoJHt2fSkpJHtmbG9hdEVuZH1gO1xuICAgICAgfVxuICAgIGNhc2UgJ211bCc6XG4gICAgICAvLyBhdG9taWNNdWwgaXMgbm90IHN1cHBvcnRlZCwgd2UgdXNlIGF0b21pY0NvbXBhcmVFeGNoYW5nZVdlYWsgdG8gc2ltdWxhdGUuXG4gICAgICByZXR1cm4gYCR7ZmxvYXRTdGFydH0oYml0Y2FzdDwke3R5cGV9PihvbGRWYWx1ZSkgKiAoJHt2fSkpJHtmbG9hdEVuZH1gO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUmVkdWN0aW9uICR7cmVkdWN0aW9ufSBpcyBub3Qgc3VwcG9ydGVkLmApO1xuICB9XG59O1xuXG5jb25zdCBjcmVhdGVTY2F0dGVyTkRQcm9ncmFtSW5mbyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogU2NhdHRlck5EQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbmRpY2VzU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlO1xuICAvLyBUT0RPOiBzdXBwb3J0IGJvb2wgd2l0aCBjb21wb25lbnRzIDQuXG4gIGNvbnN0IGNvbXBvbmVudHMgPSAxO1xuICBjb25zdCBvdXRwdXRTaXplID0gTWF0aC5jZWlsKFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24oaW5kaWNlc1NoYXBlLCBpbmRpY2VzU2hhcGUubGVuZ3RoIC0gMSkgLyBjb21wb25lbnRzKTtcbiAgY29uc3QgbGFzdEluZGV4RGltZW5zaW9uID0gaW5kaWNlc1NoYXBlW2luZGljZXNTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3QgbnVtVXBkYXRlc0VsZW1lbnRzID0gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKGlucHV0U2hhcGUsIGxhc3RJbmRleERpbWVuc2lvbik7XG5cbiAgY29uc3QgcHJvZ3JhbVVuaWZvcm1zOiBQcm9ncmFtVW5pZm9ybVtdID0gW1xuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBvdXRwdXRTaXplIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGxhc3RJbmRleERpbWVuc2lvbiB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBudW1VcGRhdGVzRWxlbWVudHMgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMV0uZGltcywgaW5wdXRzWzJdLmRpbXMsIG91dHB1dFNoYXBlKSxcbiAgXTtcblxuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IHtcbiAgICBjb25zdCBpbmRpY2VzID0gaW5wdXRWYXJpYWJsZSgnaW5kaWNlcycsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCB1cGRhdGVzID0gaW5wdXRWYXJpYWJsZSgndXBkYXRlcycsIGlucHV0c1syXS5kYXRhVHlwZSwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoLCBjb21wb25lbnRzKTtcbiAgICBjb25zdCBvdXRwdXQgPVxuICAgICAgYXR0cmlidXRlcy5yZWR1Y3Rpb24gIT09ICdub25lJyAmJiBhdHRyaWJ1dGVzLnJlZHVjdGlvbiAhPT0gJydcbiAgICAgICAgPyBhdG9taWNPdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpXG4gICAgICAgIDogb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoLCBjb21wb25lbnRzKTtcblxuICAgIHJldHVybiBgXG4gICAgICAke3NoYWRlckhlbHBlclxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdvdXRwdXRfc2l6ZScsICd1MzInKVxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdsYXN0X2luZGV4X2RpbWVuc2lvbicsICd1MzInKVxuICAgICAgICAucmVnaXN0ZXJVbmlmb3JtKCdudW1fdXBkYXRlc19lbGVtZW50cycsICd1MzInKVxuICAgICAgICAuZGVjbGFyZVZhcmlhYmxlcyhpbmRpY2VzLCB1cGRhdGVzLCBvdXRwdXQpfVxuICAgICAgJHtzaGFkZXJIZWxwZXIubWFpblN0YXJ0KCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gIHZhciBkYXRhX29mZnNldCA9IDB1O1xuICBsZXQgaW5kaWNlc19zdGFydCA9IHVuaWZvcm1zLmxhc3RfaW5kZXhfZGltZW5zaW9uICogZ2xvYmFsX2lkeDtcbiAgbGV0IGluZGljZXNfZW5kID0gaW5kaWNlc19zdGFydCArIHVuaWZvcm1zLmxhc3RfaW5kZXhfZGltZW5zaW9uO1xuICBmb3IgKHZhciBpID0gaW5kaWNlc19zdGFydDsgaSA8IGluZGljZXNfZW5kOyBpKyspIHtcbiAgICB2YXIgaW5kZXggPSBpMzIoaW5kaWNlc1tpXS54KTtcbiAgICAke1xuICAgICAgaW5wdXRzWzBdLmRpbXMubGVuZ3RoID09PSAxXG4gICAgICAgID8gYFxuICAgIGxldCBlbGVtZW50X2NvdW50X2RpbSA9IHVuaWZvcm1zLm91dHB1dF9zdHJpZGVzO1xuICAgIGxldCBkaW1fdmFsdWUgPSB1bmlmb3Jtcy5vdXRwdXRfc2hhcGU7YFxuICAgICAgICA6IGBcbiAgICBsZXQgZWxlbWVudF9jb3VudF9kaW0gPSB1bmlmb3Jtcy5vdXRwdXRfc3RyaWRlc1tpIC0gaW5kaWNlc19zdGFydF07XG4gICAgbGV0IGRpbV92YWx1ZSA9IHVuaWZvcm1zLm91dHB1dF9zaGFwZVtpIC0gaW5kaWNlc19zdGFydF07YFxuICAgIH1cbiAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgaWYgKGluZGV4ID49IGkzMihkaW1fdmFsdWUpKSB7XG4gICAgICAgIGluZGV4ID0gaTMyKGRpbV92YWx1ZSAtIDEpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaW5kZXggPCAtaTMyKGRpbV92YWx1ZSkpIHtcbiAgICAgICAgaW5kZXggPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5kZXggKz0gaTMyKGRpbV92YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGRhdGFfb2Zmc2V0ICs9IHUzMigodTMyKGluZGV4KSAqIGVsZW1lbnRfY291bnRfZGltKSk7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMHU7IGkgPCB1bmlmb3Jtcy5udW1fdXBkYXRlc19lbGVtZW50czsgaSsrKSB7XG4gICAgbGV0IHZhbHVlID0gdXBkYXRlc1t1bmlmb3Jtcy5udW1fdXBkYXRlc19lbGVtZW50cyAqIGdsb2JhbF9pZHggKyBpXTtcbiAgICAke2F0b21pY1JlZHVjdGlvblNuaXBwZXQoXG4gICAgICBhdHRyaWJ1dGVzLnJlZHVjdGlvbixcbiAgICAgICdvdXRwdXRbZGF0YV9vZmZzZXQgKyBpXScsXG4gICAgICAndmFsdWUnLFxuICAgICAgb3V0cHV0LnR5cGUudmFsdWUgYXMgUmVkdWN0aW9uVHlwZSxcbiAgICApfVxuICB9XG5cbiAgICAgIH1gO1xuICB9O1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdTY2F0dGVyTkQnLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fV8ke2F0dHJpYnV0ZXMucmVkdWN0aW9ufWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llczogWydyYW5rJywgJ3JhbmsnXSxcbiAgICB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtcyxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTY2F0dGVyTkRBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogU2NhdHRlck5EQXR0cmlidXRlcyA9PlxuICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyByZWR1Y3Rpb246IGF0dHJpYnV0ZXMucmVkdWN0aW9uIGFzIHN0cmluZyB9KTtcblxuZXhwb3J0IGNvbnN0IHNjYXR0ZXJORCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogU2NhdHRlck5EQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlU2NhdHRlck5EUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMpLCB7XG4gICAgaW5wdXRzOiBbY29udGV4dC5pbnB1dHNbMV0sIGNvbnRleHQuaW5wdXRzWzJdXSxcbiAgICBvdXRwdXRzOiBbXSxcbiAgfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbyB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtcbiAgY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMsXG4gIGdldEVsZW1lbnRBdCxcbiAgSW5kaWNlc0hlbHBlcixcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbn0gZnJvbSAnLi9jb21tb24nO1xuXG50eXBlIENvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID1cbiAgfCAnaGFsZl9waXhlbCdcbiAgfCAnYXN5bW1ldHJpYydcbiAgfCAncHl0b3JjaF9oYWxmX3BpeGVsJ1xuICB8ICd0Zl9oYWxmX3BpeGVsX2Zvcl9ubidcbiAgfCAnYWxpZ25fY29ybmVycydcbiAgfCAndGZfY3JvcF9hbmRfcmVzaXplJ1xuICB8ICdoYWxmX3BpeGVsX3N5bW1ldHJpYyc7XG5cbnR5cGUgS2VlcEFzcGVjdFJhdGlvUG9saWN5ID0gJ3N0cmV0Y2gnIHwgJ25vdF9zbWFsbGVyJyB8ICdub3RfbGFyZ2VyJztcblxudHlwZSBNb2RlID0gJ25lYXJlc3QnIHwgJ2xpbmVhcicgfCAnY3ViaWMnO1xuXG50eXBlIE5lYXJlc3RNb2RlID0gJ3JvdW5kX3ByZWZlcl9mbG9vcicgfCAncm91bmRfcHJlZmVyX2NlaWwnIHwgJ2Zsb29yJyB8ICdjZWlsJyB8ICdzaW1wbGUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlc2l6ZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBhbnRpYWxpYXM6IG51bWJlcjtcbiAgYXhlczogbnVtYmVyW107XG4gIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlOiBDb29yZGluYXRlVHJhbnNmb3JtTW9kZTtcbiAgY3ViaWNDb2VmZkE6IG51bWJlcjtcbiAgZXhjbHVkZU91dHNpZGU6IGJvb2xlYW47XG4gIGV4dHJhcG9sYXRpb25WYWx1ZTogbnVtYmVyO1xuICBrZWVwQXNwZWN0UmF0aW9Qb2xpY3k6IEtlZXBBc3BlY3RSYXRpb1BvbGljeTtcbiAgbW9kZTogTW9kZTtcbiAgbmVhcmVzdE1vZGU6IE5lYXJlc3RNb2RlO1xufVxuXG5jb25zdCB2YWxpZGF0ZVNjYWxlcyA9IChzY2FsZXM6IG51bWJlcltdLCBhdHRyaWJ1dGVzOiBSZXNpemVBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIHNjYWxlcy5ldmVyeShcbiAgICAodmFsdWUpID0+XG4gICAgICB2YWx1ZSA+IDAgfHxcbiAgICAgICgoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUmVzaXplIHJlcXVpcmVzIHNjYWxlcyBpbnB1dCB2YWx1ZXMgdG8gYmUgcG9zaXRpdmUnKTtcbiAgICAgIH0pLFxuICApO1xuICAvLyBDaGVjayBzY2FsZXMgZGltcyBiYXNlZCBvbiBtb2RlOiBMSU5FQVIsIENVQklDXG4gIGlmIChzY2FsZXMubGVuZ3RoID4gMCkge1xuICAgIGlmIChhdHRyaWJ1dGVzLm1vZGUgPT09ICdsaW5lYXInKSB7XG4gICAgICBpZiAoXG4gICAgICAgICEoXG4gICAgICAgICAgc2NhbGVzLmxlbmd0aCA9PT0gMiB8fFxuICAgICAgICAgIHNjYWxlcy5sZW5ndGggPT09IDMgfHxcbiAgICAgICAgICAoc2NhbGVzLmxlbmd0aCA9PT0gNCAmJiBzY2FsZXNbMF0gPT09IDEgJiYgc2NhbGVzWzFdID09PSAxKSB8fFxuICAgICAgICAgIChzY2FsZXMubGVuZ3RoID09PSA0ICYmIHNjYWxlc1swXSA9PT0gMSAmJiBzY2FsZXNbM10gPT09IDEpIHx8XG4gICAgICAgICAgKHNjYWxlcy5sZW5ndGggPT09IDUgJiYgc2NhbGVzWzBdID09PSAxICYmIHNjYWxlc1sxXSA9PT0gMSlcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgRm9yIGxpbmVhciBtb2RlLCBSZXNpemUgcmVxdWlyZXMgc2NhbGVzIHRvIGJlIDJELCAzRCwgNEQgd2l0aCBlaXRoZXIgdHdvIG91dGVybW9zdCBvciBvbmUgaW5uZXJtb3N0IGFuZFxuICAgICAgICAgICAgb25lIG91dGVybW9zdCBzY2FsZSB2YWx1ZXMgZXF1YWwgdG8gMSwgb3IgNUQgd2l0aCB0d28gb3V0ZXJtb3N0IHNjYWxlIHZhbHVlcyBlcXVhbCB0byAxYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMubW9kZSA9PT0gJ2N1YmljJykge1xuICAgICAgaWYgKFxuICAgICAgICAhKFxuICAgICAgICAgIHNjYWxlcy5sZW5ndGggPT09IDIgfHxcbiAgICAgICAgICAoc2NhbGVzLmxlbmd0aCA9PT0gNCAmJiBzY2FsZXNbMF0gPT09IDEgJiYgc2NhbGVzWzFdID09PSAxKSB8fFxuICAgICAgICAgIChzY2FsZXMubGVuZ3RoID09PSA0ICYmIHNjYWxlc1swXSA9PT0gMSAmJiBzY2FsZXNbM10gPT09IDEpXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc2l6ZSByZXF1aXJlcyBzY2FsZXMgaW5wdXQgc2l6ZSB0byBiZSAyIG9yIDQgZm9yIGN1YmljIG1vZGUnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbmNvbnN0IHVwZGF0ZVNjYWxlcyA9IChzY2FsZXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGVzOiByZWFkb25seSBudW1iZXJbXSwgcmFuazogbnVtYmVyKTogbnVtYmVyW10gPT4ge1xuICBheGVzLmV2ZXJ5KFxuICAgICh2YWx1ZSkgPT5cbiAgICAgICh2YWx1ZSA+PSAwICYmIHZhbHVlIDwgcmFuaykgfHxcbiAgICAgICgoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUmVzaXplIHJlcXVpcmVzIGF4ZXMgaW5wdXQgdmFsdWVzIHRvIGJlIHBvc2l0aXZlIGFuZCBsZXNzIHRoYW4gcmFuaycpO1xuICAgICAgfSksXG4gICk7XG4gIGNvbnN0IG5ld1NjYWxlcyA9IG5ldyBBcnJheShyYW5rKS5maWxsKDEuMCk7XG4gIGF4ZXMuZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiAobmV3U2NhbGVzW3ZhbHVlXSA9IHNjYWxlc1tpbmRleF0pKTtcbiAgcmV0dXJuIG5ld1NjYWxlcztcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogUmVzaXplQXR0cmlidXRlcyxcbiAgb3BzZXRWZXJzaW9uOiBudW1iZXIsXG4gIHNjYWxlczogbnVtYmVyW10sXG4gIHNpemVzOiBudW1iZXJbXSxcbiAgcm9pOiBudW1iZXJbXSxcbik6IHZvaWQgPT4ge1xuICBjb25zdCBbcm9pSW5wdXRJbmRleCwgc2NhbGVzSW5wdXRJbmRleCwgc2l6ZXNJbnB1dEluZGV4XSA9XG4gICAgb3BzZXRWZXJzaW9uID4gMTAgPyBbMSwgMiwgM10gOiBbLTEsIGlucHV0cy5sZW5ndGggPiAxID8gMSA6IC0xLCAtMV07XG4gIGNvbnN0IHJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGlmIChyb2lJbnB1dEluZGV4ID4gMCAmJiBpbnB1dHMubGVuZ3RoID4gcm9pSW5wdXRJbmRleCAmJiBpbnB1dHNbcm9pSW5wdXRJbmRleF0uZGltcy5sZW5ndGggPiAwKSB7XG4gICAgaW5wdXRzW3JvaUlucHV0SW5kZXhdLmdldEZsb2F0MzJBcnJheSgpLmZvckVhY2goKHZhbHVlKSA9PiByb2kucHVzaCh2YWx1ZSkpO1xuICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZXNpemUgcmVxdWlyZXMgUm9JIGlucHV0IHRvIGJlIHNwZWNpZmllZCB3aGVuIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlIGlzIHRmQ3JvcEFuZFJlc2l6ZScpO1xuICB9XG5cbiAgaWYgKFxuICAgIHNjYWxlc0lucHV0SW5kZXggPiAwICYmXG4gICAgaW5wdXRzLmxlbmd0aCA+IHNjYWxlc0lucHV0SW5kZXggJiZcbiAgICBpbnB1dHNbc2NhbGVzSW5wdXRJbmRleF0uZGltcy5sZW5ndGggPT09IDEgJiZcbiAgICBpbnB1dHNbc2NhbGVzSW5wdXRJbmRleF0uZGltc1swXSA+IDBcbiAgKSB7XG4gICAgaW5wdXRzW3NjYWxlc0lucHV0SW5kZXhdLmdldEZsb2F0MzJBcnJheSgpLmZvckVhY2goKHZhbHVlKSA9PiBzY2FsZXMucHVzaCh2YWx1ZSkpO1xuICAgIGlmIChcbiAgICAgIHNjYWxlcy5sZW5ndGggIT09IDAgJiZcbiAgICAgIHNjYWxlcy5sZW5ndGggIT09IHJhbmsgJiZcbiAgICAgIG9wc2V0VmVyc2lvbiA+PSAxOCAmJlxuICAgICAgc2NhbGVzLmxlbmd0aCAhPT0gYXR0cmlidXRlcy5heGVzLmxlbmd0aFxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXNpemUgcmVxdWlyZXMgc2NhbGVzIGlucHV0IHNpemUgdG8gYmUgc2FtZSBhcyBpbnB1dCByYW5rIG9yIGF4ZXMgc2l6ZSBmb3Igb3BzZXQgMTggYW5kIHVwJyk7XG4gICAgfVxuICAgIHZhbGlkYXRlU2NhbGVzKHNjYWxlcywgYXR0cmlidXRlcyk7XG4gICAgaWYgKGF0dHJpYnV0ZXMuYXhlcy5sZW5ndGggPiAwKSB7XG4gICAgICB1cGRhdGVTY2FsZXMoc2NhbGVzLCBhdHRyaWJ1dGVzLmF4ZXMsIHJhbmspLmZvckVhY2goKHZhbHVlLCBpbmRleCkgPT4gKHNjYWxlc1tpbmRleF0gPSB2YWx1ZSkpO1xuICAgIH1cbiAgfVxuICBpZiAoXG4gICAgc2l6ZXNJbnB1dEluZGV4ID4gMCAmJlxuICAgIGlucHV0cy5sZW5ndGggPiBzaXplc0lucHV0SW5kZXggJiZcbiAgICBpbnB1dHNbc2l6ZXNJbnB1dEluZGV4XS5kaW1zLmxlbmd0aCA9PT0gMSAmJlxuICAgIGlucHV0c1tzaXplc0lucHV0SW5kZXhdLmRpbXNbMF0gPiAwXG4gICkge1xuICAgIGlucHV0c1tzaXplc0lucHV0SW5kZXhdLmdldEJpZ0ludDY0QXJyYXkoKS5mb3JFYWNoKCh2YWx1ZSkgPT4gc2l6ZXMucHVzaChOdW1iZXIodmFsdWUpKSk7XG4gICAgaWYgKHNpemVzLmxlbmd0aCAhPT0gMCAmJiBzaXplcy5sZW5ndGggIT09IHJhbmsgJiYgb3BzZXRWZXJzaW9uID49IDE4ICYmIHNpemVzLmxlbmd0aCAhPT0gYXR0cmlidXRlcy5heGVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXNpemUgcmVxdWlyZXMgc2l6ZXMgaW5wdXQgc2l6ZSB0byBiZSBzYW1lIGFzIGlucHV0IHJhbmsgb3IgYXhlcyBzaXplIGZvciBvcHNldCAxOCBhbmQgdXAnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoYXR0cmlidXRlcy5heGVzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoc2NhbGVzLmxlbmd0aCAhPT0gMCAmJiBzY2FsZXMubGVuZ3RoICE9PSBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc2l6ZSByZXF1aXJlcyBcInNjYWxlc1wiIGlucHV0IHNpemUgdG8gYmUgb2YgYXhlcyByYW5rIHdoZW4gYXhlcyBhdHRyaWJ1dGVzIGlzIHNwZWNpZmllZCcpO1xuICAgIH1cbiAgICBpZiAoc2l6ZXMubGVuZ3RoICE9PSAwICYmIHNpemVzLmxlbmd0aCAhPT0gYXR0cmlidXRlcy5heGVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXNpemUgcmVxdWlyZXMgXCJzaXplc1wiIGlucHV0IHNpemUgdG8gYmUgb2YgcmFuayBheGVzIHJhbmsgd2hlbiBheGVzIGF0dHJpYnV0ZXMgaXMgc3BlY2lmaWVkJyk7XG4gICAgfVxuICB9XG4gIGlmICh0eXBlb2Ygc2NhbGVzICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygc2l6ZXMgIT09ICd1bmRlZmluZWQnICYmIHNjYWxlcy5sZW5ndGggPiAwICYmIHNpemVzLmxlbmd0aCA+IHJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc2l6ZSByZXF1aXJlcyBvbmx5IG9mIHNjYWxlcyBvciBzaXplcyB0byBiZSBzcGVjaWZpZWQnKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0U2FmZUludGVnZXJEaXZpc2lvbiA9IChhOiBzdHJpbmcsIGI6IHN0cmluZywgYzogc3RyaW5nLCBkVHlwZTogc3RyaW5nKTogc3RyaW5nID0+IGBcbiAgLy8gVGhlIHdob2xlIHBhcnQgYW5kIHRoZSBmcmFjdGlvbmFsIHBhcnQgYXJlIGNhbGN1bGF0ZWQgc2VwYXJhdGVseSBkdWUgdG8gaW5hY2N1cmFjeSBvZiBmbG9hdGluZ1xuICAvLyBwb2ludCBkaXZpc2lvbi4gQXMgYW4gZXhhbXBsZSwgZjMyKDIxKSAvIGYzMig3KSBtYXkgZXZhbHVhdGUgdG8gMi45OS4uLiBpbnN0ZWFkIG9mIDMsIGNhdXNpbmcgYW5cbiAgLy8gb2Zmc2V0LWJ5LW9uZSBlcnJvciBsYXRlciBpbiBmbG9vcigpLlxuICBsZXQgYmlnID0gKCR7YX0pICogKCR7Yn0pO1xuICBsZXQgd2hvbGUgPSAke2RUeXBlfShiaWcgLyAoJHtjfSkpO1xuICBsZXQgZnJhY3QgPSAke2RUeXBlfShiaWcgJSAoJHtjfSkpIC8gJHtkVHlwZX0oJHtjfSk7XG4gIHJldHVybiB3aG9sZSArIGZyYWN0O1xuYDtcblxuY29uc3QgZ2V0T3JpZ2luYWxDb29yZGluYXRlRnJvbVJlc2l6ZWRDb29yZGluYXRlID0gKFxuICBjb29yZGluYXRlVHJhbnNmZXJNb2RlOiBDb29yZGluYXRlVHJhbnNmb3JtTW9kZSxcbiAgZFR5cGU6IHN0cmluZyxcbik6IHN0cmluZyA9PlxuICBgZm4gZ2V0T3JpZ2luYWxDb29yZGluYXRlRnJvbVJlc2l6ZWRDb29yZGluYXRlKHhSZXNpemVkOiB1MzIsIHhTY2FsZTogZjMyLCBsZW5ndGhSZXNpemVkOiB1MzIsXG4gICAgIGxlbmd0aE9yaWdpbmFsOiB1MzIsIHJvaVN0YXJ0OiBmMzIsIHJvaUVuZDogZjMyKSAtPiAke2RUeXBlfSB7IGAgK1xuICAoKCkgPT4ge1xuICAgIHN3aXRjaCAoY29vcmRpbmF0ZVRyYW5zZmVyTW9kZSkge1xuICAgICAgY2FzZSAnYXN5bW1ldHJpYyc6XG4gICAgICAgIHJldHVybiBgXG4gICAgICAgICAgaWYgKHhTY2FsZSA8IDEuMCB8fCBmbG9vcih4U2NhbGUpICE9IHhTY2FsZSkge1xuICAgICAgICAgICAgcmV0dXJuICR7ZFR5cGV9KHhSZXNpemVkKSAvICR7ZFR5cGV9KHhTY2FsZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICR7Z2V0U2FmZUludGVnZXJEaXZpc2lvbigneFJlc2l6ZWQnLCAnbGVuZ3RoT3JpZ2luYWwnLCAnbGVuZ3RoUmVzaXplZCcsIGRUeXBlKX1cbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICBjYXNlICdweXRvcmNoX2hhbGZfcGl4ZWwnOlxuICAgICAgICByZXR1cm4gYGlmIChsZW5ndGhSZXNpemVkID4gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCR7ZFR5cGV9KHhSZXNpemVkKSArIDAuNSkgLyAke2RUeXBlfSh4U2NhbGUpIC0gMC41O1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDAuMDtcbiAgICAgICAgICAgICAgICAgIH1gO1xuICAgICAgY2FzZSAndGZfaGFsZl9waXhlbF9mb3Jfbm4nOlxuICAgICAgICByZXR1cm4gYHJldHVybiAoJHtkVHlwZX0oeFJlc2l6ZWQpICsgMC41KSAvICR7ZFR5cGV9KHhTY2FsZSk7YDtcbiAgICAgIGNhc2UgJ2FsaWduX2Nvcm5lcnMnOlxuICAgICAgICByZXR1cm4gYGlmIChsZW5ndGhSZXNpemVkID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDAuMDtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICR7Z2V0U2FmZUludGVnZXJEaXZpc2lvbigneFJlc2l6ZWQnLCAnbGVuZ3RoT3JpZ2luYWwgLSAxJywgJ2xlbmd0aFJlc2l6ZWQgLSAxJywgZFR5cGUpfVxuICAgICAgICAgICAgICAgICAgfWA7XG4gICAgICBjYXNlICd0Zl9jcm9wX2FuZF9yZXNpemUnOlxuICAgICAgICByZXR1cm4gYGlmIChsZW5ndGhSZXNpemVkID4gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHtkVHlwZX0ocm9pU3RhcnQpICogJHtkVHlwZX0obGVuZ3RoT3JpZ2luYWwgLSAxKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAoJHtkVHlwZX0oeFJlc2l6ZWQpICogJHtkVHlwZX0ocm9pRW5kIC0gcm9pU3RhcnQpICogJHtkVHlwZX0obGVuZ3RoT3JpZ2luYWwgLSAxKSkgL1xuICAgICAgICAgICAgICAgICAgICAgICAgJHtkVHlwZX0obGVuZ3RoUmVzaXplZCAtIDEpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDAuNSAqICR7ZFR5cGV9KHJvaVN0YXJ0ICsgcm9pRW5kKSAqICR7ZFR5cGV9KGxlbmd0aE9yaWdpbmFsIC0gMSk7XG4gICAgICAgICAgICAgICAgICB9YDtcbiAgICAgIGNhc2UgJ2hhbGZfcGl4ZWxfc3ltbWV0cmljJzpcbiAgICAgICAgcmV0dXJuIGBjb25zdCBvdXRwdXRXaWR0aCA9ICR7ZFR5cGV9eFNjYWxlICogJHtkVHlwZX0obGVuZ3RoUmVzaXplZCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBhZGp1c3RtZW50ID0gJHtkVHlwZX0obGVuZ3RoUmVzaXplZCkgLyBvdXRwdXRXaWR0aDtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRlciA9ICR7ZFR5cGV9KGxlbmd0aE9yaWdpbmFsKSAvIDI7XG4gICAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSBjZW50ZXIgKiAoMSAtIGFkanVzdG1lbnQpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mZnNldCArICgoJHtkVHlwZX0oeFJlc2l6ZWQpICsgMC41KSAvICR7ZFR5cGV9KHhTY2FsZSkpIC0gMC41O2A7XG4gICAgICBjYXNlICdoYWxmX3BpeGVsJzpcbiAgICAgICAgcmV0dXJuIGByZXR1cm4gKCgke2RUeXBlfSh4UmVzaXplZCkgKyAwLjUpIC8gJHtkVHlwZX0oeFNjYWxlKSkgLSAwLjU7YDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ29vcmRpbmF0ZSB0cmFuc2Zvcm0gbW9kZSAke2Nvb3JkaW5hdGVUcmFuc2Zlck1vZGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH0pKCkgK1xuICAnfSc7XG5cbmNvbnN0IGdldE5lYXJlc3RQaXhlbEZyb21PcmlnaW5hbCA9IChuZWFyZXN0TW9kZTogTmVhcmVzdE1vZGUsIG9wc2V0VmVyc2lvbjogbnVtYmVyLCBkVHlwZTogc3RyaW5nKTogc3RyaW5nID0+XG4gIGBmbiBnZXROZWFyZXN0UGl4ZWxGcm9tT3JpZ2luYWwoeE9yaWdpbmFsOiAke2RUeXBlfSwgaXNEb3duU2FtcGxlOiBib29sKSAtPiAke2RUeXBlfSB7YCArXG4gICgoKSA9PiB7XG4gICAgc3dpdGNoIChuZWFyZXN0TW9kZSkge1xuICAgICAgY2FzZSAncm91bmRfcHJlZmVyX2NlaWwnOlxuICAgICAgICByZXR1cm4gJ2lmIChmcmFjdCh4T3JpZ2luYWwpID09IDAuNSkgeyBcXFxuICAgICAgICAgICAgcmV0dXJuIGNlaWwoeE9yaWdpbmFsKTsgXFxcbiAgICAgICAgICB9IGVsc2UgeyBcXFxuICAgICAgICAgICAgcmV0dXJuIHJvdW5kKHhPcmlnaW5hbCk7IFxcXG4gICAgICAgICAgfSc7XG4gICAgICBjYXNlICdmbG9vcic6XG4gICAgICAgIHJldHVybiAncmV0dXJuIGZsb29yKHhPcmlnaW5hbCk7JztcbiAgICAgIGNhc2UgJ2NlaWwnOlxuICAgICAgICByZXR1cm4gJ3JldHVybiBjZWlsKHhPcmlnaW5hbCk7JztcbiAgICAgIGNhc2UgJ3JvdW5kX3ByZWZlcl9mbG9vcic6XG4gICAgICAgIHJldHVybiAnaWYgKGZyYWN0KHhPcmlnaW5hbCkgPT0gMC41KSB7IFxcXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmbG9vcih4T3JpZ2luYWwpOyBcXFxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgXFxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJvdW5kKHhPcmlnaW5hbCk7IFxcXG4gICAgICAgICAgICAgICAgICB9JztcbiAgICAgIGNhc2UgJ3NpbXBsZSc6XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAob3BzZXRWZXJzaW9uIDwgMTEpIHtcbiAgICAgICAgICByZXR1cm4gJ2lmIChpc0Rvd25TYW1wbGUpIFxcXG4gICAgICAgICAgICAgICAgICAgIHsgXFxcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2VpbCh4T3JpZ2luYWwpOyBcXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyBcXFxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB4T3JpZ2luYWw7IFxcXG4gICAgICAgICAgICAgICAgICAgIH0nO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTmVhcmVzdCBtb2RlICR7bmVhcmVzdE1vZGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH0pKCkgK1xuICAnfSc7XG5cbmNvbnN0IHVwZGF0ZVJvSSA9IChyb2k6IHJlYWRvbmx5IG51bWJlcltdLCBheGVzOiByZWFkb25seSBudW1iZXJbXSwgcmFuazogbnVtYmVyKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCByb2lUbXAgPSBuZXcgQXJyYXkocmFuaykuZmlsbCgwKS5jb25jYXQobmV3IEFycmF5KHJhbmspLmZpbGwoMSkpO1xuICBjb25zdCByb2lMb2NhbCA9IHJvaS5sZW5ndGggPT09IDAgPyByb2lUbXAgOiByb2kuc2xpY2UoKTtcbiAgaWYgKGF4ZXMubGVuZ3RoID4gMCkge1xuICAgIGF4ZXMuZm9yRWFjaCgodiwgaSkgPT4ge1xuICAgICAgcm9pVG1wW3ZdID0gcm9pTG9jYWxbaV07XG4gICAgICByb2lUbXBbaSArIHJhbmtdID0gcm9pTG9jYWxbYXhlcy5sZW5ndGggKyBpXTtcbiAgICB9KTtcbiAgICByZXR1cm4gcm9pVG1wO1xuICB9XG4gIHJldHVybiByb2lMb2NhbDtcbn07XG5cbmNvbnN0IGluaXRPdXRwdXRTaGFwZSA9IChcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNjYWxlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNpemVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXhlczogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBudW1iZXJbXSA9PiB7XG4gIGxldCBvdXRwdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgaWYgKHNpemVzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoYXhlcy5sZW5ndGggPiAwKSB7XG4gICAgICBpbnB1dFNoYXBlLmZvckVhY2goKHYpID0+IG91dHB1dFNoYXBlLnB1c2godikpO1xuICAgICAgaWYgKE1hdGgubWF4KC4uLmF4ZXMpID4gaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdheGVzIGlzIG91dCBvZiBib3VuZCcpO1xuICAgICAgfVxuICAgICAgYXhlcy5mb3JFYWNoKCh2LCBpKSA9PiAob3V0cHV0U2hhcGVbdl0gPSBzaXplc1tpXSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaXplcy5mb3JFYWNoKCh2KSA9PiBvdXRwdXRTaGFwZS5wdXNoKHYpKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHNjYWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUmVzaXplIHJlcXVpcmVzIGVpdGhlciBzY2FsZXMgb3Igc2l6ZXMuJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5tYXAoKHZhbHVlLCBpbmRleCkgPT4gTWF0aC5yb3VuZCh2YWx1ZSAqIHNjYWxlc1tpbmRleF0pKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dHB1dFNoYXBlO1xufTtcblxuY29uc3QgYWRqdXN0T3V0cHV0U2hhcGUgPSAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHNjYWxlczogbnVtYmVyW10sIGF0dHJpYnV0ZXM6IFJlc2l6ZUF0dHJpYnV0ZXMpID0+IHtcbiAgY29uc3Qgc2NhbGVJblBvbGljeSA9ICgoKSA9PiB7XG4gICAgc3dpdGNoIChhdHRyaWJ1dGVzLmtlZXBBc3BlY3RSYXRpb1BvbGljeSkge1xuICAgICAgY2FzZSAnbm90X2xhcmdlcic6XG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID4gMFxuICAgICAgICAgID8gTWF0aC5taW4oLi4uYXR0cmlidXRlcy5heGVzLm1hcCgoaSkgPT4gc2NhbGVzW2ldKSwgTnVtYmVyLk1BWF9WQUxVRSlcbiAgICAgICAgICA6IE1hdGgubWluKC4uLnNjYWxlcywgTnVtYmVyLk1BWF9WQUxVRSk7XG4gICAgICBjYXNlICdub3Rfc21hbGxlcic6XG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID4gMFxuICAgICAgICAgID8gTWF0aC5tYXgoLi4uYXR0cmlidXRlcy5heGVzLm1hcCgoaSkgPT4gc2NhbGVzW2ldKSwgTnVtYmVyLk1JTl9WQUxVRSlcbiAgICAgICAgICA6IE1hdGgubWF4KC4uLnNjYWxlcywgTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEtlZXAgYXNwZWN0IHJhdGlvIHBvbGljeSAke2F0dHJpYnV0ZXMua2VlcEFzcGVjdFJhdGlvUG9saWN5fSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gICAgfVxuICB9KSgpO1xuICBzY2FsZXMuZmlsbCgxLjAsIDAsIHNjYWxlcy5sZW5ndGgpO1xuICBjb25zdCBhZGp1c3RlZE91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgpO1xuICBpZiAoYXR0cmlidXRlcy5heGVzLmxlbmd0aCA+IDApIHtcbiAgICBhdHRyaWJ1dGVzLmF4ZXMuZm9yRWFjaCgodikgPT4gKHNjYWxlc1t2XSA9IHNjYWxlSW5Qb2xpY3kpKTtcbiAgICBhdHRyaWJ1dGVzLmF4ZXMuZm9yRWFjaCgodikgPT4gKGFkanVzdGVkT3V0cHV0U2hhcGVbdl0gPSBNYXRoLnJvdW5kKGlucHV0U2hhcGVbdl0gKiBzY2FsZXNbdl0pKSk7XG4gIH0gZWxzZSB7XG4gICAgc2NhbGVzLmZpbGwoc2NhbGVJblBvbGljeSwgMCwgc2NhbGVzLmxlbmd0aCk7XG4gICAgYWRqdXN0ZWRPdXRwdXRTaGFwZS5mb3JFYWNoKCh2LCBpKSA9PiAoYWRqdXN0ZWRPdXRwdXRTaGFwZVtpXSA9IE1hdGgucm91bmQodiAqIHNjYWxlc1tpXSkpKTtcbiAgfVxuICByZXR1cm4gYWRqdXN0ZWRPdXRwdXRTaGFwZTtcbn07XG5cbmNvbnN0IGNhbGN1bGF0ZU9yaWdpbmFsSW5kaWNlc0Zyb21PdXRwdXRJbmRpY2VzID0gKFxuICBvdXRwdXQ6IEluZGljZXNIZWxwZXIsXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNjYWxlc0xlbmd0aDogbnVtYmVyLFxuICByb2lMZW5ndGg6IG51bWJlcixcbik6IHN0cmluZyA9PiBgXG4gICAgZm4gY2FsY3VsYXRlT3JpZ2luYWxJbmRpY2VzRnJvbU91dHB1dEluZGljZXMob3V0cHV0X2luZGljZXM6ICR7b3V0cHV0LnR5cGUuaW5kaWNlc30pIC0+IGFycmF5PCR7XG4gICAgICBvdXRwdXQudHlwZS52YWx1ZVxuICAgIH0sICR7b3V0cHV0U2hhcGUubGVuZ3RofT4ge1xuICAgICAgdmFyIG9yaWdpbmFsX2luZGljZXM6IGFycmF5PCR7b3V0cHV0LnR5cGUudmFsdWV9LCAke291dHB1dFNoYXBlLmxlbmd0aH0+O1xuICAgICAgZm9yICh2YXIgaTp1MzIgPSAwOyBpIDwgJHtvdXRwdXRTaGFwZS5sZW5ndGh9OyBpKyspIHtcbiAgICAgICAgdmFyIG91dHB1dF9pbmRleCA9ICR7b3V0cHV0LmluZGljZXNHZXQoJ291dHB1dF9pbmRpY2VzJywgJ2knKX07XG4gICAgICAgIHZhciBzY2FsZSA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5zY2FsZXMnLCAnaScsIHNjYWxlc0xlbmd0aCl9O1xuICAgICAgICB2YXIgcm9pX2xvdyA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5yb2knLCAnaScsIHJvaUxlbmd0aCl9O1xuICAgICAgICB2YXIgcm9pX2hpID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnJvaScsIGBpICsgJHtpbnB1dFNoYXBlLmxlbmd0aH1gLCByb2lMZW5ndGgpfTtcbiAgICAgICAgaWYgKHNjYWxlID09IDEuMCkge1xuICAgICAgICAgIG9yaWdpbmFsX2luZGljZXNbaV0gPSAke291dHB1dC50eXBlLnZhbHVlfShvdXRwdXRfaW5kZXgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBpbnB1dF9zaGFwZV9pID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLmlucHV0X3NoYXBlJywgJ2knLCBpbnB1dFNoYXBlLmxlbmd0aCl9O1xuICAgICAgICAgIHZhciBvdXRwdXRfc2hhcGVfaSA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5vdXRwdXRfc2hhcGUnLCAnaScsIG91dHB1dFNoYXBlLmxlbmd0aCl9O1xuICAgICAgICAgIG9yaWdpbmFsX2luZGljZXNbaV0gPSBnZXRPcmlnaW5hbENvb3JkaW5hdGVGcm9tUmVzaXplZENvb3JkaW5hdGUob3V0cHV0X2luZGV4LCBzY2FsZSwgb3V0cHV0X3NoYXBlX2ksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF9zaGFwZV9pLCByb2lfbG93LCByb2lfaGkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gb3JpZ2luYWxfaW5kaWNlcztcbiAgICB9YDtcblxuY29uc3QgY2FsY3VsYXRlSW5wdXRJbmRpY2VzRnJvbU91dHB1dEluZGljZXMgPSAoXG4gIGlucHV0OiBJbmRpY2VzSGVscGVyLFxuICBvdXRwdXQ6IEluZGljZXNIZWxwZXIsXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNjYWxlc0xlbmd0aDogbnVtYmVyLFxuICByb2lMZW5ndGg6IG51bWJlcixcbiAgdXNlRXh0cmFwb2xhdGlvbjogYm9vbGVhbixcbik6IHN0cmluZyA9PiBgXG4gICAgZm4gY2FsY3VsYXRlSW5wdXRJbmRpY2VzRnJvbU91dHB1dEluZGljZXMob3V0cHV0X2luZGljZXM6ICR7b3V0cHV0LnR5cGUuaW5kaWNlc30pIC0+ICR7aW5wdXQudHlwZS5pbmRpY2VzfSB7XG4gICAgICB2YXIgaW5wdXRfaW5kaWNlczogJHtpbnB1dC50eXBlLmluZGljZXN9O1xuICAgICAgZm9yICh2YXIgaTp1MzIgPSAwOyBpIDwgJHtvdXRwdXRTaGFwZS5sZW5ndGh9OyBpKyspIHtcbiAgICAgICAgdmFyIG91dHB1dF9pbmRleCA9ICR7b3V0cHV0LmluZGljZXNHZXQoJ291dHB1dF9pbmRpY2VzJywgJ2knKX07XG4gICAgICAgIHZhciBpbnB1dF9pbmRleDogdTMyO1xuICAgICAgICB2YXIgc2NhbGUgPSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuc2NhbGVzJywgJ2knLCBzY2FsZXNMZW5ndGgpfTtcbiAgICAgICAgaWYgKHNjYWxlID09IDEuMCkge1xuICAgICAgICAgIGlucHV0X2luZGV4ID0gb3V0cHV0X2luZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciByb2lfbG93ID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLnJvaScsICdpJywgcm9pTGVuZ3RoKX07XG4gICAgICAgICAgdmFyIHJvaV9oaSA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5yb2knLCBgaSArICR7aW5wdXRTaGFwZS5sZW5ndGh9YCwgcm9pTGVuZ3RoKX07XG4gICAgICAgICAgdmFyIGlucHV0X3NoYXBlX2kgPSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuaW5wdXRfc2hhcGUnLCAnaScsIGlucHV0U2hhcGUubGVuZ3RoKX07XG4gICAgICAgICAgdmFyIG91dHB1dF9zaGFwZV9pID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLm91dHB1dF9zaGFwZScsICdpJywgb3V0cHV0U2hhcGUubGVuZ3RoKX07XG4gICAgICAgICAgdmFyIG9yaWdpbmFsX2lkeCA9IGdldE9yaWdpbmFsQ29vcmRpbmF0ZUZyb21SZXNpemVkQ29vcmRpbmF0ZShvdXRwdXRfaW5kZXgsIHNjYWxlLCBvdXRwdXRfc2hhcGVfaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0X3NoYXBlX2ksIHJvaV9sb3csIHJvaV9oaSk7XG4gICAgICAgICAgaWYgKCEke3VzZUV4dHJhcG9sYXRpb259IHx8IChvcmlnaW5hbF9pZHggPj0gMCAmJiBvcmlnaW5hbF9pZHggPCAke291dHB1dC50eXBlLnZhbHVlfShpbnB1dF9zaGFwZV9pKSkpIHtcbiAgICAgICAgICAgIGlmIChvcmlnaW5hbF9pZHggPCAwKSB7XG4gICAgICAgICAgICAgIGlucHV0X2luZGV4ID0gMDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAob3JpZ2luYWxfaWR4ID4gJHtvdXRwdXQudHlwZS52YWx1ZX0oaW5wdXRfc2hhcGVfaSAtIDEpKSB7XG4gICAgICAgICAgICAgIGlucHV0X2luZGV4ID0gaW5wdXRfc2hhcGVfaSAtIDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpbnB1dF9pbmRleCA9IHUzMihnZXROZWFyZXN0UGl4ZWxGcm9tT3JpZ2luYWwob3JpZ2luYWxfaWR4LCBzY2FsZSA8IDEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5wdXRfaW5kZXggPSB1MzIob3JpZ2luYWxfaWR4KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgJHtpbnB1dC5pbmRpY2VzU2V0KCdpbnB1dF9pbmRpY2VzJywgJ2knLCAnaW5wdXRfaW5kZXgnKX1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpbnB1dF9pbmRpY2VzO1xuICAgIH1gO1xuY29uc3QgY2hlY2tJbnB1dEluZGljZXMgPSAoaW5wdXQ6IEluZGljZXNIZWxwZXIsIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogc3RyaW5nID0+IGBcbiAgICBmbiBjaGVja0lucHV0SW5kaWNlcyhpbnB1dF9pbmRpY2VzOiAke2lucHV0LnR5cGUuaW5kaWNlc30pIC0+IGJvb2wge1xuICAgICAgZm9yICh2YXIgaTp1MzIgPSAwOyBpIDwgJHtpbnB1dFNoYXBlLmxlbmd0aH07IGkrKykge1xuICAgICAgICB2YXIgaW5wdXRfaW5kZXggPSAke2lucHV0LmluZGljZXNHZXQoJ2lucHV0X2luZGljZXMnLCAnaScpfTtcbiAgICAgICAgaWYgKGlucHV0X2luZGV4IDwgMCB8fCBpbnB1dF9pbmRleCA+PSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuaW5wdXRfc2hhcGUnLCAnaScsIGlucHV0U2hhcGUubGVuZ3RoKX0pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1gO1xuXG5jb25zdCBzZXRDaGFubmVsQW5kQmF0Y2hJbmRpY2VzID0gKFxuICBpbnB1dDogSW5kaWNlc0hlbHBlcixcbiAgY2hhbm5lbElkeDogbnVtYmVyLFxuICBiYXRjaElkeDogbnVtYmVyLFxuICBzcGFjaWFsRGltczogbnVtYmVyLFxuKTogc3RyaW5nID0+XG4gIGlucHV0LnJhbmsgPiBzcGFjaWFsRGltc1xuICAgID8gYFxuICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIGNoYW5uZWxJZHgsICdjaGFubmVsJyl9O1xuICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIGJhdGNoSWR4LCAnYmF0Y2gnKX07XG5gXG4gICAgOiAnJztcblxuY29uc3QgYmlsaW5lYXJJbnRlcnBvbGF0aW9uID0gKFxuICBpbnB1dDogSW5kaWNlc0hlbHBlcixcbiAgb3V0cHV0OiBJbmRpY2VzSGVscGVyLFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgdXNlRXh0cmFwb2xhdGlvbjogYm9vbGVhbixcbiAgZXh0cmFwb2xhdGlvblZhbHVlOiBudW1iZXIsXG4pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBpc05jaHcgPSB0cnVlO1xuICBjb25zdCBbYmF0Y2hJZHgsIGhlaWdodElkeCwgd2lkdGhJZHgsIGNoYW5uZWxJZHhdID1cbiAgICBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMiA/IFstMSwgMCwgMSwgLTFdIDogaXNOY2h3ID8gWzAsIDIsIDMsIDFdIDogWzAsIDEsIDIsIDNdO1xuICBjb25zdCBkVHlwZSA9IGlucHV0LnR5cGUudmFsdWU7XG4gIHJldHVybiBgXG4gICAgZm4gZ2V0SW5wdXRWYWx1ZShiYXRjaDogdTMyLCBjaGFubmVsOiB1MzIsIHJvdzogdTMyLCBjb2w6IHUzMikgLT4gJHtkVHlwZX0ge1xuICAgICAgdmFyIGlucHV0X2luZGljZXM6ICR7aW5wdXQudHlwZS5pbmRpY2VzfTtcbiAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIGhlaWdodElkeCwgYG1heCgwLCBtaW4ocm93LCAke2lucHV0U2hhcGVbaGVpZ2h0SWR4XX0gLSAxKSlgKX07XG4gICAgICAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0X2luZGljZXMnLCB3aWR0aElkeCwgYG1heCgwLCBtaW4oY29sLCAke2lucHV0U2hhcGVbd2lkdGhJZHhdfSAtIDEpKWApfTtcbiAgICAgICR7c2V0Q2hhbm5lbEFuZEJhdGNoSW5kaWNlcyhpbnB1dCwgY2hhbm5lbElkeCwgYmF0Y2hJZHgsIDIpfVxuICAgICAgcmV0dXJuICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9O1xuICAgIH1cblxuICAgIGZuIGJpbGluZWFySW50ZXJwb2xhdGlvbihvdXRwdXRfaW5kaWNlczogJHtvdXRwdXQudHlwZS5pbmRpY2VzfSkgLT4gJHtkVHlwZX0ge1xuICAgICAgdmFyIG9yaWdpbmFsSW5kaWNlcyA9IGNhbGN1bGF0ZU9yaWdpbmFsSW5kaWNlc0Zyb21PdXRwdXRJbmRpY2VzKG91dHB1dF9pbmRpY2VzKTtcbiAgICAgIHZhciByb3c6JHtkVHlwZX0gPSBvcmlnaW5hbEluZGljZXNbJHtoZWlnaHRJZHh9XTtcbiAgICAgIHZhciBjb2w6JHtkVHlwZX0gPSBvcmlnaW5hbEluZGljZXNbJHt3aWR0aElkeH1dO1xuICAgICAgJHtcbiAgICAgICAgdXNlRXh0cmFwb2xhdGlvblxuICAgICAgICAgID8gYGlmIChyb3cgPCAwIHx8IHJvdyA+ICgke2lucHV0U2hhcGVbaGVpZ2h0SWR4XX0gLSAxKSB8fCBjb2wgPCAwIHx8IGNvbCA+ICgke2lucHV0U2hhcGVbd2lkdGhJZHhdfSAtIDEpKSB7XG4gICAgICAgIHJldHVybiAke2V4dHJhcG9sYXRpb25WYWx1ZX07XG4gICAgICB9YFxuICAgICAgICAgIDogJydcbiAgICAgIH07XG4gICAgICByb3cgPSBtYXgoMCwgbWluKHJvdywgJHtpbnB1dFNoYXBlW2hlaWdodElkeF19IC0gMSkpO1xuICAgICAgY29sID0gbWF4KDAsIG1pbihjb2wsICR7aW5wdXRTaGFwZVt3aWR0aElkeF19IC0gMSkpO1xuICAgICAgdmFyIHJvdzE6IHUzMiA9IHUzMihyb3cpO1xuICAgICAgdmFyIGNvbDE6IHUzMiA9IHUzMihjb2wpO1xuICAgICAgdmFyIHJvdzI6IHUzMiA9IHUzMihyb3cgKyAxKTtcbiAgICAgIHZhciBjb2wyOiB1MzIgPSB1MzIoY29sICsgMSk7XG4gICAgICB2YXIgY2hhbm5lbDogdTMyID0gJHtpbnB1dFNoYXBlLmxlbmd0aCA+IDIgPyBgdTMyKG9yaWdpbmFsSW5kaWNlc1ske2NoYW5uZWxJZHh9XSlgIDogJzAnfTtcbiAgICAgIHZhciBiYXRjaDogdTMyID0gICR7aW5wdXRTaGFwZS5sZW5ndGggPiAyID8gYHUzMihvcmlnaW5hbEluZGljZXNbJHtiYXRjaElkeH1dKWAgOiAnMCd9O1xuICAgICAgdmFyIHgxMTogJHtkVHlwZX0gPSBnZXRJbnB1dFZhbHVlKGJhdGNoLCBjaGFubmVsLCByb3cxLCBjb2wxKTtcbiAgICAgIHZhciB4MTI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgcm93MSwgY29sMik7XG4gICAgICB2YXIgeDIxOiAke2RUeXBlfSA9IGdldElucHV0VmFsdWUoYmF0Y2gsIGNoYW5uZWwsIHJvdzIsIGNvbDEpO1xuICAgICAgdmFyIHgyMjogJHtkVHlwZX0gPSBnZXRJbnB1dFZhbHVlKGJhdGNoLCBjaGFubmVsLCByb3cyLCBjb2wyKTtcbiAgICAgIHZhciBkeDE6ICR7ZFR5cGV9ID0gYWJzKHJvdyAtICR7ZFR5cGV9KHJvdzEpKTtcbiAgICAgIHZhciBkeDI6ICR7ZFR5cGV9ID0gYWJzKCR7ZFR5cGV9KHJvdzIpIC0gcm93KTtcbiAgICAgIHZhciBkeTE6ICR7ZFR5cGV9ID0gYWJzKGNvbCAtICR7ZFR5cGV9KGNvbDEpKTtcbiAgICAgIHZhciBkeTI6ICR7ZFR5cGV9ID0gYWJzKCR7ZFR5cGV9KGNvbDIpIC0gY29sKTtcbiAgICAgIGlmIChyb3cxID09IHJvdzIpIHtcbiAgICAgICAgZHgxID0gMC41O1xuICAgICAgICBkeDIgPSAwLjU7XG4gICAgICB9XG4gICAgICBpZiAoY29sMSA9PSBjb2wyKSB7XG4gICAgICAgIGR5MSA9IDAuNTtcbiAgICAgICAgZHkyID0gMC41O1xuICAgICAgfVxuICAgICAgcmV0dXJuICh4MTEgKiBkeDIgKiBkeTIgKyB4MTIgKiBkeDIgKiBkeTEgKyB4MjEgKiBkeDEgKiBkeTIgKyB4MjIgKiBkeDEgKiBkeTEpO1xuICAgIH1gO1xufTtcblxuY29uc3QgYmljdWJpY0ludGVycG9sYXRpb24gPSAoXG4gIGlucHV0OiBJbmRpY2VzSGVscGVyLFxuICBvdXRwdXQ6IEluZGljZXNIZWxwZXIsXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHNjYWxlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHJvaTogcmVhZG9ubHkgbnVtYmVyW10sXG4gIGN1YmljQ29lZmZBOiBudW1iZXIsXG4gIHVzZUV4dHJhcG9sYXRpb246IGJvb2xlYW4sXG4gIGV4dHJhcG9sYXRpb25WYWx1ZTogbnVtYmVyLFxuICBleGNsdWRlT3V0c2lkZTogYm9vbGVhbixcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGlzMkQgPSBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMjtcbiAgY29uc3QgaXNOY2h3ID0gdHJ1ZTtcbiAgY29uc3QgW2hlaWdodElkeCwgd2lkdGhJZHhdID0gaXMyRCA/IFswLCAxXSA6IGlzTmNodyA/IFsyLCAzXSA6IFsxLCAyXTtcbiAgY29uc3QgZFR5cGUgPSBpbnB1dC50eXBlLnZhbHVlO1xuICBjb25zdCBjcmVhdGVDdWJpY0ludGVycG9sYXRpb25GdW5jdGlvbiA9IChpZHg6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gaWR4ID09PSBoZWlnaHRJZHggPyAncm93JyA6ICdjb2wnO1xuICAgIHJldHVybiBgXG4gICAgICBmbiAke2RpcmVjdGlvbn1DdWJpY0ludGVycG9sYXRpb24oaW5wdXRfaW5kaWNlczogJHtpbnB1dC50eXBlLmluZGljZXN9LCBvdXRwdXRfaW5kaWNlczogJHtcbiAgICAgICAgb3V0cHV0LnR5cGUuaW5kaWNlc1xuICAgICAgfSkgLT4gJHtkVHlwZX0ge1xuICAgICAgICB2YXIgb3V0cHV0X2luZGV4ID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCBpZHgpfTtcbiAgICAgICAgdmFyIG9yaWdpbmFsSWR4OiAke2RUeXBlfSA9IGdldE9yaWdpbmFsQ29vcmRpbmF0ZUZyb21SZXNpemVkQ29vcmRpbmF0ZShvdXRwdXRfaW5kZXgsICR7c2NhbGVzW2lkeF19LFxuICAgICAgICAke291dHB1dFNoYXBlW2lkeF19LCAke2lucHV0U2hhcGVbaWR4XX0sICR7cm9pW2lkeF19LCAke3JvaVtpZHhdfSArICR7aW5wdXRTaGFwZS5sZW5ndGh9KTtcbiAgICAgICAgdmFyIGZyYWN0T3JpZ2luYWxJZHg6ICR7ZFR5cGV9ID0gb3JpZ2luYWxJZHggLSBmbG9vcihvcmlnaW5hbElkeCk7XG4gICAgICAgIHZhciBjb2VmcyA9IGdldEN1YmljSW50ZXJwb2xhdGlvbkNvZWZzKGZyYWN0T3JpZ2luYWxJZHgpO1xuXG4gICAgICAgIGlmICgke3VzZUV4dHJhcG9sYXRpb259ICYmIChvcmlnaW5hbElkeCA8IDAgfHwgb3JpZ2luYWxJZHggPiAoJHtpbnB1dFNoYXBlW2lkeF19IC0gMSkpKSB7XG4gICAgICAgICAgcmV0dXJuICR7ZXh0cmFwb2xhdGlvblZhbHVlfTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF0YTogYXJyYXk8JHtkVHlwZX0sIDQ+ID0gYXJyYXk8JHtkVHlwZX0sIDQ+KDAuMCwgMC4wLCAwLjAsIDAuMCk7XG4gICAgICAgIGZvciAodmFyIGk6IGkzMiA9IC0xOyBpIDwgMzsgaSsrKSB7XG4gICAgICAgICAgdmFyICR7ZGlyZWN0aW9ufTogJHtkVHlwZX0gPSBvcmlnaW5hbElkeCArICR7ZFR5cGV9KGkpO1xuICAgICAgICAgIGlmICgke2RpcmVjdGlvbn0gPCAwIHx8ICR7ZGlyZWN0aW9ufSA+PSAke2lucHV0U2hhcGVbaWR4XX0pIHtcbiAgICAgICAgICAgICR7KCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGV4Y2x1ZGVPdXRzaWRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBjb2Vmc1tpICsgMV0gPSAwLjA7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtgO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHVzZUV4dHJhcG9sYXRpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYHJldHVybiAke2V4dHJhcG9sYXRpb25WYWx1ZX07YDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7ZGlyZWN0aW9ufSA9IG1heCgwLCBtaW4oJHtkaXJlY3Rpb259LCAke2lucHV0U2hhcGVbaWR4XX0gLSAxKSk7YDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkoKX07XG4gICAgICAgICAgfVxuICAgICAgICB2YXIgaW5wdXRfaW5kaWNlc19jb3B5OiAke2lucHV0LnR5cGUuaW5kaWNlc30gPSBpbnB1dF9pbmRpY2VzO1xuICAgICAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlc19jb3B5JywgaWR4LCBgdTMyKCR7ZGlyZWN0aW9ufSlgKX07XG4gICAgICAgICAgZGF0YVtpICsgMV0gPSAke1xuICAgICAgICAgICAgaWR4ID09PSBoZWlnaHRJZHhcbiAgICAgICAgICAgICAgPyBpbnB1dC5nZXRCeUluZGljZXMoJ2lucHV0X2luZGljZXNfY29weScpXG4gICAgICAgICAgICAgIDogJ3Jvd0N1YmljSW50ZXJwb2xhdGlvbihpbnB1dF9pbmRpY2VzX2NvcHksIG91dHB1dF9pbmRpY2VzKSdcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjdWJpY0ludGVycG9sYXRpb24xRChkYXRhLCBjb2Vmcyk7XG4gICAgICB9YDtcbiAgfTtcblxuICByZXR1cm4gYFxuICAgICR7Y3JlYXRlQ3ViaWNJbnRlcnBvbGF0aW9uRnVuY3Rpb24oaGVpZ2h0SWR4KX07XG4gICAgJHtjcmVhdGVDdWJpY0ludGVycG9sYXRpb25GdW5jdGlvbih3aWR0aElkeCl9O1xuICBmbiBnZXRDdWJpY0ludGVycG9sYXRpb25Db2VmcyhzOiAke2RUeXBlfSkgLT4gYXJyYXk8JHtkVHlwZX0sIDQ+IHtcbiAgICB2YXIgYWJzUyA9IGFicyhzKTtcbiAgICB2YXIgY29lZmZzOiBhcnJheTwke2RUeXBlfSwgND4gPSBhcnJheTwke2RUeXBlfSwgND4oMC4wLCAwLjAsIDAuMCwgMC4wKTtcbiAgICB2YXIgb25lTWludXNBYnNTOiAke2RUeXBlfSA9IDEuMCAtIGFic1M7XG4gICAgdmFyIHR3b01pbnVzQWJzUzogJHtkVHlwZX0gPSAyLjAgLSBhYnNTO1xuICAgIHZhciBvbmVQbHVzQWJzUzogJHtkVHlwZX0gPSAxLjAgKyBhYnNTO1xuICAgIGNvZWZmc1swXSA9ICgoJHtjdWJpY0NvZWZmQX0gKiBvbmVQbHVzQWJzUyAtIDUgKiAke2N1YmljQ29lZmZBfSkgKiBvbmVQbHVzQWJzUyArIDggKiAke1xuICAgICAgY3ViaWNDb2VmZkFcbiAgICB9KSAqIG9uZVBsdXNBYnNTIC0gNCAqICR7Y3ViaWNDb2VmZkF9O1xuICAgIGNvZWZmc1sxXSA9ICgoJHtjdWJpY0NvZWZmQX0gKyAyKSAqIGFic1MgLSAoJHtjdWJpY0NvZWZmQX0gKyAzKSkgKiBhYnNTICogYWJzUyArIDE7XG4gICAgY29lZmZzWzJdID0gKCgke2N1YmljQ29lZmZBfSArIDIpICogb25lTWludXNBYnNTIC0gKCR7Y3ViaWNDb2VmZkF9ICsgMykpICogb25lTWludXNBYnNTICogb25lTWludXNBYnNTICsgMTtcbiAgICBjb2VmZnNbM10gPSAoKCR7Y3ViaWNDb2VmZkF9ICogdHdvTWludXNBYnNTIC0gNSAqICR7Y3ViaWNDb2VmZkF9KSAqIHR3b01pbnVzQWJzUyArIDggKiAke1xuICAgICAgY3ViaWNDb2VmZkFcbiAgICB9KSAqIHR3b01pbnVzQWJzUyAtIDQgKiAke2N1YmljQ29lZmZBfTtcbiAgICByZXR1cm4gY29lZmZzO1xuICB9XG5cbiAgZm4gY3ViaWNJbnRlcnBvbGF0aW9uMUQoeDogYXJyYXk8JHtkVHlwZX0sIDQ+LCBjb2VmczogYXJyYXk8JHtkVHlwZX0sIDQ+KSAtPiAke2RUeXBlfSB7XG4gICAgdmFyIGNvZWZzU3VtOiAke2RUeXBlfSA9IGNvZWZzWzBdICsgY29lZnNbMV0gKyBjb2Vmc1syXSArIGNvZWZzWzNdO1xuICAgIHJldHVybiAoeFswXSAqIGNvZWZzWzBdICsgeFsxXSAqIGNvZWZzWzFdKyB4WzJdICogY29lZnNbMl0rIHhbM10gKiBjb2Vmc1szXSkgLyBjb2Vmc1N1bTtcbiAgfVxuXG4gIGZuIGJpY3ViaWNJbnRlcnBvbGF0aW9uKG91dHB1dF9pbmRpY2VzOiAke291dHB1dC50eXBlLmluZGljZXN9KSAtPiAke2RUeXBlfSB7XG4gICAgdmFyIGlucHV0X2luZGljZXM6ICR7aW5wdXQudHlwZS5pbmRpY2VzfSA9IG91dHB1dF9pbmRpY2VzO1xuICAgIHJldHVybiBjb2xDdWJpY0ludGVycG9sYXRpb24oaW5wdXRfaW5kaWNlcywgb3V0cHV0X2luZGljZXMpO1xuICB9XG4gICAgYDtcbn07XG5cbmNvbnN0IHRyaWxpbmVhckludGVycG9sYXRpb24gPSAoXG4gIGlucHV0OiBJbmRpY2VzSGVscGVyLFxuICBvdXRwdXQ6IEluZGljZXNIZWxwZXIsXG4gIGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICB1c2VFeHRyYXBvbGF0aW9uOiBib29sZWFuLFxuICBleHRyYXBvbGF0aW9uVmFsdWU6IG51bWJlcixcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGlzTmNodyA9IHRydWU7XG4gIGNvbnN0IFtiYXRjaElkeCwgZGVwdGhJZHgsIGhlaWdodElkeCwgd2lkdGhJZHgsIGNoYW5uZWxJZHhdID1cbiAgICBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMyA/IFstMSwgMCwgMSwgMiwgLTFdIDogaXNOY2h3ID8gWzAsIDIsIDMsIDQsIDFdIDogWzAsIDEsIDIsIDMsIDRdO1xuICBjb25zdCBkVHlwZSA9IGlucHV0LnR5cGUudmFsdWU7XG4gIHJldHVybiBgXG4gICAgZm4gZ2V0SW5wdXRWYWx1ZShiYXRjaDogdTMyLCBjaGFubmVsOiB1MzIsIGRlcHRoOnUzMiwgaGVpZ2h0OiB1MzIsIHdpZHRoOiB1MzIpIC0+ICR7ZFR5cGV9IHtcbiAgICAgIHZhciBpbnB1dF9pbmRpY2VzOiAke2lucHV0LnR5cGUuaW5kaWNlc307XG4gICAgICAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0X2luZGljZXMnLCBkZXB0aElkeCwgYG1heCgwLCBtaW4oZGVwdGgsICR7aW5wdXRTaGFwZVtkZXB0aElkeF19IC0gMSkpYCl9O1xuICAgICAgJHtpbnB1dC5pbmRpY2VzU2V0KCdpbnB1dF9pbmRpY2VzJywgaGVpZ2h0SWR4LCBgbWF4KDAsIG1pbihoZWlnaHQsICR7aW5wdXRTaGFwZVtoZWlnaHRJZHhdfSAtIDEpKWApfTtcbiAgICAgICR7aW5wdXQuaW5kaWNlc1NldCgnaW5wdXRfaW5kaWNlcycsIHdpZHRoSWR4LCBgbWF4KDAsIG1pbih3aWR0aCwgJHtpbnB1dFNoYXBlW3dpZHRoSWR4XX0gLSAxKSlgKX07XG4gICAgICAke3NldENoYW5uZWxBbmRCYXRjaEluZGljZXMoaW5wdXQsIGNoYW5uZWxJZHgsIGJhdGNoSWR4LCAzKX1cbiAgICAgIHJldHVybiAke2lucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpfTtcbiAgICB9XG5cbiAgICBmbiB0cmlsaW5lYXJJbnRlcnBvbGF0aW9uKG91dHB1dF9pbmRpY2VzOiAke291dHB1dC50eXBlLmluZGljZXN9KSAtPiAke2RUeXBlfSB7XG4gICAgICB2YXIgb3JpZ2luYWxJbmRpY2VzID0gY2FsY3VsYXRlT3JpZ2luYWxJbmRpY2VzRnJvbU91dHB1dEluZGljZXMob3V0cHV0X2luZGljZXMpO1xuICAgICAgdmFyIGRlcHRoOiR7ZFR5cGV9ID0gb3JpZ2luYWxJbmRpY2VzWyR7ZGVwdGhJZHh9XTtcbiAgICAgIHZhciBoZWlnaHQ6JHtkVHlwZX0gPSBvcmlnaW5hbEluZGljZXNbJHtoZWlnaHRJZHh9XTtcbiAgICAgIHZhciB3aWR0aDoke2RUeXBlfSA9IG9yaWdpbmFsSW5kaWNlc1ske3dpZHRoSWR4fV07XG4gICAgICAke1xuICAgICAgICB1c2VFeHRyYXBvbGF0aW9uXG4gICAgICAgICAgPyBgaWYgKGRlcHRoIDwgMCB8fCBkZXB0aCA+ICgke2lucHV0U2hhcGVbZGVwdGhJZHhdfSAtIDEpIHx8IGhlaWdodCA8IDAgfHwgaGVpZ2h0ID4gKCR7XG4gICAgICAgICAgICAgIGlucHV0U2hhcGVbaGVpZ2h0SWR4XVxuICAgICAgICAgICAgfSAtIDEpIHx8IHdpZHRoIDwgMCB8fCAod2lkdGggPiAke2lucHV0U2hhcGVbd2lkdGhJZHhdfSAtIDEpKSB7XG4gICAgICByZXR1cm4gJHtleHRyYXBvbGF0aW9uVmFsdWV9O1xuICAgICAgICB9YFxuICAgICAgICAgIDogJydcbiAgICAgIH07XG5cbiAgICBkZXB0aCA9IG1heCgwLCBtaW4oZGVwdGgsICR7aW5wdXRTaGFwZVtkZXB0aElkeF19IC0gMSkpO1xuICAgICAgaGVpZ2h0ID0gbWF4KDAsIG1pbihoZWlnaHQsICR7aW5wdXRTaGFwZVtoZWlnaHRJZHhdfSAtIDEpKTtcbiAgICAgIHdpZHRoID0gbWF4KDAsIG1pbih3aWR0aCwgJHtpbnB1dFNoYXBlW3dpZHRoSWR4XX0gLSAxKSk7XG4gICAgICB2YXIgZGVwdGgxOiB1MzIgPSB1MzIoZGVwdGgpO1xuICAgICAgdmFyIGhlaWdodDE6IHUzMiA9IHUzMihoZWlnaHQpO1xuICAgICAgdmFyIHdpZHRoMTogdTMyID0gdTMyKHdpZHRoKTtcbiAgICAgIHZhciBkZXB0aDI6IHUzMiA9IHUzMihkZXB0aCArIDEpO1xuICAgICAgdmFyIGhlaWdodDI6IHUzMiA9IHUzMihoZWlnaHQgKyAxKTtcbiAgICAgIHZhciB3aWR0aDI6IHUzMiA9IHUzMih3aWR0aCArIDEpO1xuICAgICAgdmFyIGNoYW5uZWw6IHUzMiA9ICR7aW5wdXRTaGFwZS5sZW5ndGggPiAzID8gYHUzMihvcmlnaW5hbEluZGljZXNbJHtjaGFubmVsSWR4fV0pYCA6ICcwJ307XG4gICAgICB2YXIgYmF0Y2g6IHUzMiA9ICAke2lucHV0U2hhcGUubGVuZ3RoID4gMyA/IGB1MzIob3JpZ2luYWxJbmRpY2VzWyR7YmF0Y2hJZHh9XSlgIDogJzAnfTtcblxuICAgICAgdmFyIHgxMTE6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgxLCBoZWlnaHQxLCB3aWR0aDEpO1xuICAgICAgdmFyIHgxMTI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgxLCBoZWlnaHQxLCB3aWR0aDIpO1xuICAgICAgdmFyIHgxMjE6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgxLCBoZWlnaHQyLCB3aWR0aDEpO1xuICAgICAgdmFyIHgxMjI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgxLCBoZWlnaHQyLCB3aWR0aDIpO1xuICAgICAgdmFyIHgyMTE6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgyLCBoZWlnaHQxLCB3aWR0aDEpO1xuICAgICAgdmFyIHgyMTI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgyLCBoZWlnaHQxLCB3aWR0aDIpO1xuICAgICAgdmFyIHgyMjE6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgyLCBoZWlnaHQyLCB3aWR0aDEpO1xuICAgICAgdmFyIHgyMjI6ICR7ZFR5cGV9ID0gZ2V0SW5wdXRWYWx1ZShiYXRjaCwgY2hhbm5lbCwgZGVwdGgyLCBoZWlnaHQyLCB3aWR0aDIpO1xuICAgICAgdmFyIGR4MTogJHtkVHlwZX0gPSBhYnMoZGVwdGggLSAke2RUeXBlfShkZXB0aDEpKTtcbiAgICAgIHZhciBkeDI6ICR7ZFR5cGV9ID0gYWJzKCR7ZFR5cGV9KGRlcHRoMikgLSBkZXB0aCk7XG4gICAgICB2YXIgZHkxOiAke2RUeXBlfSA9IGFicyhoZWlnaHQgLSAke2RUeXBlfShoZWlnaHQxKSk7XG4gICAgICB2YXIgZHkyOiAke2RUeXBlfSA9IGFicygke2RUeXBlfShoZWlnaHQyKSAtIGhlaWdodCk7XG4gICAgICB2YXIgZHoxOiAke2RUeXBlfSA9IGFicyh3aWR0aCAtICR7ZFR5cGV9KHdpZHRoMSkpO1xuICAgICAgdmFyIGR6MjogJHtkVHlwZX0gPSBhYnMoJHtkVHlwZX0od2lkdGgyKSAtIHdpZHRoKTtcbiAgICAgIGlmIChkZXB0aDEgPT0gZGVwdGgyKSB7XG4gICAgICAgIGR4MSA9IDAuNTtcbiAgICAgICAgZHgyID0gMC41O1xuICAgICAgfVxuICAgICAgaWYgKGhlaWdodDEgPT0gaGVpZ2h0Mikge1xuICAgICAgICBkeTEgPSAwLjU7XG4gICAgICAgIGR5MiA9IDAuNTtcbiAgICAgIH1cbiAgICAgIGlmICh3aWR0aDEgPT0gd2lkdGgyKSB7XG4gICAgICAgIGR6MSA9IDAuNTtcbiAgICAgICAgZHoyID0gMC41O1xuICAgICAgfVxuICAgICAgcmV0dXJuICh4MTExICogZHgyICogZHkyICogZHoyICsgeDExMiAqIGR4MiAqIGR5MiAqIGR6MSArIHgxMjEgKiBkeDIgKiBkeTEgKmR6MiArIHgxMjIgKiBkeDIgKiBkeTEgKiBkejEgK1xuICAgICAgICAgICAgICB4MjExICogZHgxICogZHkyICogZHoyICsgeDIxMiAqIGR4MSAqIGR5MiAqIGR6MSArIHgyMjEgKiBkeDEgKiBkeTEgKmR6MiArIHgyMjIgKiBkeDEgKiBkeTEgKiBkejEpO1xuICAgIH1gO1xufTtcblxuY29uc3QgY3JlYXRlUmVzaXplUHJvZ3JhbUluZm8gPSAoXG4gIGlucHV0VGVuc29yOiBUZW5zb3JWaWV3LFxuICBhdHRyaWJ1dGVzOiBSZXNpemVBdHRyaWJ1dGVzLFxuICBvcHNldFZlcnNpb246IG51bWJlcixcbiAgc2NhbGVzSW5wdXQ6IHJlYWRvbmx5IG51bWJlcltdLFxuICBzaXplczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHJvaUlucHV0OiByZWFkb25seSBudW1iZXJbXSxcbik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0VGVuc29yLmRpbXM7XG4gIGNvbnN0IHJvaSA9IHVwZGF0ZVJvSShyb2lJbnB1dCwgYXR0cmlidXRlcy5heGVzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG5cbiAgbGV0IG91dHB1dFNoYXBlID0gaW5pdE91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHNjYWxlc0lucHV0LCBzaXplcywgYXR0cmlidXRlcy5heGVzKTtcbiAgbGV0IHNjYWxlcyA9IHNjYWxlc0lucHV0LnNsaWNlKCk7XG4gIGlmIChzY2FsZXNJbnB1dC5sZW5ndGggPT09IDApIHtcbiAgICBzY2FsZXMgPSBpbnB1dFNoYXBlLm1hcCgodmFsdWUsIGluZGV4KSA9PiAodmFsdWUgPT09IDAgPyAxLjAgOiBvdXRwdXRTaGFwZVtpbmRleF0gLyB2YWx1ZSkpO1xuICAgIGlmIChhdHRyaWJ1dGVzLmtlZXBBc3BlY3RSYXRpb1BvbGljeSAhPT0gJ3N0cmV0Y2gnKSB7XG4gICAgICBvdXRwdXRTaGFwZSA9IGFkanVzdE91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHNjYWxlcywgYXR0cmlidXRlcyk7XG4gICAgfVxuICB9XG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dFRlbnNvci5kYXRhVHlwZSwgb3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgaW5wdXQgPSBpbnB1dFZhcmlhYmxlKCdpbnB1dCcsIGlucHV0VGVuc29yLmRhdGFUeXBlLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gIGNvbnN0IG5vU2NhbGUgPSBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gb3V0cHV0U2hhcGUubGVuZ3RoICYmIGlucHV0U2hhcGUuZXZlcnkoKGQsIGkpID0+IGQgPT09IG91dHB1dFNoYXBlW2ldKTtcbiAgY29uc3QgdXNlRXh0cmFwb2xhdGlvbiA9IGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnO1xuICBjb25zdCBleHRyYXBvbGF0aW9uVmFsdWUgPSBhdHRyaWJ1dGVzLmV4dHJhcG9sYXRpb25WYWx1ZTtcbiAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dC50eXBlLnZhbHVlO1xuICBjb25zdCBnZXRTaGFkZXJTb3VyY2UgPSAoc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIpID0+IGBcbiAgICAgICR7XG4gICAgICAgIG5vU2NhbGVcbiAgICAgICAgICA/ICcnXG4gICAgICAgICAgOiBgXG4gICAgICAke2dldE9yaWdpbmFsQ29vcmRpbmF0ZUZyb21SZXNpemVkQ29vcmRpbmF0ZShhdHRyaWJ1dGVzLmNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlLCBkYXRhVHlwZSl9O1xuICAgICAgJHsoKCkgPT4ge1xuICAgICAgICBzd2l0Y2ggKGF0dHJpYnV0ZXMubW9kZSkge1xuICAgICAgICAgIGNhc2UgJ25lYXJlc3QnOlxuICAgICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgJHtjaGVja0lucHV0SW5kaWNlcyhpbnB1dCwgaW5wdXRTaGFwZSl9O1xuICAgICAgICAgICAgICAke2dldE5lYXJlc3RQaXhlbEZyb21PcmlnaW5hbChhdHRyaWJ1dGVzLm5lYXJlc3RNb2RlLCBvcHNldFZlcnNpb24sIGRhdGFUeXBlKX07XG4gICAgICAgICAgICAgICR7Y2FsY3VsYXRlSW5wdXRJbmRpY2VzRnJvbU91dHB1dEluZGljZXMoXG4gICAgICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICAgICAgb3V0cHV0LFxuICAgICAgICAgICAgICAgIGlucHV0U2hhcGUsXG4gICAgICAgICAgICAgICAgb3V0cHV0U2hhcGUsXG4gICAgICAgICAgICAgICAgc2NhbGVzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICByb2kubGVuZ3RoLFxuICAgICAgICAgICAgICAgIHVzZUV4dHJhcG9sYXRpb24sXG4gICAgICAgICAgICAgICl9O1xuICAgICAgICAgICAgICBgO1xuICAgICAgICAgIGNhc2UgJ2xpbmVhcic6XG4gICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAke2NhbGN1bGF0ZU9yaWdpbmFsSW5kaWNlc0Zyb21PdXRwdXRJbmRpY2VzKG91dHB1dCwgaW5wdXRTaGFwZSwgb3V0cHV0U2hhcGUsIHNjYWxlcy5sZW5ndGgsIHJvaS5sZW5ndGgpfTtcbiAgICAgICAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMiB8fCBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gNCkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke2JpbGluZWFySW50ZXJwb2xhdGlvbihpbnB1dCwgb3V0cHV0LCBpbnB1dFNoYXBlLCB1c2VFeHRyYXBvbGF0aW9uLCBleHRyYXBvbGF0aW9uVmFsdWUpfWA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMyB8fCBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gNSkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke3RyaWxpbmVhckludGVycG9sYXRpb24oaW5wdXQsIG91dHB1dCwgaW5wdXRTaGFwZSwgdXNlRXh0cmFwb2xhdGlvbiwgZXh0cmFwb2xhdGlvblZhbHVlKX1gO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignTGluZWFyIG1vZGUgb25seSBzdXBwb3J0cyBpbnB1dCBkaW1zIDIsIDMsIDQgYW5kIDUgYXJlIHN1cHBvcnRlZCBpbiBsaW5lYXIgbW9kZS4nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pKCl9O1xuICAgICAgICAgICAgYDtcbiAgICAgICAgICBjYXNlICdjdWJpYyc6XG4gICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgJHsoKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoaW5wdXRTaGFwZS5sZW5ndGggPT09IDIgfHwgaW5wdXRTaGFwZS5sZW5ndGggPT09IDQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7YmljdWJpY0ludGVycG9sYXRpb24oXG4gICAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICAgIG91dHB1dCxcbiAgICAgICAgICAgICAgICAgIGlucHV0U2hhcGUsXG4gICAgICAgICAgICAgICAgICBvdXRwdXRTaGFwZSxcbiAgICAgICAgICAgICAgICAgIHNjYWxlcyxcbiAgICAgICAgICAgICAgICAgIHJvaSxcbiAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMuY3ViaWNDb2VmZkEsXG4gICAgICAgICAgICAgICAgICB1c2VFeHRyYXBvbGF0aW9uLFxuICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5leHRyYXBvbGF0aW9uVmFsdWUsXG4gICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmV4Y2x1ZGVPdXRzaWRlLFxuICAgICAgICAgICAgICAgICl9YDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignQ3ViaWMgbW9kZSBvbmx5IHN1cHBvcnRzIGlucHV0IGRpbXMgMiBhbmQgNCBhcmUgc3VwcG9ydGVkIGluIGxpbmVhciBtb2RlLicpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSgpfTtcbiAgICAgICAgICAgIGA7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIHJlc2l6ZSBtb2RlJyk7XG4gICAgICAgIH1cbiAgICAgIH0pKCl9O1xuICAgICAgYFxuICAgICAgfVxuICAgICAgJHtzaGFkZXJIZWxwZXJcbiAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnb3V0cHV0X3NpemUnLCAndTMyJylcbiAgICAgICAgLnJlZ2lzdGVyVW5pZm9ybSgnc2NhbGVzJywgJ2YzMicsIHNjYWxlcy5sZW5ndGgpXG4gICAgICAgIC5yZWdpc3RlclVuaWZvcm0oJ3JvaScsICdmMzInLCByb2kubGVuZ3RoKVxuICAgICAgICAuZGVjbGFyZVZhcmlhYmxlcyhpbnB1dCwgb3V0cHV0KX1cbiAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRfc2l6ZScpfVxuICAgICAgICAke1xuICAgICAgICAgIG5vU2NhbGVcbiAgICAgICAgICAgID8gJ291dHB1dFtnbG9iYWxfaWR4XSA9IGlucHV0W2dsb2JhbF9pZHhdOydcbiAgICAgICAgICAgIDogYFxuICAgICAgICBsZXQgb3V0cHV0X2luZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICAgIHZhciBpbnB1dF9pbmRpY2VzOiAke2lucHV0LnR5cGUuaW5kaWNlc307XG4gICAgICAgICR7KCgpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGF0dHJpYnV0ZXMubW9kZSkge1xuICAgICAgICAgICAgY2FzZSAnbmVhcmVzdCc6XG4gICAgICAgICAgICAgIHJldHVybiBgaW5wdXRfaW5kaWNlcyA9IGNhbGN1bGF0ZUlucHV0SW5kaWNlc0Zyb21PdXRwdXRJbmRpY2VzKG91dHB1dF9pbmRpY2VzKTtcbiAgICAgICAgICAgICAgICBpZiAoY2hlY2tJbnB1dEluZGljZXMoaW5wdXRfaW5kaWNlcykpIHtcbiAgICAgICAgICAgICAgICAgIG91dHB1dFtnbG9iYWxfaWR4XSA9ICR7aW5wdXQuZ2V0QnlJbmRpY2VzKCdpbnB1dF9pbmRpY2VzJyl9O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbZ2xvYmFsX2lkeF0gPSAke2F0dHJpYnV0ZXMuZXh0cmFwb2xhdGlvblZhbHVlfTtcbiAgICAgICAgICAgICAgICB9YDtcbiAgICAgICAgICAgIGNhc2UgJ2xpbmVhcic6XG4gICAgICAgICAgICAgIHJldHVybiBgb3V0cHV0W2dsb2JhbF9pZHhdID0gJHtcbiAgICAgICAgICAgICAgICBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gMiB8fCBpbnB1dFNoYXBlLmxlbmd0aCA9PT0gNCA/ICdiaWxpbmVhckludGVycG9sYXRpb24nIDogJ3RyaWxpbmVhckludGVycG9sYXRpb24nXG4gICAgICAgICAgICAgIH0ob3V0cHV0X2luZGljZXMpO2A7XG4gICAgICAgICAgICBjYXNlICdjdWJpYyc6XG4gICAgICAgICAgICAgIHJldHVybiAnb3V0cHV0W2dsb2JhbF9pZHhdID0gYmljdWJpY0ludGVycG9sYXRpb24ob3V0cHV0X2luZGljZXMpOyc7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICB0aHJvdyBFcnJvcihgVW5zdXBwb3J0ZWQgcmVzaXplIG1vZGU6ICR7YXR0cmlidXRlcy5tb2RlfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKX07XG5gXG4gICAgICAgIH1cbiAgICAgIH1gO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ1Jlc2l6ZScsXG4gICAgc2hhZGVyQ2FjaGU6IHtcbiAgICAgIGhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9fCR7b3BzZXRWZXJzaW9ufXwke1xuICAgICAgICBzY2FsZXMubGVuZ3RoID4gMCA/IChhdHRyaWJ1dGVzLm1vZGUgPT09ICdjdWJpYycgPyBzY2FsZXMgOiBzY2FsZXMubGVuZ3RoKSA6ICcnXG4gICAgICB9fCR7c2l6ZXMubGVuZ3RoID4gMCA/IHNpemVzIDogJyd9fCR7cm9pLmxlbmd0aCA+IDAgPyByb2kgOiAnJ318JHtub1NjYWxlfXwke1xuICAgICAgICBhdHRyaWJ1dGVzLm1vZGUgPT09ICduZWFyZXN0JyA/IGlucHV0U2hhcGUubGVuZ3RoIDogaW5wdXRTaGFwZVxuICAgICAgfWAsXG4gICAgICBpbnB1dERlcGVuZGVuY2llczogWydyYW5rJ10sXG4gICAgfSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gICAgZ2V0UnVuRGF0YTogKCkgPT4gKHtcbiAgICAgIG91dHB1dHM6IFt7IGRpbXM6IG91dHB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRUZW5zb3IuZGF0YVR5cGUgfV0sXG4gICAgICBkaXNwYXRjaEdyb3VwOiB7IHg6IE1hdGguY2VpbChvdXRwdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXM6IFtcbiAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS5mbG9hdCwgZGF0YTogc2NhbGVzIH0sXG4gICAgICAgIHsgdHlwZTogRGF0YVR5cGUuZmxvYXQsIGRhdGE6IHJvaSB9LFxuICAgICAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dFNoYXBlLCBvdXRwdXRTaGFwZSksXG4gICAgICBdLFxuICAgIH0pLFxuICB9O1xufTtcblxuY29uc3QgZ2V0T3BzZXRWZXJzaW9uRnJvbUN1c3RvbURhdGFCdWZmZXIgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQpOiBudW1iZXIgPT4ge1xuICBjb25zdCBjdXN0b21EYXRhQnVmZmVyID0gY29udGV4dC5jdXN0b21EYXRhQnVmZmVyO1xuICBjb25zdCBjdXN0b21EYXRhQnVmZmVyMzIgPSBuZXcgVWludDMyQXJyYXkoY3VzdG9tRGF0YUJ1ZmZlciwgY3VzdG9tRGF0YUJ1ZmZlci5ieXRlT2Zmc2V0LCAxKTtcbiAgY29uc3Qgb3BzZXRWZXJzaW9uID0gY3VzdG9tRGF0YUJ1ZmZlcjMyWzBdO1xuICByZXR1cm4gb3BzZXRWZXJzaW9uO1xufTtcblxuZXhwb3J0IGNvbnN0IHJlc2l6ZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogUmVzaXplQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBjb25zdCBzY2FsZXM6IG51bWJlcltdID0gW107XG4gIGNvbnN0IHNpemVzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCByb2k6IG51bWJlcltdID0gW107XG5cbiAgLy8gTm90ZSB0aGF0IHNjYWxlcyBpbiByZXNpemUgYXJlIGFsd2F5cyBmMzIuIHJvaSBjYW4gYmUgZjMyIG9yIGYxNi5cbiAgLy8gVE9ETzogQ3VycmVudGx5IHRoaXMgY29kZSBkb2VzIG5vdCBzdXBwb3J0IGYxNiBmb3Igcm9pIHdoZW4gcGFzc2VkIGFzIG9wdGlvbmFsIGlucHV0LlxuXG4gIGNvbnN0IG9wc2V0VmVyc2lvbiA9IGdldE9wc2V0VmVyc2lvbkZyb21DdXN0b21EYXRhQnVmZmVyKGNvbnRleHQpO1xuICBpZiAoYXR0cmlidXRlcy5hbnRpYWxpYXMgIT09IDApIHtcbiAgICB0aHJvdyBFcnJvcignT25seSBkZWZhdWx0IHZhbHVlICgwKSBmb3IgQW50aWFsaWFzIGF0dHJpYnV0ZSBpcyBzdXBwb3J0ZWQnKTtcbiAgfVxuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcywgb3BzZXRWZXJzaW9uLCBzY2FsZXMsIHNpemVzLCByb2kpO1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlUmVzaXplUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHNbMF0sIGF0dHJpYnV0ZXMsIG9wc2V0VmVyc2lvbiwgc2NhbGVzLCBzaXplcywgcm9pKSwge1xuICAgIGlucHV0czogWzBdLFxuICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZXNpemVBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYW50aWFsaWFzID0gYXR0cmlidXRlcy5hbnRpYWxpYXMgYXMgbnVtYmVyO1xuICBjb25zdCBheGVzID0gYXR0cmlidXRlcy5heGVzIGFzIG51bWJlcltdO1xuICBjb25zdCBjb29yZGluYXRlVHJhbnNmb3JtTW9kZTogQ29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPVxuICAgIGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgYXMgQ29vcmRpbmF0ZVRyYW5zZm9ybU1vZGU7XG4gIGNvbnN0IGN1YmljQ29lZmZBID0gYXR0cmlidXRlcy5jdWJpY0NvZWZmQSBhcyBudW1iZXI7XG4gIGNvbnN0IGV4Y2x1ZGVPdXRzaWRlID0gKGF0dHJpYnV0ZXMuZXhjbHVkZU91dHNpZGUgYXMgbnVtYmVyKSAhPT0gMDtcbiAgY29uc3QgZXh0cmFwb2xhdGlvblZhbHVlID0gYXR0cmlidXRlcy5leHRyYXBvbGF0aW9uVmFsdWUgYXMgbnVtYmVyO1xuICBjb25zdCBrZWVwQXNwZWN0UmF0aW9Qb2xpY3k6IEtlZXBBc3BlY3RSYXRpb1BvbGljeSA9IGF0dHJpYnV0ZXMua2VlcEFzcGVjdFJhdGlvUG9saWN5IGFzIEtlZXBBc3BlY3RSYXRpb1BvbGljeTtcbiAgY29uc3QgbW9kZTogTW9kZSA9IGF0dHJpYnV0ZXMubW9kZSBhcyBNb2RlO1xuICAvLyBJZiBuZWFyZXN0TW9kZSBpcyBub3Qgc3BlY2lmaWVkLCB1c2Ugc2ltcGxlIG1vZGUuXG4gIGNvbnN0IG5lYXJlc3RNb2RlOiBOZWFyZXN0TW9kZSA9IChhdHRyaWJ1dGVzLm5lYXJlc3RNb2RlID09PSAnJyA/ICdzaW1wbGUnIDogYXR0cmlidXRlcy5uZWFyZXN0TW9kZSkgYXMgTmVhcmVzdE1vZGU7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe1xuICAgIGFudGlhbGlhcyxcbiAgICBheGVzLFxuICAgIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlLFxuICAgIGN1YmljQ29lZmZBLFxuICAgIGV4Y2x1ZGVPdXRzaWRlLFxuICAgIGV4dHJhcG9sYXRpb25WYWx1ZSxcbiAgICBrZWVwQXNwZWN0UmF0aW9Qb2xpY3ksXG4gICAgbW9kZSxcbiAgICBuZWFyZXN0TW9kZSxcbiAgfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNhc3RUb0YzMixcbiAgZ2V0TWF4Q29tcG9uZW50cyxcbiAgaW5wdXRWYXJpYWJsZSxcbiAgb3V0cHV0VmFyaWFibGUsXG4gIFNoYWRlckhlbHBlcixcbiAgc3VtVmVjdG9yLFxuICB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2tpcExheWVyTm9ybUF0dHJpYnV0ZXMge1xuICBzaW1wbGlmaWVkOiBib29sZWFuO1xuICBlcHNpbG9uOiBudW1iZXI7XG59XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdsYXllck5vcm0gcmVxdWlyZXMgYXQgbGVhc3QgMyBpbnB1dHMuJyk7XG4gIH1cblxuICBjb25zdCBpbnB1dDogVGVuc29yVmlldyA9IGlucHV0c1swXTtcbiAgY29uc3Qgc2tpcDogVGVuc29yVmlldyA9IGlucHV0c1sxXTtcbiAgY29uc3QgZ2FtbWE6IFRlbnNvclZpZXcgPSBpbnB1dHNbMl07XG5cbiAgaWYgKGlucHV0LmRhdGFUeXBlICE9PSBza2lwLmRhdGFUeXBlIHx8IGlucHV0LmRhdGFUeXBlICE9PSBnYW1tYS5kYXRhVHlwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQWxsIGlucHV0cyBtdXN0IGhhdmUgdGhlIHNhbWUgZGF0YSB0eXBlJyk7XG4gIH1cblxuICBpZiAoaW5wdXQuZGltcy5sZW5ndGggIT09IDMgJiYgaW5wdXQuZGltcy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IG11c3QgYmUgMkQgb3IgM0QnKTtcbiAgfVxuXG4gIGlmIChza2lwLmRpbXMubGVuZ3RoICE9PSAzICYmIHNraXAuZGltcy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NraXAgbXVzdCBiZSAyRCBvciAzRCcpO1xuICB9XG5cbiAgY29uc3QgaGlkZGVuU2l6ZSA9IGlucHV0LmRpbXNbaW5wdXQuZGltcy5sZW5ndGggLSAxXTtcbiAgY29uc3Qgc2VxdWVuY2VMZW5ndGggPSBpbnB1dC5kaW1zW2lucHV0LmRpbXMubGVuZ3RoIC0gMl07XG4gIGlmIChza2lwLmRpbXNbc2tpcC5kaW1zLmxlbmd0aCAtIDFdICE9PSBoaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTa2lwIG11c3QgaGF2ZSB0aGUgc2FtZSBoaWRkZW4gc2l6ZSBhcyBpbnB1dCcpO1xuICB9XG4gIGlmIChza2lwLmRpbXNbc2tpcC5kaW1zLmxlbmd0aCAtIDJdICE9PSBzZXF1ZW5jZUxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2tpcCBtdXN0IGhhdmUgdGhlIHNhbWUgc2VxdWVuY2UgbGVuZ3RoIGFzIGlucHV0Jyk7XG4gIH1cblxuICBpZiAoZ2FtbWEuZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dhbW1hIG11c3QgYmUgMUQnKTtcbiAgfVxuICBpZiAoZ2FtbWEuZGltc1tnYW1tYS5kaW1zLmxlbmd0aCAtIDFdICE9PSBoaWRkZW5TaXplKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdHYW1tYSBtdXN0IGhhdmUgdGhlIHNhbWUgaGlkZGVuIHNpemUgYXMgaW5wdXQnKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+IDMpIHtcbiAgICBjb25zdCBiZXRhOiBUZW5zb3JWaWV3ID0gaW5wdXRzWzNdO1xuICAgIGlmIChiZXRhLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JldGEgbXVzdCBiZSAxRCcpO1xuICAgIH1cbiAgICBpZiAoYmV0YS5kaW1zW2JldGEuZGltcy5sZW5ndGggLSAxXSAhPT0gaGlkZGVuU2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCZXRhIG11c3QgaGF2ZSB0aGUgc2FtZSBoaWRkZW4gc2l6ZSBhcyBpbnB1dCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+IDQpIHtcbiAgICBjb25zdCBiaWFzOiBUZW5zb3JWaWV3ID0gaW5wdXRzWzRdO1xuICAgIGlmIChiaWFzLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JpYXMgbXVzdCBiZSAxRCcpO1xuICAgIH1cbiAgICBpZiAoYmlhcy5kaW1zW2JpYXMuZGltcy5sZW5ndGggLSAxXSAhPT0gaGlkZGVuU2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCaWFzIG11c3QgaGF2ZSB0aGUgc2FtZSBoaWRkZW4gc2l6ZSBhcyBpbnB1dCcpO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgY3JlYXRlU2tpcExheWVyTm9ybVByb2dyYW1JbmZvID0gKFxuICBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgYXR0cmlidXRlczogU2tpcExheWVyTm9ybUF0dHJpYnV0ZXMsXG4gIG91dHB1dENvdW50OiBudW1iZXIsXG4gIGlzVHJhaW5pbmc6IGJvb2xlYW4sXG4pOiBQcm9ncmFtSW5mbyA9PiB7XG4gIGNvbnN0IHNpbXBsaWZpZWQgPSBhdHRyaWJ1dGVzLnNpbXBsaWZpZWQ7XG5cbiAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbnB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShpbnB1dFNoYXBlKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlO1xuICBjb25zdCBvdXRwdXRTaXplID0gaW5wdXRTaXplO1xuICBjb25zdCBoaWRkZW5TaXplID0gaW5wdXRTaGFwZS5zbGljZSgtMSlbMF07XG4gIGNvbnN0IG1lYW5JbnZTdGREZXZEaW0gPSBpc1RyYWluaW5nID8gaW5wdXRTaGFwZS5zbGljZSgwLCAtMSkuY29uY2F0KDEpIDogW107XG4gIGNvbnN0IGhhc0JldGFJbnB1dCA9ICFzaW1wbGlmaWVkICYmIGlucHV0cy5sZW5ndGggPiAzO1xuICBjb25zdCBoYXNCaWFzSW5wdXQgPSBpbnB1dHMubGVuZ3RoID4gNDtcbiAgY29uc3QgaGFzTWVhbk91dHB1dCA9IGlzVHJhaW5pbmcgJiYgb3V0cHV0Q291bnQgPiAxO1xuICBjb25zdCBoYXNJbnZTdGREZXZPdXRwdXQgPSBpc1RyYWluaW5nICYmIG91dHB1dENvdW50ID4gMjtcbiAgY29uc3QgaGFzSW5wdXRTa2lwQmlhc1N1bU91dHB1dCA9IG91dHB1dENvdW50ID4gMztcbiAgY29uc3Qgd29ya2dyb3VwU2l6ZSA9IDY0O1xuXG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKGhpZGRlblNpemUpO1xuXG4gIGNvbnN0IHByb2dyYW1Vbmlmb3JtczogUHJvZ3JhbVVuaWZvcm1bXSA9IFtcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgIHsgdHlwZTogRGF0YVR5cGUudWludDMyLCBkYXRhOiBjb21wb25lbnRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IGhpZGRlblNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLmZsb2F0LCBkYXRhOiBhdHRyaWJ1dGVzLmVwc2lsb24gfSxcbiAgXTtcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiB7XG4gICAgY29uc3QgdW5pZm9ybXNBcnJheTogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgICB7IG5hbWU6ICdvdXRwdXRfc2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgICB7IG5hbWU6ICdjb21wb25lbnRzJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2hpZGRlbl9zaXplJywgdHlwZTogJ3UzMicgfSxcbiAgICAgIHsgbmFtZTogJ2Vwc2lsb24nLCB0eXBlOiAnZjMyJyB9LFxuICAgIF07XG4gICAgY29uc3QgdmFyaWFibGVzID0gW1xuICAgICAgaW5wdXRWYXJpYWJsZSgneCcsIGlucHV0c1swXS5kYXRhVHlwZSwgaW5wdXRzWzBdLmRpbXMsIGNvbXBvbmVudHMpLFxuICAgICAgaW5wdXRWYXJpYWJsZSgnc2tpcCcsIGlucHV0c1sxXS5kYXRhVHlwZSwgaW5wdXRzWzFdLmRpbXMsIGNvbXBvbmVudHMpLFxuICAgICAgaW5wdXRWYXJpYWJsZSgnZ2FtbWEnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLCBjb21wb25lbnRzKSxcbiAgICBdO1xuICAgIGlmIChoYXNCZXRhSW5wdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKGlucHV0VmFyaWFibGUoJ2JldGEnLCBpbnB1dHNbM10uZGF0YVR5cGUsIGlucHV0c1szXS5kaW1zLCBjb21wb25lbnRzKSk7XG4gICAgfVxuICAgIGlmIChoYXNCaWFzSW5wdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKGlucHV0VmFyaWFibGUoJ2JpYXMnLCBpbnB1dHNbNF0uZGF0YVR5cGUsIGlucHV0c1s0XS5kaW1zLCBjb21wb25lbnRzKSk7XG4gICAgfVxuICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dFZhcmlhYmxlKCdvdXRwdXQnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIG91dHB1dFNoYXBlLCBjb21wb25lbnRzKSk7XG4gICAgaWYgKGhhc01lYW5PdXRwdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dFZhcmlhYmxlKCdtZWFuX291dHB1dCcsIERhdGFUeXBlLmZsb2F0LCBtZWFuSW52U3RkRGV2RGltKSk7XG4gICAgfVxuICAgIGlmIChoYXNJbnZTdGREZXZPdXRwdXQpIHtcbiAgICAgIHZhcmlhYmxlcy5wdXNoKG91dHB1dFZhcmlhYmxlKCdpbnZfc3RkX291dHB1dCcsIERhdGFUeXBlLmZsb2F0LCBtZWFuSW52U3RkRGV2RGltKSk7XG4gICAgfVxuICAgIGlmIChoYXNJbnB1dFNraXBCaWFzU3VtT3V0cHV0KSB7XG4gICAgICB2YXJpYWJsZXMucHVzaChvdXRwdXRWYXJpYWJsZSgnaW5wdXRfc2tpcF9iaWFzX3N1bScsIGlucHV0c1swXS5kYXRhVHlwZSwgb3V0cHV0U2hhcGUsIGNvbXBvbmVudHMpKTtcbiAgICB9XG4gICAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JUeXBlVG9Xc2dsU3RvcmFnZVR5cGUoaW5wdXRzWzBdLmRhdGFUeXBlKTtcbiAgICBjb25zdCB2ZWNEYXRhVHlwZSA9IHRlbnNvclR5cGVUb1dzZ2xTdG9yYWdlVHlwZShEYXRhVHlwZS5mbG9hdCwgY29tcG9uZW50cyk7XG4gICAgcmV0dXJuIGBcblxuICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3Jtc0FycmF5KS5kZWNsYXJlVmFyaWFibGVzKC4uLnZhcmlhYmxlcyl9XG4gICAgICB2YXI8d29ya2dyb3VwPiBzdW1fc2hhcmVkIDogYXJyYXk8JHt2ZWNEYXRhVHlwZX0sICR7d29ya2dyb3VwU2l6ZX0+O1xuICAgICAgdmFyPHdvcmtncm91cD4gc3VtX3NxdWFyZWRfc2hhcmVkIDogYXJyYXk8JHt2ZWNEYXRhVHlwZX0sICR7d29ya2dyb3VwU2l6ZX0+O1xuXG4gICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoW3dvcmtncm91cFNpemUsIDEsIDFdKX1cbiAgICAgICAgbGV0IGl4ID0gbG9jYWxfaWQueDtcbiAgICAgICAgbGV0IGl5ID0gZ2xvYmFsX2lkLnggLyAke3dvcmtncm91cFNpemV9O1xuXG4gICAgICAgIGxldCBoaWRkZW5fc2l6ZV92ZWN0b3JpemVkOiB1MzIgPSB1bmlmb3Jtcy5oaWRkZW5fc2l6ZSAvIHVuaWZvcm1zLmNvbXBvbmVudHM7XG4gICAgICAgIHZhciBzdHJpZGUgPSBoaWRkZW5fc2l6ZV92ZWN0b3JpemVkIC8gJHt3b3JrZ3JvdXBTaXplfTtcbiAgICAgICAgbGV0IG9mZnNldCA9IGl4ICogc3RyaWRlICsgaXkgKiBoaWRkZW5fc2l6ZV92ZWN0b3JpemVkO1xuICAgICAgICBsZXQgb2Zmc2V0MWQgPSBzdHJpZGUgKiBpeDtcbiAgICAgICAgaWYgKGl4ID09ICR7d29ya2dyb3VwU2l6ZSAtIDF9KSB7XG4gICAgICAgICAgc3RyaWRlID0gaGlkZGVuX3NpemVfdmVjdG9yaXplZCAtIHN0cmlkZSAqIGl4O1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGk6IHUzMiA9IDA7IGkgPCBzdHJpZGU7IGkrKykge1xuICAgICAgICAgIGxldCBza2lwX3ZhbHVlID0gc2tpcFtvZmZzZXQgKyBpXTtcbiAgICAgICAgICBsZXQgYmlhc192YWx1ZSA9ICR7aGFzQmlhc0lucHV0ID8gJ2JpYXNbb2Zmc2V0MWQgKyBpXScgOiBkYXRhVHlwZSArICcoMC4wKSd9O1xuICAgICAgICAgIGxldCBpbnB1dF92YWx1ZSA9IHhbb2Zmc2V0ICsgaV07XG4gICAgICAgICAgbGV0IHZhbHVlID0gaW5wdXRfdmFsdWUgKyBza2lwX3ZhbHVlICsgYmlhc192YWx1ZTtcbiAgICAgICAgICAke2hhc0lucHV0U2tpcEJpYXNTdW1PdXRwdXQgPyAnaW5wdXRfc2tpcF9iaWFzX3N1bVtvZmZzZXQgKyBpXSA9IHZhbHVlOycgOiAnJ31cbiAgICAgICAgICBvdXRwdXRbb2Zmc2V0ICsgaV0gPSB2YWx1ZTtcbiAgICAgICAgICBsZXQgZjMyX3ZhbHVlID0gJHtjYXN0VG9GMzIoZGF0YVR5cGUsIGNvbXBvbmVudHMsICd2YWx1ZScpfTtcbiAgICAgICAgICBzdW1fc2hhcmVkW2l4XSArPSBmMzJfdmFsdWU7XG4gICAgICAgICAgc3VtX3NxdWFyZWRfc2hhcmVkW2l4XSArPSBmMzJfdmFsdWUgKiBmMzJfdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuXG4gICAgICAgIHZhciByZWR1Y2Vfc2l6ZSA6IHUzMiA9ICR7d29ya2dyb3VwU2l6ZX07XG4gICAgICAgIGZvciAodmFyIGN1cnJfc2l6ZSA9IHJlZHVjZV9zaXplID4+IDE7ICBjdXJyX3NpemUgPiAwOyBjdXJyX3NpemUgPSByZWR1Y2Vfc2l6ZSA+PiAxKSB7XG4gICAgICAgICAgcmVkdWNlX3NpemUgPSBjdXJyX3NpemUgKyAocmVkdWNlX3NpemUgJiAxKTtcbiAgICAgICAgICBpZiAoaXggPCBjdXJyX3NpemUpIHtcbiAgICAgICAgICAgIHN1bV9zaGFyZWRbaXhdICs9IHN1bV9zaGFyZWRbaXggKyByZWR1Y2Vfc2l6ZV07XG4gICAgICAgICAgICBzdW1fc3F1YXJlZF9zaGFyZWRbaXhdICs9IHN1bV9zcXVhcmVkX3NoYXJlZFtpeCArIHJlZHVjZV9zaXplXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN1bSA9IHN1bV9zaGFyZWRbMF07XG4gICAgICAgIGxldCBzcXVhcmVfc3VtID0gc3VtX3NxdWFyZWRfc2hhcmVkWzBdO1xuICAgICAgICBsZXQgbWVhbiA9ICR7c3VtVmVjdG9yKCdzdW0nLCBjb21wb25lbnRzKX0gLyBmMzIodW5pZm9ybXMuaGlkZGVuX3NpemUpO1xuICAgICAgICBsZXQgaW52X3N0ZF9kZXYgPSBpbnZlcnNlU3FydCgke3N1bVZlY3Rvcignc3F1YXJlX3N1bScsIGNvbXBvbmVudHMpfSAvIGYzMih1bmlmb3Jtcy5oaWRkZW5fc2l6ZSkgJHtcbiAgICAgICAgICBzaW1wbGlmaWVkID8gJycgOiAnLSBtZWFuICogbWVhbidcbiAgICAgICAgfSArIHVuaWZvcm1zLmVwc2lsb24pO1xuICAgICAgICAke2hhc01lYW5PdXRwdXQgPyAnbWVhbl9vdXRwdXRbZ2xvYmFsX2lkeF0gPSBtZWFuOycgOiAnJ31cbiAgICAgICAgJHtoYXNJbnZTdGREZXZPdXRwdXQgPyAnaW52X3N0ZF9vdXRwdXRbZ2xvYmFsX2lkeF0gPSBpbnZfc3RkX2RldjsnIDogJyd9XG5cbiAgICAgICAgZm9yICh2YXIgaTogdTMyID0gMDsgaSA8IHN0cmlkZTsgaSsrKSB7XG4gICAgICAgICAgb3V0cHV0W29mZnNldCArIGldID0gKG91dHB1dFtvZmZzZXQgKyBpXSAke3NpbXBsaWZpZWQgPyAnJyA6IGAtICR7ZGF0YVR5cGV9KG1lYW4pYH0pICpcbiAgICAgICAgICAgICR7ZGF0YVR5cGV9KGludl9zdGRfZGV2KSAqIGdhbW1hW29mZnNldDFkICsgaV1cbiAgICAgICAgICAgICR7aGFzQmV0YUlucHV0ID8gJysgYmV0YVtvZmZzZXQxZCArIGldJyA6ICcnfTtcbiAgICAgICAgfVxuICAgICAgfWA7XG4gIH07XG4gIGNvbnN0IG91dHB1dHMgPSBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XTtcbiAgaWYgKG91dHB1dENvdW50ID4gMSkge1xuICAgIG91dHB1dHMucHVzaCh7IGRpbXM6IG1lYW5JbnZTdGREZXZEaW0sIGRhdGFUeXBlOiBEYXRhVHlwZS5mbG9hdCB9KTtcbiAgfVxuICBpZiAob3V0cHV0Q291bnQgPiAyKSB7XG4gICAgb3V0cHV0cy5wdXNoKHsgZGltczogbWVhbkludlN0ZERldkRpbSwgZGF0YVR5cGU6IERhdGFUeXBlLmZsb2F0IH0pO1xuICB9XG4gIGlmIChvdXRwdXRDb3VudCA+IDMpIHtcbiAgICBvdXRwdXRzLnB1c2goeyBkaW1zOiBpbnB1dFNoYXBlLCBkYXRhVHlwZTogaW5wdXRzWzBdLmRhdGFUeXBlIH0pO1xuICB9XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ1NraXBMYXllck5vcm1hbGl6YXRpb24nLFxuICAgIHNoYWRlckNhY2hlOiB7XG4gICAgICBoaW50OiBgJHtjb21wb25lbnRzfTske2hhc01lYW5PdXRwdXR9OyR7aGFzSW52U3RkRGV2T3V0cHV0fTske2hhc0lucHV0U2tpcEJpYXNTdW1PdXRwdXR9YCxcbiAgICAgIGlucHV0RGVwZW5kZW5jaWVzOiBpbnB1dHMubWFwKChfaW5wdXQsIF9pbmRleCkgPT4gJ3R5cGUnKSxcbiAgICB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0cyxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHtcbiAgICAgICAgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyBoaWRkZW5TaXplKSxcbiAgICAgIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3Qgc2tpcExheWVyTm9ybSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogU2tpcExheWVyTm9ybUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gVE9ETzogaW5pdGlhbGl6ZSBpc1RyYWluaW5nIGZyb20gQ29tcHV0ZUNvbnRleHRcbiAgY29uc3QgaXNUcmFpbmluZyA9IGZhbHNlO1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIC8vIE1lYW4gYW5kIEludlN0ZERldiBhcmUgb25seSB1c2VkIGluIHRyYWluaW5nIG1vZGUgYW5kIGFyZSBub3QgcmVxdWlyZWQgZm9yIGluZmVyZW5jZS5cbiAgLy8gVGhleSBhcmUgYWRkZWQgaGVyZSBmb3IgY29tcGxldGVuZXNzIG9ubHkuXG4gIGNvbnN0IG91dHB1dHMgPSBbMF07XG4gIGlmIChjb250ZXh0Lm91dHB1dENvdW50ID4gMSkge1xuICAgIG91dHB1dHMucHVzaChpc1RyYWluaW5nID8gMSA6IC0zKTtcbiAgfVxuICBpZiAoY29udGV4dC5vdXRwdXRDb3VudCA+IDIpIHtcbiAgICBvdXRwdXRzLnB1c2goaXNUcmFpbmluZyA/IDIgOiAtMyk7XG4gIH1cbiAgaWYgKGNvbnRleHQub3V0cHV0Q291bnQgPiAzKSB7XG4gICAgb3V0cHV0cy5wdXNoKDMpO1xuICB9XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVTa2lwTGF5ZXJOb3JtUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMsIGF0dHJpYnV0ZXMsIGNvbnRleHQub3V0cHV0Q291bnQsIGlzVHJhaW5pbmcpLCB7XG4gICAgb3V0cHV0cyxcbiAgfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0LCBQcm9ncmFtSW5mbywgUHJvZ3JhbVVuaWZvcm0sIFRlbnNvckluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLFxuICBnZXRFbGVtZW50QXQsXG4gIEluZGljZXNIZWxwZXIsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIFVuaWZvcm1zQXJyYXlUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2xpY2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgc3RhcnRzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZW5kczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGF4ZXM6IG51bWJlcltdO1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0b28gZmV3IGlucHV0cycpO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoICE9PSAwKSB7XG4gICAgaWYgKGF0dHJpYnV0ZXMuYXhlcy5sZW5ndGggIT09IGF0dHJpYnV0ZXMuc3RhcnRzLmxlbmd0aCB8fCBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoICE9PSBhdHRyaWJ1dGVzLmVuZHMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2F4ZXMsIHN0YXJ0cyBhbmQgZW5kcyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoJyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMuc3RhcnRzLmxlbmd0aCAhPT0gYXR0cmlidXRlcy5lbmRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc3RhcnRzIGFuZCBlbmRzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGgnKTtcbiAgfVxuICBpbnB1dHMuc2xpY2UoMSkuZm9yRWFjaCgoXywgaWR4KSA9PiB7XG4gICAgaWYgKGlucHV0c1tpZHggKyAxXS5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuaW50MzIgJiYgaW5wdXRzW2lkeCArIDFdLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5pbnQ2NCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnB1dCAke2lkeH0gbXVzdCBiZSBhbiBhcnJheSBvZiBpbnQzMiBvciBpbnQ2NGApO1xuICAgIH1cbiAgfSk7XG59O1xuXG5jb25zdCByZWFkSW5wdXQgPSAoaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sIGlkeDogbnVtYmVyKTogbnVtYmVyW10gPT4ge1xuICBjb25zdCBpbnB1dDogbnVtYmVyW10gPSBbXTtcbiAgaWYgKGlucHV0cy5sZW5ndGggPiBpZHgpIHtcbiAgICBpZiAoaW5wdXRzW2lkeF0uZGF0YVR5cGUgPT09IERhdGFUeXBlLmludDY0KSB7XG4gICAgICBpbnB1dHNbaWR4XS5nZXRCaWdJbnQ2NEFycmF5KCkuZm9yRWFjaCgodikgPT4gaW5wdXQucHVzaChOdW1iZXIodikpKTtcbiAgICB9IGVsc2UgaWYgKGlucHV0c1tpZHhdLmRhdGFUeXBlID09PSBEYXRhVHlwZS5pbnQzMikge1xuICAgICAgaW5wdXRzW2lkeF0uZ2V0SW50MzJBcnJheSgpLmZvckVhY2goKHYpID0+IGlucHV0LnB1c2goTnVtYmVyKHYpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgJHtpZHh9IG11c3QgYmUgYW4gYXJyYXkgb2YgaW50MzIgb3IgaW50NjRgKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGlucHV0O1xufTtcblxuY29uc3QgY3JlYXRlU2xpY2VBdHRyaWJ1dGVzRnJvbUlucHV0cyA9IChcbiAgaW5wdXRzOiByZWFkb25seSBUZW5zb3JWaWV3W10sXG4gIGF0dHJpYnV0ZXM6IFNsaWNlQXR0cmlidXRlcyxcbik6IFNsaWNlQXR0cmlidXRlcyA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoID4gMSkge1xuICAgIGNvbnN0IHN0YXJ0czogbnVtYmVyW10gPSByZWFkSW5wdXQoaW5wdXRzLCAxKTtcbiAgICBjb25zdCBlbmRzOiBudW1iZXJbXSA9IHJlYWRJbnB1dChpbnB1dHMsIDIpO1xuICAgIGxldCBheGVzOiBudW1iZXJbXSA9IHJlYWRJbnB1dChpbnB1dHMsIDMpO1xuICAgIGlmIChheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgYXhlcyA9IFsuLi5BcnJheShpbnB1dHNbMF0uZGltcy5sZW5ndGgpLmtleXMoKV07XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBzdGFydHMsIGVuZHMsIGF4ZXMgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGF0dHJpYnV0ZXM7XG4gIH1cbn07XG5cbmNvbnN0IGZpeFN0YXJ0RW5kVmFsdWVzID0gKFxuICB2YWx1ZTogbnVtYmVyLFxuICBpbmRleDogbnVtYmVyLFxuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgYXhlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gIHN0ZXBzOiByZWFkb25seSBudW1iZXJbXSxcbik6IG51bWJlciA9PiB7XG4gIGxldCBuZXdWYWx1ZSA9IHZhbHVlO1xuICBpZiAodmFsdWUgPCAwKSB7XG4gICAgbmV3VmFsdWUgKz0gaW5wdXRTaGFwZVtheGVzW2luZGV4XV07XG4gIH1cbiAgaWYgKHN0ZXBzW2luZGV4XSA8IDApIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5taW4obmV3VmFsdWUsIGlucHV0U2hhcGVbYXhlc1tpbmRleF1dIC0gMSkpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBNYXRoLm1heCgwLCBNYXRoLm1pbihuZXdWYWx1ZSwgaW5wdXRTaGFwZVtheGVzW2luZGV4XV0pKTtcbiAgfVxufTtcblxuY29uc3QgY2FsY3VsYXRlSW5wdXRJbmRpY2VzSW1wbCA9IChcbiAgaW5wdXQ6IEluZGljZXNIZWxwZXIsXG4gIG91dHB1dDogSW5kaWNlc0hlbHBlcixcbiAgaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4pOiBzdHJpbmcgPT5cbiAgYGZuIGNhbGN1bGF0ZUlucHV0SW5kaWNlcyhvdXRwdXRfaW5kaWNlczogJHtvdXRwdXQudHlwZS5pbmRpY2VzfSkgLT4gJHtpbnB1dC50eXBlLmluZGljZXN9IHtcbiAgICAgICAgICB2YXIgaW5wdXRfaW5kaWNlczogJHtpbnB1dC50eXBlLmluZGljZXN9O1xuICAgICAgICAgIHZhciBjYXJyeSA9IDB1O1xuICAgICAgICAgIGZvciAodmFyIGkgPSAke2lucHV0U2hhcGUubGVuZ3RofTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGxldCBpbnB1dF9zaGFwZV9pID0gJHtnZXRFbGVtZW50QXQoJ3VuaWZvcm1zLmlucHV0X3NoYXBlJywgJ2knLCBpbnB1dFNoYXBlLmxlbmd0aCl9O1xuICAgICAgICAgICAgbGV0IHN0ZXBzX2kgPSAke2dldEVsZW1lbnRBdCgndW5pZm9ybXMuc3RlcHMnLCAnaScsIGlucHV0U2hhcGUubGVuZ3RoKX07XG4gICAgICAgICAgICBsZXQgc2lnbnNfaSA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5zaWducycsICdpJywgaW5wdXRTaGFwZS5sZW5ndGgpfTtcbiAgICAgICAgICAgIGxldCBzdGFydHNfaSA9ICR7Z2V0RWxlbWVudEF0KCd1bmlmb3Jtcy5zdGFydHMnLCAnaScsIGlucHV0U2hhcGUubGVuZ3RoKX07XG4gICAgICAgICAgICB2YXIgb3V0cHV0X2luZGV4ID0gJHtvdXRwdXQuaW5kaWNlc0dldCgnb3V0cHV0X2luZGljZXMnLCAnaScpfTtcbiAgICAgICAgICAgIHZhciBpbnB1dF9pbmRleCA9IG91dHB1dF9pbmRleCAqIHN0ZXBzX2kgKyBzdGFydHNfaSArIGNhcnJ5O1xuICAgICAgICAgICAgY2FycnkgPSBpbnB1dF9pbmRleCAvIGlucHV0X3NoYXBlX2k7XG4gICAgICAgICAgICBpbnB1dF9pbmRleCA9IGlucHV0X2luZGV4ICUgaW5wdXRfc2hhcGVfaTtcbiAgICAgICAgICAgIGlmIChzaWduc19pIDwgMCkge1xuICAgICAgICAgICAgICBpbnB1dF9pbmRleCA9IGlucHV0X3NoYXBlX2kgLSBpbnB1dF9pbmRleCAtIDF1ICsgc3RhcnRzX2k7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAke2lucHV0LmluZGljZXNTZXQoJ2lucHV0X2luZGljZXMnLCAnaScsICdpbnB1dF9pbmRleCcpfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGlucHV0X2luZGljZXM7XG4gICAgICB9YDtcblxuY29uc3QgY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSwgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IGlucHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKGlucHV0U2hhcGUpO1xuICBjb25zdCBheGVzID1cbiAgICBhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID4gMFxuICAgICAgPyBTaGFwZVV0aWwubm9ybWFsaXplQXhlcyhhdHRyaWJ1dGVzLmF4ZXMsIGlucHV0U2hhcGUubGVuZ3RoKVxuICAgICAgOiBbLi4uQXJyYXkoaW5wdXRTaGFwZS5sZW5ndGgpLmtleXMoKV07XG4gIGxldCBzdGVwcyA9IHJlYWRJbnB1dChpbnB1dHMsIDQpO1xuICBzdGVwcy5mb3JFYWNoKFxuICAgIChzdGVwKSA9PlxuICAgICAgc3RlcCAhPT0gMCB8fFxuICAgICAgKCgpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdGVwIGNhbm5vdCBiZSAwJyk7XG4gICAgICB9KSxcbiAgKTtcbiAgaWYgKHN0ZXBzLmxlbmd0aCA9PT0gMCkge1xuICAgIHN0ZXBzID0gQXJyYXkoYXhlcy5sZW5ndGgpLmZpbGwoMSk7XG4gIH1cbiAgY29uc3Qgc3RhcnRzID0gYXR0cmlidXRlcy5zdGFydHMubWFwKChzdGFydCwgaSkgPT4gZml4U3RhcnRFbmRWYWx1ZXMoc3RhcnQsIGksIGlucHV0U2hhcGUsIGF4ZXMsIHN0ZXBzKSk7XG5cbiAgY29uc3QgZW5kcyA9IGF0dHJpYnV0ZXMuZW5kcy5tYXAoKGVuZCwgaSkgPT4gZml4U3RhcnRFbmRWYWx1ZXMoZW5kLCBpLCBpbnB1dFNoYXBlLCBheGVzLCBzdGVwcykpO1xuXG4gIGlmIChheGVzLmxlbmd0aCAhPT0gc3RhcnRzLmxlbmd0aCB8fCBheGVzLmxlbmd0aCAhPT0gZW5kcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0YXJ0LCBlbmRzIGFuZCBheGVzIHNob3VsZCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBlbGVtZW50cycpO1xuICB9XG5cbiAgaWYgKGF4ZXMubGVuZ3RoICE9PSBpbnB1dFNoYXBlLmxlbmd0aCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRTaGFwZS5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKCFheGVzLmluY2x1ZGVzKGkpKSB7XG4gICAgICAgIHN0YXJ0cy5zcGxpY2UoaSwgMCwgMCk7XG4gICAgICAgIGVuZHMuc3BsaWNlKGksIDAsIGlucHV0U2hhcGVbaV0pO1xuICAgICAgICBzdGVwcy5zcGxpY2UoaSwgMCwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGNvbnN0IHNpZ25zID0gc3RlcHMubWFwKChzdGVwKSA9PiBNYXRoLnNpZ24oc3RlcCkpO1xuICAvLyBDb252ZXJ0IG5lZ2F0aXZlIHN0ZXBzIHRvIHBvc2l0aXZlIHN0ZXBzIGFuZCByZXZlcnNlIHN0YXJ0cyBhbmQgZW5kc1xuICBzdGVwcy5mb3JFYWNoKChzdGVwLCBpLCBhcnJheSkgPT4ge1xuICAgIGlmIChzdGVwIDwgMCkge1xuICAgICAgY29uc3QgbnVtU3RlcHMgPSAoZW5kc1tpXSAtIHN0YXJ0c1tpXSkgLyBzdGVwO1xuICAgICAgY29uc3QgbmV3RW5kID0gc3RhcnRzW2ldO1xuICAgICAgY29uc3QgbmV3U3RhcnQgPSBuZXdFbmQgKyBudW1TdGVwcyAqIHN0ZXBzW2ldO1xuICAgICAgc3RhcnRzW2ldID0gbmV3U3RhcnQ7XG4gICAgICBlbmRzW2ldID0gbmV3RW5kO1xuICAgICAgYXJyYXlbaV0gPSAtc3RlcDtcbiAgICB9XG4gIH0pO1xuICAvLyBPdXRwdXQgcmFuayBpcyBleHBlY3RlZCB0byBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGlucHV0IHJhbmsuXG4gIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgwKTtcbiAgYXhlcy5mb3JFYWNoKChheGlzLCBfKSA9PiB7XG4gICAgb3V0cHV0U2hhcGVbYXhpc10gPSBNYXRoLmNlaWwoKGVuZHNbYXhpc10gLSBzdGFydHNbYXhpc10pIC8gc3RlcHNbYXhpc10pO1xuICB9KTtcbiAgY29uc3Qgb3V0cHV0VGVuc29ySW5mbzogVGVuc29ySW5mbyA9IHsgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBpbnB1dHNbMF0uZGF0YVR5cGUgfTtcblxuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgaW5wdXRzWzBdLmRhdGFUeXBlLCBpbnB1dHNbMF0uZGltcy5sZW5ndGgpO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICBjb25zdCB1bmlmb3JtczogVW5pZm9ybXNBcnJheVR5cGUgPSBbXG4gICAgeyBuYW1lOiAnb3V0cHV0U2l6ZScsIHR5cGU6ICd1MzInIH0sXG4gICAgeyBuYW1lOiAnc3RhcnRzJywgdHlwZTogJ3UzMicsIGxlbmd0aDogc3RhcnRzLmxlbmd0aCB9LFxuICAgIHsgbmFtZTogJ3NpZ25zJywgdHlwZTogJ2kzMicsIGxlbmd0aDogc2lnbnMubGVuZ3RoIH0sXG4gICAgeyBuYW1lOiAnc3RlcHMnLCB0eXBlOiAndTMyJywgbGVuZ3RoOiBzdGVwcy5sZW5ndGggfSxcbiAgXTtcblxuICBjb25zdCBwcm9ncmFtVW5pZm9ybXM6IFByb2dyYW1Vbmlmb3JtW10gPSBbXG4gICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IG91dHB1dFNpemUgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogc3RhcnRzIH0sXG4gICAgeyB0eXBlOiBEYXRhVHlwZS5pbnQzMiwgZGF0YTogc2lnbnMgfSxcbiAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogc3RlcHMgfSxcbiAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgb3V0cHV0U2hhcGUpLFxuICBdO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3Jtcyh1bmlmb3JtcykuZGVjbGFyZVZhcmlhYmxlcyhpbnB1dCwgb3V0cHV0KX1cbiAgICAgICAgJHtjYWxjdWxhdGVJbnB1dEluZGljZXNJbXBsKGlucHV0LCBvdXRwdXQsIGlucHV0U2hhcGUpfVxuICAgICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy5vdXRwdXRTaXplJyl9XG4gICAgICAgICAgbGV0IG91dHB1dF9pbmRpY2VzID0gJHtvdXRwdXQub2Zmc2V0VG9JbmRpY2VzKCdnbG9iYWxfaWR4Jyl9O1xuICAgICAgICAgIGxldCBpbnB1dF9pbmRpY2VzID0gY2FsY3VsYXRlSW5wdXRJbmRpY2VzKG91dHB1dF9pbmRpY2VzKTtcbiAgICAgICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIGlucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpKX1cbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICdTbGljZScsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaGludDogYCR7c2lnbnMubGVuZ3RofV8ke3N0YXJ0cy5sZW5ndGh9XyR7c3RlcHMubGVuZ3RofWAsIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW291dHB1dFRlbnNvckluZm9dLFxuICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiBNYXRoLmNlaWwoaW5wdXRTaXplIC8gNjQgLyogd29ya2dyb3VwIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXMsXG4gICAgfSksXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3Qgc2xpY2UgPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZXM6IFNsaWNlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnN0IHVwZGF0ZWRBdHRyaWJ1dGVzID0gY3JlYXRlU2xpY2VBdHRyaWJ1dGVzRnJvbUlucHV0cyhjb250ZXh0LmlucHV0cywgYXR0cmlidXRlcyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVTbGljZVByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzLCB1cGRhdGVkQXR0cmlidXRlcyksIHsgaW5wdXRzOiBbMF0gfSk7XG4gIC8vIGlmIChTaGFwZVV0aWwuc2l6ZShwcm9ncmFtLm91dHB1dHNbMF0uZGltcykgPiAwKSB7XG4gIC8vICAgY29udGV4dC5jb21wdXRlKHByb2dyYW1JbmZvTG9hZGVyLCB7aW5wdXRzOiBbMF19KTtcbiAgLy8gfSBlbHNlIHtcbiAgLy8gICAvLyBUT0RPOiBzdXBwb3J0IGVtcHR5IG91dHB1dFxuICAvLyAgIHRocm93IG5ldyBFcnJvcignc2xpY2U6IG91dHB1dCBzaXplIGlzIDAnKTtcbiAgLy8gfVxufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU2xpY2VBdHRyaWJ1dGVzID0gKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogU2xpY2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3Qgc3RhcnRzID0gYXR0cmlidXRlcy5zdGFydHMgYXMgbnVtYmVyW107XG4gIGNvbnN0IGVuZHMgPSBhdHRyaWJ1dGVzLmVuZHMgYXMgbnVtYmVyW107XG4gIGNvbnN0IGF4ZXMgPSBhdHRyaWJ1dGVzLmF4ZXMgYXMgbnVtYmVyW107XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoeyBzdGFydHMsIGVuZHMsIGF4ZXMgfSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vLyBUT0RPOiB0aGlzIGlzIHRoZSBzYW1lIG5haXZlIGltcGxlbWVudGF0aW9uIHdlIHVzZSBmb3IgcmVkdWNlIHRoYXQgaGFzXG4vLyBwZXJmb3JtYW5jZSBsaW1pdGF0aW9ucyB3aGVuIHRoZSByZWR1Y2VkIGF4aXMgaXMgbG9uZy4gTmVlZCB0byBhZGRcbi8vIGEgb3B0aW1pemVkIGNvZGVwYXRoIGZvciB0aGlzLlxuXG5pbXBvcnQgeyBEYXRhVHlwZSB9IGZyb20gJy4uLy4uLy4uL3dhc20tY29tbW9uJztcbmltcG9ydCB7IFRlbnNvclZpZXcgfSBmcm9tICcuLi8uLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IEF0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IH0gZnJvbSAnLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7IENvbXB1dGVDb250ZXh0IH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8gfSBmcm9tICcuL3RyYW5zcG9zZSc7XG5cbmltcG9ydCB7XG4gIGdldE1heENvbXBvbmVudHMsXG4gIGlucHV0VmFyaWFibGUsXG4gIG91dHB1dFZhcmlhYmxlLFxuICBTaGFkZXJIZWxwZXIsXG4gIHN1bVZlY3RvcixcbiAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlLFxufSBmcm9tICcuL2NvbW1vbic7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvZnRtYXggb3AgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxufTtcblxuZXhwb3J0IGludGVyZmFjZSBTb2Z0bWF4QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4aXM6IG51bWJlcjtcbn1cblxuY29uc3QgY3JlYXRlU29mdG1heFByb2dyYW1JbmZvID0gKGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBhdHRyaWJ1dGVzOiBTb2Z0bWF4QXR0cmlidXRlcykgPT4ge1xuICBjb25zdCBpbnB1dCA9IGNvbnRleHQuaW5wdXRzWzBdO1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXQuZGltcztcbiAgY29uc3Qgb3V0cHV0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKGlucHV0U2hhcGUpO1xuICBjb25zdCBpbnB1dFJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRSYW5rKTtcbiAgY29uc3QgaXNUcmFuc3Bvc2VSZXF1aXJlZCA9IGF4aXMgPCBpbnB1dFNoYXBlLmxlbmd0aCAtIDE7XG4gIGxldCB0cmFuc3Bvc2VkSW5wdXQ6IFRlbnNvclZpZXc7XG4gIGxldCBwZXJtOiBudW1iZXJbXSA9IFtdO1xuXG4gIGlmIChpc1RyYW5zcG9zZVJlcXVpcmVkKSB7XG4gICAgcGVybSA9IEFycmF5LmZyb20oeyBsZW5ndGg6IGlucHV0UmFuayB9LCAoXywgaSkgPT4gaSk7XG4gICAgcGVybVtheGlzXSA9IGlucHV0UmFuayAtIDE7XG4gICAgcGVybVtpbnB1dFJhbmsgLSAxXSA9IGF4aXM7XG5cbiAgICB0cmFuc3Bvc2VkSW5wdXQgPSBjb250ZXh0LmNvbXB1dGUoY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5wdXQsIHBlcm0pLCB7XG4gICAgICBpbnB1dHM6IFtpbnB1dF0sXG4gICAgICBvdXRwdXRzOiBbLTFdLFxuICAgIH0pWzBdO1xuICB9IGVsc2Uge1xuICAgIHRyYW5zcG9zZWRJbnB1dCA9IGlucHV0O1xuICB9XG5cbiAgY29uc3QgdHJhbnNwb3NlZElucHV0U2hhcGUgPSB0cmFuc3Bvc2VkSW5wdXQuZGltcztcbiAgY29uc3QgY29scyA9IHRyYW5zcG9zZWRJbnB1dFNoYXBlW2lucHV0UmFuayAtIDFdO1xuICBjb25zdCByb3dzID0gb3V0cHV0U2l6ZSAvIGNvbHM7XG4gIGNvbnN0IGNvbXBvbmVudHMgPSBnZXRNYXhDb21wb25lbnRzKGNvbHMpO1xuICBjb25zdCBwYWNrZWRDb2xzID0gY29scyAvIGNvbXBvbmVudHM7XG4gIGxldCBXRyA9IDY0O1xuICAvLyBJZiBvbmx5IG9uZSB3b3JrZ3JvdXAgaXMgZGlzcGF0Y2hlZCwgaW5jcmVhc2Ugd29ya2dyb3VwU2l6ZSB0byBpbXByb3ZlIHBhcmFsbGVsaXNtLlxuICBpZiAocm93cyA9PT0gMSkge1xuICAgIFdHID0gMjU2O1xuICB9XG4gIGNvbnN0IG1heFZlY3RvciA9IChuYW1lOiBzdHJpbmcsIGNvbXBvbmVudHM6IG51bWJlcikgPT4ge1xuICAgIGlmIChjb21wb25lbnRzID09PSA0KSB7XG4gICAgICByZXR1cm4gYG1heChtYXgoJHtuYW1lfS54LCAke25hbWV9LnkpLCBtYXgoJHtuYW1lfS56LCAke25hbWV9LncpKWA7XG4gICAgfSBlbHNlIGlmIChjb21wb25lbnRzID09PSAyKSB7XG4gICAgICByZXR1cm4gYG1heCgke25hbWV9LngsICR7bmFtZX0ueSlgO1xuICAgIH0gZWxzZSBpZiAoY29tcG9uZW50cyA9PT0gMykge1xuICAgICAgcmV0dXJuIGBtYXgobWF4KCR7bmFtZX0ueCwgJHtuYW1lfS55KSwgJHtuYW1lfS56KWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5hbWU7XG4gIH07XG4gIGNvbnN0IHggPSBpbnB1dFZhcmlhYmxlKCd4JywgdHJhbnNwb3NlZElucHV0LmRhdGFUeXBlLCB0cmFuc3Bvc2VkSW5wdXQuZGltcywgY29tcG9uZW50cyk7XG4gIGNvbnN0IG91dHB1dCA9IG91dHB1dFZhcmlhYmxlKCdyZXN1bHQnLCB0cmFuc3Bvc2VkSW5wdXQuZGF0YVR5cGUsIHRyYW5zcG9zZWRJbnB1dC5kaW1zLCBjb21wb25lbnRzKTtcbiAgY29uc3QgdmFsdWVUeXBlID0geC50eXBlLnZhbHVlO1xuICAvLyA2LjIuNCBpbiB3Z3NsIHNwZWNcbiAgY29uc3QgdGhyZWFkTWF4RGVjbCA9XG4gICAgdGVuc29yVHlwZVRvV3NnbFN0b3JhZ2VUeXBlKHRyYW5zcG9zZWRJbnB1dC5kYXRhVHlwZSkgPT09ICdmMzInXG4gICAgICA/IGB2YXIgdGhyZWFkTWF4ID0gJHt2YWx1ZVR5cGV9KC0zLjQwMjgyM2UrMzhmKTtgXG4gICAgICA6IGB2YXIgdGhyZWFkTWF4ID0gJHt2YWx1ZVR5cGV9KC02NTUwNC4waCk7YDtcbiAgY29uc3QgZ2V0U2hhZGVyU291cmNlID0gKHNoYWRlckhlbHBlcjogU2hhZGVySGVscGVyKSA9PiBgXG4gICAgICB2YXI8d29ya2dyb3VwPiByb3dNYXhTaGFyZWQgOiAke3ZhbHVlVHlwZX07XG4gICAgICB2YXI8d29ya2dyb3VwPiByb3dTdW1TaGFyZWQgOiAke3ZhbHVlVHlwZX07XG4gICAgICB2YXI8d29ya2dyb3VwPiB0aHJlYWRTaGFyZWQgOiBhcnJheTwke3ZhbHVlVHlwZX0sICR7V0d9PjtcblxuICAgICAgZm4gZ2V0VmFsdWUocm93OiBpMzIsIGNvbDogaTMyLCByb3dfc3RyaWRlOiBpMzIpIC0+ICR7dmFsdWVUeXBlfSB7XG4gICAgICAgIGxldCBpbmRleCA9IHJvdyAqIHJvd19zdHJpZGUgKyBjb2w7XG4gICAgICAgIHJldHVybiB4W2luZGV4XTtcbiAgICAgIH1cblxuICAgICAgZm4gc2V0VmFsdWUocm93OiBpMzIsIGNvbDogaTMyLCByb3dfc3RyaWRlOiBpMzIsIHZhbHVlOiAke3ZhbHVlVHlwZX0pIHtcbiAgICAgICAgbGV0IGluZGV4ID0gcm93ICogcm93X3N0cmlkZSArIGNvbDtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3JtKCdwYWNrZWRDb2xzJywgJ2kzMicpLmRlY2xhcmVWYXJpYWJsZXMoeCwgb3V0cHV0KX1cbiAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydChXRyl9XG4gICAgICAgIGxldCBnaW5kZXggPSBpMzIoZ2xvYmFsX2lkeCk7XG4gICAgICAgIGxldCBsaW5kZXggPSBpMzIobG9jYWxfaWR4KTtcbiAgICAgICAgY29uc3Qgd2cgPSAke1dHfTtcbiAgICAgICAgbGV0IHJvdyA9IGdpbmRleCAvIHdnO1xuICAgICAgICBsZXQgY29scyA9IHVuaWZvcm1zLnBhY2tlZENvbHM7XG4gICAgICAgIGxldCByb3dfc3RyaWRlIDogaTMyID0gdW5pZm9ybXMucGFja2VkQ29scztcblxuICAgICAgICAvLyBmaW5kIHRoZSByb3dzIG1heFxuICAgICAgICAke3RocmVhZE1heERlY2x9XG4gICAgICAgIGZvciAodmFyIGNvbCA9IGxpbmRleDsgY29sIDwgY29sczsgY29sICs9IHdnKSB7XG4gICAgICAgICAgbGV0IHZhbHVlID0gZ2V0VmFsdWUocm93LCBjb2wsIHJvd19zdHJpZGUpO1xuICAgICAgICAgIHRocmVhZE1heCA9IG1heCh0aHJlYWRNYXgsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGluZGV4IDwgY29scykge1xuICAgICAgICAgIHRocmVhZFNoYXJlZFtsaW5kZXhdID0gdGhyZWFkTWF4O1xuICAgICAgICB9XG4gICAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgICAgICB2YXIgcmVkdWNlU2l6ZSA9IG1pbihjb2xzLCB3Zyk7XG4gICAgICAgIGZvciAodmFyIGN1cnJTaXplID0gcmVkdWNlU2l6ZSA+PiAxOyAgY3VyclNpemUgPiAwOyBjdXJyU2l6ZSA9IHJlZHVjZVNpemUgPj4gMSkge1xuICAgICAgICAgIHJlZHVjZVNpemUgPSBjdXJyU2l6ZSArIChyZWR1Y2VTaXplICYgMSk7XG4gICAgICAgICAgaWYgKGxpbmRleCA8IGN1cnJTaXplKSB7XG4gICAgICAgICAgICB0aHJlYWRTaGFyZWRbbGluZGV4XSA9IG1heCh0aHJlYWRTaGFyZWRbbGluZGV4XSwgdGhyZWFkU2hhcmVkW2xpbmRleCArIHJlZHVjZVNpemVdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgd29ya2dyb3VwQmFycmllcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW5kZXggPT0gMCkge1xuICAgICAgICAgIHJvd01heFNoYXJlZCA9ICR7dmFsdWVUeXBlfSgke21heFZlY3RvcigndGhyZWFkU2hhcmVkWzBdJywgY29tcG9uZW50cyl9KTtcbiAgICAgICAgfVxuICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgICAgLy8gZmluZCB0aGUgcm93cyBzdW1cbiAgICAgICAgdmFyIHRocmVhZFN1bSA9ICR7dmFsdWVUeXBlfSgwLjApO1xuICAgICAgICBmb3IgKHZhciBjb2wgPSBsaW5kZXg7IGNvbCA8IGNvbHM7IGNvbCArPSB3Zykge1xuICAgICAgICAgIGxldCBzdWJFeHAgPSBleHAoZ2V0VmFsdWUocm93LCBjb2wsIHJvd19zdHJpZGUpIC0gcm93TWF4U2hhcmVkKTtcbiAgICAgICAgICB0aHJlYWRTdW0gKz0gc3ViRXhwO1xuICAgICAgICB9XG4gICAgICAgIHRocmVhZFNoYXJlZFtsaW5kZXhdID0gdGhyZWFkU3VtO1xuICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG5cbiAgICAgICAgZm9yICh2YXIgY3VyclNpemUgPSB3ZyA+PiAxOyAgY3VyclNpemUgPiAwOyBjdXJyU2l6ZSA9IGN1cnJTaXplID4+IDEpIHtcbiAgICAgICAgICBpZiAobGluZGV4IDwgY3VyclNpemUpIHtcbiAgICAgICAgICAgIHRocmVhZFNoYXJlZFtsaW5kZXhdID0gdGhyZWFkU2hhcmVkW2xpbmRleF0gKyB0aHJlYWRTaGFyZWRbbGluZGV4ICsgY3VyclNpemVdO1xuICAgICAgICAgIH1cbiAgICAgICAgICB3b3JrZ3JvdXBCYXJyaWVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxpbmRleCA9PSAwKSB7XG4gICAgICAgICAgcm93U3VtU2hhcmVkID0gJHt2YWx1ZVR5cGV9KCR7c3VtVmVjdG9yKCd0aHJlYWRTaGFyZWRbMF0nLCBjb21wb25lbnRzKX0pO1xuICAgICAgICB9XG4gICAgICAgIHdvcmtncm91cEJhcnJpZXIoKTtcblxuICAgICAgICAvLyBjYWxjdWxhdGUgZmluYWwgdmFsdWUgZm9yIGVhY2ggZWxlbWVudCBpbiB0aGUgcm93XG4gICAgICAgIGZvciAodmFyIGNvbCA9IGxpbmRleDsgY29sIDwgY29sczsgY29sICs9IHdnKSB7XG4gICAgICAgICAgbGV0IHZhbHVlID0gZXhwKGdldFZhbHVlKHJvdywgY29sLCByb3dfc3RyaWRlKSAtIHJvd01heFNoYXJlZCkgLyByb3dTdW1TaGFyZWQ7XG4gICAgICAgICAgc2V0VmFsdWUocm93LCBjb2wsIHJvd19zdHJpZGUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfWA7XG4gIGNvbnN0IHJlc3VsdCA9IGNvbnRleHQuY29tcHV0ZShcbiAgICB7XG4gICAgICBuYW1lOiAnU29mdG1heCcsXG4gICAgICAvLyBOb3RlIHRoYXQgaW4gSlNFUCwgV0cgc2l6ZSBpcyBub3QgaW5jbHVkZWQgaW4gY2FjaGUgYnkgZGVmYXVsdCwgYnV0IFdlYkdQVSBFUCBpdCBpcy5cbiAgICAgIHNoYWRlckNhY2hlOiB7IGhpbnQ6IGAke2NvbXBvbmVudHN9OyR7V0d9YCwgaW5wdXREZXBlbmRlbmNpZXM6IFsndHlwZSddIH0sXG4gICAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgICBvdXRwdXRzOiBbeyBkaW1zOiB0cmFuc3Bvc2VkSW5wdXRTaGFwZSwgZGF0YVR5cGU6IHRyYW5zcG9zZWRJbnB1dC5kYXRhVHlwZSB9XSxcbiAgICAgICAgZGlzcGF0Y2hHcm91cDogeyB4OiByb3dzIH0sXG4gICAgICAgIHByb2dyYW1Vbmlmb3JtczogW3sgdHlwZTogRGF0YVR5cGUuaW50MzIsIGRhdGE6IHBhY2tlZENvbHMgfV0sXG4gICAgICB9KSxcbiAgICAgIGdldFNoYWRlclNvdXJjZSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGlucHV0czogW3RyYW5zcG9zZWRJbnB1dF0sXG4gICAgICBvdXRwdXRzOiBbaXNUcmFuc3Bvc2VSZXF1aXJlZCA/IC0xIDogMF0sXG4gICAgfSxcbiAgKVswXTtcblxuICBpZiAoaXNUcmFuc3Bvc2VSZXF1aXJlZCkge1xuICAgIGNvbnRleHQuY29tcHV0ZShjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyhyZXN1bHQsIHBlcm0pLCB7XG4gICAgICBpbnB1dHM6IFtyZXN1bHRdLFxuICAgIH0pO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc29mdG1heCA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCwgYXR0cmlidXRlczogU29mdG1heEF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoY29udGV4dC5pbnB1dHMpO1xuICBjcmVhdGVTb2Z0bWF4UHJvZ3JhbUluZm8oY29udGV4dCwgYXR0cmlidXRlcyk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTb2Z0bWF4QXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFNvZnRtYXhBdHRyaWJ1dGVzID0+XG4gIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7IGF4aXM6IGF0dHJpYnV0ZXMuYXhpcyBhcyBudW1iZXIgfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi4vLi4vLi4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgVGVuc29yVmlldyB9IGZyb20gJy4uLy4uL3RlbnNvci12aWV3JztcbmltcG9ydCB7IFNoYXBlVXRpbCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcywgaW5wdXRWYXJpYWJsZSwgb3V0cHV0VmFyaWFibGUsIFNoYWRlckhlbHBlciB9IGZyb20gJy4vY29tbW9uJztcblxuY29uc3QgZ2V0UmVwZWF0cyA9IChyZXBlYXRzVGVuc29yVmlldzogVGVuc29yVmlldyk6IHJlYWRvbmx5IG51bWJlcltdID0+XG4gIEFycmF5LmZyb20ocmVwZWF0c1RlbnNvclZpZXcuZ2V0QmlnSW50NjRBcnJheSgpLCBOdW1iZXIpO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKFxuICAgIGlucHV0c1swXS5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuZmxvYXQgJiZcbiAgICBpbnB1dHNbMF0uZGF0YVR5cGUgIT09IERhdGFUeXBlLmZsb2F0MTYgJiZcbiAgICBpbnB1dHNbMF0uZGF0YVR5cGUgIT09IERhdGFUeXBlLmludDMyICYmXG4gICAgaW5wdXRzWzBdLmRhdGFUeXBlICE9PSBEYXRhVHlwZS51aW50MzJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIG9ubHkgc3VwcG9ydCBmbG9hdCwgZmxvYXQxNiwgaW50MzIsIGFuZCB1aW50MzIgZGF0YSB0eXBlcycpO1xuICB9XG5cbiAgaWYgKGlucHV0c1sxXS5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuaW50NjQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RpbGUgYHJlcGVhdHNgIGlucHV0IHNob3VsZCBiZSBvZiBpbnQ2NCBkYXRhIHR5cGUnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RpbGUgYHJlcGVhdHNgIGlucHV0IHNob3VsZCBiZSAxLUQnKTtcbiAgfVxuXG4gIGNvbnN0IHJlcGVhdHM6IHJlYWRvbmx5IG51bWJlcltdID0gZ2V0UmVwZWF0cyhpbnB1dHNbMV0pO1xuXG4gIGlmIChyZXBlYXRzLmxlbmd0aCAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIGByZXBlYXRzYCBpbnB1dCBzaG91bGQgaGF2ZSBzYW1lIG51bWJlciBvZiBlbGVtZW50cyBhcyByYW5rIG9mIGlucHV0IGRhdGEgdGVuc29yJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdldE91dHB1dFNoYXBlID0gKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCByZXBlYXRzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGU6IG51bWJlcltdID0gW107XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dFNoYXBlLmxlbmd0aDsgKytpKSB7XG4gICAgb3V0cHV0U2hhcGUucHVzaChpbnB1dFNoYXBlW2ldICogcmVwZWF0c1tpXSk7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0U2hhcGU7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVGlsZVByb2dyYW1JbmZvID0gKGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLCBzaGFwZT86IG51bWJlcltdKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIGNvbnN0IHJlcGVhdHM6IHJlYWRvbmx5IG51bWJlcltdID0gc2hhcGUgPT0gbnVsbCA/IGdldFJlcGVhdHMoaW5wdXRzWzFdKSA6IHNoYXBlO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGdldE91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHJlcGVhdHMpO1xuICBjb25zdCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuXG4gIGNvbnN0IGRhdGFUeXBlID0gaW5wdXRzWzBdLmRhdGFUeXBlO1xuICBjb25zdCBpbnB1dCA9IGlucHV0VmFyaWFibGUoJ2lucHV0JywgZGF0YVR5cGUsIGlucHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0VmFyaWFibGUoJ291dHB1dCcsIGRhdGFUeXBlLCBvdXRwdXRTaGFwZS5sZW5ndGgpO1xuXG4gIGNvbnN0IGdldFNoYWRlclNvdXJjZSA9IChzaGFkZXJIZWxwZXI6IFNoYWRlckhlbHBlcikgPT4gYFxuICAgICAgY29uc3QgaW5wdXRTaGFwZSA9ICR7aW5wdXQuaW5kaWNlcyguLi5pbnB1dFNoYXBlKX07XG4gICAgICAke3NoYWRlckhlbHBlci5yZWdpc3RlclVuaWZvcm0oJ291dHB1dF9zaXplJywgJ3UzMicpLmRlY2xhcmVWYXJpYWJsZXMoaW5wdXQsIG91dHB1dCl9XG4gICAgICAke3NoYWRlckhlbHBlci5tYWluU3RhcnQoKX1cbiAgICAgICR7c2hhZGVySGVscGVyLmd1YXJkQWdhaW5zdE91dE9mQm91bmRzV29ya2dyb3VwU2l6ZXMoJ3VuaWZvcm1zLm91dHB1dF9zaXplJyl9XG4gICAgICBsZXQgb3V0cHV0X2luZGljZXMgPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoJ2dsb2JhbF9pZHgnKX07XG4gICAgICB2YXIgaW5wdXRfaW5kaWNlczogJHtpbnB1dC50eXBlLmluZGljZXN9O1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAke2lucHV0U2hhcGUubGVuZ3RofTsgaSsrKSB7XG4gICAgICAgIGxldCBpbnB1dF9kaW1faSA9ICR7aW5wdXQuaW5kaWNlc0dldCgndW5pZm9ybXMuaW5wdXRfc2hhcGUnLCAnaScpfTtcbiAgICAgICAgbGV0IGlucHV0X2RpbV92YWx1ZSA9ICR7b3V0cHV0LmluZGljZXNHZXQoJ291dHB1dF9pbmRpY2VzJywgJ2knKX0gICUgaW5wdXRfZGltX2k7XG5cbiAgICAgICAgJHtpbnB1dC5pbmRpY2VzU2V0KCdpbnB1dF9pbmRpY2VzJywgJ2knLCAnaW5wdXRfZGltX3ZhbHVlJyl9XG4gICAgICB9XG4gICAgICAke291dHB1dC5zZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcsIGlucHV0LmdldEJ5SW5kaWNlcygnaW5wdXRfaW5kaWNlcycpKX1cbiAgICB9YDtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdUaWxlJyxcbiAgICBzaGFkZXJDYWNoZTogeyBoaW50OiBgJHtyZXBlYXRzfWAsIGlucHV0RGVwZW5kZW5jaWVzOiBbJ3JhbmsnXSB9LFxuICAgIGdldFJ1bkRhdGE6ICgpID0+ICh7XG4gICAgICBvdXRwdXRzOiBbeyBkaW1zOiBvdXRwdXRTaGFwZSwgZGF0YVR5cGU6IGlucHV0c1swXS5kYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLykgfSxcbiAgICAgIHByb2dyYW1Vbmlmb3JtczogW1xuICAgICAgICB7IHR5cGU6IERhdGFUeXBlLnVpbnQzMiwgZGF0YTogb3V0cHV0U2l6ZSB9LFxuICAgICAgICAuLi5jcmVhdGVUZW5zb3JTaGFwZVZhcmlhYmxlcyhpbnB1dHNbMF0uZGltcywgb3V0cHV0U2hhcGUpLFxuICAgICAgXSxcbiAgICB9KSxcbiAgICBnZXRTaGFkZXJTb3VyY2UsXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgdGlsZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhjb250ZXh0LmlucHV0cyk7XG4gIGNvbnRleHQuY29tcHV0ZShjcmVhdGVUaWxlUHJvZ3JhbUluZm8oY29udGV4dC5pbnB1dHMpLCB7IGlucHV0czogWzBdIH0pO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuLi8uLi8uLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi4vLi4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBDb21wdXRlQ29udGV4dCwgUHJvZ3JhbUluZm8gfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7IGNyZWF0ZVRlbnNvclNoYXBlVmFyaWFibGVzLCBpbnB1dFZhcmlhYmxlLCBvdXRwdXRWYXJpYWJsZSwgU2hhZGVySGVscGVyIH0gZnJvbSAnLi9jb21tb24nO1xuXG5jb25zdCBjcmVhdGVXaGVyZU9wUHJvZ3JhbVNoYWRlciA9IChcbiAgc2hhZGVySGVscGVyOiBTaGFkZXJIZWxwZXIsXG4gIGlucHV0czogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBkaW1zT3V0cHV0OiByZWFkb25seSBudW1iZXJbXSxcbiAgaXNCcm9hZGNhc3Q6IGJvb2xlYW4sXG4gIHR5cGVPdXRwdXQ6IG51bWJlcixcbikgPT4ge1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRWYXJpYWJsZSgnb3V0cHV0X2RhdGEnLCB0eXBlT3V0cHV0LCBkaW1zT3V0cHV0Lmxlbmd0aCwgNCk7XG4gIGNvbnN0IGEgPSBpbnB1dFZhcmlhYmxlKCdhX2RhdGEnLCBpbnB1dHNbMV0uZGF0YVR5cGUsIGlucHV0c1sxXS5kaW1zLmxlbmd0aCwgNCk7XG4gIGNvbnN0IGIgPSBpbnB1dFZhcmlhYmxlKCdiX2RhdGEnLCBpbnB1dHNbMl0uZGF0YVR5cGUsIGlucHV0c1syXS5kaW1zLmxlbmd0aCwgNCk7XG4gIGNvbnN0IGMgPSBpbnB1dFZhcmlhYmxlKCdjX2RhdGEnLCBpbnB1dHNbMF0uZGF0YVR5cGUsIGlucHV0c1swXS5kaW1zLmxlbmd0aCwgNCk7XG5cbiAgbGV0IGFzc2lnbm1lbnQ6IHN0cmluZztcbiAgY29uc3QgZXhwcmVzc2lvbiA9IChhOiBzdHJpbmcsIGI6IHN0cmluZywgYzogc3RyaW5nKSA9PiBgc2VsZWN0KCR7Yn0sICR7YX0sICR7Y30pYDtcbiAgaWYgKCFpc0Jyb2FkY2FzdCkge1xuICAgIGFzc2lnbm1lbnQgPSBvdXRwdXQuc2V0QnlPZmZzZXQoXG4gICAgICAnZ2xvYmFsX2lkeCcsXG4gICAgICBleHByZXNzaW9uKGEuZ2V0QnlPZmZzZXQoJ2dsb2JhbF9pZHgnKSwgYi5nZXRCeU9mZnNldCgnZ2xvYmFsX2lkeCcpLCBjLmdldEJ5T2Zmc2V0KCdnbG9iYWxfaWR4JykpLFxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgc2luZ2xlQXNzaWdubWVudCA9IChyZXNTdHI6IHN0cmluZywgeDogbnVtYmVyLCB0eXBlQ2FzdCA9ICcnKSA9PiB7XG4gICAgICBjb25zdCBleHByZXNzaW9uQSA9IGBhX2RhdGFbaW5kZXhfYSR7eH1dW2NvbXBvbmVudF9hJHt4fV1gO1xuICAgICAgY29uc3QgZXhwcmVzc2lvbkIgPSBgYl9kYXRhW2luZGV4X2Ike3h9XVtjb21wb25lbnRfYiR7eH1dYDtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgICBjb25zdCBleHByZXNzaW9uQyA9IGBib29sKGNfZGF0YVtpbmRleF9jJHt4fV0gJiAoMHhmZnUgPDwgKGNvbXBvbmVudF9jJHt4fSAqIDgpKSlgO1xuICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgIGxldCBvdXRwdXRfaW5kaWNlcyR7eH0gPSAke291dHB1dC5vZmZzZXRUb0luZGljZXMoYGdsb2JhbF9pZHggKiA0dSArICR7eH11YCl9O1xuICAgICAgICAgICAgbGV0IG9mZnNldF9hJHt4fSA9ICR7YS5icm9hZGNhc3RlZEluZGljZXNUb09mZnNldChgb3V0cHV0X2luZGljZXMke3h9YCwgb3V0cHV0KX07XG4gICAgICAgICAgICBsZXQgb2Zmc2V0X2Ike3h9ID0gJHtiLmJyb2FkY2FzdGVkSW5kaWNlc1RvT2Zmc2V0KGBvdXRwdXRfaW5kaWNlcyR7eH1gLCBvdXRwdXQpfTtcbiAgICAgICAgICAgIGxldCBvZmZzZXRfYyR7eH0gPSAke2MuYnJvYWRjYXN0ZWRJbmRpY2VzVG9PZmZzZXQoYG91dHB1dF9pbmRpY2VzJHt4fWAsIG91dHB1dCl9O1xuICAgICAgICAgICAgbGV0IGluZGV4X2Eke3h9ID0gb2Zmc2V0X2Eke3h9IC8gNHU7XG4gICAgICAgICAgICBsZXQgaW5kZXhfYiR7eH0gPSBvZmZzZXRfYiR7eH0gLyA0dTtcbiAgICAgICAgICAgIGxldCBpbmRleF9jJHt4fSA9IG9mZnNldF9jJHt4fSAvIDR1O1xuICAgICAgICAgICAgbGV0IGNvbXBvbmVudF9hJHt4fSA9IG9mZnNldF9hJHt4fSAlIDR1O1xuICAgICAgICAgICAgbGV0IGNvbXBvbmVudF9iJHt4fSA9IG9mZnNldF9iJHt4fSAlIDR1O1xuICAgICAgICAgICAgbGV0IGNvbXBvbmVudF9jJHt4fSA9IG9mZnNldF9jJHt4fSAlIDR1O1xuICAgICAgICAgICAgJHtyZXNTdHJ9WyR7eH1dID0gJHt0eXBlQ2FzdH0oJHtleHByZXNzaW9uKGV4cHJlc3Npb25BLCBleHByZXNzaW9uQiwgZXhwcmVzc2lvbkMpfSk7XG4gICAgICAgICAgYDtcbiAgICB9O1xuICAgIGlmICh0eXBlT3V0cHV0ID09PSBEYXRhVHlwZS5ib29sKSB7XG4gICAgICBhc3NpZ25tZW50ID0gYFxuICAgICAgICAgICAgdmFyIGRhdGEgPSB2ZWM0PHUzMj4oMCk7XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAwLCAndTMyJyl9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAxLCAndTMyJyl9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAyLCAndTMyJyl9XG4gICAgICAgICAgICAke3NpbmdsZUFzc2lnbm1lbnQoJ2RhdGEnLCAzLCAndTMyJyl9XG4gICAgICAgICAgICBvdXRwdXRfZGF0YVtnbG9iYWxfaWR4XSA9IGRvdCh2ZWM0PHUzMj4oMHgxLCAweDEwMCwgMHgxMDAwMCwgMHgxMDAwMDAwKSwgdmVjNDx1MzI+KGRhdGEpKTtgO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NpZ25tZW50ID0gYFxuICAgICAgICAgICAgJHtzaW5nbGVBc3NpZ25tZW50KCdvdXRwdXRfZGF0YVtnbG9iYWxfaWR4XScsIDApfVxuICAgICAgICAgICAgJHtzaW5nbGVBc3NpZ25tZW50KCdvdXRwdXRfZGF0YVtnbG9iYWxfaWR4XScsIDEpfVxuICAgICAgICAgICAgJHtzaW5nbGVBc3NpZ25tZW50KCdvdXRwdXRfZGF0YVtnbG9iYWxfaWR4XScsIDIpfVxuICAgICAgICAgICAgJHtzaW5nbGVBc3NpZ25tZW50KCdvdXRwdXRfZGF0YVtnbG9iYWxfaWR4XScsIDMpfVxuICAgICAgICAgIGA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGBcbiAgICAgICAgJHtzaGFkZXJIZWxwZXIucmVnaXN0ZXJVbmlmb3JtKCd2ZWNfc2l6ZScsICd1MzInKS5kZWNsYXJlVmFyaWFibGVzKGMsIGEsIGIsIG91dHB1dCl9XG4gICAgICAgICR7c2hhZGVySGVscGVyLm1haW5TdGFydCgpfVxuICAgICAgICAke3NoYWRlckhlbHBlci5ndWFyZEFnYWluc3RPdXRPZkJvdW5kc1dvcmtncm91cFNpemVzKCd1bmlmb3Jtcy52ZWNfc2l6ZScpfVxuICAgICAgICAke2Fzc2lnbm1lbnR9XG4gICAgICB9YDtcbn07XG5cbmNvbnN0IGNyZWF0ZVdoZXJlT3BQcm9ncmFtSW5mbyA9IChpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSk6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZGltc0EgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3QgZGltc0IgPSBpbnB1dHNbMl0uZGltcztcbiAgY29uc3QgZGltc0MgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3Qgb3V0cHV0RGF0YVR5cGUgPSBpbnB1dHNbMV0uZGF0YVR5cGU7XG5cbiAgY29uc3QgaXNCcm9hZGNhc3QgPSAhKFNoYXBlVXRpbC5hcmVFcXVhbChkaW1zQSwgZGltc0IpICYmIFNoYXBlVXRpbC5hcmVFcXVhbChkaW1zQiwgZGltc0MpKTtcbiAgbGV0IG91dHB1dFNoYXBlID0gZGltc0E7XG4gIGxldCBvdXRwdXRTaXplID0gU2hhcGVVdGlsLnNpemUoZGltc0EpO1xuICAvLyBUT0RPOiBkZWFsIHdpdGggemVyby1zaXplZCB0ZW5zb3JzIChlZy4gZGltcz1bMSwwXSlcblxuICBpZiAoaXNCcm9hZGNhc3QpIHtcbiAgICBjb25zdCBjYWxjdWxhdGVkU2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShkaW1zQSwgZGltc0IsIGZhbHNlKSEsIGRpbXNDLCBmYWxzZSk7XG4gICAgaWYgKCFjYWxjdWxhdGVkU2hhcGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHBlcmZvcm0gd2hlcmUgb3Agb24gdGhlIGdpdmVuIHRlbnNvcnNcIik7XG4gICAgfVxuICAgIG91dHB1dFNoYXBlID0gY2FsY3VsYXRlZFNoYXBlO1xuICAgIG91dHB1dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXRTaGFwZSk7XG4gIH1cblxuICBjb25zdCB2ZWNTaXplID0gTWF0aC5jZWlsKG91dHB1dFNpemUgLyA0KTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdXaGVyZScsXG4gICAgc2hhZGVyQ2FjaGU6IHsgaW5wdXREZXBlbmRlbmNpZXM6IFsncmFuaycsICdyYW5rJywgJ3JhbmsnXSB9LFxuICAgIGdldFNoYWRlclNvdXJjZTogKHNoYWRlckhlbHBlcikgPT5cbiAgICAgIGNyZWF0ZVdoZXJlT3BQcm9ncmFtU2hhZGVyKHNoYWRlckhlbHBlciwgaW5wdXRzLCBvdXRwdXRTaGFwZSwgaXNCcm9hZGNhc3QsIG91dHB1dERhdGFUeXBlKSxcbiAgICBnZXRSdW5EYXRhOiAoKSA9PiAoe1xuICAgICAgb3V0cHV0czogW3sgZGltczogb3V0cHV0U2hhcGUsIGRhdGFUeXBlOiBvdXRwdXREYXRhVHlwZSB9XSxcbiAgICAgIGRpc3BhdGNoR3JvdXA6IHsgeDogTWF0aC5jZWlsKG91dHB1dFNpemUgLyA2NCAvKiB3b3JrZ3JvdXAgc2l6ZSAqLyAvIDQgLyogdmVjIHNpemUgKi8pIH0sXG4gICAgICBwcm9ncmFtVW5pZm9ybXM6IFtcbiAgICAgICAgeyB0eXBlOiBEYXRhVHlwZS51aW50MzIsIGRhdGE6IHZlY1NpemUgfSxcbiAgICAgICAgLi4uY3JlYXRlVGVuc29yU2hhcGVWYXJpYWJsZXMoZGltc0MsIGRpbXNBLCBkaW1zQiwgb3V0cHV0U2hhcGUpLFxuICAgICAgXSxcbiAgICB9KSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCB3aGVyZSA9IChjb250ZXh0OiBDb21wdXRlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb250ZXh0LmNvbXB1dGUoY3JlYXRlV2hlcmVPcFByb2dyYW1JbmZvKGNvbnRleHQuaW5wdXRzKSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBhcmdNYXgsIGFyZ01pbiwgcGFyc2VBcmdNaW5NYXhBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvYXJnbWlubWF4JztcbmltcG9ydCB7IGF0dGVudGlvbiB9IGZyb20gJy4vb3BzL2F0dGVudGlvbic7XG5pbXBvcnQgeyBiYXRjaE5vcm0gfSBmcm9tICcuL29wcy9iYXRjaC1ub3JtJztcbmltcG9ydCB7IGJpYXNBZGQgfSBmcm9tICcuL29wcy9iaWFzLWFkZCc7XG5pbXBvcnQgeyBiaWFzU3BsaXRHZWx1IH0gZnJvbSAnLi9vcHMvYmlhcy1zcGxpdC1nZWx1JztcbmltcG9ydCAqIGFzIGJpbmFyeU9wcyBmcm9tICcuL29wcy9iaW5hcnktb3AnO1xuaW1wb3J0IHsgY29uY2F0LCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9jb25jYXQnO1xuaW1wb3J0IHsgY29udiwgcGFyc2VDb252QXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2NvbnYnO1xuaW1wb3J0IHsgY29udlRyYW5zcG9zZSwgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2NvbnYtdHJhbnNwb3NlJztcbmltcG9ydCB7IGN1bXN1bSwgcGFyc2VDdW1TdW1BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvY3Vtc3VtJztcbmltcG9ydCB7IGRlcHRoVG9TcGFjZSwgcGFyc2VEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZGVwdGgtdG8tc3BhY2UnO1xuaW1wb3J0IHsgZWluc3VtLCBwYXJzZUVpbnN1bUF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9laW5zdW0nO1xuaW1wb3J0IHsgZXhwYW5kIH0gZnJvbSAnLi9vcHMvZXhwYW5kJztcbmltcG9ydCB7IGZhc3RHZWx1IH0gZnJvbSAnLi9vcHMvZmFzdC1nZWx1JztcbmltcG9ydCB7IGdhdGhlciwgcGFyc2VHYXRoZXJBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZ2F0aGVyJztcbmltcG9ydCB7IGdhdGhlck5ELCBwYXJzZUdhdGhlck5EQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2dhdGhlci1uZCc7XG5pbXBvcnQgeyBnYXRoZXJCbG9ja1F1YW50aXplZCwgcGFyc2VHYXRoZXJCbG9ja1F1YW50aXplZEF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9nYXRoZXItYmxvY2stcXVhbnRpemVkJztcbmltcG9ydCB7IGdhdGhlckVsZW1lbnRzLCBwYXJzZUdhdGhlckVsZW1lbnRzQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL2dhdGhlci1lbGVtZW50cyc7XG5pbXBvcnQgeyBnZW1tLCBwYXJzZUdlbW1BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZ2VtbSc7XG5pbXBvcnQgeyBncmlkU2FtcGxlLCBwYXJzZUdyaWRTYW1wbGVBdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvZ3JpZC1zYW1wbGUnO1xuaW1wb3J0IHsgZ3JvdXBRdWVyeUF0dGVudGlvbiB9IGZyb20gJy4vb3BzL2dyb3VwLXF1ZXJ5LWF0dGVudGlvbic7XG5pbXBvcnQgeyBpbnN0YW5jZU5vcm0gfSBmcm9tICcuL29wcy9pbnN0YW5jZS1ub3JtJztcbmltcG9ydCB7IGxheWVyTm9ybSB9IGZyb20gJy4vb3BzL2xheWVyLW5vcm0nO1xuaW1wb3J0IHsgbWF0TXVsIH0gZnJvbSAnLi9vcHMvbWF0bXVsJztcbmltcG9ydCB7IG1hdE11bE5CaXRzLCBwYXJzZU1hdE11bE5CaXRzQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL21hdG11bG5iaXRzJztcbmltcG9ydCB7IG11bHRpSGVhZEF0dGVudGlvbiwgcGFyc2VNdWx0aUhlYWRBdHRlbnRpb25BdHRyaWJ1dGVzIH0gZnJvbSAnLi9vcHMvbXVsdGloZWFkLWF0dGVudGlvbic7XG5pbXBvcnQgeyBwYWQgfSBmcm9tICcuL29wcy9wYWQnO1xuaW1wb3J0ICogYXMgcG9vbCBmcm9tICcuL29wcy9wb29sJztcbmltcG9ydCB7IGRlcXVhbnRpemVMaW5lYXIsIHBhcnNlRGVxdWFudGl6ZUxpbmVhckF0dHJpYnV0ZXMgfSBmcm9tICcuL29wcy9xdWFudGl6ZS1saW5lYXInO1xuaW1wb3J0IHsgcmFuZ2UgfSBmcm9tICcuL29wcy9yYW5nZSc7XG5pbXBvcnQgeyBzY2F0dGVyTkQsIHBhcnNlU2NhdHRlck5EQXR0cmlidXRlcyB9IGZyb20gJy4vb3BzL3NjYXR0ZXItbmQnO1xuaW1wb3J0IHtcbiAgcmVkdWNlTDEsXG4gIHJlZHVjZUwyLFxuICByZWR1Y2VMb2dTdW0sXG4gIHJlZHVjZUxvZ1N1bUV4cCxcbiAgcmVkdWNlTWF4LFxuICByZWR1Y2VNZWFuLFxuICByZWR1Y2VNaW4sXG4gIHJlZHVjZVByb2QsXG4gIHJlZHVjZVN1bSxcbiAgcmVkdWNlU3VtU3F1YXJlLFxufSBmcm9tICcuL29wcy9yZWR1Y2UnO1xuaW1wb3J0IHsgcGFyc2VSZXNpemVBdHRyaWJ1dGVzLCByZXNpemUgfSBmcm9tICcuL29wcy9yZXNpemUnO1xuaW1wb3J0IHsgcm90YXJ5RW1iZWRkaW5nIH0gZnJvbSAnLi9vcHMvcm90YXJ5LWVtYmVkZGluZyc7XG5pbXBvcnQgeyBza2lwTGF5ZXJOb3JtIH0gZnJvbSAnLi9vcHMvc2tpcC1sYXllci1ub3JtJztcbmltcG9ydCB7IHBhcnNlU2xpY2VBdHRyaWJ1dGVzLCBzbGljZSB9IGZyb20gJy4vb3BzL3NsaWNlJztcbmltcG9ydCB7IHBhcnNlU29mdG1heEF0dHJpYnV0ZXMsIHNvZnRtYXggfSBmcm9tICcuL29wcy9zb2Z0bWF4JztcbmltcG9ydCB7IHBhcnNlU3BsaXRBdHRyaWJ1dGVzLCBzcGxpdCB9IGZyb20gJy4vb3BzL3NwbGl0JztcbmltcG9ydCB7IHRpbGUgfSBmcm9tICcuL29wcy90aWxlJztcbmltcG9ydCB7IHBhcnNlVHJhbnNwb3NlQXR0cmlidXRlcywgdHJhbnNwb3NlIH0gZnJvbSAnLi9vcHMvdHJhbnNwb3NlJztcbmltcG9ydCAqIGFzIHVuYXJ5T3BzIGZyb20gJy4vb3BzL3VuYXJ5LW9wJztcbmltcG9ydCB7IHdoZXJlIH0gZnJvbSAnLi9vcHMvd2hlcmUnO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbnRleHQgfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IHR5cGUgUnVuRnVuY3Rpb24gPSAoY29udGV4dDogQ29tcHV0ZUNvbnRleHQsIGF0dHJpYnV0ZT86IHVua25vd24pID0+IHZvaWQ7XG5leHBvcnQgdHlwZSBQYXJzZUF0dHJpYnV0ZUZ1bmN0aW9uID0gKGF0dHJpYnV0ZVJhdzogdW5rbm93bikgPT4gdW5rbm93bjtcbmV4cG9ydCB0eXBlIE9wZXJhdG9ySW1wbGVtZW50YXRpb24gPSBbUnVuRnVuY3Rpb25dIHwgW1J1bkZ1bmN0aW9uLCBQYXJzZUF0dHJpYnV0ZUZ1bmN0aW9uXTtcblxuZXhwb3J0IGNvbnN0IFdFQkdQVV9PUF9SRVNPTFZFX1JVTEVTOiBNYXA8c3RyaW5nLCBPcGVyYXRvckltcGxlbWVudGF0aW9uPiA9IG5ldyBNYXAoW1xuICBbJ0FicycsIFt1bmFyeU9wcy5hYnNdXSxcbiAgWydBY29zJywgW3VuYXJ5T3BzLmFjb3NdXSxcbiAgWydBY29zaCcsIFt1bmFyeU9wcy5hY29zaF1dLFxuICBbJ0FkZCcsIFtiaW5hcnlPcHMuYWRkXV0sXG4gIFsnQXJnTWF4JywgW2FyZ01heCwgcGFyc2VBcmdNaW5NYXhBdHRyaWJ1dGVzXV0sXG4gIFsnQXJnTWluJywgW2FyZ01pbiwgcGFyc2VBcmdNaW5NYXhBdHRyaWJ1dGVzXV0sXG4gIFsnQXNpbicsIFt1bmFyeU9wcy5hc2luXV0sXG4gIFsnQXNpbmgnLCBbdW5hcnlPcHMuYXNpbmhdXSxcbiAgWydBdGFuJywgW3VuYXJ5T3BzLmF0YW5dXSxcbiAgWydBdGFuaCcsIFt1bmFyeU9wcy5hdGFuaF1dLFxuICBbJ0F0dGVudGlvbicsIFthdHRlbnRpb25dXSxcbiAgLy8gVE9ETzogc3VwcG9ydCBuZXcgYXR0cmlidXRlcyBmb3IgQXZlcmFnZVBvb2wtMTBcbiAgWydBdmVyYWdlUG9vbCcsIFtwb29sLmF2ZXJhZ2VQb29sLCBwb29sLnBhcnNlQXZlcmFnZVBvb2xBdHRyaWJ1dGVzXV0sXG4gIFsnQmF0Y2hOb3JtYWxpemF0aW9uJywgW2JhdGNoTm9ybV1dLFxuICBbJ0JpYXNBZGQnLCBbYmlhc0FkZF1dLFxuICBbJ0JpYXNTcGxpdEdlbHUnLCBbYmlhc1NwbGl0R2VsdV1dLFxuICBbJ0Nhc3QnLCBbdW5hcnlPcHMuY2FzdCwgdW5hcnlPcHMucGFyc2VDYXN0QXR0cmlidXRlc11dLFxuICBbJ0NlaWwnLCBbdW5hcnlPcHMuY2VpbF1dLFxuICBbJ0NsaXAnLCBbdW5hcnlPcHMuY2xpcF1dLFxuICBbJ0NvbmNhdCcsIFtjb25jYXQsIHBhcnNlQ29uY2F0QXR0cmlidXRlc11dLFxuICBbJ0NvbnYnLCBbY29udiwgcGFyc2VDb252QXR0cmlidXRlc11dLFxuICBbJ0NvbnZUcmFuc3Bvc2UnLCBbY29udlRyYW5zcG9zZSwgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlc11dLFxuICBbJ0NvcycsIFt1bmFyeU9wcy5jb3NdXSxcbiAgWydDb3NoJywgW3VuYXJ5T3BzLmNvc2hdXSxcbiAgWydDdW1TdW0nLCBbY3Vtc3VtLCBwYXJzZUN1bVN1bUF0dHJpYnV0ZXNdXSxcbiAgWydEZXB0aFRvU3BhY2UnLCBbZGVwdGhUb1NwYWNlLCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXNdXSxcbiAgWydEZXF1YW50aXplTGluZWFyJywgW2RlcXVhbnRpemVMaW5lYXIsIHBhcnNlRGVxdWFudGl6ZUxpbmVhckF0dHJpYnV0ZXNdXSxcbiAgWydEaXYnLCBbYmluYXJ5T3BzLmRpdl1dLFxuICBbJ0VpbnN1bScsIFtlaW5zdW0sIHBhcnNlRWluc3VtQXR0cmlidXRlc11dLFxuICBbJ0VsdScsIFt1bmFyeU9wcy5lbHUsIHVuYXJ5T3BzLnBhcnNlQWxwaGFBdHRyaWJ1dGVzXV0sXG4gIFsnRXF1YWwnLCBbYmluYXJ5T3BzLmVxdWFsXV0sXG4gIFsnRXJmJywgW3VuYXJ5T3BzLmVyZl1dLFxuICBbJ0V4cCcsIFt1bmFyeU9wcy5leHBdXSxcbiAgWydFeHBhbmQnLCBbZXhwYW5kXV0sXG4gIFsnRmFzdEdlbHUnLCBbZmFzdEdlbHVdXSxcbiAgWydGbG9vcicsIFt1bmFyeU9wcy5mbG9vcl1dLFxuICBbJ0Z1c2VkQ29udicsIFtjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzXV0sXG4gIFsnR2F0aGVyJywgW2dhdGhlciwgcGFyc2VHYXRoZXJBdHRyaWJ1dGVzXV0sXG4gIFsnR2F0aGVyRWxlbWVudHMnLCBbZ2F0aGVyRWxlbWVudHMsIHBhcnNlR2F0aGVyRWxlbWVudHNBdHRyaWJ1dGVzXV0sXG4gIFsnR2F0aGVyQmxvY2tRdWFudGl6ZWQnLCBbZ2F0aGVyQmxvY2tRdWFudGl6ZWQsIHBhcnNlR2F0aGVyQmxvY2tRdWFudGl6ZWRBdHRyaWJ1dGVzXV0sXG4gIFsnR2F0aGVyTkQnLCBbZ2F0aGVyTkQsIHBhcnNlR2F0aGVyTkRBdHRyaWJ1dGVzXV0sXG4gIFsnR2VsdScsIFt1bmFyeU9wcy5nZWx1XV0sXG4gIFsnR2VtbScsIFtnZW1tLCBwYXJzZUdlbW1BdHRyaWJ1dGVzXV0sXG4gIFsnR2xvYmFsQXZlcmFnZVBvb2wnLCBbcG9vbC5nbG9iYWxBdmVyYWdlUG9vbCwgcG9vbC5wYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlc11dLFxuICBbJ0dsb2JhbE1heFBvb2wnLCBbcG9vbC5nbG9iYWxNYXhQb29sLCBwb29sLnBhcnNlR2xvYmFsTWF4UG9vbEF0dHJpYnV0ZXNdXSxcbiAgWydHcmVhdGVyJywgW2JpbmFyeU9wcy5ncmVhdGVyXV0sXG4gIFsnR3JlYXRlck9yRXF1YWwnLCBbYmluYXJ5T3BzLmdyZWF0ZXJPckVxdWFsXV0sXG4gIFsnR3JpZFNhbXBsZScsIFtncmlkU2FtcGxlLCBwYXJzZUdyaWRTYW1wbGVBdHRyaWJ1dGVzXV0sXG4gIFsnR3JvdXBRdWVyeUF0dGVudGlvbicsIFtncm91cFF1ZXJ5QXR0ZW50aW9uXV0sXG4gIFsnSGFyZFNpZ21vaWQnLCBbdW5hcnlPcHMuaGFyZFNpZ21vaWQsIHVuYXJ5T3BzLnBhcnNlSGFyZFNpZ21vaWRBdHRyaWJ1dGVzXV0sXG4gIFsnSW5zdGFuY2VOb3JtYWxpemF0aW9uJywgW2luc3RhbmNlTm9ybV1dLFxuICBbJ0xheWVyTm9ybWFsaXphdGlvbicsIFtsYXllck5vcm1dXSxcbiAgWydMZWFreVJlbHUnLCBbdW5hcnlPcHMubGVha3lSZWx1LCB1bmFyeU9wcy5wYXJzZUFscGhhQXR0cmlidXRlc11dLFxuICBbJ0xlc3MnLCBbYmluYXJ5T3BzLmxlc3NdXSxcbiAgWydMZXNzT3JFcXVhbCcsIFtiaW5hcnlPcHMubGVzc09yRXF1YWxdXSxcbiAgWydMb2cnLCBbdW5hcnlPcHMubG9nXV0sXG4gIFsnTWF0TXVsJywgW21hdE11bF1dLFxuICBbJ01hdE11bE5CaXRzJywgW21hdE11bE5CaXRzLCBwYXJzZU1hdE11bE5CaXRzQXR0cmlidXRlc11dLFxuICAvLyBUT0RPOiBzdXBwb3J0IG5ldyBhdHRyaWJ1dGVzIGZvciBNYXhQb29sLTggYW5kIE1heFBvb2wtMTBcbiAgWydNYXhQb29sJywgW3Bvb2wubWF4UG9vbCwgcG9vbC5wYXJzZU1heFBvb2xBdHRyaWJ1dGVzXV0sXG4gIFsnTXVsJywgW2JpbmFyeU9wcy5tdWxdXSxcbiAgWydNdWx0aUhlYWRBdHRlbnRpb24nLCBbbXVsdGlIZWFkQXR0ZW50aW9uLCBwYXJzZU11bHRpSGVhZEF0dGVudGlvbkF0dHJpYnV0ZXNdXSxcbiAgWydOZWcnLCBbdW5hcnlPcHMubmVnXV0sXG4gIFsnTm90JywgW3VuYXJ5T3BzLm5vdF1dLFxuICBbJ1BhZCcsIFtwYWRdXSxcbiAgWydQb3cnLCBbYmluYXJ5T3BzLnBvd11dLFxuICBbJ1F1aWNrR2VsdScsIFt1bmFyeU9wcy5xdWlja2dlbHUsIHVuYXJ5T3BzLnBhcnNlQWxwaGFBdHRyaWJ1dGVzXV0sXG4gIFsnUmFuZ2UnLCBbcmFuZ2VdXSxcbiAgWydSZWNpcHJvY2FsJywgW3VuYXJ5T3BzLnJlY2lwcm9jYWxdXSxcbiAgWydSZWR1Y2VNaW4nLCBbcmVkdWNlTWluXV0sXG4gIFsnUmVkdWNlTWVhbicsIFtyZWR1Y2VNZWFuXV0sXG4gIFsnUmVkdWNlTWF4JywgW3JlZHVjZU1heF1dLFxuICBbJ1JlZHVjZVN1bScsIFtyZWR1Y2VTdW1dXSxcbiAgWydSZWR1Y2VQcm9kJywgW3JlZHVjZVByb2RdXSxcbiAgWydSZWR1Y2VMMScsIFtyZWR1Y2VMMV1dLFxuICBbJ1JlZHVjZUwyJywgW3JlZHVjZUwyXV0sXG4gIFsnUmVkdWNlTG9nU3VtJywgW3JlZHVjZUxvZ1N1bV1dLFxuICBbJ1JlZHVjZUxvZ1N1bUV4cCcsIFtyZWR1Y2VMb2dTdW1FeHBdXSxcbiAgWydSZWR1Y2VTdW1TcXVhcmUnLCBbcmVkdWNlU3VtU3F1YXJlXV0sXG4gIFsnUmVsdScsIFt1bmFyeU9wcy5yZWx1XV0sXG4gIFsnUmVzaXplJywgW3Jlc2l6ZSwgcGFyc2VSZXNpemVBdHRyaWJ1dGVzXV0sXG4gIFsnUm90YXJ5RW1iZWRkaW5nJywgW3JvdGFyeUVtYmVkZGluZ11dLFxuICBbJ1NjYXR0ZXJORCcsIFtzY2F0dGVyTkQsIHBhcnNlU2NhdHRlck5EQXR0cmlidXRlc11dLFxuICBbJ1NpZ21vaWQnLCBbdW5hcnlPcHMuc2lnbW9pZF1dLFxuICBbJ1NpbicsIFt1bmFyeU9wcy5zaW5dXSxcbiAgWydTaW5oJywgW3VuYXJ5T3BzLnNpbmhdXSxcbiAgWydTbGljZScsIFtzbGljZSwgcGFyc2VTbGljZUF0dHJpYnV0ZXNdXSxcbiAgWydTa2lwTGF5ZXJOb3JtYWxpemF0aW9uJywgW3NraXBMYXllck5vcm1dXSxcbiAgWydTcGxpdCcsIFtzcGxpdCwgcGFyc2VTcGxpdEF0dHJpYnV0ZXNdXSxcbiAgWydTcXJ0JywgW3VuYXJ5T3BzLnNxcnRdXSxcbiAgWydTb2Z0bWF4JywgW3NvZnRtYXgsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNdXSxcbiAgWydTdWInLCBbYmluYXJ5T3BzLnN1Yl1dLFxuICBbJ1RhbicsIFt1bmFyeU9wcy50YW5dXSxcbiAgWydUYW5oJywgW3VuYXJ5T3BzLnRhbmhdXSxcbiAgWydUaHJlc2hvbGRlZFJlbHUnLCBbdW5hcnlPcHMudGhyZXNob2xkZWRSZWx1LCB1bmFyeU9wcy5wYXJzZUFscGhhQXR0cmlidXRlc11dLFxuICBbJ1RpbGUnLCBbdGlsZV1dLFxuICBbJ1RyYW5zcG9zZScsIFt0cmFuc3Bvc2UsIHBhcnNlVHJhbnNwb3NlQXR0cmlidXRlc11dLFxuICBbJ1doZXJlJywgW3doZXJlXV0sXG5dKTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgVFJBQ0VfRlVOQ19CRUdJTiwgVFJBQ0VfRlVOQ19FTkQgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBXZWJHcHVCYWNrZW5kIH0gZnJvbSAnLi4vYmFja2VuZC13ZWJncHUnO1xuaW1wb3J0IHsgTE9HX0RFQlVHIH0gZnJvbSAnLi4vbG9nJztcblxuaW1wb3J0IHsgY3JlYXRlU2hhZGVySGVscGVyIH0gZnJvbSAnLi9vcHMvY29tbW9uJztcbmltcG9ydCB7IEFydGlmYWN0LCBHcHVEYXRhLCBQcm9ncmFtSW5mbyB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIFByb2dyYW1NYW5hZ2VyIGlzIHRoZSBtYWluIGNsYXNzIGJlaGluZCBydW5uaW5nIGNvbXB1dGF0aW9uc1xuICogSXQgYnVpbGRzIFByb2dyYW1JbmZvJ3MgaW50byBBcnRpZmFjdHNcbiAqIEl0IGNvbXBpbGVzIGdpdmVuIFByb2dyYW1JbmZvJ3MgaW50byBXZWJHTCBQcm9yYW1zIChjYWNoZWQgYXMgQXJ0aWZhY3RzKVxuICogVXNlcyB0aGUgYXJ0aWZhY3QgdG8gcnVuIHRoZSBjb21wdXRhdGlvbiBieSBjYWxsaW5nIERyYXcgb25cbiAqIHRoZSBXZWJHTCBkcmF3aW5nIGJ1ZmZlclxuICogUHJvZ3JhbU1hbmFnZXIgYXV0b21hdGljYWxseSBtYXBzIChiaW5kcykgaW5wdXQgdmFyaWFibGVzIHRvIHRoZWlyXG4gKiBjb3JyZXNwb25kaW5nIExvY2F0aW9uJ3MgaW4gdGhlIGJpbmFyeSBwcm9ncmFtXG4gKi9cbmV4cG9ydCBjbGFzcyBQcm9ncmFtTWFuYWdlciB7XG4gIHJlcG86IE1hcDx1bmtub3duLCBBcnRpZmFjdD47IC8vIHRoaXMgc2hvdWxkIGJlIHBlci1zZXNzaW9uIG9iamVjdFxuICBhdHRyaWJ1dGVzQm91bmQ6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBiYWNrZW5kOiBXZWJHcHVCYWNrZW5kKSB7XG4gICAgdGhpcy5yZXBvID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuYXR0cmlidXRlc0JvdW5kID0gZmFsc2U7XG4gIH1cbiAgZ2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duKTogQXJ0aWZhY3QgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJlcG8uZ2V0KGtleSk7XG4gIH1cbiAgc2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duLCBhcnRpZmFjdDogQXJ0aWZhY3QpOiB2b2lkIHtcbiAgICB0aGlzLnJlcG8uc2V0KGtleSwgYXJ0aWZhY3QpO1xuICB9XG4gIHJ1bihcbiAgICBidWlsZEFydGlmYWN0OiBBcnRpZmFjdCxcbiAgICBpbnB1dHM6IEdwdURhdGFbXSxcbiAgICBvdXRwdXRzOiBHcHVEYXRhW10sXG4gICAgZGlzcGF0Y2hHcm91cDogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIHVuaWZvcm1CdWZmZXJCaW5kaW5nOiBHUFVCaW5kaW5nUmVzb3VyY2UgfCB1bmRlZmluZWQsXG4gICk6IHZvaWQge1xuICAgIFRSQUNFX0ZVTkNfQkVHSU4oYnVpbGRBcnRpZmFjdC5wcm9ncmFtSW5mby5uYW1lKTtcbiAgICBjb25zdCBkZXZpY2UgPSB0aGlzLmJhY2tlbmQuZGV2aWNlO1xuICAgIGNvbnN0IGNvbXB1dGVQYXNzRW5jb2RlciA9IHRoaXMuYmFja2VuZC5nZXRDb21wdXRlUGFzc0VuY29kZXIoKTtcbiAgICB0aGlzLmJhY2tlbmQud3JpdGVUaW1lc3RhbXAodGhpcy5iYWNrZW5kLnBlbmRpbmdEaXNwYXRjaE51bWJlciAqIDIpO1xuICAgIGNvbnN0IGVudHJpZXMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGlucHV0IG9mIGlucHV0cykge1xuICAgICAgZW50cmllcy5wdXNoKHsgYmluZGluZzogZW50cmllcy5sZW5ndGgsIHJlc291cmNlOiB7IGJ1ZmZlcjogaW5wdXQuYnVmZmVyIH0gfSk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG91dHB1dHMpIHtcbiAgICAgIGVudHJpZXMucHVzaCh7IGJpbmRpbmc6IGVudHJpZXMubGVuZ3RoLCByZXNvdXJjZTogeyBidWZmZXI6IG91dHB1dC5idWZmZXIgfSB9KTtcbiAgICB9XG4gICAgaWYgKHVuaWZvcm1CdWZmZXJCaW5kaW5nKSB7XG4gICAgICBlbnRyaWVzLnB1c2goeyBiaW5kaW5nOiBlbnRyaWVzLmxlbmd0aCwgcmVzb3VyY2U6IHVuaWZvcm1CdWZmZXJCaW5kaW5nIH0pO1xuICAgIH1cbiAgICBjb25zdCBiaW5kR3JvdXAgPSBkZXZpY2UuY3JlYXRlQmluZEdyb3VwKHtcbiAgICAgIGxheW91dDogYnVpbGRBcnRpZmFjdC5jb21wdXRlUGlwZWxpbmUuZ2V0QmluZEdyb3VwTGF5b3V0KDApLFxuICAgICAgZW50cmllcyxcbiAgICAgIGxhYmVsOiBidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLm5hbWUsXG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5iYWNrZW5kLnNlc3Npb25TdGF0dXMgPT09ICdjYXB0dXJpbmcnKSB7XG4gICAgICBjb25zdCBjb21tYW5kSW5mbyA9IHtcbiAgICAgICAga2VybmVsSWQ6IHRoaXMuYmFja2VuZC5jdXJyZW50S2VybmVsSWQhLFxuICAgICAgICBjb21wdXRlUGlwZWxpbmU6IGJ1aWxkQXJ0aWZhY3QuY29tcHV0ZVBpcGVsaW5lLFxuICAgICAgICBiaW5kR3JvdXAsXG4gICAgICAgIGRpc3BhdGNoR3JvdXAsXG4gICAgICB9O1xuICAgICAgY29uc3Qgc2Vzc2lvbkNvbW1hbmRMaXN0ID0gdGhpcy5iYWNrZW5kLmNhcHR1cmVkQ29tbWFuZExpc3QuZ2V0KHRoaXMuYmFja2VuZC5jdXJyZW50U2Vzc2lvbklkISk7XG4gICAgICBzZXNzaW9uQ29tbWFuZExpc3QhLnB1c2goY29tbWFuZEluZm8pO1xuICAgIH1cblxuICAgIGNvbXB1dGVQYXNzRW5jb2Rlci5zZXRQaXBlbGluZShidWlsZEFydGlmYWN0LmNvbXB1dGVQaXBlbGluZSk7XG4gICAgY29tcHV0ZVBhc3NFbmNvZGVyLnNldEJpbmRHcm91cCgwLCBiaW5kR3JvdXApO1xuICAgIGNvbXB1dGVQYXNzRW5jb2Rlci5kaXNwYXRjaFdvcmtncm91cHMoLi4uZGlzcGF0Y2hHcm91cCk7XG4gICAgdGhpcy5iYWNrZW5kLndyaXRlVGltZXN0YW1wKHRoaXMuYmFja2VuZC5wZW5kaW5nRGlzcGF0Y2hOdW1iZXIgKiAyICsgMSk7XG4gICAgdGhpcy5iYWNrZW5kLnBlbmRpbmdEaXNwYXRjaE51bWJlcisrO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5iYWNrZW5kLnBlbmRpbmdEaXNwYXRjaE51bWJlciA+PSB0aGlzLmJhY2tlbmQubWF4RGlzcGF0Y2hOdW1iZXIgfHxcbiAgICAgIHRoaXMuYmFja2VuZC5xdWVyeVR5cGUgPT09ICdhdC1wYXNzZXMnXG4gICAgKSB7XG4gICAgICB0aGlzLmJhY2tlbmQuZW5kQ29tcHV0ZVBhc3MoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuYmFja2VuZC5wZW5kaW5nRGlzcGF0Y2hOdW1iZXIgPj0gdGhpcy5iYWNrZW5kLm1heERpc3BhdGNoTnVtYmVyKSB7XG4gICAgICB0aGlzLmJhY2tlbmQuZmx1c2goKTtcbiAgICB9XG4gICAgVFJBQ0VfRlVOQ19FTkQoYnVpbGRBcnRpZmFjdC5wcm9ncmFtSW5mby5uYW1lKTtcbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIC8vIHRoaXMucmVwby5mb3JFYWNoKGEgPT4gdGhpcy5nbENvbnRleHQuZGVsZXRlUHJvZ3JhbShhLnByb2dyYW0pKTtcbiAgfVxuICBidWlsZChwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm8sIG5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwU2l6ZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdKTogQXJ0aWZhY3Qge1xuICAgIFRSQUNFX0ZVTkNfQkVHSU4ocHJvZ3JhbUluZm8ubmFtZSk7XG4gICAgY29uc3QgZGV2aWNlID0gdGhpcy5iYWNrZW5kLmRldmljZTtcbiAgICBjb25zdCBlbmFibGVEaXJlY3RpdmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gRW5hYmxlIFdHU0wgZXh0ZW5zaW9ucyBiYXNlZCBvbiBhdmFpbGFibGUgV2ViR1BVIGZlYXR1cmVzXG4gICAgY29uc3QgZXh0ZW5zaW9uc0luZm86IEFycmF5PHsgZmVhdHVyZTogR1BVRmVhdHVyZU5hbWU7IGV4dGVuc2lvbjogc3RyaW5nIH0+ID0gW1xuICAgICAgeyBmZWF0dXJlOiAnc2hhZGVyLWYxNicsIGV4dGVuc2lvbjogJ2YxNicgfSxcbiAgICAgIHsgZmVhdHVyZTogJ3N1Ymdyb3VwcycgYXMgR1BVRmVhdHVyZU5hbWUsIGV4dGVuc2lvbjogJ3N1Ymdyb3VwcycgfSxcbiAgICBdO1xuICAgIGV4dGVuc2lvbnNJbmZvLmZvckVhY2goKGluZm8pID0+IHtcbiAgICAgIGlmIChkZXZpY2UuZmVhdHVyZXMuaGFzKGluZm8uZmVhdHVyZSkpIHtcbiAgICAgICAgZW5hYmxlRGlyZWN0aXZlcy5wdXNoKGBlbmFibGUgJHtpbmZvLmV4dGVuc2lvbn07YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBzaGFkZXJIZWxwZXIgPSBjcmVhdGVTaGFkZXJIZWxwZXIobm9ybWFsaXplZERpc3BhdGNoR3JvdXBTaXplLCB0aGlzLmJhY2tlbmQuZGV2aWNlLmxpbWl0cyk7XG4gICAgY29uc3QgdXNlckNvZGUgPSBwcm9ncmFtSW5mby5nZXRTaGFkZXJTb3VyY2Uoc2hhZGVySGVscGVyKTtcbiAgICBjb25zdCBjb2RlID0gYCR7ZW5hYmxlRGlyZWN0aXZlcy5qb2luKCdcXG4nKX1cXG4ke3NoYWRlckhlbHBlci5hZGRpdGlvbmFsSW1wbGVtZW50YXRpb25zfVxcbiR7dXNlckNvZGV9YDtcbiAgICBjb25zdCBzaGFkZXJNb2R1bGUgPSBkZXZpY2UuY3JlYXRlU2hhZGVyTW9kdWxlKHsgY29kZSwgbGFiZWw6IHByb2dyYW1JbmZvLm5hbWUgfSk7XG4gICAgTE9HX0RFQlVHKCd2ZXJib3NlJywgKCkgPT4gYFtXZWJHUFVdICR7cHJvZ3JhbUluZm8ubmFtZX0gc2hhZGVyIGNvZGU6ICR7Y29kZX1gKTtcblxuICAgIGNvbnN0IGNvbXB1dGVQaXBlbGluZSA9IGRldmljZS5jcmVhdGVDb21wdXRlUGlwZWxpbmUoe1xuICAgICAgY29tcHV0ZTogeyBtb2R1bGU6IHNoYWRlck1vZHVsZSwgZW50cnlQb2ludDogJ21haW4nIH0sXG4gICAgICBsYXlvdXQ6ICdhdXRvJyxcbiAgICAgIGxhYmVsOiBwcm9ncmFtSW5mby5uYW1lLFxuICAgIH0pO1xuXG4gICAgVFJBQ0VfRlVOQ19FTkQocHJvZ3JhbUluZm8ubmFtZSk7XG4gICAgcmV0dXJuIHsgcHJvZ3JhbUluZm8sIGNvbXB1dGVQaXBlbGluZSwgdW5pZm9ybVZhcmlhYmxlc0luZm86IHNoYWRlckhlbHBlci52YXJpYWJsZXNJbmZvIH07XG4gIH1cblxuICBub3JtYWxpemVEaXNwYXRjaEdyb3VwU2l6ZShcbiAgICBkaXNwYXRjaEdyb3VwOiBSZXR1cm5UeXBlPFByb2dyYW1JbmZvWydnZXRSdW5EYXRhJ10+WydkaXNwYXRjaEdyb3VwJ10sXG4gICk6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3QgeCA9IHR5cGVvZiBkaXNwYXRjaEdyb3VwID09PSAnbnVtYmVyJyA/IGRpc3BhdGNoR3JvdXAgOiBkaXNwYXRjaEdyb3VwLng7XG4gICAgY29uc3QgeSA9IHR5cGVvZiBkaXNwYXRjaEdyb3VwID09PSAnbnVtYmVyJyA/IDEgOiBkaXNwYXRjaEdyb3VwLnkgfHwgMTtcbiAgICBjb25zdCB6ID0gdHlwZW9mIGRpc3BhdGNoR3JvdXAgPT09ICdudW1iZXInID8gMSA6IGRpc3BhdGNoR3JvdXAueiB8fCAxO1xuICAgIGNvbnN0IGxpbWl0UGVyRGltZW5zaW9uID0gdGhpcy5iYWNrZW5kLmRldmljZS5saW1pdHMubWF4Q29tcHV0ZVdvcmtncm91cHNQZXJEaW1lbnNpb247XG4gICAgaWYgKHggPD0gbGltaXRQZXJEaW1lbnNpb24gJiYgeSA8PSBsaW1pdFBlckRpbWVuc2lvbiAmJiB6IDw9IGxpbWl0UGVyRGltZW5zaW9uKSB7XG4gICAgICByZXR1cm4gW3gsIHksIHpdO1xuICAgIH1cbiAgICBjb25zdCBzaXplID0geCAqIHkgKiB6O1xuICAgIGxldCBkaXNwYXRjaEF2ZXJhZ2UgPSBNYXRoLmNlaWwoTWF0aC5zcXJ0KHNpemUpKTtcbiAgICBpZiAoZGlzcGF0Y2hBdmVyYWdlID4gbGltaXRQZXJEaW1lbnNpb24pIHtcbiAgICAgIGRpc3BhdGNoQXZlcmFnZSA9IE1hdGguY2VpbChNYXRoLmNicnQoc2l6ZSkpO1xuICAgICAgaWYgKGRpc3BhdGNoQXZlcmFnZSA+IGxpbWl0UGVyRGltZW5zaW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVG90YWwgZGlzcGF0Y2ggc2l6ZSBleGNlZWRzIFdlYkdQVSBtYXhpbXVtLicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtkaXNwYXRjaEF2ZXJhZ2UsIGRpc3BhdGNoQXZlcmFnZSwgZGlzcGF0Y2hBdmVyYWdlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFtkaXNwYXRjaEF2ZXJhZ2UsIGRpc3BhdGNoQXZlcmFnZSwgMV07XG4gICAgfVxuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7IEVudiwgVGVuc29yLCBUUkFDRSwgVFJBQ0VfRlVOQ19CRUdJTiwgVFJBQ0VfRlVOQ19FTkQgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBEYXRhVHlwZSwgdGVuc29yRGF0YVR5cGVFbnVtVG9TdHJpbmcgfSBmcm9tICcuLi93YXNtLWNvbW1vbic7XG5cbmltcG9ydCB7IGNvbmZpZ3VyZUxvZ2dlciwgTE9HX0RFQlVHIH0gZnJvbSAnLi9sb2cnO1xuaW1wb3J0IHsgY3JlYXRlVmlldywgVGVuc29yVmlldyB9IGZyb20gJy4vdGVuc29yLXZpZXcnO1xuaW1wb3J0IHsgY3JlYXRlR3B1RGF0YU1hbmFnZXIsIGRvd25sb2FkR3B1RGF0YSwgR3B1RGF0YU1hbmFnZXIgfSBmcm9tICcuL3dlYmdwdS9ncHUtZGF0YS1tYW5hZ2VyJztcbmltcG9ydCB7IFJ1bkZ1bmN0aW9uLCBXRUJHUFVfT1BfUkVTT0xWRV9SVUxFUyB9IGZyb20gJy4vd2ViZ3B1L29wLXJlc29sdmUtcnVsZXMnO1xuaW1wb3J0IHsgUHJvZ3JhbU1hbmFnZXIgfSBmcm9tICcuL3dlYmdwdS9wcm9ncmFtLW1hbmFnZXInO1xuaW1wb3J0IHtcbiAgQWRhcHRlckluZm8sXG4gIENvbXB1dGVDb250ZXh0LFxuICBHcHVBcmNoaXRlY3R1cmUsXG4gIEdwdURhdGEsXG4gIEdwdVZlbmRvcixcbiAgUHJvZ3JhbUluZm8sXG4gIFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5LFxuICBTZXNzaW9uU3RhdGUsXG4gIFRpbWVzdGFtcFF1ZXJ5LFxufSBmcm9tICcuL3dlYmdwdS90eXBlcyc7XG5cbmludGVyZmFjZSBDb21tYW5kSW5mbyB7XG4gIHJlYWRvbmx5IGtlcm5lbElkOiBudW1iZXI7XG4gIHJlYWRvbmx5IGNvbXB1dGVQaXBlbGluZTogR1BVQ29tcHV0ZVBpcGVsaW5lO1xuICByZWFkb25seSBiaW5kR3JvdXA6IEdQVUJpbmRHcm91cDtcbiAgcmVhZG9ubHkgZGlzcGF0Y2hHcm91cDogW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xufVxuXG5pbnRlcmZhY2UgS2VybmVsSW5mbyB7XG4gIHJlYWRvbmx5IGtlcm5lbFR5cGU6IHN0cmluZztcbiAgcmVhZG9ubHkga2VybmVsTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBrZXJuZWxFbnRyeTogUnVuRnVuY3Rpb247XG4gIHJlYWRvbmx5IGF0dHJpYnV0ZXM6IFsoKGF0dHJpYnV0ZTogdW5rbm93bikgPT4gdW5rbm93bikgfCB1bmRlZmluZWQsIHVua25vd25dO1xufVxuXG5pbnRlcmZhY2UgUGVuZGluZ0tlcm5lbEluZm8ge1xuICByZWFkb25seSBrZXJuZWxJZDogbnVtYmVyO1xuICByZWFkb25seSBwcm9ncmFtTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBpbnB1dFRlbnNvclZpZXdzOiByZWFkb25seSBUZW5zb3JWaWV3W107XG4gIHJlYWRvbmx5IG91dHB1dFRlbnNvclZpZXdzOiByZWFkb25seSBUZW5zb3JWaWV3W107XG59XG5cbmNvbnN0IGdldFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5S2V5ID0gKFxuICBpbnB1dFRlbnNvcnM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgaW5wdXREZXBlbmRlbmNpZXM6IHJlYWRvbmx5IFByb2dyYW1JbnB1dFRlbnNvckluZm9EZXBlbmRlbmN5W10sXG4pOiBzdHJpbmcgPT4ge1xuICBpZiAoaW5wdXREZXBlbmRlbmNpZXMubGVuZ3RoICE9PSBpbnB1dFRlbnNvcnMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYGlucHV0RGVwZW5kZW5jaWVzIGxlbmd0aCAke2lucHV0RGVwZW5kZW5jaWVzLmxlbmd0aH0gaXMgbm90IGVxdWFsIHRvIGlucHV0VGVuc29ycyBsZW5ndGggJHtcbiAgICAgICAgaW5wdXRUZW5zb3JzLmxlbmd0aFxuICAgICAgfS5gLFxuICAgICk7XG4gIH1cblxuICBjb25zdCBpbnB1dEluZm9zOiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0VGVuc29ycy5sZW5ndGg7ICsraSkge1xuICAgIGNvbnN0IHR5cGUgPSBpbnB1dFRlbnNvcnNbaV0uZGF0YVR5cGU7XG4gICAgc3dpdGNoIChpbnB1dERlcGVuZGVuY2llc1tpXSkge1xuICAgICAgY2FzZSAnbm9uZSc6IHtcbiAgICAgICAgaW5wdXRJbmZvcy5wdXNoKCcnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICd0eXBlJzoge1xuICAgICAgICBpbnB1dEluZm9zLnB1c2goYCR7dHlwZX1gKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdyYW5rJzoge1xuICAgICAgICBjb25zdCByYW5rID0gaW5wdXRUZW5zb3JzW2ldLmRpbXMubGVuZ3RoO1xuICAgICAgICBpbnB1dEluZm9zLnB1c2goYCR7dHlwZX07JHtyYW5rfWApO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2RpbXMnOiB7XG4gICAgICAgIGNvbnN0IGRpbXMgPSBpbnB1dFRlbnNvcnNbaV0uZGltcy5qb2luKCcsJyk7XG4gICAgICAgIGlucHV0SW5mb3MucHVzaChgJHt0eXBlfTske2RpbXN9YCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBpbnB1dCBkZXBlbmRlbmN5OiAke2lucHV0RGVwZW5kZW5jaWVzW2ldfWApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBpbnB1dEluZm9zLmpvaW4oJ3wnKTtcbn07XG5cbi8qKlxuICogZ2V0IGEgdW5pcXVlIGtleSByZXByZXNlbnRpbmcgdGhlIHByb2dyYW0gZnJvbSB0aGUgcHJvZ3JhbSBpbmZvLCBpbnB1dCBzaGFwZXMgYW5kIHR5cGVzLlxuICpcbiAqIEByZXR1cm5zIGEgdW5pcXVlIGtleSBpcyBhIHNob3J0ZXIgc3RyaW5nIHRoYW4gdGhlIHNoYWRlciBzb3VyY2UsIHdoaWNoIGNvbnRhaW5zIGFsbCB0aGUgaW5mb3JtYXRpb24gdG8gaWRlbnRpZnkgYVxuICogcHJvZ3JhbS4gaWYgdGhlIGtleSBpcyB0aGUgc2FtZSwgdGhlIHByb2dyYW0gc2hhZGVyIHNvdXJjZSBzaG91bGQgYmUgdGhlIHNhbWUsIHNvIHdlIGNhbiByZXVzZSB0aGUgcHJvZ3JhbS5cbiAqXG4gKi9cbmNvbnN0IGdldFByb2dyYW1JbmZvVW5pcXVlS2V5ID0gKFxuICBwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm8sXG4gIGlucHV0VGVuc29yczogcmVhZG9ubHkgVGVuc29yVmlld1tdLFxuICBpczFEaW1lbnNpb25EaXNwYXRjaDogYm9vbGVhbixcbik6IHN0cmluZyA9PiB7XG4gIC8vIGZpbmFsIGtleSBmb3JtYXQ6XG4gIC8vIDxQUk9HUkFNX05BTUU+WzxQUk9HUkFNX0NVU1RPTV9DQUNIRV9ISU5UPl06aXMxRGltZW5zaW9uRGlzcGF0Y2g6PElOUFVUU19JTkZPXzA+fDxJTlBVVFNfSU5GT18xPnwuLi5cbiAgbGV0IGtleSA9IHByb2dyYW1JbmZvLm5hbWU7XG4gIGlmIChwcm9ncmFtSW5mby5zaGFkZXJDYWNoZT8uaGludCkge1xuICAgIGtleSArPSAnWycgKyBwcm9ncmFtSW5mby5zaGFkZXJDYWNoZS5oaW50ICsgJ10nO1xuICB9XG4gIGtleSArPVxuICAgICc6JyArXG4gICAgaXMxRGltZW5zaW9uRGlzcGF0Y2ggK1xuICAgIGA6JHtnZXRQcm9ncmFtSW5wdXRUZW5zb3JJbmZvRGVwZW5kZW5jeUtleShcbiAgICAgIGlucHV0VGVuc29ycyxcbiAgICAgIHByb2dyYW1JbmZvLnNoYWRlckNhY2hlPy5pbnB1dERlcGVuZGVuY2llcyA/P1xuICAgICAgICBuZXcgQXJyYXk8UHJvZ3JhbUlucHV0VGVuc29ySW5mb0RlcGVuZGVuY3k+KGlucHV0VGVuc29ycy5sZW5ndGgpLmZpbGwoJ2RpbXMnKSxcbiAgICApfWA7XG4gIHJldHVybiBrZXk7XG59O1xuXG5jbGFzcyBBZGFwdGVySW5mb0ltcGwgaW1wbGVtZW50cyBBZGFwdGVySW5mbyB7XG4gIHJlYWRvbmx5IGFyY2hpdGVjdHVyZT86IHN0cmluZztcbiAgcmVhZG9ubHkgdmVuZG9yPzogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXJJbmZvOiBHUFVBZGFwdGVySW5mbykge1xuICAgIGlmIChhZGFwdGVySW5mbykge1xuICAgICAgdGhpcy5hcmNoaXRlY3R1cmUgPSBhZGFwdGVySW5mby5hcmNoaXRlY3R1cmU7XG4gICAgICB0aGlzLnZlbmRvciA9IGFkYXB0ZXJJbmZvLnZlbmRvcjtcbiAgICB9XG4gIH1cblxuICBpc0FyY2hpdGVjdHVyZShhcmNoaXRlY3R1cmU6IEdwdUFyY2hpdGVjdHVyZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmFyY2hpdGVjdHVyZSA9PT0gYXJjaGl0ZWN0dXJlO1xuICB9XG5cbiAgaXNWZW5kb3IodmVuZG9yOiBHcHVWZW5kb3IpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52ZW5kb3IgPT09IHZlbmRvcjtcbiAgfVxufVxuXG4vKipcbiAqIHRoaXMgY2xhc3MgaXMgZGVzaWduZWQgdG8gc3RvcmUgc3RhdHVzIGFuZCBiZWluZyB1c2VkIGFzIGEgc2luZ2xldG9uIGZvciBKU0VQLiBJdCB3aWxsIGJlIHBhc3NlZCB0byBqc2VwSW5pdCgpIGFzXG4gKiB0aGUgZmlyc3QgcGFyYW1ldGVyIHNvIHRoYXQgaXQgaXMgc3RvcmVkIGZvciBmdXR1cmUgdXNlLlxuICovXG5leHBvcnQgY2xhc3MgV2ViR3B1QmFja2VuZCB7XG4gIGFkYXB0ZXJJbmZvOiBBZGFwdGVySW5mb0ltcGw7XG4gIGRldmljZTogR1BVRGV2aWNlO1xuICAvKipcbiAgICogYW4gaW5zdGFuY2Ugb2YgR3B1RGF0YU1hbmFnZXIgdG8gbWFuYWdlIGEgR3B1RGF0YUlkIC0+IEdwdUJ1ZmZlciBtYXBwaW5nXG4gICAqL1xuICBncHVEYXRhTWFuYWdlcjogR3B1RGF0YU1hbmFnZXI7XG4gIC8qKlxuICAgKiBhbiBpbnN0YW5jZSBvZiBQcm9ncmFtTWFuYWdlciB0byBidWlsZCBhbmQgcnVuIFdlYkdQVSBjb21wdXRlIHNoYWRlciBwcm9ncmFtLCBhbmQgbWFuYWdlIGEgUHJvZ3JhbUtleSAtPiBQcm9ncmFtXG4gICAqIGFydGlmYWN0cyBtYXBwaW5nXG4gICAqL1xuICBwcm9ncmFtTWFuYWdlcjogUHJvZ3JhbU1hbmFnZXI7XG5cbiAgLyoqXG4gICAqIHJlcHJlc2VudGluZyB0aGUgc2Vzc2lvbiBJRCBvZiB3aGljaCBpcyBjdXJyZW50bHkgYmVpbmcgcnVuLlxuICAgKiBgbnVsbGAgbWVhbnMgbm8gc2Vzc2lvbiBpcyBiZWluZyBydW4uXG4gICAqIG9ubHkgdmFsaWQgd2hlbiBzZXNzaW9uLnJ1biBpcyBleGVjdXRlZC5cbiAgICovXG4gIGN1cnJlbnRTZXNzaW9uSWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiByZXByZXNlbnRpbmcgdGhlIGtlcm5lbCBJRCBvZiB3aGljaCBpcyBjdXJyZW50bHkgYmVpbmcgY29tcHV0ZWQgKENQVSBjb2RlIHBlcnNwZWN0aXZlKS5cbiAgICogYG51bGxgIG1lYW5zIG5vIGtlcm5lbCBpcyBiZWluZyBjb21wdXRlZC5cbiAgICogb25seSBvbmUga2VybmVsIGNhbiBiZSBjb21wdXRlZCBhdCBhIG1vbWVudC5cbiAgICovXG4gIGN1cnJlbnRLZXJuZWxJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIC8qKlxuICAgKiBhIGxpc3Qgb2YgdGVtcG9yYXJ5IEdQVSBkYXRhIGZvciB0aGUgY3VycmVudCBrZXJuZWwuIHNob3VsZCByZWxlYXNlIHdoZW4gdGhlIGtlcm5lbCBkb25lIGNvbXB1dGF0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSB0ZW1wb3JhcnlEYXRhOiBHcHVEYXRhW107XG4gIC8qKlxuICAgKiBhIEtlcm5lbElEIC0+IGEgR1BVIGRhdGEgbGlzdCwgd2hpY2ggc3RvcmVzIHBlcnNpc3RlbnQgR1BVIGRhdGEgb3duZWQgYnkgdGhlIHNwZWNpZmljIGtlcm5lbC5cbiAgICovXG4gIHByaXZhdGUga2VybmVsUGVyc2lzdGVudERhdGE6IE1hcDxudW1iZXIsIEdwdURhdGFbXT47XG4gIC8qKlxuICAgKiBhIEtlcm5lbElEIC0+IGEgY3VzdG9tIGRhdGEsIHdoaWNoIHN0b3JlcyBjdXN0b20gZGF0YSBvd25lZCBieSB0aGUgc3BlY2lmaWMga2VybmVsLlxuICAgKi9cbiAgcHJpdmF0ZSBrZXJuZWxDdXN0b21EYXRhOiBNYXA8bnVtYmVyLCB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfT47XG4gIC8qKlxuICAgKiBnZXQgdGhlIGN1c3RvbSBkYXRhIG9mIHRoZSBjdXJyZW50IGtlcm5lbFxuICAgKi9cbiAgZ2V0IGN1cnJlbnRLZXJuZWxDdXN0b21EYXRhKCk6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9IHtcbiAgICBpZiAodGhpcy5jdXJyZW50S2VybmVsSWQgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudEtlcm5lbEN1c3RvbURhdGEoKTogY3VycmVudEtlcm5lbElkIGlzIG51bGwuIChzaG91bGQgbm90IGhhcHBlbiknKTtcbiAgICB9XG5cbiAgICBsZXQgZGF0YSA9IHRoaXMua2VybmVsQ3VzdG9tRGF0YS5nZXQodGhpcy5jdXJyZW50S2VybmVsSWQpO1xuICAgIGlmICghZGF0YSkge1xuICAgICAgZGF0YSA9IHt9O1xuICAgICAgdGhpcy5rZXJuZWxDdXN0b21EYXRhLnNldCh0aGlzLmN1cnJlbnRLZXJuZWxJZCwgZGF0YSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICAvLyBLZXJuZWxJRCAtPiBrZXJuZWxJbmZvIG1hcHBpbmdcbiAga2VybmVsczogTWFwPG51bWJlciwgS2VybmVsSW5mbz47XG4gIHByaXZhdGUgY29tbWFuZEVuY29kZXI6IEdQVUNvbW1hbmRFbmNvZGVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY29tcHV0ZVBhc3NFbmNvZGVyOiBHUFVDb21wdXRlUGFzc0VuY29kZXIgfCBudWxsID0gbnVsbDtcbiAgbWF4RGlzcGF0Y2hOdW1iZXIgPSAxNjtcbiAgcGVuZGluZ0Rpc3BhdGNoTnVtYmVyID0gMDtcblxuICAvLyBpbmZvIG9mIGtlcm5lbHMgcGVuZGluZyBzdWJtaXNzaW9uIGZvciBhIHNpbmdsZSBiYXRjaFxuICBwcml2YXRlIHBlbmRpbmdLZXJuZWxzOiBQZW5kaW5nS2VybmVsSW5mb1tdID0gW107XG4gIC8vIHF1ZXJ5UmVhZEJ1ZmZlciAtPiBwZW5kaW5nS2VybmVscyBtYXBwaW5nIGZvciBhbGwgdGhlIGJhdGNoZXNcbiAgcHJpdmF0ZSBwZW5kaW5nUXVlcmllczogTWFwPEdQVUJ1ZmZlciwgUGVuZGluZ0tlcm5lbEluZm9bXT4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgcXVlcnlSZXNvbHZlQnVmZmVyPzogR1BVQnVmZmVyO1xuICBwcml2YXRlIHF1ZXJ5U2V0PzogR1BVUXVlcnlTZXQ7XG4gIHByaXZhdGUgcXVlcnlUaW1lQmFzZT86IGJpZ2ludDtcbiAgcXVlcnlUeXBlOiBUaW1lc3RhbXBRdWVyeTtcblxuICBlbnY6IEVudjtcbiAgc2Vzc2lvblN0YXR1czogU2Vzc2lvblN0YXRlID0gJ2RlZmF1bHQnO1xuICAvKipcbiAgICogYSBTZXNzaW9uSUQgLT4gQ29tbWFuZEluZm9bXSBtYXBwaW5nLiBJdCdzIHVzZWQgdG8gcmVjb3JkIGFsbCBHUFUgY29tbWFuZHMgZm9yIGNvcnJlc3BvbmRpbmcgc2Vzc2lvbi5cbiAgICovXG4gIGNhcHR1cmVkQ29tbWFuZExpc3Q6IE1hcDxudW1iZXIsIENvbW1hbmRJbmZvW10+ID0gbmV3IE1hcCgpO1xuXG4gIC8qKlxuICAgKiBhIFNlc3Npb25JRCAtPiBQZW5kaW5nS2VybmVsSW5mb1tdIG1hcHBpbmcgZm9yIHByb2ZpbGluZy5cbiAgICovXG4gIHByaXZhdGUgY2FwdHVyZWRQZW5kaW5nS2VybmVsczogTWFwPG51bWJlciwgUGVuZGluZ0tlcm5lbEluZm9bXT4gPSBuZXcgTWFwKCk7XG5cbiAgLyoqXG4gICAqIGEgU2Vzc2lvbklEIC0+IGEgTWFwIG9mIChJbnB1dE91dHB1dEluZGV4IC0+IFtJRCwgR1BVQnVmZmVyXSkgbWFwcGluZy5cbiAgICovXG4gIHNlc3Npb25FeHRlcm5hbERhdGFNYXBwaW5nOiBNYXA8bnVtYmVyLCBNYXA8bnVtYmVyLCBbbnVtYmVyLCBHUFVCdWZmZXJdPj4gPSBuZXcgTWFwKCk7XG5cbiAgYXN5bmMgaW5pdGlhbGl6ZShlbnY6IEVudiwgYWRhcHRlcjogR1BVQWRhcHRlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuZW52ID0gZW52O1xuICAgIGNvbnN0IHJlcXVpcmVkRmVhdHVyZXM6IEdQVUZlYXR1cmVOYW1lW10gPSBbXTtcbiAgICBjb25zdCBkZXZpY2VEZXNjcmlwdG9yOiBHUFVEZXZpY2VEZXNjcmlwdG9yID0ge1xuICAgICAgcmVxdWlyZWRMaW1pdHM6IHtcbiAgICAgICAgbWF4Q29tcHV0ZVdvcmtncm91cFN0b3JhZ2VTaXplOiBhZGFwdGVyLmxpbWl0cy5tYXhDb21wdXRlV29ya2dyb3VwU3RvcmFnZVNpemUsXG4gICAgICAgIG1heENvbXB1dGVXb3JrZ3JvdXBzUGVyRGltZW5zaW9uOiBhZGFwdGVyLmxpbWl0cy5tYXhDb21wdXRlV29ya2dyb3Vwc1BlckRpbWVuc2lvbixcbiAgICAgICAgbWF4U3RvcmFnZUJ1ZmZlckJpbmRpbmdTaXplOiBhZGFwdGVyLmxpbWl0cy5tYXhTdG9yYWdlQnVmZmVyQmluZGluZ1NpemUsXG4gICAgICAgIG1heEJ1ZmZlclNpemU6IGFkYXB0ZXIubGltaXRzLm1heEJ1ZmZlclNpemUsXG4gICAgICAgIG1heENvbXB1dGVJbnZvY2F0aW9uc1Blcldvcmtncm91cDogYWRhcHRlci5saW1pdHMubWF4Q29tcHV0ZUludm9jYXRpb25zUGVyV29ya2dyb3VwLFxuICAgICAgICBtYXhDb21wdXRlV29ya2dyb3VwU2l6ZVg6IGFkYXB0ZXIubGltaXRzLm1heENvbXB1dGVXb3JrZ3JvdXBTaXplWCxcbiAgICAgICAgbWF4Q29tcHV0ZVdvcmtncm91cFNpemVZOiBhZGFwdGVyLmxpbWl0cy5tYXhDb21wdXRlV29ya2dyb3VwU2l6ZVksXG4gICAgICAgIG1heENvbXB1dGVXb3JrZ3JvdXBTaXplWjogYWRhcHRlci5saW1pdHMubWF4Q29tcHV0ZVdvcmtncm91cFNpemVaLFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkRmVhdHVyZXMsXG4gICAgfTtcblxuICAgIC8vIFRyeSByZXF1aXJpbmcgV2ViR1BVIGZlYXR1cmVzXG4gICAgY29uc3QgcmVxdWlyZUZlYXR1cmVJZkF2YWlsYWJsZSA9IChmZWF0dXJlOiBHUFVGZWF0dXJlTmFtZSkgPT5cbiAgICAgIGFkYXB0ZXIuZmVhdHVyZXMuaGFzKGZlYXR1cmUpICYmIHJlcXVpcmVkRmVhdHVyZXMucHVzaChmZWF0dXJlKSAmJiB0cnVlO1xuICAgIC8vIFRyeSBjaHJvbWl1bS1leHBlcmltZW50YWwtdGltZXN0YW1wLXF1ZXJ5LWluc2lkZS1wYXNzZXMgYW5kIGZhbGxiYWNrIHRvIHRpbWVzdGFtcC1xdWVyeVxuICAgIGlmICghcmVxdWlyZUZlYXR1cmVJZkF2YWlsYWJsZSgnY2hyb21pdW0tZXhwZXJpbWVudGFsLXRpbWVzdGFtcC1xdWVyeS1pbnNpZGUtcGFzc2VzJyBhcyBHUFVGZWF0dXJlTmFtZSkpIHtcbiAgICAgIHJlcXVpcmVGZWF0dXJlSWZBdmFpbGFibGUoJ3RpbWVzdGFtcC1xdWVyeScpO1xuICAgIH1cbiAgICByZXF1aXJlRmVhdHVyZUlmQXZhaWxhYmxlKCdzaGFkZXItZjE2Jyk7XG4gICAgLy8gVHJ5IHN1Ymdyb3Vwc1xuICAgIHJlcXVpcmVGZWF0dXJlSWZBdmFpbGFibGUoJ3N1Ymdyb3VwcycgYXMgR1BVRmVhdHVyZU5hbWUpO1xuXG4gICAgdGhpcy5kZXZpY2UgPSBhd2FpdCBhZGFwdGVyLnJlcXVlc3REZXZpY2UoZGV2aWNlRGVzY3JpcHRvcik7XG4gICAgdGhpcy5hZGFwdGVySW5mbyA9IG5ldyBBZGFwdGVySW5mb0ltcGwoYWRhcHRlci5pbmZvIHx8IChhd2FpdCBhZGFwdGVyLnJlcXVlc3RBZGFwdGVySW5mbygpKSk7XG4gICAgdGhpcy5ncHVEYXRhTWFuYWdlciA9IGNyZWF0ZUdwdURhdGFNYW5hZ2VyKHRoaXMpO1xuICAgIHRoaXMucHJvZ3JhbU1hbmFnZXIgPSBuZXcgUHJvZ3JhbU1hbmFnZXIodGhpcyk7XG4gICAgdGhpcy5rZXJuZWxzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMua2VybmVsUGVyc2lzdGVudERhdGEgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5rZXJuZWxDdXN0b21EYXRhID0gbmV3IE1hcCgpO1xuXG4gICAgLy8gc2V0IHVwIGZsYWdzIGZvciBsb2dnZXJcbiAgICBjb25maWd1cmVMb2dnZXIoZW52LmxvZ0xldmVsISwgISFlbnYuZGVidWcpO1xuXG4gICAgLy8gVE9ETzogc2V0IHVwIGZsYWdzXG5cbiAgICB0aGlzLmRldmljZS5vbnVuY2FwdHVyZWRlcnJvciA9IChldikgPT4ge1xuICAgICAgaWYgKGV2LmVycm9yIGluc3RhbmNlb2YgR1BVVmFsaWRhdGlvbkVycm9yKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEFuIHVuY2F1Z2h0IFdlYkdQVSB2YWxpZGF0aW9uIGVycm9yIHdhcyByYWlzZWQ6ICR7ZXYuZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMuZW52LndlYmdwdSwgJ2RldmljZScsIHtcbiAgICAgIHZhbHVlOiB0aGlzLmRldmljZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLmVudi53ZWJncHUsICdhZGFwdGVyJywge1xuICAgICAgdmFsdWU6IGFkYXB0ZXIsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIC8vIGluaXQgcXVlcnlUeXBlLCB3aGljaCBpcyBuZWNlc3NhcnkgZm9yIEluZmVyZW5jZVNlc3Npb24uY3JlYXRlXG4gICAgdGhpcy5zZXRRdWVyeVR5cGUoKTtcbiAgfVxuXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnF1ZXJ5U2V0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5xdWVyeVNldC5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMuZ3B1RGF0YU1hbmFnZXIuZGlzcG9zZSgpO1xuICB9XG5cbiAgZ2V0Q29tbWFuZEVuY29kZXIoKTogR1BVQ29tbWFuZEVuY29kZXIge1xuICAgIGlmICghdGhpcy5jb21tYW5kRW5jb2Rlcikge1xuICAgICAgdGhpcy5jb21tYW5kRW5jb2RlciA9IHRoaXMuZGV2aWNlLmNyZWF0ZUNvbW1hbmRFbmNvZGVyKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbW1hbmRFbmNvZGVyO1xuICB9XG5cbiAgZ2V0Q29tcHV0ZVBhc3NFbmNvZGVyKCk6IEdQVUNvbXB1dGVQYXNzRW5jb2RlciB7XG4gICAgaWYgKCF0aGlzLmNvbXB1dGVQYXNzRW5jb2Rlcikge1xuICAgICAgY29uc3QgY29tbWFuZEVuY29kZXIgPSB0aGlzLmdldENvbW1hbmRFbmNvZGVyKCk7XG4gICAgICBjb25zdCBjb21wdXRlUGFzc0Rlc2NyaXB0b3I6IEdQVUNvbXB1dGVQYXNzRGVzY3JpcHRvciA9IHt9O1xuXG4gICAgICBpZiAodGhpcy5xdWVyeVR5cGUgPT09ICdhdC1wYXNzZXMnKSB7XG4gICAgICAgIGNvbXB1dGVQYXNzRGVzY3JpcHRvci50aW1lc3RhbXBXcml0ZXMgPSB7XG4gICAgICAgICAgcXVlcnlTZXQ6IHRoaXMucXVlcnlTZXQhLFxuICAgICAgICAgIGJlZ2lubmluZ09mUGFzc1dyaXRlSW5kZXg6IHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyICogMixcbiAgICAgICAgICBlbmRPZlBhc3NXcml0ZUluZGV4OiB0aGlzLnBlbmRpbmdEaXNwYXRjaE51bWJlciAqIDIgKyAxLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLmNvbXB1dGVQYXNzRW5jb2RlciA9IGNvbW1hbmRFbmNvZGVyLmJlZ2luQ29tcHV0ZVBhc3MoY29tcHV0ZVBhc3NEZXNjcmlwdG9yKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZVBhc3NFbmNvZGVyO1xuICB9XG5cbiAgZW5kQ29tcHV0ZVBhc3MoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29tcHV0ZVBhc3NFbmNvZGVyKSB7XG4gICAgICB0aGlzLmNvbXB1dGVQYXNzRW5jb2Rlci5lbmQoKTtcbiAgICAgIHRoaXMuY29tcHV0ZVBhc3NFbmNvZGVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBmbHVzaCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY29tbWFuZEVuY29kZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBUUkFDRV9GVU5DX0JFR0lOKCk7XG5cbiAgICB0aGlzLmVuZENvbXB1dGVQYXNzKCk7XG4gICAgbGV0IHF1ZXJ5UmVhZEJ1ZmZlcjogR1BVQnVmZmVyO1xuICAgIGlmICh0aGlzLnF1ZXJ5VHlwZSAhPT0gJ25vbmUnKSB7XG4gICAgICB0aGlzLmNvbW1hbmRFbmNvZGVyLnJlc29sdmVRdWVyeVNldChcbiAgICAgICAgdGhpcy5xdWVyeVNldCEsXG4gICAgICAgIDAsXG4gICAgICAgIHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyICogMixcbiAgICAgICAgdGhpcy5xdWVyeVJlc29sdmVCdWZmZXIhLFxuICAgICAgICAwLFxuICAgICAgKTtcblxuICAgICAgcXVlcnlSZWFkQnVmZmVyID0gdGhpcy5kZXZpY2UuY3JlYXRlQnVmZmVyKFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZVxuICAgICAgICB7IHNpemU6IHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyICogMiAqIDgsIHVzYWdlOiBHUFVCdWZmZXJVc2FnZS5NQVBfUkVBRCB8IEdQVUJ1ZmZlclVzYWdlLkNPUFlfRFNUIH0sXG4gICAgICApO1xuXG4gICAgICB0aGlzLnBlbmRpbmdRdWVyaWVzLnNldChxdWVyeVJlYWRCdWZmZXIsIHRoaXMucGVuZGluZ0tlcm5lbHMpO1xuICAgICAgdGhpcy5wZW5kaW5nS2VybmVscyA9IFtdO1xuICAgICAgdGhpcy5jb21tYW5kRW5jb2Rlci5jb3B5QnVmZmVyVG9CdWZmZXIoXG4gICAgICAgIHRoaXMucXVlcnlSZXNvbHZlQnVmZmVyISxcbiAgICAgICAgMCxcbiAgICAgICAgcXVlcnlSZWFkQnVmZmVyLFxuICAgICAgICAwLFxuICAgICAgICB0aGlzLnBlbmRpbmdEaXNwYXRjaE51bWJlciAqIDIgKiA4LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmRldmljZS5xdWV1ZS5zdWJtaXQoW3RoaXMuY29tbWFuZEVuY29kZXIuZmluaXNoKCldKTtcbiAgICB0aGlzLmdwdURhdGFNYW5hZ2VyLnJlZnJlc2hQZW5kaW5nQnVmZmVycygpO1xuICAgIHRoaXMuY29tbWFuZEVuY29kZXIgPSBudWxsO1xuICAgIHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyID0gMDtcblxuICAgIGlmICh0aGlzLnF1ZXJ5VHlwZSAhPT0gJ25vbmUnKSB7XG4gICAgICB2b2lkIHF1ZXJ5UmVhZEJ1ZmZlciEubWFwQXN5bmMoR1BVTWFwTW9kZS5SRUFEKS50aGVuKCgpID0+IHtcbiAgICAgICAgY29uc3QgbWFwcGVkRGF0YSA9IG5ldyBCaWdVaW50NjRBcnJheShxdWVyeVJlYWRCdWZmZXIuZ2V0TWFwcGVkUmFuZ2UoKSk7XG4gICAgICAgIGNvbnN0IHBlbmRpbmdLZXJuZWxzID0gdGhpcy5wZW5kaW5nUXVlcmllcy5nZXQocXVlcnlSZWFkQnVmZmVyKSE7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWFwcGVkRGF0YS5sZW5ndGggLyAyOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBwZW5kaW5nS2VybmVsSW5mbyA9IHBlbmRpbmdLZXJuZWxzW2ldO1xuICAgICAgICAgIGNvbnN0IGtlcm5lbElkID0gcGVuZGluZ0tlcm5lbEluZm8ua2VybmVsSWQ7XG4gICAgICAgICAgY29uc3Qga2VybmVsSW5mbyA9IHRoaXMua2VybmVscy5nZXQoa2VybmVsSWQpITtcbiAgICAgICAgICBjb25zdCBrZXJuZWxUeXBlID0ga2VybmVsSW5mby5rZXJuZWxUeXBlO1xuICAgICAgICAgIGNvbnN0IGtlcm5lbE5hbWUgPSBrZXJuZWxJbmZvLmtlcm5lbE5hbWU7XG4gICAgICAgICAgY29uc3QgcHJvZ3JhbU5hbWUgPSBwZW5kaW5nS2VybmVsSW5mby5wcm9ncmFtTmFtZTtcbiAgICAgICAgICBjb25zdCBpbnB1dFRlbnNvclZpZXdzID0gcGVuZGluZ0tlcm5lbEluZm8uaW5wdXRUZW5zb3JWaWV3cztcbiAgICAgICAgICBjb25zdCBvdXRwdXRUZW5zb3JWaWV3cyA9IHBlbmRpbmdLZXJuZWxJbmZvLm91dHB1dFRlbnNvclZpZXdzO1xuICAgICAgICAgIGNvbnN0IHN0YXJ0VGltZVU2NCA9IG1hcHBlZERhdGFbaSAqIDJdO1xuICAgICAgICAgIGNvbnN0IGVuZFRpbWVVNjQgPSBtYXBwZWREYXRhW2kgKiAyICsgMV07XG5cbiAgICAgICAgICBpZiAodHlwZW9mIHRoaXMucXVlcnlUaW1lQmFzZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRoaXMucXVlcnlUaW1lQmFzZSA9IHN0YXJ0VGltZVU2NDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBOdW1iZXIoc3RhcnRUaW1lVTY0IC0gdGhpcy5xdWVyeVRpbWVCYXNlKTtcbiAgICAgICAgICBjb25zdCBlbmRUaW1lID0gTnVtYmVyKGVuZFRpbWVVNjQgLSB0aGlzLnF1ZXJ5VGltZUJhc2UpO1xuXG4gICAgICAgICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihzdGFydFRpbWUpIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcihlbmRUaW1lKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luY29ycmVjdCB0aW1lc3RhbXAgcmFuZ2UnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGhpcy5lbnYud2ViZ3B1LnByb2ZpbGluZz8ub25kYXRhKSB7XG4gICAgICAgICAgICB0aGlzLmVudi53ZWJncHUucHJvZmlsaW5nLm9uZGF0YSh7XG4gICAgICAgICAgICAgIHZlcnNpb246IDEsXG4gICAgICAgICAgICAgIGlucHV0c01ldGFkYXRhOiBpbnB1dFRlbnNvclZpZXdzLm1hcCgodmFsdWUpID0+ICh7XG4gICAgICAgICAgICAgICAgZGltczogdmFsdWUuZGltcyxcbiAgICAgICAgICAgICAgICBkYXRhVHlwZTogdGVuc29yRGF0YVR5cGVFbnVtVG9TdHJpbmcodmFsdWUuZGF0YVR5cGUpLFxuICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICAgIG91dHB1dHNNZXRhZGF0YTogb3V0cHV0VGVuc29yVmlld3MubWFwKCh2YWx1ZSkgPT4gKHtcbiAgICAgICAgICAgICAgICBkaW1zOiB2YWx1ZS5kaW1zLFxuICAgICAgICAgICAgICAgIGRhdGFUeXBlOiB0ZW5zb3JEYXRhVHlwZUVudW1Ub1N0cmluZyh2YWx1ZS5kYXRhVHlwZSksXG4gICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICAga2VybmVsSWQsXG4gICAgICAgICAgICAgIGtlcm5lbFR5cGUsXG4gICAgICAgICAgICAgIGtlcm5lbE5hbWUsXG4gICAgICAgICAgICAgIHByb2dyYW1OYW1lLFxuICAgICAgICAgICAgICBzdGFydFRpbWUsXG4gICAgICAgICAgICAgIGVuZFRpbWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaWYgbm8gY2FsbGJhY2sgaXMgcHJvdmlkZWQsIHByaW50IHRoZSBwcm9maWxpbmcgbWVzc2FnZSB0byBjb25zb2xlXG4gICAgICAgICAgICBsZXQgaW5wdXRTaGFwZXMgPSAnJztcbiAgICAgICAgICAgIGlucHV0VGVuc29yVmlld3MuZm9yRWFjaCgodmFsdWUsIGkpID0+IHtcbiAgICAgICAgICAgICAgaW5wdXRTaGFwZXMgKz0gYGlucHV0WyR7aX1dOiBbJHt2YWx1ZS5kaW1zfV0gfCAke3RlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nKHZhbHVlLmRhdGFUeXBlKX0sIGA7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGxldCBvdXRwdXRTaGFwZXMgPSAnJztcbiAgICAgICAgICAgIG91dHB1dFRlbnNvclZpZXdzLmZvckVhY2goKHZhbHVlLCBpKSA9PiB7XG4gICAgICAgICAgICAgIG91dHB1dFNoYXBlcyArPSBgb3V0cHV0WyR7aX1dOiBbJHt2YWx1ZS5kaW1zfV0gfCAke3RlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nKHZhbHVlLmRhdGFUeXBlKX0sIGA7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgYFtwcm9maWxpbmddIGtlcm5lbCBcIiR7a2VybmVsSWR9fCR7a2VybmVsVHlwZX18JHtrZXJuZWxOYW1lfXwke3Byb2dyYW1OYW1lfVwiICR7aW5wdXRTaGFwZXN9JHtcbiAgICAgICAgICAgICAgICBvdXRwdXRTaGFwZXNcbiAgICAgICAgICAgICAgfWV4ZWN1dGlvbiB0aW1lOiAke2VuZFRpbWUgLSBzdGFydFRpbWV9IG5zYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIFRSQUNFKCdHUFUnLCBgJHtwcm9ncmFtTmFtZX06OiR7c3RhcnRUaW1lVTY0fTo6JHtlbmRUaW1lVTY0fWApO1xuICAgICAgICB9XG4gICAgICAgIHF1ZXJ5UmVhZEJ1ZmZlci51bm1hcCgpO1xuICAgICAgICB0aGlzLnBlbmRpbmdRdWVyaWVzLmRlbGV0ZShxdWVyeVJlYWRCdWZmZXIpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIFRSQUNFX0ZVTkNfRU5EKCk7XG4gIH1cblxuICAvKipcbiAgICogcnVuIGEgV2ViR1BVIHByb2dyYW0uXG4gICAqIEBwYXJhbSBwcm9ncmFtIGEgUHJvZ3JhbUluZm8gaW5zdGFuY2VcbiAgICogQHBhcmFtIGlucHV0VGVuc29yVmlld3MgYSBUZW5zb3JWaWV3IGFycmF5LiBlYWNoIGVsZW1lbnQgcmVwcmVzZW50cyBhIHZhbHVlIGFscmVhZHkgZXhpc3RzIGluIEdQVS5cbiAgICogQHBhcmFtIG91dHB1dEluZGljZXMgYW4gaW5kaWNlcyBhcnJheS4gZWFjaCBlbGVtZW50IGNhbiBiZSBlaXRoZXIgLTEgKHRlbXBvcmFyeSBkYXRhKSwgLTIgKHBlcnNpc3RlbnQgZGF0YSkgb3IgYW5cbiAgICogaW5kZXggdG8gdGhlIGtlcm5lbCdzIG91dHB1dC5cbiAgICogQHBhcmFtIGNyZWF0ZUtlcm5lbE91dHB1dCBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgY3JlYXRlIGEgdmFsdWUgdG8ga2VybmVsJ3Mgb3V0cHV0IHdpdGggdGhlIGdpdmVuIGluZGV4XG4gICAqIEBwYXJhbSBjcmVhdGVJbnRlcm1lZGlhdGVPdXRwdXQgYSBjYWxsYmFjayBmdW5jdGlvbiB0aGF0IGNyZWF0ZSBhIHZhbHVlIGFzIGEgaW50ZXJtZWRpYXRlIHZhbHVlLCBlaXRoZXIgdGVtcG9yYXJ5XG4gICAqIG9yIHBlcnNpc3RlbnQgKG93bmVkIGJ5IHRoZSBjdXJyZW50IGtlcm5lbClcbiAgICogQHJldHVybnMgYSBUZW5zb3JWaWV3IGFycmF5IHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LlxuICAgKi9cbiAgcnVuKFxuICAgIHByb2dyYW06IFByb2dyYW1JbmZvLFxuICAgIGlucHV0VGVuc29yVmlld3M6IHJlYWRvbmx5IFRlbnNvclZpZXdbXSxcbiAgICBvdXRwdXRJbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSxcbiAgICBjcmVhdGVLZXJuZWxPdXRwdXQ6IChpbmRleDogbnVtYmVyLCBkYXRhVHlwZTogbnVtYmVyLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSkgPT4gVGVuc29yVmlldyxcbiAgICBjcmVhdGVJbnRlcm1lZGlhdGVPdXRwdXQ6IChkYXRhVHlwZTogbnVtYmVyLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSkgPT4gVGVuc29yVmlldyxcbiAgICBvdXRwdXRDb3VudDogbnVtYmVyLFxuICApOiBUZW5zb3JWaWV3W10ge1xuICAgIFRSQUNFX0ZVTkNfQkVHSU4ocHJvZ3JhbS5uYW1lKTtcbiAgICAvLyBjcmVhdGUgaW5mbyBmb3IgaW5wdXRzXG4gICAgY29uc3QgaW5wdXREYXRhczogR3B1RGF0YVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dFRlbnNvclZpZXdzLmxlbmd0aDsgKytpKSB7XG4gICAgICBjb25zdCBkYXRhID0gaW5wdXRUZW5zb3JWaWV3c1tpXS5kYXRhO1xuICAgICAgLy8gaWYgdGVuc29yIHZpZXcgZGF0YSBpcyAwLCBpdCBtZWFucyB0aGUgb3V0cHV0IGlzIHplcm8tc2l6ZWQgdGVuc29yLCBhbmQgdGhlcmUgaXMgbm8gR1BVIGRhdGEgZm9yIGl0LlxuICAgICAgaWYgKGRhdGEgPT09IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBncHVEYXRhID0gdGhpcy5ncHVEYXRhTWFuYWdlci5nZXQoZGF0YSk7XG4gICAgICBpZiAoIWdwdURhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBubyBHUFUgZGF0YSBmb3IgaW5wdXQ6ICR7ZGF0YX1gKTtcbiAgICAgIH1cbiAgICAgIGlucHV0RGF0YXMucHVzaChncHVEYXRhKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IG91dHB1dHMsIGRpc3BhdGNoR3JvdXAsIHByb2dyYW1Vbmlmb3JtcyB9ID0gcHJvZ3JhbS5nZXRSdW5EYXRhKGlucHV0VGVuc29yVmlld3MpO1xuXG4gICAgLy8gY2hlY2sgb3V0cHV0IGluZGljZXNcbiAgICBjb25zdCB2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzID0gb3V0cHV0SW5kaWNlcy5sZW5ndGggPT09IDAgPyBvdXRwdXRzLm1hcCgoXywgaSkgPT4gaSkgOiBvdXRwdXRJbmRpY2VzO1xuICAgIGlmICh2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzLmxlbmd0aCAhPT0gb3V0cHV0cy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgT3V0cHV0IHNpemUgJHt2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzLmxlbmd0aH0gbXVzdCBiZSBlcXVhbCB0byAke291dHB1dHMubGVuZ3RofS5gKTtcbiAgICB9XG5cbiAgICAvLyBjcmVhdGUgaW5mbyBmb3Igb3V0cHV0c1xuICAgIGNvbnN0IG91dHB1dFRlbnNvclZpZXdzOiBUZW5zb3JWaWV3W10gPSBbXTtcbiAgICBjb25zdCBvdXRwdXREYXRhczogR3B1RGF0YVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAvLyB2YWx1ZSAtMSBhbmQgLTIgYXJlIHVzZWQgZm9yIGNyZWF0aW5nIHRlbXBvcmFyeSBhbmQgcGVyc2lzdGVudCBvdXRwdXRzLlxuICAgICAgLy8gdmFsdWUgLTMgaXMgdXNlZCBmb3IgcGxhY2Vob2xkZXIgb3V0cHV0LiBTbyAtMywgLTIsIC0xIGFuZCAwLCAxLCAyLCAuLi4gYXJlIHZhbGlkXG4gICAgICAvLyBvdXRwdXQgaW5kaWNlcy4gc2VlIHR5cGUgZGVmaW5pdGlvbiBvZiBDb21wdXRlQ29udGV4dElucHV0c091dHB1dHNNYXBwaW5nIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICBpZiAoXG4gICAgICAgICFOdW1iZXIuaXNJbnRlZ2VyKHZhbGlkYXRlZE91dHB1dEluZGljZXNbaV0pIHx8XG4gICAgICAgIHZhbGlkYXRlZE91dHB1dEluZGljZXNbaV0gPCAtMyB8fFxuICAgICAgICB2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzW2ldID49IG91dHB1dENvdW50XG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG91dHB1dCBpbmRleDogJHt2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzW2ldfWApO1xuICAgICAgfVxuICAgICAgaWYgKHZhbGlkYXRlZE91dHB1dEluZGljZXNbaV0gPT09IC0zKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgaXNUZW1wb3JhcnkgPSB2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzW2ldID09PSAtMTtcbiAgICAgIGNvbnN0IGlzUGVyc2lzdGVudCA9IHZhbGlkYXRlZE91dHB1dEluZGljZXNbaV0gPT09IC0yO1xuICAgICAgY29uc3QgdGVuc29yVmlldyA9XG4gICAgICAgIGlzVGVtcG9yYXJ5IHx8IGlzUGVyc2lzdGVudFxuICAgICAgICAgID8gY3JlYXRlSW50ZXJtZWRpYXRlT3V0cHV0KG91dHB1dHNbaV0uZGF0YVR5cGUsIG91dHB1dHNbaV0uZGltcylcbiAgICAgICAgICA6IGNyZWF0ZUtlcm5lbE91dHB1dCh2YWxpZGF0ZWRPdXRwdXRJbmRpY2VzW2ldLCBvdXRwdXRzW2ldLmRhdGFUeXBlLCBvdXRwdXRzW2ldLmRpbXMpO1xuICAgICAgb3V0cHV0VGVuc29yVmlld3MucHVzaCh0ZW5zb3JWaWV3KTtcbiAgICAgIC8vIGlmIHRlbnNvciB2aWV3IGRhdGEgaXMgMCwgaXQgbWVhbnMgdGhlIG91dHB1dCBpcyB6ZXJvLXNpemVkIHRlbnNvciwgYW5kIHRoZXJlIGlzIG5vIEdQVSBkYXRhIGZvciBpdC5cbiAgICAgIGlmICh0ZW5zb3JWaWV3LmRhdGEgPT09IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBncHVEYXRhID0gdGhpcy5ncHVEYXRhTWFuYWdlci5nZXQodGVuc29yVmlldy5kYXRhKTtcbiAgICAgIGlmICghZ3B1RGF0YSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIEdQVSBkYXRhIGZvciBvdXRwdXQ6ICR7dGVuc29yVmlldy5kYXRhfWApO1xuICAgICAgfVxuICAgICAgaWYgKGlzVGVtcG9yYXJ5KSB7XG4gICAgICAgIHRoaXMudGVtcG9yYXJ5RGF0YS5wdXNoKGdwdURhdGEpO1xuICAgICAgfVxuICAgICAgaWYgKGlzUGVyc2lzdGVudCkge1xuICAgICAgICBsZXQgcGVyc2lzdGVudERhdGEgPSB0aGlzLmtlcm5lbFBlcnNpc3RlbnREYXRhLmdldCh0aGlzLmN1cnJlbnRLZXJuZWxJZCEpO1xuICAgICAgICBpZiAoIXBlcnNpc3RlbnREYXRhKSB7XG4gICAgICAgICAgcGVyc2lzdGVudERhdGEgPSBbXTtcbiAgICAgICAgICB0aGlzLmtlcm5lbFBlcnNpc3RlbnREYXRhLnNldCh0aGlzLmN1cnJlbnRLZXJuZWxJZCEsIHBlcnNpc3RlbnREYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBwZXJzaXN0ZW50RGF0YS5wdXNoKGdwdURhdGEpO1xuICAgICAgfVxuICAgICAgb3V0cHV0RGF0YXMucHVzaChncHVEYXRhKTtcbiAgICB9XG5cbiAgICAvLyB3aGVuIHRoZXJlIGFyZSBhbnkgemVyby1zaXplZCB0ZW5zb3IgaW4gdGhlIGlucHV0cyBvciBvdXRwdXRzLCB3ZSBzaG91bGQgcmVwb3J0IGVycm9yIHVubGVzcyBhbGwgb3V0cHV0cyBhcmVcbiAgICAvLyB6ZXJvLXNpemVkIHRlbnNvcnMuXG4gICAgaWYgKGlucHV0RGF0YXMubGVuZ3RoICE9PSBpbnB1dFRlbnNvclZpZXdzLmxlbmd0aCB8fCBvdXRwdXREYXRhcy5sZW5ndGggIT09IG91dHB1dFRlbnNvclZpZXdzLmxlbmd0aCkge1xuICAgICAgLy8gaWYgYWxsIG91dHB1dHMgYXJlIHplcm8tc2l6ZWQgdGVuc29ycywgdGhlcmUgaXMgbm8gbmVlZCB0byBydW4gdGhlIHByb2dyYW0uXG4gICAgICBpZiAob3V0cHV0RGF0YXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIFRSQUNFX0ZVTkNfRU5EKHByb2dyYW0ubmFtZSk7XG4gICAgICAgIHJldHVybiBvdXRwdXRUZW5zb3JWaWV3cztcbiAgICAgIH1cbiAgICAgIC8vIGlmIHNvbWUgb3V0cHV0cyBhcmUgemVyby1zaXplZCB0ZW5zb3JzLCByZXBvcnQgYW4gZXJyb3IuXG4gICAgICAvL1xuICAgICAgLy8gVE9ETzogc28gZmFyIHdlIGRvbid0IHNlZSBhbnkgdXNlIGNhc2UgdGhhdCBvdXRwdXRzIGluY2x1ZGUgYm90aCB6ZXJvLXNpemVkIHRlbnNvcnMgYW5kIG5vbi16ZXJvLXNpemVkIHRlbnNvcnMuXG4gICAgICAvLyBJZiB3ZSBzZWUgc3VjaCB1c2UgY2FzZSwgd2UgbmVlZCB0byBtYWtlIGEgY2hhbmdlIGhlcmUgdG8gc3VwcG9ydCBpdC5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFByb2dyYW0gJHtwcm9ncmFtLm5hbWV9IGhhcyB6ZXJvLXNpemVkIHRlbnNvcihzKSBpbiBpbnB1dHMgb3Igb3V0cHV0cy4gVGhpcyBpcyBub3Qgc3VwcG9ydGVkIG5vdy5gLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBsb2FkIHVuaWZvcm1zXG4gICAgLy8gVE9ETzogYWRkIGNhY2hlIGZvciB1bmlmb3JtIChpcyBpdCBuZWNlc3Nhcnk/KVxuICAgIC8vXG4gICAgbGV0IHVuaWZvcm1CdWZmZXJCaW5kaW5nOiBHUFVCaW5kaW5nUmVzb3VyY2UgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHByb2dyYW1Vbmlmb3Jtcykge1xuICAgICAgbGV0IGN1cnJlbnRPZmZzZXQgPSAwO1xuICAgICAgY29uc3Qgb2Zmc2V0czogbnVtYmVyW10gPSBbXTtcblxuICAgICAgcHJvZ3JhbVVuaWZvcm1zLmZvckVhY2goKHYpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHR5cGVvZiB2LmRhdGEgPT09ICdudW1iZXInID8gW3YuZGF0YV0gOiB2LmRhdGE7XG4gICAgICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBodHRwczovL3d3dy53My5vcmcvVFIvV0dTTC8jYWxpZ25vZlxuICAgICAgICBjb25zdCBzaXplT2ZFbGVtZW50ID0gdi50eXBlID09PSBEYXRhVHlwZS5mbG9hdDE2ID8gMiA6IDQ7XG4gICAgICAgIGxldCBzaXplT2ZWZWNPck1hdDtcbiAgICAgICAgbGV0IGJhc2VBbGlnbm1lbnQ7XG4gICAgICAgIGlmICh2LnR5cGUgPT09IERhdGFUeXBlLmZsb2F0MTYpIHtcbiAgICAgICAgICBiYXNlQWxpZ25tZW50ID0gZGF0YS5sZW5ndGggPiA0ID8gMTYgOiBkYXRhLmxlbmd0aCA+IDIgPyA4IDogZGF0YS5sZW5ndGggKiBzaXplT2ZFbGVtZW50O1xuICAgICAgICAgIHNpemVPZlZlY09yTWF0ID0gZGF0YS5sZW5ndGggPiA0ID8gMTYgOiBzaXplT2ZFbGVtZW50ICogZGF0YS5sZW5ndGg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYmFzZUFsaWdubWVudCA9IGRhdGEubGVuZ3RoIDw9IDIgPyBkYXRhLmxlbmd0aCAqIHNpemVPZkVsZW1lbnQgOiAxNjtcbiAgICAgICAgICBzaXplT2ZWZWNPck1hdCA9IDE2O1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRPZmZzZXQgPSBNYXRoLmNlaWwoY3VycmVudE9mZnNldCAvIGJhc2VBbGlnbm1lbnQpICogYmFzZUFsaWdubWVudDtcbiAgICAgICAgb2Zmc2V0cy5wdXNoKGN1cnJlbnRPZmZzZXQpO1xuICAgICAgICAvLyBGb3Igbm9uLWZsb2F0MTYgdHlwZSwgd2hlbiBkYXRhLmxlbmd0aCA+IDQsIHRoZSB1bmlmb3JtIHZhcmlhYmxlIGlzIG9mIHR5cGUgYXJyYXk8dmVjNDxpMzJ8dTMyfGYzMj4sTj4sIHdoZXJlXG4gICAgICAgIC8vIE4gPSBNYXRoLmNlaWwoZGF0YS5sZW5ndGggLyA0KSBhbmQgU2l6ZU9mKHZlYzQ8aTMyfHUzMnxmMzI+KSA9IDE2LiBUaGUgdG90YWwgYnl0ZSBsZW5ndGggaXMgTiAqXG4gICAgICAgIC8vIFNpemVPZih2ZWM0PGkzMnx1MzJ8ZjMyPikuIEZvciBmbG9hdDE2IHR5cGUsIHdoZW4gZGF0YS5sZW5ndGggPiA0LCB0aGUgdW5pZm9ybSB2YXJpYWJsZSBpcyBvZiB0eXBlXG4gICAgICAgIC8vIGFycmF5PG1hdDJ4NDxmMTY+LE4+LCB3aGVyZSBOID0gTWF0aC5jZWlsKGRhdGEubGVuZ3RoIC8gOCkgYW5kIFNpemVPZihtYXQyeDQ8ZjE2PikgPSAxNi4gVGhlIHRvdGFsIGJ5dGVcbiAgICAgICAgLy8gbGVuZ3RoIGlzIE4gKiBTaXplT2YobWF0Mng0PGYxNj4pLlxuICAgICAgICBjb25zdCBlbGVtZW50UGVyVmVjT3JNYXQgPSB2LnR5cGUgPT09IERhdGFUeXBlLmZsb2F0MTYgPyA4IDogNDtcbiAgICAgICAgY3VycmVudE9mZnNldCArPVxuICAgICAgICAgIGRhdGEubGVuZ3RoID4gNCA/IE1hdGguY2VpbChkYXRhLmxlbmd0aCAvIGVsZW1lbnRQZXJWZWNPck1hdCkgKiBzaXplT2ZWZWNPck1hdCA6IGRhdGEubGVuZ3RoICogc2l6ZU9mRWxlbWVudDtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBNZWV0IGFsaWdubWVudCBvZiBzdHJ1Y3QgaGVyZTogaHR0cHM6Ly93d3cudzMub3JnL1RSL1dHU0wvI2FsaWdubWVudC1hbmQtc2l6ZS4gRm9yIHNpbXBsaWNpdHksIHNldFxuICAgICAgLy8gbWF4QWxpZ25tZW50T2ZGaWVsZCB0byAxNiBzaW5jZSB0aGUgdW5kZXJseWluZyBidWZmZXIgaGFzIGJlZW4gcm91bmRlZCB1cCB0byAxNi5cbiAgICAgIGNvbnN0IG1heEFsaWdubWVudE9mRmllbGQgPSAxNjtcbiAgICAgIGN1cnJlbnRPZmZzZXQgPSBNYXRoLmNlaWwoY3VycmVudE9mZnNldCAvIG1heEFsaWdubWVudE9mRmllbGQpICogbWF4QWxpZ25tZW50T2ZGaWVsZDtcbiAgICAgIGNvbnN0IGFycmF5QnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGN1cnJlbnRPZmZzZXQpO1xuICAgICAgcHJvZ3JhbVVuaWZvcm1zLmZvckVhY2goKHYsIGkpID0+IHtcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gb2Zmc2V0c1tpXTtcbiAgICAgICAgY29uc3QgZGF0YSA9IHR5cGVvZiB2LmRhdGEgPT09ICdudW1iZXInID8gW3YuZGF0YV0gOiB2LmRhdGE7XG4gICAgICAgIGlmICh2LnR5cGUgPT09IERhdGFUeXBlLmludDMyKSB7XG4gICAgICAgICAgbmV3IEludDMyQXJyYXkoYXJyYXlCdWZmZXIsIG9mZnNldCwgZGF0YS5sZW5ndGgpLnNldChkYXRhKTtcbiAgICAgICAgfSBlbHNlIGlmICh2LnR5cGUgPT09IERhdGFUeXBlLnVpbnQzMikge1xuICAgICAgICAgIG5ldyBVaW50MzJBcnJheShhcnJheUJ1ZmZlciwgb2Zmc2V0LCBkYXRhLmxlbmd0aCkuc2V0KGRhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKHYudHlwZSA9PT0gRGF0YVR5cGUuZmxvYXQxNikge1xuICAgICAgICAgIG5ldyBVaW50MTZBcnJheShhcnJheUJ1ZmZlciwgb2Zmc2V0LCBkYXRhLmxlbmd0aCkuc2V0KGRhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKHYudHlwZSA9PT0gRGF0YVR5cGUuZmxvYXQpIHtcbiAgICAgICAgICBuZXcgRmxvYXQzMkFycmF5KGFycmF5QnVmZmVyLCBvZmZzZXQsIGRhdGEubGVuZ3RoKS5zZXQoZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCB1bmlmb3JtIHR5cGU6ICR7dGVuc29yRGF0YVR5cGVFbnVtVG9TdHJpbmcodi50eXBlKX1gKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHVuaWZvcm1CdWZmZXJEYXRhID1cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWJpdHdpc2VcbiAgICAgICAgdGhpcy5ncHVEYXRhTWFuYWdlci5jcmVhdGUoY3VycmVudE9mZnNldCwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QgfCBHUFVCdWZmZXJVc2FnZS5VTklGT1JNKTtcbiAgICAgIHRoaXMuZGV2aWNlLnF1ZXVlLndyaXRlQnVmZmVyKHVuaWZvcm1CdWZmZXJEYXRhLmJ1ZmZlciwgMCwgYXJyYXlCdWZmZXIsIDAsIGN1cnJlbnRPZmZzZXQpO1xuICAgICAgdGhpcy5ncHVEYXRhTWFuYWdlci5yZWxlYXNlKHVuaWZvcm1CdWZmZXJEYXRhLmlkKTtcbiAgICAgIHVuaWZvcm1CdWZmZXJCaW5kaW5nID0geyBvZmZzZXQ6IDAsIHNpemU6IGN1cnJlbnRPZmZzZXQsIGJ1ZmZlcjogdW5pZm9ybUJ1ZmZlckRhdGEuYnVmZmVyIH07XG4gICAgfVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZERpc3BhdGNoR3JvdXAgPSB0aGlzLnByb2dyYW1NYW5hZ2VyLm5vcm1hbGl6ZURpc3BhdGNoR3JvdXBTaXplKGRpc3BhdGNoR3JvdXApO1xuICAgIGNvbnN0IGlzMURpbWVuc2lvbkRpc3BhdGNoID0gbm9ybWFsaXplZERpc3BhdGNoR3JvdXBbMV0gPT09IDEgJiYgbm9ybWFsaXplZERpc3BhdGNoR3JvdXBbMl0gPT09IDE7XG4gICAgLy8gZ2V0IHByb2dyYW0gaW5mb1xuICAgIGNvbnN0IGtleSA9IGdldFByb2dyYW1JbmZvVW5pcXVlS2V5KHByb2dyYW0sIGlucHV0VGVuc29yVmlld3MsIGlzMURpbWVuc2lvbkRpc3BhdGNoKTtcbiAgICBsZXQgYXJ0aWZhY3QgPSB0aGlzLnByb2dyYW1NYW5hZ2VyLmdldEFydGlmYWN0KGtleSk7XG4gICAgaWYgKCFhcnRpZmFjdCkge1xuICAgICAgYXJ0aWZhY3QgPSB0aGlzLnByb2dyYW1NYW5hZ2VyLmJ1aWxkKHByb2dyYW0sIG5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwKTtcbiAgICAgIHRoaXMucHJvZ3JhbU1hbmFnZXIuc2V0QXJ0aWZhY3Qoa2V5LCBhcnRpZmFjdCk7XG4gICAgICBMT0dfREVCVUcoJ2luZm8nLCAoKSA9PiBgW2FydGlmYWN0XSBrZXk6ICR7a2V5fSwgcHJvZ3JhbU5hbWU6ICR7cHJvZ3JhbS5uYW1lfWApO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIHVuaWZvcm0gdmFyaWFibGVzXG4gICAgaWYgKHByb2dyYW1Vbmlmb3JtcyAmJiBhcnRpZmFjdC51bmlmb3JtVmFyaWFibGVzSW5mbykge1xuICAgICAgaWYgKHByb2dyYW1Vbmlmb3Jtcy5sZW5ndGggIT09IGFydGlmYWN0LnVuaWZvcm1WYXJpYWJsZXNJbmZvLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFVuaWZvcm0gdmFyaWFibGVzIGNvdW50IG1pc21hdGNoOiBleHBlY3QgJHthcnRpZmFjdC51bmlmb3JtVmFyaWFibGVzSW5mby5sZW5ndGh9LCBnb3QgJHtcbiAgICAgICAgICAgIHByb2dyYW1Vbmlmb3Jtcy5sZW5ndGhcbiAgICAgICAgICB9IGluIHByb2dyYW0gXCIke2FydGlmYWN0LnByb2dyYW1JbmZvLm5hbWV9XCIuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvZ3JhbVVuaWZvcm1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHVuaWZvcm0gPSBwcm9ncmFtVW5pZm9ybXNbaV07XG4gICAgICAgIGNvbnN0IGFjdHVhbFR5cGUgPSB1bmlmb3JtLnR5cGU7XG4gICAgICAgIGNvbnN0IGFjdHVhbExlbmd0aCA9IHR5cGVvZiB1bmlmb3JtLmRhdGEgPT09ICdudW1iZXInID8gMSA6IHVuaWZvcm0uZGF0YS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IFt0eXBlLCBsZW5ndGhdID0gYXJ0aWZhY3QudW5pZm9ybVZhcmlhYmxlc0luZm9baV07XG4gICAgICAgIGlmIChhY3R1YWxUeXBlICE9PSB0eXBlIHx8IGFjdHVhbExlbmd0aCAhPT0gbGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFVuaWZvcm0gdmFyaWFibGUgJHtpfSBtaXNtYXRjaDogZXhwZWN0IHR5cGUgJHt0eXBlfSB3aXRoIHNpemUgJHtsZW5ndGh9LCBnb3QgdHlwZSAke1xuICAgICAgICAgICAgICBhY3R1YWxUeXBlXG4gICAgICAgICAgICB9IHdpdGggc2l6ZSAke2FjdHVhbExlbmd0aH0gaW4gcHJvZ3JhbSBcIiR7YXJ0aWZhY3QucHJvZ3JhbUluZm8ubmFtZX1cIi5gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBMT0dfREVCVUcoXG4gICAgICAnaW5mbycsXG4gICAgICAoKSA9PlxuICAgICAgICBgW1Byb2dyYW1NYW5hZ2VyXSBydW4gXCIke3Byb2dyYW0ubmFtZX1cIiAoa2V5PSR7a2V5fSkgd2l0aCAke25vcm1hbGl6ZWREaXNwYXRjaEdyb3VwWzBdfXgke1xuICAgICAgICAgIG5vcm1hbGl6ZWREaXNwYXRjaEdyb3VwWzFdXG4gICAgICAgIH14JHtub3JtYWxpemVkRGlzcGF0Y2hHcm91cFsyXX1gLFxuICAgICk7XG5cbiAgICBpZiAodGhpcy5xdWVyeVR5cGUgIT09ICdub25lJyB8fCB0aGlzLnNlc3Npb25TdGF0dXMgPT09ICdjYXB0dXJpbmcnKSB7XG4gICAgICBjb25zdCBwZW5kaW5nS2VybmVsSW5mbzogUGVuZGluZ0tlcm5lbEluZm8gPSB7XG4gICAgICAgIGtlcm5lbElkOiB0aGlzLmN1cnJlbnRLZXJuZWxJZCEsXG4gICAgICAgIHByb2dyYW1OYW1lOiBhcnRpZmFjdC5wcm9ncmFtSW5mby5uYW1lLFxuICAgICAgICBpbnB1dFRlbnNvclZpZXdzLFxuICAgICAgICBvdXRwdXRUZW5zb3JWaWV3cyxcbiAgICAgIH07XG4gICAgICB0aGlzLnBlbmRpbmdLZXJuZWxzLnB1c2gocGVuZGluZ0tlcm5lbEluZm8pO1xuXG4gICAgICBpZiAodGhpcy5zZXNzaW9uU3RhdHVzID09PSAnY2FwdHVyaW5nJykge1xuICAgICAgICBjb25zdCBzZXNzaW9uUGVuZGluZ0tlcm5lbHMgPSB0aGlzLmNhcHR1cmVkUGVuZGluZ0tlcm5lbHMuZ2V0KHRoaXMuY3VycmVudFNlc3Npb25JZCEpO1xuICAgICAgICBzZXNzaW9uUGVuZGluZ0tlcm5lbHMhLnB1c2gocGVuZGluZ0tlcm5lbEluZm8pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMucHJvZ3JhbU1hbmFnZXIucnVuKGFydGlmYWN0LCBpbnB1dERhdGFzLCBvdXRwdXREYXRhcywgbm9ybWFsaXplZERpc3BhdGNoR3JvdXAsIHVuaWZvcm1CdWZmZXJCaW5kaW5nKTtcblxuICAgIFRSQUNFX0ZVTkNfRU5EKHByb2dyYW0ubmFtZSk7XG4gICAgcmV0dXJuIG91dHB1dFRlbnNvclZpZXdzO1xuICB9XG5cbiAgdXBsb2FkKGdwdURhdGFJZDogbnVtYmVyLCBkYXRhOiBVaW50OEFycmF5KTogdm9pZCB7XG4gICAgdGhpcy5ncHVEYXRhTWFuYWdlci51cGxvYWQoZ3B1RGF0YUlkLCBkYXRhKTtcbiAgfVxuXG4gIG1lbWNweShzcmM6IG51bWJlciwgZHN0OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmdwdURhdGFNYW5hZ2VyLm1lbWNweShzcmMsIGRzdCk7XG4gIH1cblxuICBhc3luYyBkb3dubG9hZChncHVEYXRhSWQ6IG51bWJlciwgZ2V0VGFyZ2V0QnVmZmVyOiAoKSA9PiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gdGhlIHVuZGVybHlpbmcgYnVmZmVyIG1heSBiZSBjaGFuZ2VkIGFmdGVyIHRoZSBhc3luYyBmdW5jdGlvbiBpcyBjYWxsZWQuIHNvIHdlIHVzZSBhIGdldHRlciBmdW5jdGlvbiB0byBtYWtlIHN1cmVcbiAgICAvLyB0aGUgYnVmZmVyIGlzIHVwLXRvLWRhdGUuXG4gICAgYXdhaXQgdGhpcy5ncHVEYXRhTWFuYWdlci5kb3dubG9hZChncHVEYXRhSWQsIGdldFRhcmdldEJ1ZmZlcik7XG4gIH1cblxuICBhbGxvYyhzaXplOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmdwdURhdGFNYW5hZ2VyLmNyZWF0ZShzaXplKS5pZDtcbiAgfVxuXG4gIGZyZWUocHRyOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmdwdURhdGFNYW5hZ2VyLnJlbGVhc2UocHRyKTtcbiAgfVxuXG4gIGNyZWF0ZUtlcm5lbChrZXJuZWxUeXBlOiBzdHJpbmcsIGtlcm5lbElkOiBudW1iZXIsIGF0dHJpYnV0ZTogdW5rbm93biwga2VybmVsTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3Qgb3AgPSBXRUJHUFVfT1BfUkVTT0xWRV9SVUxFUy5nZXQoa2VybmVsVHlwZSk7XG4gICAgaWYgKCFvcCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBrZXJuZWwgbm90IGltcGxlbWVudGVkOiAke2tlcm5lbFR5cGV9YCk7XG4gICAgfVxuXG4gICAgY29uc3Qga2VybmVsSW5mbzogS2VybmVsSW5mbyA9IHtcbiAgICAgIGtlcm5lbFR5cGUsXG4gICAgICBrZXJuZWxOYW1lLFxuICAgICAga2VybmVsRW50cnk6IG9wWzBdLFxuICAgICAgYXR0cmlidXRlczogW29wWzFdLCBhdHRyaWJ1dGVdLFxuICAgIH07XG4gICAgdGhpcy5rZXJuZWxzLnNldChrZXJuZWxJZCwga2VybmVsSW5mbyk7XG4gIH1cblxuICByZWxlYXNlS2VybmVsKGtlcm5lbElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBwZXJzaXN0ZW50RGF0YSA9IHRoaXMua2VybmVsUGVyc2lzdGVudERhdGEuZ2V0KGtlcm5lbElkKTtcbiAgICBpZiAocGVyc2lzdGVudERhdGEpIHtcbiAgICAgIGZvciAoY29uc3QgZGF0YSBvZiBwZXJzaXN0ZW50RGF0YSkge1xuICAgICAgICB0aGlzLmdwdURhdGFNYW5hZ2VyLnJlbGVhc2UoZGF0YS5pZCk7XG4gICAgICB9XG4gICAgICB0aGlzLmtlcm5lbFBlcnNpc3RlbnREYXRhLmRlbGV0ZShrZXJuZWxJZCk7XG4gICAgfVxuXG4gICAgdGhpcy5rZXJuZWxDdXN0b21EYXRhLmRlbGV0ZShrZXJuZWxJZCk7XG4gICAgdGhpcy5rZXJuZWxzLmRlbGV0ZShrZXJuZWxJZCk7XG4gIH1cblxuICBjb21wdXRlS2VybmVsKGtlcm5lbElkOiBudW1iZXIsIGNvbnRleHQ6IENvbXB1dGVDb250ZXh0LCBlcnJvcnM6IEFycmF5PFByb21pc2U8c3RyaW5nIHwgbnVsbD4+KTogbnVtYmVyIHtcbiAgICBjb25zdCBrZXJuZWwgPSB0aGlzLmtlcm5lbHMuZ2V0KGtlcm5lbElkKTtcbiAgICBpZiAoIWtlcm5lbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBrZXJuZWwgbm90IGNyZWF0ZWQ6ICR7a2VybmVsSWR9YCk7XG4gICAgfVxuICAgIGNvbnN0IGtlcm5lbFR5cGUgPSBrZXJuZWwua2VybmVsVHlwZTtcbiAgICBjb25zdCBrZXJuZWxOYW1lID0ga2VybmVsLmtlcm5lbE5hbWU7XG4gICAgY29uc3Qga2VybmVsRW50cnkgPSBrZXJuZWwua2VybmVsRW50cnk7XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IGtlcm5lbC5hdHRyaWJ1dGVzO1xuICAgIGlmICh0aGlzLmN1cnJlbnRLZXJuZWxJZCAhPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBrZXJuZWwgXCJbJHtrZXJuZWxUeXBlfV0gJHtrZXJuZWxOYW1lfVwiIGlzIG5vdCBhbGxvd2VkIHRvIGJlIGNhbGxlZCByZWN1cnNpdmVseWApO1xuICAgIH1cbiAgICB0aGlzLmN1cnJlbnRLZXJuZWxJZCA9IGtlcm5lbElkO1xuXG4gICAgLy8gcGFyc2UgYXR0cmlidXRlcyBpZiBuZWNlc3NhcnlcbiAgICBpZiAoYXR0cmlidXRlc1swXSkge1xuICAgICAgYXR0cmlidXRlc1sxXSA9IGF0dHJpYnV0ZXNbMF0oYXR0cmlidXRlc1sxXSk7XG4gICAgICBhdHRyaWJ1dGVzWzBdID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIExPR19ERUJVRygnaW5mbycsICgpID0+IGBbV2ViR1BVXSBTdGFydCB0byBydW4ga2VybmVsIFwiWyR7a2VybmVsVHlwZX1dICR7a2VybmVsTmFtZX1cIi4uLmApO1xuXG4gICAgY29uc3QgdXNlRXJyb3JTY29wZSA9IHRoaXMuZW52LmRlYnVnO1xuXG4gICAgdGhpcy50ZW1wb3JhcnlEYXRhID0gW107XG4gICAgdHJ5IHtcbiAgICAgIGlmICh1c2VFcnJvclNjb3BlKSB7XG4gICAgICAgIHRoaXMuZGV2aWNlLnB1c2hFcnJvclNjb3BlKCd2YWxpZGF0aW9uJyk7XG4gICAgICB9XG5cbiAgICAgIGtlcm5lbEVudHJ5KGNvbnRleHQsIGF0dHJpYnV0ZXNbMV0pO1xuICAgICAgcmV0dXJuIDA7IC8vIE9SVF9PS1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGVycm9ycy5wdXNoKFByb21pc2UucmVzb2x2ZShgW1dlYkdQVV0gS2VybmVsIFwiWyR7a2VybmVsVHlwZX1dICR7a2VybmVsTmFtZX1cIiBmYWlsZWQuICR7ZX1gKSk7XG4gICAgICByZXR1cm4gMTsgLy8gT1JUX0ZBSUxcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKHVzZUVycm9yU2NvcGUpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgICAgdGhpcy5kZXZpY2VcbiAgICAgICAgICAgIC5wb3BFcnJvclNjb3BlKClcbiAgICAgICAgICAgIC50aGVuKChlcnIpID0+XG4gICAgICAgICAgICAgIGVyciA/IGBHUFUgdmFsaWRhdGlvbiBlcnJvciBmb3Iga2VybmVsIFwiWyR7a2VybmVsVHlwZX1dICR7a2VybmVsTmFtZX1cIjogJHtlcnIubWVzc2FnZX1gIDogbnVsbCxcbiAgICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZGF0YSBvZiB0aGlzLnRlbXBvcmFyeURhdGEpIHtcbiAgICAgICAgdGhpcy5ncHVEYXRhTWFuYWdlci5yZWxlYXNlKGRhdGEuaWQpO1xuICAgICAgfVxuICAgICAgdGhpcy50ZW1wb3JhcnlEYXRhID0gW107XG4gICAgICB0aGlzLmN1cnJlbnRLZXJuZWxJZCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLy8gI3JlZ2lvbiBleHRlcm5hbCBidWZmZXJcbiAgcmVnaXN0ZXJCdWZmZXIoc2Vzc2lvbklkOiBudW1iZXIsIGluZGV4OiBudW1iZXIsIGJ1ZmZlcjogR1BVQnVmZmVyLCBzaXplOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBzZXNzaW9uSW5wdXRPdXRwdXRNYXBwaW5nID0gdGhpcy5zZXNzaW9uRXh0ZXJuYWxEYXRhTWFwcGluZy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoIXNlc3Npb25JbnB1dE91dHB1dE1hcHBpbmcpIHtcbiAgICAgIHNlc3Npb25JbnB1dE91dHB1dE1hcHBpbmcgPSBuZXcgTWFwKCk7XG4gICAgICB0aGlzLnNlc3Npb25FeHRlcm5hbERhdGFNYXBwaW5nLnNldChzZXNzaW9uSWQsIHNlc3Npb25JbnB1dE91dHB1dE1hcHBpbmcpO1xuICAgIH1cblxuICAgIC8vIHRoZSBidWZmZXIgbWF5IGJlIHVzZXIgY3JlYXRlZCwgb3IgbWFuYWdlZCBieSBHUFUgZGF0YSBtYW5hZ2VyLlxuICAgIC8vIFRoZSBHUFUgZGF0YSBtYW5hZ2VyIHdpbGwgbm90IG1hbmFnZSB0aGVzZSBidWZmZXJzLiB3ZSByZWdpc3RlciB0aGVtIGFzIGV4dGVybmFsIGJ1ZmZlcnMuXG4gICAgLy9cbiAgICAvLyBUaGUgbWFwIGBzZXNzaW9uSW5wdXRPdXRwdXRNYXBwaW5nYCBpcyB1c2VkIHRvIHN0b3JlIHRoZSBkYXRhIElEIGFuZCBidWZmZXIgZm9yIGVhY2ggaW5wdXQvb3V0cHV0LiBPbmNlIGFcbiAgICAvLyBzcGVjaWZpYyBpbnB1dC9vdXRwdXQgaXMgcmVnaXN0ZXJlZCwgdGhlIGRhdGEgSUQgd2lsbCBub3QgY2hhbmdlLlxuICAgIGNvbnN0IHByZXZpb3VzQnVmZmVyID0gc2Vzc2lvbklucHV0T3V0cHV0TWFwcGluZy5nZXQoaW5kZXgpO1xuICAgIGNvbnN0IGlkID0gdGhpcy5ncHVEYXRhTWFuYWdlci5yZWdpc3RlckV4dGVybmFsQnVmZmVyKGJ1ZmZlciwgc2l6ZSwgcHJldmlvdXNCdWZmZXIpO1xuICAgIHNlc3Npb25JbnB1dE91dHB1dE1hcHBpbmcuc2V0KGluZGV4LCBbaWQsIGJ1ZmZlcl0pO1xuICAgIHJldHVybiBpZDtcbiAgfVxuICB1bnJlZ2lzdGVyQnVmZmVycyhzZXNzaW9uSWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHNlc3Npb25JbnB1dE91dHB1dE1hcHBpbmcgPSB0aGlzLnNlc3Npb25FeHRlcm5hbERhdGFNYXBwaW5nLmdldChzZXNzaW9uSWQpO1xuICAgIGlmIChzZXNzaW9uSW5wdXRPdXRwdXRNYXBwaW5nKSB7XG4gICAgICBzZXNzaW9uSW5wdXRPdXRwdXRNYXBwaW5nLmZvckVhY2goKGJ1ZmZlckluZm8pID0+IHRoaXMuZ3B1RGF0YU1hbmFnZXIudW5yZWdpc3RlckV4dGVybmFsQnVmZmVyKGJ1ZmZlckluZm9bMF0pKTtcbiAgICAgIHRoaXMuc2Vzc2lvbkV4dGVybmFsRGF0YU1hcHBpbmcuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgfVxuICB9XG4gIGdldEJ1ZmZlcihncHVEYXRhSWQ6IG51bWJlcik6IEdQVUJ1ZmZlciB7XG4gICAgY29uc3QgZ3B1RGF0YSA9IHRoaXMuZ3B1RGF0YU1hbmFnZXIuZ2V0KGdwdURhdGFJZCk7XG4gICAgaWYgKCFncHVEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIEdQVSBkYXRhIGZvciBidWZmZXI6ICR7Z3B1RGF0YUlkfWApO1xuICAgIH1cbiAgICByZXR1cm4gZ3B1RGF0YS5idWZmZXI7XG4gIH1cbiAgY3JlYXRlRG93bmxvYWRlcihcbiAgICBncHVCdWZmZXI6IEdQVUJ1ZmZlcixcbiAgICBzaXplOiBudW1iZXIsXG4gICAgdHlwZTogVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlcyxcbiAgKTogKCkgPT4gUHJvbWlzZTxUZW5zb3IuRGF0YVR5cGU+IHtcbiAgICByZXR1cm4gYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGRvd25sb2FkR3B1RGF0YSh0aGlzLCBncHVCdWZmZXIsIHNpemUpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVZpZXcoZGF0YS5idWZmZXIsIHR5cGUpO1xuICAgIH07XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuICB3cml0ZVRpbWVzdGFtcChpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucXVlcnlUeXBlICE9PSAnaW5zaWRlLXBhc3NlcycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICh0aGlzLmNvbXB1dGVQYXNzRW5jb2RlciBhcyBhbnkpLndyaXRlVGltZXN0YW1wKHRoaXMucXVlcnlTZXQsIGluZGV4KTtcbiAgfVxuICBzZXRRdWVyeVR5cGUoKTogdm9pZCB7XG4gICAgdGhpcy5xdWVyeVR5cGUgPSAnbm9uZSc7XG4gICAgaWYgKFxuICAgICAgdGhpcy5lbnYud2ViZ3B1LnByb2ZpbGluZz8ubW9kZSA9PT0gJ2RlZmF1bHQnIHx8XG4gICAgICAodHlwZW9mIHRoaXMuZW52LnRyYWNlID09PSAndW5kZWZpbmVkJyA/IHRoaXMuZW52Lndhc20udHJhY2UgOiB0aGlzLmVudi50cmFjZSlcbiAgICApIHtcbiAgICAgIGlmICh0aGlzLmRldmljZS5mZWF0dXJlcy5oYXMoJ2Nocm9taXVtLWV4cGVyaW1lbnRhbC10aW1lc3RhbXAtcXVlcnktaW5zaWRlLXBhc3NlcycpKSB7XG4gICAgICAgIHRoaXMucXVlcnlUeXBlID0gJ2luc2lkZS1wYXNzZXMnO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmRldmljZS5mZWF0dXJlcy5oYXMoJ3RpbWVzdGFtcC1xdWVyeScpKSB7XG4gICAgICAgIHRoaXMucXVlcnlUeXBlID0gJ2F0LXBhc3Nlcyc7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnF1ZXJ5VHlwZSAhPT0gJ25vbmUnICYmIHR5cGVvZiB0aGlzLnF1ZXJ5U2V0ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aGlzLnF1ZXJ5U2V0ID0gdGhpcy5kZXZpY2UuY3JlYXRlUXVlcnlTZXQoe1xuICAgICAgICAgIHR5cGU6ICd0aW1lc3RhbXAnLFxuICAgICAgICAgIGNvdW50OiB0aGlzLm1heERpc3BhdGNoTnVtYmVyICogMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucXVlcnlSZXNvbHZlQnVmZmVyID0gdGhpcy5kZXZpY2UuY3JlYXRlQnVmZmVyKFxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgICAgICAgeyBzaXplOiB0aGlzLm1heERpc3BhdGNoTnVtYmVyICogMiAqIDgsIHVzYWdlOiBHUFVCdWZmZXJVc2FnZS5DT1BZX1NSQyB8IEdQVUJ1ZmZlclVzYWdlLlFVRVJZX1JFU09MVkUgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjYXB0dXJlQmVnaW4oKTogdm9pZCB7XG4gICAgTE9HX0RFQlVHKCdpbmZvJywgJ2NhcHR1cmVCZWdpbicpO1xuICAgIGlmICghdGhpcy5jYXB0dXJlZENvbW1hbmRMaXN0LmdldCh0aGlzLmN1cnJlbnRTZXNzaW9uSWQhKSkge1xuICAgICAgdGhpcy5jYXB0dXJlZENvbW1hbmRMaXN0LnNldCh0aGlzLmN1cnJlbnRTZXNzaW9uSWQhLCBbXSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5jYXB0dXJlZFBlbmRpbmdLZXJuZWxzLmdldCh0aGlzLmN1cnJlbnRTZXNzaW9uSWQhKSkge1xuICAgICAgdGhpcy5jYXB0dXJlZFBlbmRpbmdLZXJuZWxzLnNldCh0aGlzLmN1cnJlbnRTZXNzaW9uSWQhLCBbXSk7XG4gICAgfVxuICAgIC8vIGZsdXNoIHRoZSBsZWZ0IGNvbW1hbmRzIGJlZm9yZSB3ZSBjaGFuZ2UgdGhlIHN0YXR1cy5cbiAgICB0aGlzLmZsdXNoKCk7XG4gICAgdGhpcy5zZXNzaW9uU3RhdHVzID0gJ2NhcHR1cmluZyc7XG4gIH1cbiAgY2FwdHVyZUVuZCgpOiB2b2lkIHtcbiAgICBMT0dfREVCVUcoJ2luZm8nLCAnY2FwdHVyZUVuZCcpO1xuICAgIC8vIGZsdXNoIHRoZSBsZWZ0IGNvbW1hbmRzIGJlZm9yZSB3ZSBjaGFuZ2UgdGhlIHN0YXR1cy5cbiAgICB0aGlzLmZsdXNoKCk7XG4gICAgdGhpcy5zZXNzaW9uU3RhdHVzID0gJ2RlZmF1bHQnO1xuICB9XG4gIHJlcGxheSgpOiB2b2lkIHtcbiAgICBMT0dfREVCVUcoJ2luZm8nLCAncmVwbGF5Jyk7XG4gICAgdGhpcy5zZXNzaW9uU3RhdHVzID0gJ3JlcGxheWluZyc7XG4gICAgY29uc3Qgc2Vzc2lvbkNvbW1hbmRMaXN0ID0gdGhpcy5jYXB0dXJlZENvbW1hbmRMaXN0LmdldCh0aGlzLmN1cnJlbnRTZXNzaW9uSWQhKTtcbiAgICBjb25zdCBzZXNzaW9uUGVuZGluZ0tlcm5lbHMgPSB0aGlzLmNhcHR1cmVkUGVuZGluZ0tlcm5lbHMuZ2V0KHRoaXMuY3VycmVudFNlc3Npb25JZCEpO1xuICAgIGNvbnN0IGxlbmd0aCA9IHNlc3Npb25Db21tYW5kTGlzdCEubGVuZ3RoO1xuICAgIHRoaXMucGVuZGluZ0tlcm5lbHMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBjb21wdXRlUGFzc0VuY29kZXIgPSB0aGlzLmdldENvbXB1dGVQYXNzRW5jb2RlcigpO1xuICAgICAgY29uc3QgY29tbWFuZCA9IHNlc3Npb25Db21tYW5kTGlzdCFbaV07XG4gICAgICB0aGlzLndyaXRlVGltZXN0YW1wKHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyICogMik7XG4gICAgICBjb21wdXRlUGFzc0VuY29kZXIuc2V0UGlwZWxpbmUoY29tbWFuZC5jb21wdXRlUGlwZWxpbmUpO1xuICAgICAgY29tcHV0ZVBhc3NFbmNvZGVyLnNldEJpbmRHcm91cCgwLCBjb21tYW5kLmJpbmRHcm91cCk7XG4gICAgICBjb21wdXRlUGFzc0VuY29kZXIuZGlzcGF0Y2hXb3JrZ3JvdXBzKC4uLmNvbW1hbmQuZGlzcGF0Y2hHcm91cCk7XG4gICAgICB0aGlzLndyaXRlVGltZXN0YW1wKHRoaXMucGVuZGluZ0Rpc3BhdGNoTnVtYmVyICogMiArIDEpO1xuICAgICAgdGhpcy5wZW5kaW5nRGlzcGF0Y2hOdW1iZXIrKztcbiAgICAgIGlmICh0aGlzLnF1ZXJ5VHlwZSAhPT0gJ25vbmUnKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0tlcm5lbHMucHVzaChzZXNzaW9uUGVuZGluZ0tlcm5lbHMhW2ldKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnBlbmRpbmdEaXNwYXRjaE51bWJlciA+PSB0aGlzLm1heERpc3BhdGNoTnVtYmVyIHx8IHRoaXMucXVlcnlUeXBlID09PSAnYXQtcGFzc2VzJykge1xuICAgICAgICB0aGlzLmVuZENvbXB1dGVQYXNzKCk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5wZW5kaW5nRGlzcGF0Y2hOdW1iZXIgPj0gdGhpcy5tYXhEaXNwYXRjaE51bWJlcikge1xuICAgICAgICB0aGlzLmZsdXNoKCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGZsdXNoIHRoZSBsZWZ0IGNvbW1hbmRzIGJlZm9yZSB3ZSBjaGFuZ2UgdGhlIHN0YXR1cy5cbiAgICB0aGlzLmZsdXNoKCk7XG4gICAgdGhpcy5zZXNzaW9uU3RhdHVzID0gJ2RlZmF1bHQnO1xuICB9XG5cbiAgb25DcmVhdGVTZXNzaW9uKCk6IHZvaWQge1xuICAgIHRoaXMuZ3B1RGF0YU1hbmFnZXIub25DcmVhdGVTZXNzaW9uKCk7XG4gIH1cblxuICBvblJlbGVhc2VTZXNzaW9uKHNlc3Npb25JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy51bnJlZ2lzdGVyQnVmZmVycyhzZXNzaW9uSWQpO1xuICAgIGlmICh0aGlzLmNhcHR1cmVkQ29tbWFuZExpc3QuaGFzKHNlc3Npb25JZCkpIHtcbiAgICAgIHRoaXMuY2FwdHVyZWRDb21tYW5kTGlzdC5kZWxldGUoc2Vzc2lvbklkKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY2FwdHVyZWRQZW5kaW5nS2VybmVscy5oYXMoc2Vzc2lvbklkKSkge1xuICAgICAgdGhpcy5jYXB0dXJlZFBlbmRpbmdLZXJuZWxzLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgIH1cbiAgICB0aGlzLmdwdURhdGFNYW5hZ2VyLm9uUmVsZWFzZVNlc3Npb24oc2Vzc2lvbklkKTtcbiAgfVxuXG4gIG9uUnVuU3RhcnQoc2Vzc2lvbklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmN1cnJlbnRTZXNzaW9uSWQgPSBzZXNzaW9uSWQ7XG4gICAgdGhpcy5zZXRRdWVyeVR5cGUoKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgdHlwZSB7IEVudiB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IGNhbGN1bGF0ZVRlbnNvclNpemVJbkJ5dGVzLCBEYXRhVHlwZSB9IGZyb20gJy4uL3dhc20tY29tbW9uJztcblxuaW1wb3J0IHR5cGUgeyBPcnRXYXNtTW9kdWxlIH0gZnJvbSAnLi4vd2FzbS10eXBlcyc7XG5cbmltcG9ydCB0eXBlIHsgV2ViR3B1QmFja2VuZCB9IGZyb20gJy4vYmFja2VuZC13ZWJncHUnO1xuaW1wb3J0IHsgTE9HX0RFQlVHIH0gZnJvbSAnLi9sb2cnO1xuaW1wb3J0IHR5cGUgeyBUZW5zb3JWaWV3IH0gZnJvbSAnLi90ZW5zb3Itdmlldyc7XG5pbXBvcnQgeyBTaGFwZVV0aWwgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IHR5cGUgeyBBZGFwdGVySW5mbywgQ29tcHV0ZUNvbnRleHQsIENvbXB1dGVDb250ZXh0SW5wdXRzT3V0cHV0c01hcHBpbmcsIFByb2dyYW1JbmZvIH0gZnJvbSAnLi93ZWJncHUvdHlwZXMnO1xuaW1wb3J0IHsgV2ViTk5CYWNrZW5kIH0gZnJvbSAnLi9iYWNrZW5kLXdlYm5uJztcblxuLyogZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSAqL1xuXG5jbGFzcyBUZW5zb3JWaWV3SW1wbCBpbXBsZW1lbnRzIFRlbnNvclZpZXcge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG1vZHVsZTogT3J0V2FzbU1vZHVsZSxcbiAgICBwdWJsaWMgcmVhZG9ubHkgZGF0YVR5cGU6IG51bWJlcixcbiAgICBwdWJsaWMgcmVhZG9ubHkgZGF0YTogbnVtYmVyLFxuICAgIHB1YmxpYyByZWFkb25seSBkaW1zOiByZWFkb25seSBudW1iZXJbXSxcbiAgKSB7fVxuXG4gIGdldEZsb2F0MzJBcnJheSgpOiBGbG9hdDMyQXJyYXkge1xuICAgIGlmICh0aGlzLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5mbG9hdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGEgdHlwZScpO1xuICAgIH1cbiAgICBjb25zdCBlbGVtZW50Q291bnQgPSBTaGFwZVV0aWwuc2l6ZSh0aGlzLmRpbXMpO1xuICAgIHJldHVybiBlbGVtZW50Q291bnQgPT09IDBcbiAgICAgID8gbmV3IEZsb2F0MzJBcnJheSgpXG4gICAgICA6IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5tb2R1bGUuSEVBUDguYnVmZmVyLCB0aGlzLmRhdGEsIGVsZW1lbnRDb3VudCk7XG4gIH1cblxuICBnZXRCaWdJbnQ2NEFycmF5KCk6IEJpZ0ludDY0QXJyYXkge1xuICAgIGlmICh0aGlzLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5pbnQ2NCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGEgdHlwZScpO1xuICAgIH1cbiAgICBjb25zdCBlbGVtZW50Q291bnQgPSBTaGFwZVV0aWwuc2l6ZSh0aGlzLmRpbXMpO1xuICAgIHJldHVybiBlbGVtZW50Q291bnQgPT09IDBcbiAgICAgID8gbmV3IEJpZ0ludDY0QXJyYXkoKVxuICAgICAgOiBuZXcgQmlnSW50NjRBcnJheSh0aGlzLm1vZHVsZS5IRUFQOC5idWZmZXIsIHRoaXMuZGF0YSwgZWxlbWVudENvdW50KTtcbiAgfVxuXG4gIGdldEludDMyQXJyYXkoKTogSW50MzJBcnJheSB7XG4gICAgaWYgKHRoaXMuZGF0YVR5cGUgIT09IERhdGFUeXBlLmludDMyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZGF0YSB0eXBlJyk7XG4gICAgfVxuICAgIGNvbnN0IGVsZW1lbnRDb3VudCA9IFNoYXBlVXRpbC5zaXplKHRoaXMuZGltcyk7XG4gICAgcmV0dXJuIGVsZW1lbnRDb3VudCA9PT0gMCA/IG5ldyBJbnQzMkFycmF5KCkgOiBuZXcgSW50MzJBcnJheSh0aGlzLm1vZHVsZS5IRUFQOC5idWZmZXIsIHRoaXMuZGF0YSwgZWxlbWVudENvdW50KTtcbiAgfVxuXG4gIGdldFVpbnQxNkFycmF5KCk6IFVpbnQxNkFycmF5IHtcbiAgICBpZiAodGhpcy5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuZmxvYXQxNiAmJiB0aGlzLmRhdGFUeXBlICE9PSBEYXRhVHlwZS51aW50MTYpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBkYXRhIHR5cGUnKTtcbiAgICB9XG4gICAgY29uc3QgZWxlbWVudENvdW50ID0gU2hhcGVVdGlsLnNpemUodGhpcy5kaW1zKTtcbiAgICByZXR1cm4gZWxlbWVudENvdW50ID09PSAwID8gbmV3IFVpbnQxNkFycmF5KCkgOiBuZXcgVWludDE2QXJyYXkodGhpcy5tb2R1bGUuSEVBUDguYnVmZmVyLCB0aGlzLmRhdGEsIGVsZW1lbnRDb3VudCk7XG4gIH1cblxuICByZXNoYXBlKG5ld0RpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yVmlldyB7XG4gICAgaWYgKFNoYXBlVXRpbC5zaXplKG5ld0RpbXMpICE9PSBTaGFwZVV0aWwuc2l6ZSh0aGlzLmRpbXMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbmV3IHNoYXBlJyk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgVGVuc29yVmlld0ltcGwodGhpcy5tb2R1bGUsIHRoaXMuZGF0YVR5cGUsIHRoaXMuZGF0YSwgbmV3RGltcyk7XG4gIH1cbn1cblxuY2xhc3MgQ29tcHV0ZUNvbnRleHRJbXBsIGltcGxlbWVudHMgQ29tcHV0ZUNvbnRleHQge1xuICByZWFkb25seSBhZGFwdGVySW5mbzogQWRhcHRlckluZm87XG4gIHJlYWRvbmx5IG9wS2VybmVsQ29udGV4dDogbnVtYmVyO1xuICByZWFkb25seSBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvclZpZXdbXTtcbiAgcmVhZG9ubHkgb3V0cHV0Q291bnQ6IG51bWJlcjtcbiAgZ2V0IGtlcm5lbEN1c3RvbURhdGEoKTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0ge1xuICAgIHJldHVybiB0aGlzLmJhY2tlbmQuY3VycmVudEtlcm5lbEN1c3RvbURhdGE7XG4gIH1cbiAgZ2V0IGN1c3RvbURhdGFCdWZmZXIoKTogVWludDhBcnJheSB7XG4gICAgcmV0dXJuIHRoaXMubW9kdWxlLkhFQVBVOC5zdWJhcnJheSh0aGlzLmN1c3RvbURhdGFPZmZzZXQsIHRoaXMuY3VzdG9tRGF0YU9mZnNldCArIHRoaXMuY3VzdG9tRGF0YVNpemUpO1xuICB9XG4gIHByaXZhdGUgY3VzdG9tRGF0YU9mZnNldCA9IDA7XG4gIHByaXZhdGUgY3VzdG9tRGF0YVNpemUgPSAwO1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG1vZHVsZTogT3J0V2FzbU1vZHVsZSxcbiAgICBwcml2YXRlIGJhY2tlbmQ6IFdlYkdwdUJhY2tlbmQsXG4gICAgY29udGV4dERhdGFPZmZzZXQ6IG51bWJlcixcbiAgKSB7XG4gICAgdGhpcy5hZGFwdGVySW5mbyA9IGJhY2tlbmQuYWRhcHRlckluZm87XG5cbiAgICAvLyBleHRyYWN0IGNvbnRleHQgZGF0YVxuICAgIGNvbnN0IHB0clNpemUgPSBtb2R1bGUuUFRSX1NJWkU7XG4gICAgbGV0IGRhdGFJbmRleCA9IGNvbnRleHREYXRhT2Zmc2V0IC8gbW9kdWxlLlBUUl9TSVpFO1xuICAgIGNvbnN0IHR5cGUgPSBwdHJTaXplID09PSA0ID8gJ2kzMicgOiAnaTY0JztcbiAgICB0aGlzLm9wS2VybmVsQ29udGV4dCA9IE51bWJlcihtb2R1bGUuZ2V0VmFsdWUocHRyU2l6ZSAqIGRhdGFJbmRleCsrLCB0eXBlKSk7XG4gICAgY29uc3QgaW5wdXRDb3VudCA9IE51bWJlcihtb2R1bGUuZ2V0VmFsdWUocHRyU2l6ZSAqIGRhdGFJbmRleCsrLCB0eXBlKSk7XG4gICAgdGhpcy5vdXRwdXRDb3VudCA9IE51bWJlcihtb2R1bGUuZ2V0VmFsdWUocHRyU2l6ZSAqIGRhdGFJbmRleCsrLCB0eXBlKSk7XG4gICAgdGhpcy5jdXN0b21EYXRhT2Zmc2V0ID0gTnVtYmVyKG1vZHVsZS5nZXRWYWx1ZShwdHJTaXplICogZGF0YUluZGV4KyssICcqJykpO1xuICAgIHRoaXMuY3VzdG9tRGF0YVNpemUgPSBOdW1iZXIobW9kdWxlLmdldFZhbHVlKHB0clNpemUgKiBkYXRhSW5kZXgrKywgdHlwZSkpO1xuXG4gICAgY29uc3QgaW5wdXRzOiBUZW5zb3JWaWV3W10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Q291bnQ7IGkrKykge1xuICAgICAgY29uc3QgZGF0YVR5cGUgPSBOdW1iZXIobW9kdWxlLmdldFZhbHVlKHB0clNpemUgKiBkYXRhSW5kZXgrKywgdHlwZSkpO1xuICAgICAgY29uc3QgZGF0YSA9IE51bWJlcihtb2R1bGUuZ2V0VmFsdWUocHRyU2l6ZSAqIGRhdGFJbmRleCsrLCAnKicpKTtcbiAgICAgIGNvbnN0IGRpbSA9IE51bWJlcihtb2R1bGUuZ2V0VmFsdWUocHRyU2l6ZSAqIGRhdGFJbmRleCsrLCB0eXBlKSk7XG4gICAgICBjb25zdCBkaW1zOiBudW1iZXJbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgZCA9IDA7IGQgPCBkaW07IGQrKykge1xuICAgICAgICBkaW1zLnB1c2goTnVtYmVyKG1vZHVsZS5nZXRWYWx1ZShwdHJTaXplICogZGF0YUluZGV4KyssIHR5cGUpKSk7XG4gICAgICB9XG4gICAgICBpbnB1dHMucHVzaChuZXcgVGVuc29yVmlld0ltcGwobW9kdWxlLCBkYXRhVHlwZSwgZGF0YSwgZGltcykpO1xuICAgIH1cbiAgICB0aGlzLmlucHV0cyA9IGlucHV0cztcbiAgfVxuXG4gIGNvbXB1dGUocHJvZ3JhbTogUHJvZ3JhbUluZm8sIGlucHV0c091dHB1dHNNYXBwaW5nPzogQ29tcHV0ZUNvbnRleHRJbnB1dHNPdXRwdXRzTWFwcGluZyk6IFRlbnNvclZpZXdbXSB7XG4gICAgLy8gcHJlcGFyZSBpbnB1dHMuIGlucHV0cyBzaG91bGQgYWx3YXlzIGJlIHZhbGlkIGRhdGEuXG4gICAgY29uc3QgbWFwcGVkSW5wdXRzID1cbiAgICAgIGlucHV0c091dHB1dHNNYXBwaW5nPy5pbnB1dHM/Lm1hcCgoaSkgPT4gKHR5cGVvZiBpID09PSAnbnVtYmVyJyA/IHRoaXMuaW5wdXRzW2ldIDogaSkpID8/IHRoaXMuaW5wdXRzO1xuICAgIC8vIHByZXBhcmUgb3V0cHV0cy5cbiAgICBjb25zdCBvdXRwdXRJbmRpY2VzID0gaW5wdXRzT3V0cHV0c01hcHBpbmc/Lm91dHB1dHMgPz8gW107XG4gICAgY29uc3QgY3JlYXRlS2VybmVsT3V0cHV0ID0gKGluZGV4OiBudW1iZXIsIGRhdGFUeXBlOiBudW1iZXIsIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yVmlldyA9PlxuICAgICAgbmV3IFRlbnNvclZpZXdJbXBsKHRoaXMubW9kdWxlLCBkYXRhVHlwZSwgdGhpcy5vdXRwdXQoaW5kZXgsIGRpbXMpLCBkaW1zKTtcbiAgICBjb25zdCBjcmVhdGVUZW1wb3JhcnlPdXRwdXQgPSAoZGF0YVR5cGU6IG51bWJlciwgZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3JWaWV3ID0+IHtcbiAgICAgIGNvbnN0IGJ1ZmZlclNpemUgPSBjYWxjdWxhdGVUZW5zb3JTaXplSW5CeXRlcyhkYXRhVHlwZSwgZGltcyk7XG4gICAgICBpZiAoIWJ1ZmZlclNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7ZGF0YVR5cGV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBncHVEYXRhSWQgPSBidWZmZXJTaXplID4gMCA/IHRoaXMuYmFja2VuZC5ncHVEYXRhTWFuYWdlci5jcmVhdGUoYnVmZmVyU2l6ZSkuaWQgOiAwO1xuICAgICAgcmV0dXJuIG5ldyBUZW5zb3JWaWV3SW1wbCh0aGlzLm1vZHVsZSwgZGF0YVR5cGUsIGdwdURhdGFJZCwgZGltcyk7XG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5iYWNrZW5kLnJ1bihcbiAgICAgIHByb2dyYW0sXG4gICAgICBtYXBwZWRJbnB1dHMsXG4gICAgICBvdXRwdXRJbmRpY2VzLFxuICAgICAgY3JlYXRlS2VybmVsT3V0cHV0LFxuICAgICAgY3JlYXRlVGVtcG9yYXJ5T3V0cHV0LFxuICAgICAgdGhpcy5vdXRwdXRDb3VudCxcbiAgICApO1xuICB9XG5cbiAgb3V0cHV0KGluZGV4OiBudW1iZXIsIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICBjb25zdCBzdGFjayA9IHRoaXMubW9kdWxlLnN0YWNrU2F2ZSgpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwdHJTaXplID0gdGhpcy5tb2R1bGUuUFRSX1NJWkU7XG4gICAgICBjb25zdCB0eXBlID0gcHRyU2l6ZSA9PT0gNCA/ICdpMzInIDogJ2k2NCc7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5tb2R1bGUuc3RhY2tBbGxvYygoMSArIGRpbXMubGVuZ3RoKSAqIHB0clNpemUgLyogc2l6ZW9mKHNpemVfdCkgKi8pO1xuICAgICAgdGhpcy5tb2R1bGUuc2V0VmFsdWUoZGF0YSwgZGltcy5sZW5ndGgsIHR5cGUpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMubW9kdWxlLnNldFZhbHVlKGRhdGEgKyBwdHJTaXplICogKGkgKyAxKSwgZGltc1tpXSwgdHlwZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5tb2R1bGUuX0pzZXBPdXRwdXQhKHRoaXMub3BLZXJuZWxDb250ZXh0LCBpbmRleCwgZGF0YSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGdlbmVyYXRlIGtlcm5lbCdzIG91dHB1dFske2luZGV4fV0gd2l0aCBkaW1zIFske2RpbXN9XS4gYCArXG4gICAgICAgICAgJ0lmIHlvdSBhcmUgcnVubmluZyB3aXRoIHByZS1hbGxvY2F0ZWQgb3V0cHV0LCBwbGVhc2UgbWFrZSBzdXJlIHRoZSBvdXRwdXQgdHlwZS9kaW1zIGFyZSBjb3JyZWN0LiAnICtcbiAgICAgICAgICBgRXJyb3I6ICR7ZX1gLFxuICAgICAgKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5tb2R1bGUuc3RhY2tSZXN0b3JlKHN0YWNrKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIEpTRVAgd2l0aCBXZWJHUFUgYmFja2VuZC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGFmdGVyIHRoZSBXZWJBc3NlbWJseSBtb2R1bGUgaXMgbG9hZGVkIGFuZCBpbml0aWFsaXplZCAoXCJfT3J0SW5pdFwiIGlzIGNhbGxlZCksIG9uY2UgZm9yXG4gKiBlYWNoIG9mIHRoZSBmb2xsb3dpbmcgRVBzIGlmIHRoZXkgYXJlIHNwZWNpZmllZDpcbiAqIC0gXCJ3ZWJncHVcIlxuICogLSBcIndlYm5uXCJcbiAqXG4gKiBGb3IgV2ViR1BVLCB0aGlzIGZ1bmN0aW9uIGV4cGVjdHM6XG4gKiAgLSBXZWJHUFUgaXMgZW5hYmxlZCBpbiBidWlsZCAoQlVJTERfREVGUy5ESVNBQkxFX0pTRVAgPT09IGZhbHNlKS5cbiAqICAtIFdlYkdQVSBpcyBhdmFpbGFibGUgaW4gY3VycmVudCBlbnZpcm9ubWVudC4gKGEgdmFsaWQgR1BVQWRhcHRlciBpcyBwYXNzZWQgaW4pXG4gKlxuICogRm9yIFdlYk5OLCB0aGlzIGZ1bmN0aW9uIGV4cGVjdHM6XG4gKiAtIFdlYk5OIGlzIGVuYWJsZWQgaW4gYnVpbGQgKEJVSUxEX0RFRlMuRElTQUJMRV9KU0VQID09PSBmYWxzZSkuXG4gKiAtIFdlYk5OIGlzIGF2YWlsYWJsZSBpbiBjdXJyZW50IGVudmlyb25tZW50LiAobmF2aWdhdG9yLm1sIGlzIG5vdCB1bmRlZmluZWQpXG4gKlxuICogSWYgdGhlIFdlYkFzc2VtYmx5IG1vZHVsZSBpcyBub3QgYnVpbHQgd2l0aCBKU0VQIHN1cHBvcnQsIHRoaXMgZnVuY3Rpb24gd2lsbCB0aHJvdyBhbiBlcnJvci4gVGhpcyB3aWxsIGludmFsaWRhdGVcbiAqICd3ZWJncHUnLyd3ZWJubicgYmFja2VuZC5cbiAqXG4gKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIG9mIHRoZSBFUCwgZWl0aGVyIFwid2ViZ3B1XCIgb3IgXCJ3ZWJublwiXG4gKiBAcGFyYW0gbW9kdWxlIC0gdGhlIE9SVCBXZWJBc3NlbWJseSBtb2R1bGVcbiAqIEBwYXJhbSBlbnYgLSB0aGUgT1JUIGVudmlyb25tZW50IHZhcmlhYmxlIChvcnQuZW52KVxuICogQHBhcmFtIGdwdUFkYXB0ZXIgLSB0aGUgcHJlLWNyZWF0ZWQgR1BVIGFkYXB0ZXJcbiAqL1xuZXhwb3J0IGNvbnN0IGluaXQgPSBhc3luYyAoXG4gIG5hbWU6ICd3ZWJncHUnIHwgJ3dlYm5uJyxcbiAgbW9kdWxlOiBPcnRXYXNtTW9kdWxlLFxuICBlbnY6IEVudixcbiAgZ3B1QWRhcHRlcj86IEdQVUFkYXB0ZXIsXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgY29uc3QganNlcEluaXQgPSBtb2R1bGUuanNlcEluaXQ7XG4gIGlmICghanNlcEluaXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBpbml0aWFsaXplIEpTRVAuIFRoZSBXZWJBc3NlbWJseSBtb2R1bGUgaXMgbm90IGJ1aWx0IHdpdGggSlNFUCBzdXBwb3J0LicpO1xuICB9XG5cbiAgaWYgKG5hbWUgPT09ICd3ZWJncHUnKSB7XG4gICAgaWYgKCFCVUlMRF9ERUZTLlVTRV9XRUJHUFVfRVApIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG4gICAgICBjb25zdCB3ZWJHcHVCYWNrZW5kSW1wbCA9IHJlcXVpcmUoJy4vYmFja2VuZC13ZWJncHUnKS5XZWJHcHVCYWNrZW5kO1xuICAgICAgY29uc3QgYmFja2VuZCA9IG5ldyB3ZWJHcHVCYWNrZW5kSW1wbCgpO1xuICAgICAgYXdhaXQgYmFja2VuZC5pbml0aWFsaXplKGVudiwgZ3B1QWRhcHRlciEpO1xuXG4gICAgICBqc2VwSW5pdCgnd2ViZ3B1JywgW1xuICAgICAgICAvLyBiYWNrZW5kXG4gICAgICAgIGJhY2tlbmQsXG5cbiAgICAgICAgLy8ganNlcEFsbG9jKClcbiAgICAgICAgKHNpemU6IG51bWJlcikgPT4gYmFja2VuZC5hbGxvYyhOdW1iZXIoc2l6ZSkpLFxuXG4gICAgICAgIC8vIGpzZXBGcmVlKClcbiAgICAgICAgKHB0cjogbnVtYmVyKSA9PiBiYWNrZW5kLmZyZWUocHRyKSxcblxuICAgICAgICAvLyBqc2VwQ29weShzcmMsIGRzdCwgc2l6ZSwgaXNTb3VyY2VHcHUpXG4gICAgICAgIChzcmM6IG51bWJlciwgZHN0OiBudW1iZXIsIHNpemU6IG51bWJlciwgaXNTb3VyY2VHcHUgPSBmYWxzZSkgPT4ge1xuICAgICAgICAgIGlmIChpc1NvdXJjZUdwdSkge1xuICAgICAgICAgICAgTE9HX0RFQlVHKFxuICAgICAgICAgICAgICAndmVyYm9zZScsXG4gICAgICAgICAgICAgICgpID0+IGBbV2ViR1BVXSBqc2VwQ29weUdwdVRvR3B1OiBzcmM9JHtOdW1iZXIoc3JjKX0sIGRzdD0ke051bWJlcihkc3QpfSwgc2l6ZT0ke051bWJlcihzaXplKX1gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGJhY2tlbmQubWVtY3B5KE51bWJlcihzcmMpLCBOdW1iZXIoZHN0KSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExPR19ERUJVRyhcbiAgICAgICAgICAgICAgJ3ZlcmJvc2UnLFxuICAgICAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgICAgIGBbV2ViR1BVXSBqc2VwQ29weUNwdVRvR3B1OiBkYXRhT2Zmc2V0PSR7TnVtYmVyKHNyYyl9LCBncHVEYXRhSWQ9JHtOdW1iZXIoZHN0KX0sIHNpemU9JHtOdW1iZXIoc2l6ZSl9YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0gbW9kdWxlLkhFQVBVOC5zdWJhcnJheShOdW1iZXIoc3JjID4+PiAwKSwgTnVtYmVyKHNyYyA+Pj4gMCkgKyBOdW1iZXIoc2l6ZSkpO1xuICAgICAgICAgICAgYmFja2VuZC51cGxvYWQoTnVtYmVyKGRzdCksIGRhdGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvLyBqc2VwQ29weUFzeW5jKHNyYywgZHN0LCBzaXplKVxuICAgICAgICBhc3luYyAoZ3B1RGF0YUlkOiBudW1iZXIsIGRhdGFPZmZzZXQ6IG51bWJlciwgc2l6ZTogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgICAgTE9HX0RFQlVHKFxuICAgICAgICAgICAgJ3ZlcmJvc2UnLFxuICAgICAgICAgICAgKCkgPT4gYFtXZWJHUFVdIGpzZXBDb3B5R3B1VG9DcHU6IGdwdURhdGFJZD0ke2dwdURhdGFJZH0sIGRhdGFPZmZzZXQ9JHtkYXRhT2Zmc2V0fSwgc2l6ZT0ke3NpemV9YCxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgYXdhaXQgYmFja2VuZC5kb3dubG9hZChOdW1iZXIoZ3B1RGF0YUlkKSwgKCkgPT5cbiAgICAgICAgICAgIG1vZHVsZS5IRUFQVTguc3ViYXJyYXkoTnVtYmVyKGRhdGFPZmZzZXQpID4+PiAwLCBOdW1iZXIoZGF0YU9mZnNldCArIHNpemUpID4+PiAwKSxcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8vIGpzZXBDcmVhdGVLZXJuZWxcbiAgICAgICAgKGtlcm5lbFR5cGU6IHN0cmluZywga2VybmVsSWQ6IG51bWJlciwgYXR0cmlidXRlOiB1bmtub3duKSA9PlxuICAgICAgICAgIGJhY2tlbmQuY3JlYXRlS2VybmVsKFxuICAgICAgICAgICAga2VybmVsVHlwZSxcbiAgICAgICAgICAgIE51bWJlcihrZXJuZWxJZCksXG4gICAgICAgICAgICBhdHRyaWJ1dGUsXG4gICAgICAgICAgICBtb2R1bGUuVVRGOFRvU3RyaW5nKG1vZHVsZS5fSnNlcEdldE5vZGVOYW1lIShOdW1iZXIoa2VybmVsSWQpKSksXG4gICAgICAgICAgKSxcblxuICAgICAgICAvLyBqc2VwUmVsZWFzZUtlcm5lbFxuICAgICAgICAoa2VybmVsOiBudW1iZXIpID0+IGJhY2tlbmQucmVsZWFzZUtlcm5lbChrZXJuZWwpLFxuXG4gICAgICAgIC8vIGpzZXBSdW5cbiAgICAgICAgKGtlcm5lbDogbnVtYmVyLCBjb250ZXh0RGF0YU9mZnNldDogbnVtYmVyLCBzZXNzaW9uSGFuZGxlOiBudW1iZXIsIGVycm9yczogQXJyYXk8UHJvbWlzZTxzdHJpbmcgfCBudWxsPj4pID0+IHtcbiAgICAgICAgICBMT0dfREVCVUcoXG4gICAgICAgICAgICAndmVyYm9zZScsXG4gICAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgICBgW1dlYkdQVV0ganNlcFJ1bjogc2Vzc2lvbkhhbmRsZT0ke3Nlc3Npb25IYW5kbGV9LCBrZXJuZWw9JHtrZXJuZWx9LCBjb250ZXh0RGF0YU9mZnNldD0ke2NvbnRleHREYXRhT2Zmc2V0fWAsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IENvbXB1dGVDb250ZXh0SW1wbChtb2R1bGUsIGJhY2tlbmQsIE51bWJlcihjb250ZXh0RGF0YU9mZnNldCkpO1xuICAgICAgICAgIHJldHVybiBiYWNrZW5kLmNvbXB1dGVLZXJuZWwoTnVtYmVyKGtlcm5lbCksIGNvbnRleHQsIGVycm9ycyk7XG4gICAgICAgIH0sXG4gICAgICAgIC8vIGpzZXBDYXB0dXJlQmVnaW5cbiAgICAgICAgKCkgPT4gYmFja2VuZC5jYXB0dXJlQmVnaW4oKSxcbiAgICAgICAgLy8ganNlcENhcHR1cmVFbmRcbiAgICAgICAgKCkgPT4gYmFja2VuZC5jYXB0dXJlRW5kKCksXG4gICAgICAgIC8vIGpzZXBSZXBsYXlcbiAgICAgICAgKCkgPT4gYmFja2VuZC5yZXBsYXkoKSxcbiAgICAgIF0pO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBjb25zdCBiYWNrZW5kID0gbmV3IFdlYk5OQmFja2VuZChlbnYpO1xuICAgIGpzZXBJbml0KCd3ZWJubicsIFtcbiAgICAgIGJhY2tlbmQsXG4gICAgICAvLyBqc2VwUmVzZXJ2ZVRlbnNvcklkXG4gICAgICAoKSA9PiBiYWNrZW5kLnJlc2VydmVUZW5zb3JJZCgpLFxuICAgICAgLy8ganNlcFJlbGVhc2VUZW5zb3JJZCxcbiAgICAgICh0ZW5zb3JJZDogbnVtYmVyKSA9PiBiYWNrZW5kLnJlbGVhc2VUZW5zb3JJZCh0ZW5zb3JJZCksXG4gICAgICAvLyBqc2VwRW5zdXJlVGVuc29yXG4gICAgICBhc3luYyAoc2Vzc2lvbklkOiBudW1iZXIgfCB1bmRlZmluZWQsIHRlbnNvcklkOiBudW1iZXIsIG9ubnhEYXRhVHlwZTogbnVtYmVyLCBzaGFwZTogbnVtYmVyW10sIGNvcHlPbGQpID0+XG4gICAgICAgIGJhY2tlbmQuZW5zdXJlVGVuc29yKHNlc3Npb25JZCwgdGVuc29ySWQsIG9ubnhEYXRhVHlwZSwgc2hhcGUsIGNvcHlPbGQpLFxuICAgICAgLy8ganNlcFVwbG9hZFRlbnNvclxuICAgICAgKHRlbnNvcklkOiBudW1iZXIsIGRhdGE6IFVpbnQ4QXJyYXkpID0+IHtcbiAgICAgICAgYmFja2VuZC51cGxvYWRUZW5zb3IodGVuc29ySWQsIGRhdGEpO1xuICAgICAgfSxcbiAgICAgIC8vIGpzZXBEb3dubG9hZFRlbnNvclxuICAgICAgYXN5bmMgKHRlbnNvcklkOiBudW1iZXIsIGRzdEJ1ZmZlcjogQXJyYXlCdWZmZXJWaWV3IHwgQXJyYXlCdWZmZXIpID0+IGJhY2tlbmQuZG93bmxvYWRUZW5zb3IodGVuc29ySWQsIGRzdEJ1ZmZlciksXG4gICAgXSk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8vIFdlYk5OIEFQSSBjdXJyZW50bHkgZG9lcyBub3QgaGF2ZSBhIFR5cGVTY3JpcHQgZGVmaW5pdGlvbiBmaWxlLiBUaGlzIGZpbGUgaXMgYSB3b3JrYXJvdW5kIHdpdGggdHlwZXMgZ2VuZXJhdGVkIGZyb21cbi8vIFdlYk5OIEFQSSBzcGVjaWZpY2F0aW9uLlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3dlYm1hY2hpbmVsZWFybmluZy93ZWJubi9pc3N1ZXMvNjc3XG4vLy8gPHJlZmVyZW5jZSBwYXRoPVwianNlcC93ZWJubi93ZWJubi5kLnRzXCIgLz5cblxuaW1wb3J0IHsgRW52LCBJbmZlcmVuY2VTZXNzaW9uLCBUZW5zb3IgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQge1xuICBTZXJpYWxpemFibGVJbnRlcm5hbEJ1ZmZlcixcbiAgU2VyaWFsaXphYmxlU2Vzc2lvbk1ldGFkYXRhLFxuICBTZXJpYWxpemFibGVUZW5zb3JNZXRhZGF0YSxcbiAgVGVuc29yTWV0YWRhdGEsXG59IGZyb20gJy4vcHJveHktbWVzc2FnZXMnO1xuaW1wb3J0IHsgc2V0UnVuT3B0aW9ucyB9IGZyb20gJy4vcnVuLW9wdGlvbnMnO1xuaW1wb3J0IHsgc2V0U2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuL3Nlc3Npb24tb3B0aW9ucyc7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVUZW5zb3JTaXplSW5CeXRlcyxcbiAgZGF0YUxvY2F0aW9uU3RyaW5nVG9FbnVtLFxuICBpc0dwdUJ1ZmZlclN1cHBvcnRlZFR5cGUsXG4gIGlzTUxUZW5zb3JTdXBwb3J0ZWRUeXBlLFxuICBsb2dMZXZlbFN0cmluZ1RvRW51bSxcbiAgdGVuc29yRGF0YVR5cGVFbnVtVG9TdHJpbmcsXG4gIHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtLFxuICB0ZW5zb3JUeXBlVG9UeXBlZEFycmF5Q29uc3RydWN0b3IsXG59IGZyb20gJy4vd2FzbS1jb21tb24nO1xuaW1wb3J0IHsgZ2V0SW5zdGFuY2UgfSBmcm9tICcuL3dhc20tZmFjdG9yeSc7XG5pbXBvcnQgeyBhbGxvY1dhc21TdHJpbmcsIGNoZWNrTGFzdEVycm9yIH0gZnJvbSAnLi93YXNtLXV0aWxzJztcbmltcG9ydCB7IGxvYWRGaWxlIH0gZnJvbSAnLi93YXNtLXV0aWxzLWxvYWQtZmlsZSc7XG5cbi8vICNyZWdpb24gSW5pdGlhbGl6YXRpb25zXG5cbi8qKlxuICogVGhlcmUgYXJlIDQgZGlmZmVyZW50IFwiaW5pdGlhbGl6YXRpb25cIiBzdGVwcyBmb3IgT1JULiBUaGV5IGhhcHBlbiBpbiBkaWZmZXJlbnQgcGxhY2VzIGFuZCBkaWZmZXJlbnQgdGltZS5cbiAqXG4gKiAxLiBKYXZhU2NyaXB0IGluaXRpYWxpemF0aW9uIGZvciBvbm54cnVudGltZS1jb21tb24gYW5kIG9ubnhydW50aW1lLXdlYi5cbiAqICAgIFRoaXMgaXMgdGhlIGZpcnN0IGluaXRpYWxpemF0aW9uIHN0ZXAuIEluIHRoaXMgc3RlcCwgb25ueHJ1bnRpbWUtd2ViIGNhbGxzIG9ubnhydW50aW1lLWNvbW1vbidzIHJlZ2lzdGVyQmFja2VuZCgpXG4gKiBmdW5jdGlvbiBtdWx0aXBsZSB0aW1lcyB0byByZWdpc3RlciBhbGwgdGhlIGF2YWlsYWJsZSBiYWNrZW5kcy4gVGhlIGJhY2tlbmQgcmVnaXN0cmF0aW9uIGlzIHZlcnkgZmFzdC4gSXQgb25seVxuICogcmVnaXN0ZXJzIHRoZSBiYWNrZW5kIG5hbWUgd2l0aCB0aGUgdW5pbml0aWFsaXplZCBiYWNrZW5kIG9iamVjdC4gTm8gaGVhdnkgaW5pdGlhbGl6YXRpb24gaXMgZG9uZSBpbiB0aGlzIHN0ZXAuXG4gKiAgICBSZWZlciB0byB3ZWIvbGliL2luZGV4LnRzIGZvciB0aGUgYmFja2VuZCByZWdpc3RyYXRpb24uXG4gKlxuICogMi4gV2ViQXNzZW1ibHkgYXJ0aWZhY3QgaW5pdGlhbGl6YXRpb24uXG4gKiAgICBUaGlzIGhhcHBlbnMgd2hlbiBhbnkgcmVnaXN0ZXJlZCB3YXNtIGJhY2tlbmQgaXMgdXNlZCBmb3IgdGhlIGZpcnN0IHRpbWUgKGllLiBgb3J0LkluZmVyZW5jZVNlc3Npb24uY3JlYXRlKClgIGlzXG4gKiBjYWxsZWQpLiBJbiB0aGlzIHN0ZXAsIG9ubnhydW50aW1lLXdlYiBkb2VzIHRoZSBmb2xsb3dpbmdzOlxuICogICAgIC0gY3JlYXRlIGEgcHJveHkgd29ya2VyIGFuZCBtYWtlIHN1cmUgdGhlIHByb3h5IHdvcmtlciBpcyByZWFkeSB0byByZWNlaXZlIG1lc3NhZ2VzLCBpZiBwcm94eSBpcyBlbmFibGVkLlxuICogICAgIC0gcGVyZm9ybSBmZWF0dXJlIGRldGVjdGlvbiwgbG9jYXRlIGNvcnJlY3QgV2ViQXNzZW1ibHkgYXJ0aWZhY3QgcGF0aCBhbmQgY2FsbCB0aGUgRW1zY3JpcHRlbiBnZW5lcmF0ZWRcbiAqIEphdmFTY3JpcHQgY29kZSB0byBpbml0aWFsaXplIHRoZSBXZWJBc3NlbWJseSBydW50aW1lLlxuICogICAgICAgICAtIGlmIHByb3h5IGlzIGVuYWJsZWQsIHRoaXMgc3RlcCBoYXBwZW5zIGluIHRoZSBwcm94eSB3b3JrZXIgdXNpbmcgbWVzc2FnZSAnaW5pdC13YXNtJy5cbiAqICAgICAgICAgLSBkb3dubG9hZGluZyB0aGUgJ29ydC13YXNtey4uLn0ud2FzbScgZmlsZSBpcyBkb25lIGluIHRoaXMgc3RlcC5cbiAqICAgICAgICAgLSBpZiBtdWx0aS10aHJlYWQgaXMgZW5hYmxlZCwgb25lIG9yIG1vcmUgd2Vid29ya2VyIHdpbGwgYmUgY3JlYXRlZCB0byBpbml0aWFsaXplIHRoZSBQVGhyZWFkIHRocmVhZHBvb2wuXG4gKlxuICogMy4gT1JUIGVudmlyb25tZW50IGluaXRpYWxpemF0aW9uLlxuICogICAgVGhpcyBoYXBwZW5zIGFmdGVyIHN0ZXAgMi4gSW4gdGhpcyBzdGVwLCBvbm54cnVudGltZS13ZWIgcGVyZm9ybXMgT05OWCBSdW50aW1lIGVudmlyb25tZW50IGluaXRpYWxpemF0aW9uLlxuICogRnVuY3Rpb24gYF9PcnRJbml0KClgIGlzIGNhbGxlZCBpbiB0aGlzIHN0ZXAuXG4gKiAgICAgLSBpZiBwcm94eSBpcyBlbmFibGVkLCB0aGlzIHN0ZXAgaGFwcGVucyBpbiB0aGUgcHJveHkgd29ya2VyIHVzaW5nIG1lc3NhZ2UgJ2luaXQtb3J0Jy5cbiAqICAgICAtIGxvZ2dpbmcgbGV2ZWwgKG9ydC5lbnYubG9nTGV2ZWwpIGFuZCB0aHJlYWQgbnVtYmVyIChvcnQuZW52Lndhc20ubnVtVGhyZWFkcykgYXJlIHNldCBpbiB0aGlzIHN0ZXAuXG4gKlxuICogNC4gU2Vzc2lvbiBpbml0aWFsaXphdGlvbi5cbiAqICAgIFRoaXMgaGFwcGVucyB3aGVuIGBvcnQuSW5mZXJlbmNlU2Vzc2lvbi5jcmVhdGUoKWAgaXMgY2FsbGVkLiBVbmxpa2UgdGhlIGZpcnN0IDMgc3RlcHMgKHRoZXkgb25seSBjYWxsZWQgb25jZSksXG4gKiB0aGlzIHN0ZXAgd2lsbCBiZSBkb25lIGZvciBlYWNoIHNlc3Npb24uIEluIHRoaXMgc3RlcCwgb25ueHJ1bnRpbWUtd2ViIGRvZXMgdGhlIGZvbGxvd2luZ3M6XG4gKiAgICBJZiB0aGUgcGFyYW1ldGVyIGlzIGEgVVJMOlxuICogICAgLSBkb3dubG9hZCB0aGUgbW9kZWwgZGF0YSBmcm9tIHRoZSBVUkwuXG4gKiAgICAtIGNvcHkgdGhlIG1vZGVsIGRhdGEgdG8gdGhlIFdBU00gaGVhcC4gKHByb3h5OiAnY29weS1mcm9tJylcbiAqICAgIC0gZGVyZWZlcmVuY2UgdGhlIG1vZGVsIGJ1ZmZlci4gVGhpcyBzdGVwIGFsbG93cyB0aGUgb3JpZ2luYWwgQXJyYXlCdWZmZXIgdG8gYmUgZ2FyYmFnZSBjb2xsZWN0ZWQuXG4gKiAgICAtIGNhbGwgYF9PcnRDcmVhdGVTZXNzaW9uKClgIHRvIGNyZWF0ZSB0aGUgc2Vzc2lvbi4gKHByb3h5OiAnY3JlYXRlJylcbiAqXG4gKiAgICBJZiB0aGUgcGFyYW1ldGVyIGlzIGEgVWludDhBcnJheSBvYmplY3Q6XG4gKiAgICAtIGNvcHkgdGhlIG1vZGVsIGRhdGEgdG8gdGhlIFdBU00gaGVhcC4gKHByb3h5OiAnY29weS1mcm9tJylcbiAqICAgIC0gY2FsbCBgX09ydENyZWF0ZVNlc3Npb24oKWAgdG8gY3JlYXRlIHRoZSBzZXNzaW9uLiAocHJveHk6ICdjcmVhdGUnKVxuICpcbiAqXG4gKi9cblxuLyoqXG4gKiBpbml0aWFsaXplIE9SVCBlbnZpcm9ubWVudC5cbiAqXG4gKiBAcGFyYW0gbnVtVGhyZWFkcyBTZXRHbG9iYWxJbnRyYU9wTnVtVGhyZWFkcyhudW1UaHJlYWRzKVxuICogQHBhcmFtIGxvZ2dpbmdMZXZlbCBDcmVhdGVFbnYoc3RhdGljX2Nhc3Q8T3J0TG9nZ2luZ0xldmVsPihsb2dnaW5nX2xldmVsKSlcbiAqL1xuY29uc3QgaW5pdE9ydCA9IChudW1UaHJlYWRzOiBudW1iZXIsIGxvZ2dpbmdMZXZlbDogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGNvbnN0IGVycm9yQ29kZSA9IGdldEluc3RhbmNlKCkuX09ydEluaXQobnVtVGhyZWFkcywgbG9nZ2luZ0xldmVsKTtcbiAgaWYgKGVycm9yQ29kZSAhPT0gMCkge1xuICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgaW5pdGlhbGl6ZSBvbm54cnVudGltZS5cIik7XG4gIH1cbn07XG5cbi8qKlxuICogaW5pdGlhbGl6ZSBydW50aW1lIGVudmlyb25tZW50LlxuICogQHBhcmFtIGVudiBwYXNzZWQgaW4gdGhlIGVudmlyb25tZW50IGNvbmZpZyBvYmplY3QuXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0UnVudGltZSA9IGFzeW5jIChlbnY6IEVudik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAvLyBpbml0IE9SVFxuICBpbml0T3J0KGVudi53YXNtLm51bVRocmVhZHMhLCBsb2dMZXZlbFN0cmluZ1RvRW51bShlbnYubG9nTGV2ZWwpKTtcbn07XG5cbi8qKlxuICogcGVyZm9ybSBFUCBzcGVjaWZpYyBpbml0aWFsaXphdGlvbi5cbiAqXG4gKiBAcGFyYW0gZW52XG4gKiBAcGFyYW0gZXBOYW1lXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0RXAgPSBhc3luYyAoZW52OiBFbnYsIGVwTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIC8vIGluaXRpYWxpemUgQVNZTkNJRlkgc3VwcG9ydFxuICBnZXRJbnN0YW5jZSgpLmFzeW5jSW5pdD8uKCk7XG5cbiAgaWYgKGVwTmFtZSA9PT0gJ3dlYmdwdScgJiYgQlVJTERfREVGUy5VU0VfV0VCR1BVX0VQKSB7XG4gICAgZ2V0SW5zdGFuY2UoKS53ZWJncHVJbml0ISgoZGV2aWNlKSA9PiB7XG4gICAgICBlbnYud2ViZ3B1LmRldmljZSA9IGRldmljZTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX0pTRVApIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cywgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICAgIGNvbnN0IGluaXRKc2VwID0gcmVxdWlyZSgnLi9qc2VwL2luaXQnKS5pbml0O1xuXG4gICAgaWYgKGVwTmFtZSA9PT0gJ3dlYmdwdScgJiYgIUJVSUxEX0RFRlMuVVNFX1dFQkdQVV9FUCkge1xuICAgICAgLy8gcGVyZm9ybSBXZWJHUFUgYXZhaWxhYmlsaXR5IGNoZWNrXG4gICAgICBpZiAodHlwZW9mIG5hdmlnYXRvciA9PT0gJ3VuZGVmaW5lZCcgfHwgIW5hdmlnYXRvci5ncHUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHUFUgaXMgbm90IHN1cHBvcnRlZCBpbiBjdXJyZW50IGVudmlyb25tZW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGxldCBhZGFwdGVyID0gZW52LndlYmdwdS5hZGFwdGVyIGFzIEdQVUFkYXB0ZXIgfCBudWxsO1xuICAgICAgaWYgKCFhZGFwdGVyKSB7XG4gICAgICAgIC8vIGlmIGFkYXB0ZXIgaXMgbm90IHNldCwgcmVxdWVzdCBhIG5ldyBhZGFwdGVyLlxuICAgICAgICBjb25zdCBwb3dlclByZWZlcmVuY2UgPSBlbnYud2ViZ3B1LnBvd2VyUHJlZmVyZW5jZTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHBvd2VyUHJlZmVyZW5jZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgcG93ZXJQcmVmZXJlbmNlICE9PSAnbG93LXBvd2VyJyAmJlxuICAgICAgICAgIHBvd2VyUHJlZmVyZW5jZSAhPT0gJ2hpZ2gtcGVyZm9ybWFuY2UnXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwb3dlclByZWZlcmVuY2Ugc2V0dGluZzogXCIke3Bvd2VyUHJlZmVyZW5jZX1cImApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZvcmNlRmFsbGJhY2tBZGFwdGVyID0gZW52LndlYmdwdS5mb3JjZUZhbGxiYWNrQWRhcHRlcjtcbiAgICAgICAgaWYgKGZvcmNlRmFsbGJhY2tBZGFwdGVyICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGZvcmNlRmFsbGJhY2tBZGFwdGVyICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZm9yY2VGYWxsYmFja0FkYXB0ZXIgc2V0dGluZzogXCIke2ZvcmNlRmFsbGJhY2tBZGFwdGVyfVwiYCk7XG4gICAgICAgIH1cbiAgICAgICAgYWRhcHRlciA9IGF3YWl0IG5hdmlnYXRvci5ncHUucmVxdWVzdEFkYXB0ZXIoeyBwb3dlclByZWZlcmVuY2UsIGZvcmNlRmFsbGJhY2tBZGFwdGVyIH0pO1xuICAgICAgICBpZiAoIWFkYXB0ZXIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAnRmFpbGVkIHRvIGdldCBHUFUgYWRhcHRlci4gJyArXG4gICAgICAgICAgICAgICdZb3UgbWF5IG5lZWQgdG8gZW5hYmxlIGZsYWcgXCItLWVuYWJsZS11bnNhZmUtd2ViZ3B1XCIgaWYgeW91IGFyZSB1c2luZyBDaHJvbWUuJyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBpZiBhZGFwdGVyIGlzIHNldCwgdmFsaWRhdGUgaXQuXG4gICAgICAgIGlmIChcbiAgICAgICAgICB0eXBlb2YgYWRhcHRlci5saW1pdHMgIT09ICdvYmplY3QnIHx8XG4gICAgICAgICAgdHlwZW9mIGFkYXB0ZXIuZmVhdHVyZXMgIT09ICdvYmplY3QnIHx8XG4gICAgICAgICAgdHlwZW9mIGFkYXB0ZXIucmVxdWVzdERldmljZSAhPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgR1BVIGFkYXB0ZXIgc2V0IGluIGBlbnYud2ViZ3B1LmFkYXB0ZXJgLiBJdCBtdXN0IGJlIGEgR1BVQWRhcHRlciBvYmplY3QuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYXdhaXQgaW5pdEpzZXAoJ3dlYmdwdScsIGdldEluc3RhbmNlKCksIGVudiwgYWRhcHRlcik7XG4gICAgfVxuICAgIGlmIChlcE5hbWUgPT09ICd3ZWJubicpIHtcbiAgICAgIC8vIHBlcmZvcm0gV2ViTk4gYXZhaWxhYmlsaXR5IGNoZWNrXG4gICAgICBpZiAodHlwZW9mIG5hdmlnYXRvciA9PT0gJ3VuZGVmaW5lZCcgfHwgIShuYXZpZ2F0b3IgYXMgdW5rbm93biBhcyB7IG1sOiB1bmtub3duIH0pLm1sKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignV2ViTk4gaXMgbm90IHN1cHBvcnRlZCBpbiBjdXJyZW50IGVudmlyb25tZW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGluaXRKc2VwKCd3ZWJubicsIGdldEluc3RhbmNlKCksIGVudik7XG4gICAgfVxuICB9XG59O1xuXG4vLyAjZW5kcmVnaW9uIEluaXRpYWxpemF0aW9uc1xuXG4vKipcbiAqIHZhbGlkIGRhdGEgbG9jYXRpb25zIGZvciBpbnB1dC9vdXRwdXQgdGVuc29ycy5cbiAqL1xudHlwZSBTdXBwb3J0ZWRUZW5zb3JEYXRhTG9jYXRpb25Gb3JJbnB1dE91dHB1dCA9XG4gIHwgJ2NwdSdcbiAgfCAnY3B1LXBpbm5lZCdcbiAgfCAnZ3B1LWJ1ZmZlcidcbiAgfCAnbWwtdGVuc29yJ1xuICAvLyBVc2UgJ21sLXRlbnNvcicgZHVyaW5nIGluZmVyZW5jZSwgYnV0IG91dHB1dCBhIHRlbnNvciBsb2NhdGVkIG9uIHRoZSBDUFUuXG4gIHwgJ21sLXRlbnNvci1jcHUtb3V0cHV0JztcblxudHlwZSBJT0JpbmRpbmdTdGF0ZSA9IHtcbiAgLyoqXG4gICAqIHRoZSBoYW5kbGUgb2YgSU8gYmluZGluZy5cbiAgICovXG4gIHJlYWRvbmx5IGhhbmRsZTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiB0aGUgcHJlZmVycmVkIGxvY2F0aW9uIGZvciBlYWNoIG91dHB1dCB0ZW5zb3IuXG4gICAqXG4gICAqIHZhbHVlIGlzIG9uZSBvZiAnY3B1JywgJ2NwdS1waW5uZWQnLCAnZ3B1LWJ1ZmZlcicsICdtbC10ZW5zb3InLlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zOiByZWFkb25seSBTdXBwb3J0ZWRUZW5zb3JEYXRhTG9jYXRpb25Gb3JJbnB1dE91dHB1dFtdO1xuXG4gIC8qKlxuICAgKiBlbnVtIHZhbHVlIG9mIHRoZSBwcmVmZXJyZWQgbG9jYXRpb24gZm9yIGVhY2ggb3V0cHV0IHRlbnNvci5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dFByZWZlcnJlZExvY2F0aW9uc0VuY29kZWQ6IHJlYWRvbmx5IG51bWJlcltdO1xufTtcblxuLyoqXG4gKiAgdHVwbGUgZWxlbWVudHMgYXJlOiBJbmZlcmVuY2VTZXNzaW9uIElEOyBpbnB1dE5hbWVzVVRGOEVuY29kZWQ7IG91dHB1dE5hbWVzVVRGOEVuY29kZWQ7IGJpbmRpbmdTdGF0ZVxuICovXG50eXBlIFNlc3Npb25NZXRhZGF0YSA9IFtcbiAgaW5mZXJlbmNlU2Vzc2lvbklkOiBudW1iZXIsXG4gIGlucHV0TmFtZXNVVEY4RW5jb2RlZDogbnVtYmVyW10sXG4gIG91dHB1dE5hbWVzVVRGOEVuY29kZWQ6IG51bWJlcltdLFxuICBiaW5kaW5nU3RhdGU6IElPQmluZGluZ1N0YXRlIHwgbnVsbCxcbiAgZW5hYmxlR3JhcGhDYXB0dXJlOiBib29sZWFuLFxuICBpbnB1dE91dHB1dEJvdW5kOiBib29sZWFuLFxuXTtcblxuY29uc3QgYWN0aXZlU2Vzc2lvbnMgPSBuZXcgTWFwPG51bWJlciwgU2Vzc2lvbk1ldGFkYXRhPigpO1xuXG4vKipcbiAqIGdldCB0aGUgaW5wdXQvb3V0cHV0IGNvdW50IG9mIHRoZSBzZXNzaW9uLlxuICogQHBhcmFtIHNlc3Npb25IYW5kbGUgdGhlIGhhbmRsZSByZXByZXNlbnRpbmcgdGhlIHNlc3Npb24uIHNob3VsZCBiZSBub24temVyby5cbiAqIEByZXR1cm5zIGEgdHVwbGUgaW5jbHVkaW5nIDIgbnVtYmVycywgcmVwcmVzZW50aW5nIHRoZSBpbnB1dCBjb3VudCBhbmQgb3V0cHV0IGNvdW50LlxuICovXG5jb25zdCBnZXRTZXNzaW9uSW5wdXRPdXRwdXRDb3VudCA9IChzZXNzaW9uSGFuZGxlOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG4gIGNvbnN0IHN0YWNrID0gd2FzbS5zdGFja1NhdmUoKTtcbiAgdHJ5IHtcbiAgICBjb25zdCBwdHJTaXplID0gd2FzbS5QVFJfU0laRTtcbiAgICBjb25zdCBkYXRhT2Zmc2V0ID0gd2FzbS5zdGFja0FsbG9jKDIgKiBwdHJTaXplKTtcbiAgICBjb25zdCBlcnJvckNvZGUgPSB3YXNtLl9PcnRHZXRJbnB1dE91dHB1dENvdW50KHNlc3Npb25IYW5kbGUsIGRhdGFPZmZzZXQsIGRhdGFPZmZzZXQgKyBwdHJTaXplKTtcbiAgICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XG4gICAgICBjaGVja0xhc3RFcnJvcihcIkNhbid0IGdldCBzZXNzaW9uIGlucHV0L291dHB1dCBjb3VudC5cIik7XG4gICAgfVxuICAgIGNvbnN0IHR5cGUgPSBwdHJTaXplID09PSA0ID8gJ2kzMicgOiAnaTY0JztcbiAgICByZXR1cm4gW051bWJlcih3YXNtLmdldFZhbHVlKGRhdGFPZmZzZXQsIHR5cGUpKSwgTnVtYmVyKHdhc20uZ2V0VmFsdWUoZGF0YU9mZnNldCArIHB0clNpemUsIHR5cGUpKV07XG4gIH0gZmluYWxseSB7XG4gICAgd2FzbS5zdGFja1Jlc3RvcmUoc3RhY2spO1xuICB9XG59O1xuXG5jb25zdCBnZXRTZXNzaW9uSW5wdXRPdXRwdXRNZXRhZGF0YSA9IChcbiAgc2Vzc2lvbkhhbmRsZTogbnVtYmVyLFxuICBpbmRleDogbnVtYmVyLFxuKTogW25hbWVPZmZzZXQ6IG51bWJlciwgZWxlbWVudFR5cGU6IG51bWJlciwgZGltcz86IEFycmF5PG51bWJlciB8IHN0cmluZz5dID0+IHtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG4gIGNvbnN0IHN0YWNrID0gd2FzbS5zdGFja1NhdmUoKTtcbiAgbGV0IG1ldGFkYXRhT2Zmc2V0ID0gMDtcbiAgdHJ5IHtcbiAgICBjb25zdCBwdHJTaXplID0gd2FzbS5QVFJfU0laRTtcbiAgICBjb25zdCBkYXRhT2Zmc2V0ID0gd2FzbS5zdGFja0FsbG9jKDIgKiBwdHJTaXplKTtcbiAgICBjb25zdCBlcnJvckNvZGUgPSB3YXNtLl9PcnRHZXRJbnB1dE91dHB1dE1ldGFkYXRhKHNlc3Npb25IYW5kbGUsIGluZGV4LCBkYXRhT2Zmc2V0LCBkYXRhT2Zmc2V0ICsgcHRyU2l6ZSk7XG4gICAgaWYgKGVycm9yQ29kZSAhPT0gMCkge1xuICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCBnZXQgc2Vzc2lvbiBpbnB1dC9vdXRwdXQgbWV0YWRhdGEuXCIpO1xuICAgIH1cbiAgICBjb25zdCBuYW1lT2Zmc2V0ID0gTnVtYmVyKHdhc20uZ2V0VmFsdWUoZGF0YU9mZnNldCwgJyonKSk7XG4gICAgbWV0YWRhdGFPZmZzZXQgPSBOdW1iZXIod2FzbS5nZXRWYWx1ZShkYXRhT2Zmc2V0ICsgcHRyU2l6ZSwgJyonKSk7XG4gICAgLy8gZ2V0IGVsZW1lbnQgdHlwZVxuICAgIGNvbnN0IGVsZW1lbnRUeXBlID0gd2FzbS5IRUFQMzJbbWV0YWRhdGFPZmZzZXQgLyA0XTtcbiAgICBpZiAoZWxlbWVudFR5cGUgPT09IDApIHtcbiAgICAgIHJldHVybiBbbmFtZU9mZnNldCwgMF07IC8vIG5vbi10ZW5zb3JcbiAgICB9XG5cbiAgICAvLyBnZXQgZGltcyBjb3VudFxuICAgIGNvbnN0IGRpbXNDb3VudCA9IHdhc20uSEVBUFUzMlttZXRhZGF0YU9mZnNldCAvIDQgKyAxXTtcbiAgICAvLyBnZXQgZGltc1xuICAgIGNvbnN0IGRpbXM6IEFycmF5PG51bWJlciB8IHN0cmluZz4gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXNDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCBzeW1ib2xpY0RpbU5hbWVPZmZzZXQgPSBOdW1iZXIod2FzbS5nZXRWYWx1ZShtZXRhZGF0YU9mZnNldCArIDggKyBpICogcHRyU2l6ZSwgJyonKSk7XG4gICAgICBkaW1zLnB1c2goXG4gICAgICAgIHN5bWJvbGljRGltTmFtZU9mZnNldCAhPT0gMFxuICAgICAgICAgID8gd2FzbS5VVEY4VG9TdHJpbmcoc3ltYm9saWNEaW1OYW1lT2Zmc2V0KVxuICAgICAgICAgIDogTnVtYmVyKHdhc20uZ2V0VmFsdWUobWV0YWRhdGFPZmZzZXQgKyA4ICsgKGkgKyBkaW1zQ291bnQpICogcHRyU2l6ZSwgJyonKSksXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gW25hbWVPZmZzZXQsIGVsZW1lbnRUeXBlLCBkaW1zXTtcbiAgfSBmaW5hbGx5IHtcbiAgICB3YXNtLnN0YWNrUmVzdG9yZShzdGFjayk7XG4gICAgaWYgKG1ldGFkYXRhT2Zmc2V0ICE9PSAwKSB7XG4gICAgICB3YXNtLl9PcnRGcmVlKG1ldGFkYXRhT2Zmc2V0KTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogYWxsb2NhdGUgdGhlIG1lbW9yeSBhbmQgbWVtY3B5IHRoZSBleHRlcm5hbCBidWZmZXIuXG4gKlxuICogQHBhcmFtIG1vZGVsIC0gdGhlIGV4dGVybmFsIGJ1ZmZlciBjb250YWluaW5nIHRoZSBtb2RlbCBkYXRhLiBNdXN0IG5vdCBiZSB0aGUgc2FtZSBidWZmZXIgYXMgdGhlIFdBU00gaGVhcC5cbiAqIEByZXR1cm5zIGEgMi1lbGVtZW50cyB0dXBsZSAtIHRoZSBwb2ludGVyIGFuZCBzaXplIG9mIHRoZSBhbGxvY2F0ZWQgYnVmZmVyXG4gKi9cbmV4cG9ydCBjb25zdCBjb3B5RnJvbUV4dGVybmFsQnVmZmVyID0gKG1vZGVsOiBVaW50OEFycmF5KTogW251bWJlciwgbnVtYmVyXSA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBjb25zdCBtb2RlbERhdGFPZmZzZXQgPSB3YXNtLl9tYWxsb2MobW9kZWwuYnl0ZUxlbmd0aCk7XG4gIGlmIChtb2RlbERhdGFPZmZzZXQgPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbid0IGNyZWF0ZSBhIHNlc3Npb24uIGZhaWxlZCB0byBhbGxvY2F0ZSBhIGJ1ZmZlciBvZiBzaXplICR7bW9kZWwuYnl0ZUxlbmd0aH0uYCk7XG4gIH1cbiAgd2FzbS5IRUFQVTguc2V0KG1vZGVsLCBtb2RlbERhdGFPZmZzZXQpO1xuICByZXR1cm4gW21vZGVsRGF0YU9mZnNldCwgbW9kZWwuYnl0ZUxlbmd0aF07XG59O1xuXG4vKipcbiAqIGNyZWF0ZSBhbiBpbmZlcmVuY2Ugc2Vzc2lvbiBmcm9tIGEgbW9kZWwgZGF0YSBidWZmZXIuXG4gKlxuICogQHBhcmFtIG1vZGVsRGF0YSAtIGVpdGhlciBhIFVpbnQ4QXJyYXkgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgbW9kZWwgZGF0YSwgb3IgYSAyLWVsZW1lbnRzIHR1cGxlIGNvbnRhaW5pbmcgdGhlXG4gKiAgICAgcG9pbnRlciBhbmQgc2l6ZSBvZiB0aGUgbW9kZWwgZGF0YSBidWZmZXIuXG4gKiBAcGFyYW0gb3B0aW9ucyBhbiBvcHRpb25hbCBzZXNzaW9uIG9wdGlvbnMgb2JqZWN0LlxuICogQHJldHVybnMgYSAzLWVsZW1lbnRzIHR1cGxlIGNvbnRhaW5pbmcgW3Nlc3Npb24gaGFuZGxlLCBpbnB1dCBuYW1lcywgb3V0cHV0IG5hbWVzXVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlU2Vzc2lvbiA9IGFzeW5jIChcbiAgbW9kZWxEYXRhOiBVaW50OEFycmF5IHwgU2VyaWFsaXphYmxlSW50ZXJuYWxCdWZmZXIsXG4gIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLFxuKTogUHJvbWlzZTxTZXJpYWxpemFibGVTZXNzaW9uTWV0YWRhdGE+ID0+IHtcbiAgbGV0IG1vZGVsRGF0YU9mZnNldDogbnVtYmVyLCBtb2RlbERhdGFMZW5ndGg6IG51bWJlcjtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkobW9kZWxEYXRhKSkge1xuICAgIC8vIGlmIG1vZGVsIGRhdGEgaXMgYW4gYXJyYXksIGl0IG11c3QgYmUgYSAyLWVsZW1lbnRzIHR1cGxlIGNvbnRhaW5pbmcgdGhlIHBvaW50ZXIgYW5kIHNpemUgb2YgdGhlIG1vZGVsIGRhdGFcbiAgICBbbW9kZWxEYXRhT2Zmc2V0LCBtb2RlbERhdGFMZW5ndGhdID0gbW9kZWxEYXRhO1xuICB9IGVsc2UgaWYgKG1vZGVsRGF0YS5idWZmZXIgPT09IHdhc20uSEVBUFU4LmJ1ZmZlcikge1xuICAgIC8vIGlmIG1vZGVsIGRhdGEgdXNlcyB0aGUgc2FtZSBidWZmZXIgYXMgdGhlIFdBU00gaGVhcCwgd2UgZG9uJ3QgbmVlZCB0byBjb3B5IGl0LlxuICAgIFttb2RlbERhdGFPZmZzZXQsIG1vZGVsRGF0YUxlbmd0aF0gPSBbbW9kZWxEYXRhLmJ5dGVPZmZzZXQsIG1vZGVsRGF0YS5ieXRlTGVuZ3RoXTtcbiAgfSBlbHNlIHtcbiAgICAvLyBvdGhlcndpc2UsIGNvcHkgdGhlIG1vZGVsIGRhdGEgdG8gdGhlIFdBU00gaGVhcC5cbiAgICBbbW9kZWxEYXRhT2Zmc2V0LCBtb2RlbERhdGFMZW5ndGhdID0gY29weUZyb21FeHRlcm5hbEJ1ZmZlcihtb2RlbERhdGEpO1xuICB9XG5cbiAgbGV0IHNlc3Npb25IYW5kbGUgPSAwO1xuICBsZXQgc2Vzc2lvbk9wdGlvbnNIYW5kbGUgPSAwO1xuICBsZXQgaW9CaW5kaW5nSGFuZGxlID0gMDtcbiAgbGV0IGFsbG9jczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaW5wdXROYW1lc1VURjhFbmNvZGVkID0gW107XG4gIGNvbnN0IG91dHB1dE5hbWVzVVRGOEVuY29kZWQgPSBbXTtcblxuICB0cnkge1xuICAgIFtzZXNzaW9uT3B0aW9uc0hhbmRsZSwgYWxsb2NzXSA9IGF3YWl0IHNldFNlc3Npb25PcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgaWYgKG9wdGlvbnM/LmV4dGVybmFsRGF0YSAmJiB3YXNtLm1vdW50RXh0ZXJuYWxEYXRhKSB7XG4gICAgICBjb25zdCBsb2FkaW5nUHJvbWlzZXMgPSBbXTtcbiAgICAgIGZvciAoY29uc3QgZmlsZSBvZiBvcHRpb25zLmV4dGVybmFsRGF0YSkge1xuICAgICAgICBjb25zdCBwYXRoID0gdHlwZW9mIGZpbGUgPT09ICdzdHJpbmcnID8gZmlsZSA6IGZpbGUucGF0aDtcbiAgICAgICAgbG9hZGluZ1Byb21pc2VzLnB1c2goXG4gICAgICAgICAgbG9hZEZpbGUodHlwZW9mIGZpbGUgPT09ICdzdHJpbmcnID8gZmlsZSA6IGZpbGUuZGF0YSkudGhlbigoZGF0YSkgPT4ge1xuICAgICAgICAgICAgd2FzbS5tb3VudEV4dGVybmFsRGF0YShwYXRoLCBkYXRhKTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gd2FpdCBmb3IgYWxsIGV4dGVybmFsIGRhdGEgZmlsZXMgdG8gYmUgbG9hZGVkXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChsb2FkaW5nUHJvbWlzZXMpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcHJvdmlkZXIgb2Ygb3B0aW9ucz8uZXhlY3V0aW9uUHJvdmlkZXJzID8/IFtdKSB7XG4gICAgICBjb25zdCBwcm92aWRlck5hbWUgPSB0eXBlb2YgcHJvdmlkZXIgPT09ICdzdHJpbmcnID8gcHJvdmlkZXIgOiBwcm92aWRlci5uYW1lO1xuICAgICAgaWYgKHByb3ZpZGVyTmFtZSA9PT0gJ3dlYm5uJykge1xuICAgICAgICB3YXNtLnNob3VsZFRyYW5zZmVyVG9NTFRlbnNvciA9IGZhbHNlO1xuICAgICAgICBpZiAodHlwZW9mIHByb3ZpZGVyICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIGNvbnN0IHdlYm5uT3B0aW9ucyA9IHByb3ZpZGVyIGFzIEluZmVyZW5jZVNlc3Npb24uV2ViTk5FeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICAgICAgICBjb25zdCBjb250ZXh0ID0gKHdlYm5uT3B0aW9ucyBhcyBJbmZlcmVuY2VTZXNzaW9uLldlYk5OT3B0aW9uc1dpdGhNTENvbnRleHQpPy5jb250ZXh0O1xuICAgICAgICAgIGNvbnN0IGdwdURldmljZSA9ICh3ZWJubk9wdGlvbnMgYXMgSW5mZXJlbmNlU2Vzc2lvbi5XZWJOTk9wdGlvbnNXZWJHcHUpPy5ncHVEZXZpY2U7XG4gICAgICAgICAgY29uc3QgZGV2aWNlVHlwZSA9ICh3ZWJubk9wdGlvbnMgYXMgSW5mZXJlbmNlU2Vzc2lvbi5XZWJOTkNvbnRleHRPcHRpb25zKT8uZGV2aWNlVHlwZTtcbiAgICAgICAgICBjb25zdCBwb3dlclByZWZlcmVuY2UgPSAod2Vibm5PcHRpb25zIGFzIEluZmVyZW5jZVNlc3Npb24uV2ViTk5Db250ZXh0T3B0aW9ucyk/LnBvd2VyUHJlZmVyZW5jZTtcbiAgICAgICAgICBpZiAoY29udGV4dCkge1xuICAgICAgICAgICAgd2FzbS5jdXJyZW50Q29udGV4dCA9IGNvbnRleHQgYXMgTUxDb250ZXh0O1xuICAgICAgICAgIH0gZWxzZSBpZiAoZ3B1RGV2aWNlKSB7XG4gICAgICAgICAgICB3YXNtLmN1cnJlbnRDb250ZXh0ID0gYXdhaXQgd2FzbS53ZWJubkNyZWF0ZU1MQ29udGV4dCEoZ3B1RGV2aWNlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd2FzbS5jdXJyZW50Q29udGV4dCA9IGF3YWl0IHdhc20ud2Vibm5DcmVhdGVNTENvbnRleHQhKHsgZGV2aWNlVHlwZSwgcG93ZXJQcmVmZXJlbmNlIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB3YXNtLmN1cnJlbnRDb250ZXh0ID0gYXdhaXQgd2FzbS53ZWJubkNyZWF0ZU1MQ29udGV4dCEoKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXNzaW9uSGFuZGxlID0gYXdhaXQgd2FzbS5fT3J0Q3JlYXRlU2Vzc2lvbihtb2RlbERhdGFPZmZzZXQsIG1vZGVsRGF0YUxlbmd0aCwgc2Vzc2lvbk9wdGlvbnNIYW5kbGUpO1xuICAgIHdhc20ud2ViZ3B1T25DcmVhdGVTZXNzaW9uPy4oc2Vzc2lvbkhhbmRsZSk7XG4gICAgaWYgKHNlc3Npb25IYW5kbGUgPT09IDApIHtcbiAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgY3JlYXRlIGEgc2Vzc2lvbi5cIik7XG4gICAgfVxuXG4gICAgd2FzbS5qc2VwT25DcmVhdGVTZXNzaW9uPy4oKTtcblxuICAgIC8vIGNsZWFyIGN1cnJlbnQgTUxDb250ZXh0IGFmdGVyIHNlc3Npb24gY3JlYXRpb25cbiAgICBpZiAod2FzbS5jdXJyZW50Q29udGV4dCkge1xuICAgICAgd2FzbS53ZWJublJlZ2lzdGVyTUxDb250ZXh0IShzZXNzaW9uSGFuZGxlLCB3YXNtLmN1cnJlbnRDb250ZXh0KTtcbiAgICAgIHdhc20uY3VycmVudENvbnRleHQgPSB1bmRlZmluZWQ7XG4gICAgICB3YXNtLnNob3VsZFRyYW5zZmVyVG9NTFRlbnNvciA9IHRydWU7XG4gICAgfVxuXG4gICAgY29uc3QgW2lucHV0Q291bnQsIG91dHB1dENvdW50XSA9IGdldFNlc3Npb25JbnB1dE91dHB1dENvdW50KHNlc3Npb25IYW5kbGUpO1xuXG4gICAgY29uc3QgZW5hYmxlR3JhcGhDYXB0dXJlID0gISFvcHRpb25zPy5lbmFibGVHcmFwaENhcHR1cmU7XG5cbiAgICBjb25zdCBpbnB1dE5hbWVzID0gW107XG4gICAgY29uc3Qgb3V0cHV0TmFtZXMgPSBbXTtcbiAgICBjb25zdCBpbnB1dE1ldGFkYXRhOiBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXSA9IFtdO1xuICAgIGNvbnN0IG91dHB1dE1ldGFkYXRhOiBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXSA9IFtdO1xuICAgIGNvbnN0IG91dHB1dFByZWZlcnJlZExvY2F0aW9uczogU3VwcG9ydGVkVGVuc29yRGF0YUxvY2F0aW9uRm9ySW5wdXRPdXRwdXRbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCBbbmFtZU9mZnNldCwgZWxlbWVudFR5cGUsIHNoYXBlXSA9IGdldFNlc3Npb25JbnB1dE91dHB1dE1ldGFkYXRhKHNlc3Npb25IYW5kbGUsIGkpO1xuICAgICAgaWYgKG5hbWVPZmZzZXQgPT09IDApIHtcbiAgICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCBnZXQgYW4gaW5wdXQgbmFtZS5cIik7XG4gICAgICB9XG4gICAgICBpbnB1dE5hbWVzVVRGOEVuY29kZWQucHVzaChuYW1lT2Zmc2V0KTtcbiAgICAgIGNvbnN0IG5hbWUgPSB3YXNtLlVURjhUb1N0cmluZyhuYW1lT2Zmc2V0KTtcbiAgICAgIGlucHV0TmFtZXMucHVzaChuYW1lKTtcbiAgICAgIGlucHV0TWV0YWRhdGEucHVzaChcbiAgICAgICAgZWxlbWVudFR5cGUgPT09IDBcbiAgICAgICAgICA/IHsgbmFtZSwgaXNUZW5zb3I6IGZhbHNlIH1cbiAgICAgICAgICA6IHsgbmFtZSwgaXNUZW5zb3I6IHRydWUsIHR5cGU6IHRlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nKGVsZW1lbnRUeXBlKSwgc2hhcGU6IHNoYXBlISB9LFxuICAgICAgKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCBbbmFtZU9mZnNldCwgZWxlbWVudFR5cGUsIHNoYXBlXSA9IGdldFNlc3Npb25JbnB1dE91dHB1dE1ldGFkYXRhKHNlc3Npb25IYW5kbGUsIGkgKyBpbnB1dENvdW50KTtcbiAgICAgIGlmIChuYW1lT2Zmc2V0ID09PSAwKSB7XG4gICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgZ2V0IGFuIG91dHB1dCBuYW1lLlwiKTtcbiAgICAgIH1cbiAgICAgIG91dHB1dE5hbWVzVVRGOEVuY29kZWQucHVzaChuYW1lT2Zmc2V0KTtcbiAgICAgIGNvbnN0IG5hbWVTdHJpbmcgPSB3YXNtLlVURjhUb1N0cmluZyhuYW1lT2Zmc2V0KTtcbiAgICAgIG91dHB1dE5hbWVzLnB1c2gobmFtZVN0cmluZyk7XG4gICAgICBvdXRwdXRNZXRhZGF0YS5wdXNoKFxuICAgICAgICBlbGVtZW50VHlwZSA9PT0gMFxuICAgICAgICAgID8geyBuYW1lOiBuYW1lU3RyaW5nLCBpc1RlbnNvcjogZmFsc2UgfVxuICAgICAgICAgIDogeyBuYW1lOiBuYW1lU3RyaW5nLCBpc1RlbnNvcjogdHJ1ZSwgdHlwZTogdGVuc29yRGF0YVR5cGVFbnVtVG9TdHJpbmcoZWxlbWVudFR5cGUpLCBzaGFwZTogc2hhcGUhIH0sXG4gICAgICApO1xuXG4gICAgICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQKSB7XG4gICAgICAgIGlmIChlbmFibGVHcmFwaENhcHR1cmUgJiYgb3B0aW9ucz8ucHJlZmVycmVkT3V0cHV0TG9jYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG91dHB1dFByZWZlcnJlZExvY2F0aW9ucy5wdXNoKCdncHUtYnVmZmVyJyk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbG9jYXRpb24gPVxuICAgICAgICAgIHR5cGVvZiBvcHRpb25zPy5wcmVmZXJyZWRPdXRwdXRMb2NhdGlvbiA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgID8gb3B0aW9ucy5wcmVmZXJyZWRPdXRwdXRMb2NhdGlvblxuICAgICAgICAgICAgOiAob3B0aW9ucz8ucHJlZmVycmVkT3V0cHV0TG9jYXRpb24/LltuYW1lU3RyaW5nXSA/PyAnY3B1Jyk7XG4gICAgICAgIGNvbnN0IGlzR3JhcGhPdXRwdXQgPSB3YXNtLndlYm5uSXNHcmFwaE91dHB1dDtcbiAgICAgICAgaWYgKGxvY2F0aW9uID09PSAnY3B1JyAmJiBpc0dyYXBoT3V0cHV0ICYmIGlzR3JhcGhPdXRwdXQoc2Vzc2lvbkhhbmRsZSwgbmFtZVN0cmluZykpIHtcbiAgICAgICAgICBvdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnMucHVzaCgnbWwtdGVuc29yLWNwdS1vdXRwdXQnKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobG9jYXRpb24gIT09ICdjcHUnICYmIGxvY2F0aW9uICE9PSAnY3B1LXBpbm5lZCcgJiYgbG9jYXRpb24gIT09ICdncHUtYnVmZmVyJyAmJiBsb2NhdGlvbiAhPT0gJ21sLXRlbnNvcicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBzdXBwb3J0ZWQgcHJlZmVycmVkIG91dHB1dCBsb2NhdGlvbjogJHtsb2NhdGlvbn0uYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuYWJsZUdyYXBoQ2FwdHVyZSAmJiBsb2NhdGlvbiAhPT0gJ2dwdS1idWZmZXInKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYE5vdCBzdXBwb3J0ZWQgcHJlZmVycmVkIG91dHB1dCBsb2NhdGlvbjogJHtsb2NhdGlvbn0uIE9ubHkgJ2dwdS1idWZmZXInIGxvY2F0aW9uIGlzIHN1cHBvcnRlZCB3aGVuIGVuYWJsZUdyYXBoQ2FwdHVyZSBpcyB0cnVlLmAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBvdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnMucHVzaChsb2NhdGlvbik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdXNlIElPIGJpbmRpbmcgb25seSB3aGVuIGF0IGxlYXN0IG9uZSBvdXRwdXQgaXMgcHJlZmVycmVkIHRvIGJlIG9uIEdQVS5cbiAgICBsZXQgYmluZGluZ1N0YXRlOiBJT0JpbmRpbmdTdGF0ZSB8IG51bGwgPSBudWxsO1xuICAgIGlmIChcbiAgICAgICFCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUCAmJlxuICAgICAgb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zLnNvbWUoKGwpID0+IGwgPT09ICdncHUtYnVmZmVyJyB8fCBsID09PSAnbWwtdGVuc29yJyB8fCBsID09PSAnbWwtdGVuc29yLWNwdS1vdXRwdXQnKVxuICAgICkge1xuICAgICAgaW9CaW5kaW5nSGFuZGxlID0gd2FzbS5fT3J0Q3JlYXRlQmluZGluZyhzZXNzaW9uSGFuZGxlKTtcbiAgICAgIGlmIChpb0JpbmRpbmdIYW5kbGUgPT09IDApIHtcbiAgICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCBjcmVhdGUgSU8gYmluZGluZy5cIik7XG4gICAgICB9XG5cbiAgICAgIGJpbmRpbmdTdGF0ZSA9IHtcbiAgICAgICAgaGFuZGxlOiBpb0JpbmRpbmdIYW5kbGUsXG4gICAgICAgIG91dHB1dFByZWZlcnJlZExvY2F0aW9ucyxcbiAgICAgICAgb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zRW5jb2RlZDogb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zXG4gICAgICAgICAgLy8gJ21sLXRlbnNvci1jcHUtb3V0cHV0JyBpcyB0cmVhdGVkIGFzICdtbC10ZW5zb3InIGZvciB0aGUgcHVycG9zZSBvZiBJTyBiaW5kaW5nLlxuICAgICAgICAgIC5tYXAoKGwpID0+IChsID09PSAnbWwtdGVuc29yLWNwdS1vdXRwdXQnID8gJ21sLXRlbnNvcicgOiBsKSlcbiAgICAgICAgICAubWFwKChsKSA9PiBkYXRhTG9jYXRpb25TdHJpbmdUb0VudW0obCkpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBhY3RpdmVTZXNzaW9ucy5zZXQoc2Vzc2lvbkhhbmRsZSwgW1xuICAgICAgc2Vzc2lvbkhhbmRsZSxcbiAgICAgIGlucHV0TmFtZXNVVEY4RW5jb2RlZCxcbiAgICAgIG91dHB1dE5hbWVzVVRGOEVuY29kZWQsXG4gICAgICBiaW5kaW5nU3RhdGUsXG4gICAgICBlbmFibGVHcmFwaENhcHR1cmUsXG4gICAgICBmYWxzZSxcbiAgICBdKTtcbiAgICByZXR1cm4gW3Nlc3Npb25IYW5kbGUsIGlucHV0TmFtZXMsIG91dHB1dE5hbWVzLCBpbnB1dE1ldGFkYXRhLCBvdXRwdXRNZXRhZGF0YV07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpbnB1dE5hbWVzVVRGOEVuY29kZWQuZm9yRWFjaCgoYnVmKSA9PiB3YXNtLl9PcnRGcmVlKGJ1ZikpO1xuICAgIG91dHB1dE5hbWVzVVRGOEVuY29kZWQuZm9yRWFjaCgoYnVmKSA9PiB3YXNtLl9PcnRGcmVlKGJ1ZikpO1xuXG4gICAgaWYgKGlvQmluZGluZ0hhbmRsZSAhPT0gMCkge1xuICAgICAgaWYgKHdhc20uX09ydFJlbGVhc2VCaW5kaW5nKGlvQmluZGluZ0hhbmRsZSkgIT09IDApIHtcbiAgICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCByZWxlYXNlIElPIGJpbmRpbmcuXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZXNzaW9uSGFuZGxlICE9PSAwKSB7XG4gICAgICBpZiAod2FzbS5fT3J0UmVsZWFzZVNlc3Npb24oc2Vzc2lvbkhhbmRsZSkgIT09IDApIHtcbiAgICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCByZWxlYXNlIHNlc3Npb24uXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9IGZpbmFsbHkge1xuICAgIHdhc20uX2ZyZWUobW9kZWxEYXRhT2Zmc2V0KTtcbiAgICBpZiAoc2Vzc2lvbk9wdGlvbnNIYW5kbGUgIT09IDApIHtcbiAgICAgIGlmICh3YXNtLl9PcnRSZWxlYXNlU2Vzc2lvbk9wdGlvbnMoc2Vzc2lvbk9wdGlvbnNIYW5kbGUpICE9PSAwKSB7XG4gICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgcmVsZWFzZSBzZXNzaW9uIG9wdGlvbnMuXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICBhbGxvY3MuZm9yRWFjaCgoYWxsb2MpID0+IHdhc20uX2ZyZWUoYWxsb2MpKTtcblxuICAgIC8vIHVubW91bnQgZXh0ZXJuYWwgZGF0YSBpZiBuZWNlc3NhcnlcbiAgICB3YXNtLnVubW91bnRFeHRlcm5hbERhdGE/LigpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVsZWFzZVNlc3Npb24gPSAoc2Vzc2lvbklkOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG4gIGNvbnN0IHNlc3Npb24gPSBhY3RpdmVTZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgaWYgKCFzZXNzaW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgcmVsZWFzZSBzZXNzaW9uLiBpbnZhbGlkIHNlc3Npb24gaWQ6ICR7c2Vzc2lvbklkfWApO1xuICB9XG4gIGNvbnN0IFtzZXNzaW9uSGFuZGxlLCBpbnB1dE5hbWVzVVRGOEVuY29kZWQsIG91dHB1dE5hbWVzVVRGOEVuY29kZWQsIGlvQmluZGluZ1N0YXRlLCBlbmFibGVHcmFwaENhcHR1cmVdID0gc2Vzc2lvbjtcblxuICBpZiAoaW9CaW5kaW5nU3RhdGUpIHtcbiAgICBpZiAoZW5hYmxlR3JhcGhDYXB0dXJlKSB7XG4gICAgICBpZiAod2FzbS5fT3J0Q2xlYXJCb3VuZE91dHB1dHMoaW9CaW5kaW5nU3RhdGUuaGFuZGxlKSAhPT0gMCkge1xuICAgICAgICBjaGVja0xhc3RFcnJvcihcIkNhbid0IGNsZWFyIGJvdW5kIG91dHB1dHMuXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAod2FzbS5fT3J0UmVsZWFzZUJpbmRpbmcoaW9CaW5kaW5nU3RhdGUuaGFuZGxlKSAhPT0gMCkge1xuICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCByZWxlYXNlIElPIGJpbmRpbmcuXCIpO1xuICAgIH1cbiAgfVxuXG4gIHdhc20uanNlcE9uUmVsZWFzZVNlc3Npb24/LihzZXNzaW9uSWQpO1xuICB3YXNtLndlYm5uT25SZWxlYXNlU2Vzc2lvbj8uKHNlc3Npb25JZCk7XG4gIHdhc20ud2ViZ3B1T25SZWxlYXNlU2Vzc2lvbj8uKHNlc3Npb25JZCk7XG5cbiAgaW5wdXROYW1lc1VURjhFbmNvZGVkLmZvckVhY2goKGJ1ZikgPT4gd2FzbS5fT3J0RnJlZShidWYpKTtcbiAgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZC5mb3JFYWNoKChidWYpID0+IHdhc20uX09ydEZyZWUoYnVmKSk7XG4gIGlmICh3YXNtLl9PcnRSZWxlYXNlU2Vzc2lvbihzZXNzaW9uSGFuZGxlKSAhPT0gMCkge1xuICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgcmVsZWFzZSBzZXNzaW9uLlwiKTtcbiAgfVxuICBhY3RpdmVTZXNzaW9ucy5kZWxldGUoc2Vzc2lvbklkKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwcmVwYXJlSW5wdXRPdXRwdXRUZW5zb3IgPSBhc3luYyAoXG4gIHRlbnNvcjogVGVuc29yTWV0YWRhdGEgfCBudWxsLFxuICB0ZW5zb3JIYW5kbGVzOiBudW1iZXJbXSxcbiAgYWxsb2NzOiBudW1iZXJbXSxcbiAgc2Vzc2lvbklkOiBudW1iZXIsXG4gIHRlbnNvck5hbWVVVEY4RW5jb2RlZDogbnVtYmVyLFxuICBpbmRleDogbnVtYmVyLFxuICBlbmFibGVHcmFwaENhcHR1cmUgPSBmYWxzZSxcbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoIXRlbnNvcikge1xuICAgIHRlbnNvckhhbmRsZXMucHVzaCgwKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB3YXNtID0gZ2V0SW5zdGFuY2UoKTtcbiAgY29uc3QgcHRyU2l6ZSA9IHdhc20uUFRSX1NJWkU7XG5cbiAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JbMF07XG4gIGNvbnN0IGRpbXMgPSB0ZW5zb3JbMV07XG4gIGNvbnN0IGxvY2F0aW9uID0gdGVuc29yWzNdO1xuICBsZXQgYWN0dWFsTG9jYXRpb24gPSBsb2NhdGlvbjtcblxuICBsZXQgcmF3RGF0YTogbnVtYmVyO1xuICBsZXQgZGF0YUJ5dGVMZW5ndGg6IG51bWJlcjtcblxuICBpZiAoZGF0YVR5cGUgPT09ICdzdHJpbmcnICYmIChsb2NhdGlvbiA9PT0gJ2dwdS1idWZmZXInIHx8IGxvY2F0aW9uID09PSAnbWwtdGVuc29yJykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1N0cmluZyB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZCBvbiBHUFUuJyk7XG4gIH1cblxuICBpZiAoZW5hYmxlR3JhcGhDYXB0dXJlICYmIGxvY2F0aW9uICE9PSAnZ3B1LWJ1ZmZlcicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRXh0ZXJuYWwgYnVmZmVyIG11c3QgYmUgcHJvdmlkZWQgZm9yIGlucHV0L291dHB1dCBpbmRleCAke2luZGV4fSB3aGVuIGVuYWJsZUdyYXBoQ2FwdHVyZSBpcyB0cnVlLmAsXG4gICAgKTtcbiAgfVxuXG4gIGlmIChsb2NhdGlvbiA9PT0gJ2dwdS1idWZmZXInKSB7XG4gICAgY29uc3QgZ3B1QnVmZmVyID0gdGVuc29yWzJdLmdwdUJ1ZmZlcjtcbiAgICBkYXRhQnl0ZUxlbmd0aCA9IGNhbGN1bGF0ZVRlbnNvclNpemVJbkJ5dGVzKHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtKGRhdGFUeXBlKSwgZGltcykhO1xuXG4gICAgaWYgKEJVSUxEX0RFRlMuVVNFX1dFQkdQVV9FUCkge1xuICAgICAgY29uc3QgcmVnaXN0ZXJCdWZmZXIgPSB3YXNtLndlYmdwdVJlZ2lzdGVyQnVmZmVyO1xuICAgICAgaWYgKCFyZWdpc3RlckJ1ZmZlcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbnNvciBsb2NhdGlvbiBcImdwdS1idWZmZXJcIiBpcyBub3Qgc3VwcG9ydGVkIHdpdGhvdXQgdXNpbmcgV2ViR1BVLicpO1xuICAgICAgfVxuXG4gICAgICByYXdEYXRhID0gcmVnaXN0ZXJCdWZmZXIoZ3B1QnVmZmVyLCBzZXNzaW9uSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCByZWdpc3RlckJ1ZmZlciA9IHdhc20uanNlcFJlZ2lzdGVyQnVmZmVyO1xuICAgICAgaWYgKCFyZWdpc3RlckJ1ZmZlcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbnNvciBsb2NhdGlvbiBcImdwdS1idWZmZXJcIiBpcyBub3Qgc3VwcG9ydGVkIHdpdGhvdXQgdXNpbmcgV2ViR1BVLicpO1xuICAgICAgfVxuICAgICAgcmF3RGF0YSA9IHJlZ2lzdGVyQnVmZmVyKHNlc3Npb25JZCwgaW5kZXgsIGdwdUJ1ZmZlciwgZGF0YUJ5dGVMZW5ndGgpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChsb2NhdGlvbiA9PT0gJ21sLXRlbnNvcicpIHtcbiAgICBjb25zdCBtbFRlbnNvciA9IHRlbnNvclsyXS5tbFRlbnNvciBhcyBNTFRlbnNvcjtcbiAgICBkYXRhQnl0ZUxlbmd0aCA9IGNhbGN1bGF0ZVRlbnNvclNpemVJbkJ5dGVzKHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtKGRhdGFUeXBlKSwgZGltcykhO1xuXG4gICAgY29uc3QgcmVnaXN0ZXJNTFRlbnNvciA9IHdhc20ud2Vibm5SZWdpc3Rlck1MVGVuc29yO1xuICAgIGlmICghcmVnaXN0ZXJNTFRlbnNvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUZW5zb3IgbG9jYXRpb24gXCJtbC10ZW5zb3JcIiBpcyBub3Qgc3VwcG9ydGVkIHdpdGhvdXQgdXNpbmcgV2ViTk4uJyk7XG4gICAgfVxuICAgIHJhd0RhdGEgPSByZWdpc3Rlck1MVGVuc29yKHNlc3Npb25JZCwgbWxUZW5zb3IsIHRlbnNvckRhdGFUeXBlU3RyaW5nVG9FbnVtKGRhdGFUeXBlKSwgZGltcyk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgZGF0YSA9IHRlbnNvclsyXTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAvLyBzdHJpbmcgdGVuc29yXG4gICAgICBkYXRhQnl0ZUxlbmd0aCA9IHB0clNpemUgKiBkYXRhLmxlbmd0aDtcbiAgICAgIHJhd0RhdGEgPSB3YXNtLl9tYWxsb2MoZGF0YUJ5dGVMZW5ndGgpO1xuICAgICAgYWxsb2NzLnB1c2gocmF3RGF0YSk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhW2ldICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYHRlbnNvciBkYXRhIGF0IGluZGV4ICR7aX0gaXMgbm90IGEgc3RyaW5nYCk7XG4gICAgICAgIH1cbiAgICAgICAgd2FzbS5zZXRWYWx1ZShyYXdEYXRhICsgaSAqIHB0clNpemUsIGFsbG9jV2FzbVN0cmluZyhkYXRhW2ldLCBhbGxvY3MpLCAnKicpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBpc0dyYXBoSW5wdXQgPSB3YXNtLndlYm5uSXNHcmFwaElucHV0O1xuICAgICAgY29uc3QgaXNHcmFwaE91dHB1dCA9IHdhc20ud2Vibm5Jc0dyYXBoT3V0cHV0O1xuICAgICAgaWYgKGRhdGFUeXBlICE9PSAnc3RyaW5nJyAmJiBpc0dyYXBoSW5wdXQgJiYgaXNHcmFwaE91dHB1dCkge1xuICAgICAgICBjb25zdCB0ZW5zb3JOYW1lID0gd2FzbS5VVEY4VG9TdHJpbmcodGVuc29yTmFtZVVURjhFbmNvZGVkKTtcbiAgICAgICAgLy8gUHJvbW90ZSB0aGUgdGVuc29yIHRvICdtbC10ZW5zb3InIGlmIGl0IGlzIGEgZ3JhcGggaW5wdXQuXG4gICAgICAgIGlmIChpc0dyYXBoSW5wdXQoc2Vzc2lvbklkLCB0ZW5zb3JOYW1lKSB8fCBpc0dyYXBoT3V0cHV0KHNlc3Npb25JZCwgdGVuc29yTmFtZSkpIHtcbiAgICAgICAgICBjb25zdCBkYXRhVHlwZUVudW0gPSB0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bShkYXRhVHlwZSk7XG4gICAgICAgICAgZGF0YUJ5dGVMZW5ndGggPSBjYWxjdWxhdGVUZW5zb3JTaXplSW5CeXRlcyhkYXRhVHlwZUVudW0sIGRpbXMpITtcbiAgICAgICAgICBhY3R1YWxMb2NhdGlvbiA9ICdtbC10ZW5zb3InO1xuICAgICAgICAgIGNvbnN0IGNyZWF0ZVRlbXBvcmFyeVRlbnNvciA9IHdhc20ud2Vibm5DcmVhdGVUZW1wb3JhcnlUZW5zb3I7XG4gICAgICAgICAgY29uc3QgdXBsb2FkVGVuc29yID0gd2FzbS53ZWJublVwbG9hZFRlbnNvcjtcbiAgICAgICAgICBpZiAoIWNyZWF0ZVRlbXBvcmFyeVRlbnNvciB8fCAhdXBsb2FkVGVuc29yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbnNvciBsb2NhdGlvbiBcIm1sLXRlbnNvclwiIGlzIG5vdCBzdXBwb3J0ZWQgd2l0aG91dCB1c2luZyBXZWJOTi4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgdGVuc29ySWQgPSBhd2FpdCBjcmVhdGVUZW1wb3JhcnlUZW5zb3Ioc2Vzc2lvbklkLCBkYXRhVHlwZUVudW0sIGRpbXMgYXMgbnVtYmVyW10pO1xuICAgICAgICAgIHVwbG9hZFRlbnNvcih0ZW5zb3JJZCwgbmV3IFVpbnQ4QXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgZGF0YS5ieXRlTGVuZ3RoKSk7XG4gICAgICAgICAgcmF3RGF0YSA9IHRlbnNvcklkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRhdGFCeXRlTGVuZ3RoID0gZGF0YS5ieXRlTGVuZ3RoO1xuICAgICAgICAgIHJhd0RhdGEgPSB3YXNtLl9tYWxsb2MoZGF0YUJ5dGVMZW5ndGgpO1xuICAgICAgICAgIGFsbG9jcy5wdXNoKHJhd0RhdGEpO1xuICAgICAgICAgIHdhc20uSEVBUFU4LnNldChuZXcgVWludDhBcnJheShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0LCBkYXRhQnl0ZUxlbmd0aCksIHJhd0RhdGEpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkYXRhQnl0ZUxlbmd0aCA9IGRhdGEuYnl0ZUxlbmd0aDtcbiAgICAgICAgcmF3RGF0YSA9IHdhc20uX21hbGxvYyhkYXRhQnl0ZUxlbmd0aCk7XG4gICAgICAgIGFsbG9jcy5wdXNoKHJhd0RhdGEpO1xuICAgICAgICB3YXNtLkhFQVBVOC5zZXQobmV3IFVpbnQ4QXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgZGF0YUJ5dGVMZW5ndGgpLCByYXdEYXRhKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBzdGFjayA9IHdhc20uc3RhY2tTYXZlKCk7XG4gIGNvbnN0IGRpbXNPZmZzZXQgPSB3YXNtLnN0YWNrQWxsb2MoNCAqIGRpbXMubGVuZ3RoKTtcbiAgdHJ5IHtcbiAgICBkaW1zLmZvckVhY2goKGQsIGluZGV4KSA9PiB3YXNtLnNldFZhbHVlKGRpbXNPZmZzZXQgKyBpbmRleCAqIHB0clNpemUsIGQsIHB0clNpemUgPT09IDQgPyAnaTMyJyA6ICdpNjQnKSk7XG4gICAgY29uc3QgdGVuc29yID0gd2FzbS5fT3J0Q3JlYXRlVGVuc29yKFxuICAgICAgdGVuc29yRGF0YVR5cGVTdHJpbmdUb0VudW0oZGF0YVR5cGUpLFxuICAgICAgcmF3RGF0YSxcbiAgICAgIGRhdGFCeXRlTGVuZ3RoLFxuICAgICAgZGltc09mZnNldCxcbiAgICAgIGRpbXMubGVuZ3RoLFxuICAgICAgZGF0YUxvY2F0aW9uU3RyaW5nVG9FbnVtKGFjdHVhbExvY2F0aW9uKSxcbiAgICApO1xuICAgIGlmICh0ZW5zb3IgPT09IDApIHtcbiAgICAgIGNoZWNrTGFzdEVycm9yKGBDYW4ndCBjcmVhdGUgdGVuc29yIGZvciBpbnB1dC9vdXRwdXQuIHNlc3Npb249JHtzZXNzaW9uSWR9LCBpbmRleD0ke2luZGV4fS5gKTtcbiAgICB9XG4gICAgdGVuc29ySGFuZGxlcy5wdXNoKHRlbnNvcik7XG4gIH0gZmluYWxseSB7XG4gICAgd2FzbS5zdGFja1Jlc3RvcmUoc3RhY2spO1xuICB9XG59O1xuXG4vKipcbiAqIHBlcmZvcm0gaW5mZXJlbmNlIHJ1blxuICovXG5leHBvcnQgY29uc3QgcnVuID0gYXN5bmMgKFxuICBzZXNzaW9uSWQ6IG51bWJlcixcbiAgaW5wdXRJbmRpY2VzOiBudW1iZXJbXSxcbiAgaW5wdXRUZW5zb3JzOiBUZW5zb3JNZXRhZGF0YVtdLFxuICBvdXRwdXRJbmRpY2VzOiBudW1iZXJbXSxcbiAgb3V0cHV0VGVuc29yczogQXJyYXk8VGVuc29yTWV0YWRhdGEgfCBudWxsPixcbiAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zLFxuKTogUHJvbWlzZTxUZW5zb3JNZXRhZGF0YVtdPiA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBjb25zdCBwdHJTaXplID0gd2FzbS5QVFJfU0laRTtcbiAgY29uc3Qgc2Vzc2lvbiA9IGFjdGl2ZVNlc3Npb25zLmdldChzZXNzaW9uSWQpO1xuICBpZiAoIXNlc3Npb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBydW4gaW5mZXJlbmNlLiBpbnZhbGlkIHNlc3Npb24gaWQ6ICR7c2Vzc2lvbklkfWApO1xuICB9XG4gIGNvbnN0IHNlc3Npb25IYW5kbGUgPSBzZXNzaW9uWzBdO1xuICBjb25zdCBpbnB1dE5hbWVzVVRGOEVuY29kZWQgPSBzZXNzaW9uWzFdO1xuICBjb25zdCBvdXRwdXROYW1lc1VURjhFbmNvZGVkID0gc2Vzc2lvblsyXTtcbiAgY29uc3QgaW9CaW5kaW5nU3RhdGUgPSBzZXNzaW9uWzNdO1xuICBjb25zdCBlbmFibGVHcmFwaENhcHR1cmUgPSBzZXNzaW9uWzRdO1xuICBjb25zdCBpbnB1dE91dHB1dEJvdW5kID0gc2Vzc2lvbls1XTtcblxuICBjb25zdCBpbnB1dENvdW50ID0gaW5wdXRJbmRpY2VzLmxlbmd0aDtcbiAgY29uc3Qgb3V0cHV0Q291bnQgPSBvdXRwdXRJbmRpY2VzLmxlbmd0aDtcblxuICBsZXQgcnVuT3B0aW9uc0hhbmRsZSA9IDA7XG4gIGxldCBydW5PcHRpb25zQWxsb2NzOiBudW1iZXJbXSA9IFtdO1xuXG4gIGNvbnN0IGlucHV0VGVuc29ySGFuZGxlczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3Qgb3V0cHV0VGVuc29ySGFuZGxlczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaW5wdXRPdXRwdXRBbGxvY3M6IG51bWJlcltdID0gW107XG5cbiAgY29uc3QgYmVmb3JlUnVuU3RhY2sgPSB3YXNtLnN0YWNrU2F2ZSgpO1xuICBjb25zdCBpbnB1dFZhbHVlc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyhpbnB1dENvdW50ICogcHRyU2l6ZSk7XG4gIGNvbnN0IGlucHV0TmFtZXNPZmZzZXQgPSB3YXNtLnN0YWNrQWxsb2MoaW5wdXRDb3VudCAqIHB0clNpemUpO1xuICBjb25zdCBvdXRwdXRWYWx1ZXNPZmZzZXQgPSB3YXNtLnN0YWNrQWxsb2Mob3V0cHV0Q291bnQgKiBwdHJTaXplKTtcbiAgY29uc3Qgb3V0cHV0TmFtZXNPZmZzZXQgPSB3YXNtLnN0YWNrQWxsb2Mob3V0cHV0Q291bnQgKiBwdHJTaXplKTtcblxuICB0cnkge1xuICAgIFtydW5PcHRpb25zSGFuZGxlLCBydW5PcHRpb25zQWxsb2NzXSA9IHNldFJ1bk9wdGlvbnMob3B0aW9ucyk7XG5cbiAgICAvLyBjcmVhdGUgaW5wdXQgdGVuc29yc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRDb3VudDsgaSsrKSB7XG4gICAgICBhd2FpdCBwcmVwYXJlSW5wdXRPdXRwdXRUZW5zb3IoXG4gICAgICAgIGlucHV0VGVuc29yc1tpXSxcbiAgICAgICAgaW5wdXRUZW5zb3JIYW5kbGVzLFxuICAgICAgICBpbnB1dE91dHB1dEFsbG9jcyxcbiAgICAgICAgc2Vzc2lvbklkLFxuICAgICAgICBpbnB1dE5hbWVzVVRGOEVuY29kZWRbaW5wdXRJbmRpY2VzW2ldXSxcbiAgICAgICAgaW5wdXRJbmRpY2VzW2ldLFxuICAgICAgICBlbmFibGVHcmFwaENhcHR1cmUsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIGNyZWF0ZSBvdXRwdXQgdGVuc29yc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0Q291bnQ7IGkrKykge1xuICAgICAgYXdhaXQgcHJlcGFyZUlucHV0T3V0cHV0VGVuc29yKFxuICAgICAgICBvdXRwdXRUZW5zb3JzW2ldLFxuICAgICAgICBvdXRwdXRUZW5zb3JIYW5kbGVzLFxuICAgICAgICBpbnB1dE91dHB1dEFsbG9jcyxcbiAgICAgICAgc2Vzc2lvbklkLFxuICAgICAgICBvdXRwdXROYW1lc1VURjhFbmNvZGVkW291dHB1dEluZGljZXNbaV1dLFxuICAgICAgICBpbnB1dENvdW50ICsgb3V0cHV0SW5kaWNlc1tpXSxcbiAgICAgICAgZW5hYmxlR3JhcGhDYXB0dXJlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Q291bnQ7IGkrKykge1xuICAgICAgd2FzbS5zZXRWYWx1ZShpbnB1dFZhbHVlc09mZnNldCArIGkgKiBwdHJTaXplLCBpbnB1dFRlbnNvckhhbmRsZXNbaV0sICcqJyk7XG4gICAgICB3YXNtLnNldFZhbHVlKGlucHV0TmFtZXNPZmZzZXQgKyBpICogcHRyU2l6ZSwgaW5wdXROYW1lc1VURjhFbmNvZGVkW2lucHV0SW5kaWNlc1tpXV0sICcqJyk7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0Q291bnQ7IGkrKykge1xuICAgICAgd2FzbS5zZXRWYWx1ZShvdXRwdXRWYWx1ZXNPZmZzZXQgKyBpICogcHRyU2l6ZSwgb3V0cHV0VGVuc29ySGFuZGxlc1tpXSwgJyonKTtcbiAgICAgIHdhc20uc2V0VmFsdWUob3V0cHV0TmFtZXNPZmZzZXQgKyBpICogcHRyU2l6ZSwgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZFtvdXRwdXRJbmRpY2VzW2ldXSwgJyonKTtcbiAgICB9XG5cbiAgICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQICYmIGlvQmluZGluZ1N0YXRlICYmICFpbnB1dE91dHB1dEJvdW5kKSB7XG4gICAgICBjb25zdCB7IGhhbmRsZSwgb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zLCBvdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnNFbmNvZGVkIH0gPSBpb0JpbmRpbmdTdGF0ZTtcblxuICAgICAgaWYgKGlucHV0TmFtZXNVVEY4RW5jb2RlZC5sZW5ndGggIT09IGlucHV0Q291bnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBpbnB1dCBjb3VudCBmcm9tIGZlZWRzICgke2lucHV0Q291bnR9KSBpcyBleHBlY3RlZCB0byBiZSBhbHdheXMgZXF1YWwgdG8gbW9kZWwncyBpbnB1dCBjb3VudCAoJHtpbnB1dE5hbWVzVVRGOEVuY29kZWQubGVuZ3RofSkuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gcHJvY2VzcyBpbnB1dHNcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRDb3VudDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gaW5wdXRJbmRpY2VzW2ldO1xuICAgICAgICBjb25zdCBlcnJvckNvZGUgPSBhd2FpdCB3YXNtLl9PcnRCaW5kSW5wdXQoaGFuZGxlLCBpbnB1dE5hbWVzVVRGOEVuY29kZWRbaW5kZXhdLCBpbnB1dFRlbnNvckhhbmRsZXNbaV0pO1xuICAgICAgICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XG4gICAgICAgICAgY2hlY2tMYXN0RXJyb3IoYENhbid0IGJpbmQgaW5wdXRbJHtpfV0gZm9yIHNlc3Npb249JHtzZXNzaW9uSWR9LmApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHByb2Nlc3MgcHJlLWFsbG9jYXRlZCBvdXRwdXRzXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dENvdW50OyBpKyspIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBvdXRwdXRJbmRpY2VzW2ldO1xuICAgICAgICBjb25zdCBsb2NhdGlvbiA9IG91dHB1dFRlbnNvcnNbaV0/LlszXTsgLy8gdW5kZWZpbmVkIG1lYW5zIG91dHB1dCBpcyBub3QgcHJlLWFsbG9jYXRlZC5cblxuICAgICAgICBpZiAobG9jYXRpb24pIHtcbiAgICAgICAgICAvLyBvdXRwdXQgaXMgcHJlLWFsbG9jYXRlZC4gYmluZCB0aGUgdGVuc29yLlxuICAgICAgICAgIGNvbnN0IGVycm9yQ29kZSA9IHdhc20uX09ydEJpbmRPdXRwdXQoaGFuZGxlLCBvdXRwdXROYW1lc1VURjhFbmNvZGVkW2luZGV4XSwgb3V0cHV0VGVuc29ySGFuZGxlc1tpXSwgMCk7XG4gICAgICAgICAgaWYgKGVycm9yQ29kZSAhPT0gMCkge1xuICAgICAgICAgICAgY2hlY2tMYXN0RXJyb3IoYENhbid0IGJpbmQgcHJlLWFsbG9jYXRlZCBvdXRwdXRbJHtpfV0gZm9yIHNlc3Npb249JHtzZXNzaW9uSWR9LmApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBvdXRwdXQgaXMgbm90IHByZS1hbGxvY2F0ZWQuIHJlc2V0IHByZWZlcnJlZCBsb2NhdGlvbi5cbiAgICAgICAgICBjb25zdCBlcnJvckNvZGUgPSB3YXNtLl9PcnRCaW5kT3V0cHV0KFxuICAgICAgICAgICAgaGFuZGxlLFxuICAgICAgICAgICAgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZFtpbmRleF0sXG4gICAgICAgICAgICAwLFxuICAgICAgICAgICAgb3V0cHV0UHJlZmVycmVkTG9jYXRpb25zRW5jb2RlZFtpbmRleF0sXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XG4gICAgICAgICAgICBjaGVja0xhc3RFcnJvcihgQ2FuJ3QgYmluZCBvdXRwdXRbJHtpfV0gdG8gJHtvdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnNbaV19IGZvciBzZXNzaW9uPSR7c2Vzc2lvbklkfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGFjdGl2ZVNlc3Npb25zLnNldChzZXNzaW9uSWQsIFtcbiAgICAgICAgc2Vzc2lvbkhhbmRsZSxcbiAgICAgICAgaW5wdXROYW1lc1VURjhFbmNvZGVkLFxuICAgICAgICBvdXRwdXROYW1lc1VURjhFbmNvZGVkLFxuICAgICAgICBpb0JpbmRpbmdTdGF0ZSxcbiAgICAgICAgZW5hYmxlR3JhcGhDYXB0dXJlLFxuICAgICAgICB0cnVlLFxuICAgICAgXSk7XG4gICAgfVxuXG4gICAgd2FzbS5qc2VwT25SdW5TdGFydD8uKHNlc3Npb25IYW5kbGUpO1xuICAgIHdhc20ud2Vibm5PblJ1blN0YXJ0Py4oc2Vzc2lvbkhhbmRsZSk7XG5cbiAgICBsZXQgZXJyb3JDb2RlOiBudW1iZXI7XG4gICAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfSlNFUCAmJiBpb0JpbmRpbmdTdGF0ZSkge1xuICAgICAgZXJyb3JDb2RlID0gYXdhaXQgd2FzbS5fT3J0UnVuV2l0aEJpbmRpbmcoXG4gICAgICAgIHNlc3Npb25IYW5kbGUsXG4gICAgICAgIGlvQmluZGluZ1N0YXRlLmhhbmRsZSxcbiAgICAgICAgb3V0cHV0Q291bnQsXG4gICAgICAgIG91dHB1dFZhbHVlc09mZnNldCxcbiAgICAgICAgcnVuT3B0aW9uc0hhbmRsZSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yQ29kZSA9IGF3YWl0IHdhc20uX09ydFJ1bihcbiAgICAgICAgc2Vzc2lvbkhhbmRsZSxcbiAgICAgICAgaW5wdXROYW1lc09mZnNldCxcbiAgICAgICAgaW5wdXRWYWx1ZXNPZmZzZXQsXG4gICAgICAgIGlucHV0Q291bnQsXG4gICAgICAgIG91dHB1dE5hbWVzT2Zmc2V0LFxuICAgICAgICBvdXRwdXRDb3VudCxcbiAgICAgICAgb3V0cHV0VmFsdWVzT2Zmc2V0LFxuICAgICAgICBydW5PcHRpb25zSGFuZGxlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XG4gICAgICBjaGVja0xhc3RFcnJvcignZmFpbGVkIHRvIGNhbGwgT3J0UnVuKCkuJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3V0cHV0OiBUZW5zb3JNZXRhZGF0YVtdID0gW107XG4gICAgY29uc3Qgb3V0cHV0UHJvbWlzZXM6IEFycmF5PFByb21pc2U8W251bWJlciwgVGVuc29yLkRhdGFUeXBlXT4+ID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dENvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IHRlbnNvciA9IE51bWJlcih3YXNtLmdldFZhbHVlKG91dHB1dFZhbHVlc09mZnNldCArIGkgKiBwdHJTaXplLCAnKicpKTtcbiAgICAgIGlmICh0ZW5zb3IgPT09IG91dHB1dFRlbnNvckhhbmRsZXNbaV0pIHtcbiAgICAgICAgLy8gb3V0cHV0IHRlbnNvciBpcyBwcmUtYWxsb2NhdGVkLiBubyBuZWVkIHRvIGNvcHkgZGF0YS5cbiAgICAgICAgb3V0cHV0LnB1c2gob3V0cHV0VGVuc29yc1tpXSEpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmVmb3JlR2V0VGVuc29yRGF0YVN0YWNrID0gd2FzbS5zdGFja1NhdmUoKTtcbiAgICAgIC8vIHN0YWNrIGFsbG9jYXRlIDQgcG9pbnRlciB2YWx1ZVxuICAgICAgY29uc3QgdGVuc29yRGF0YU9mZnNldCA9IHdhc20uc3RhY2tBbGxvYyg0ICogcHRyU2l6ZSk7XG5cbiAgICAgIGxldCBrZWVwT3V0cHV0VGVuc29yID0gZmFsc2U7XG4gICAgICBsZXQgdHlwZTogVGVuc29yLlR5cGUgfCB1bmRlZmluZWQsXG4gICAgICAgIGRhdGFPZmZzZXQgPSAwO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZXJyb3JDb2RlID0gd2FzbS5fT3J0R2V0VGVuc29yRGF0YShcbiAgICAgICAgICB0ZW5zb3IsXG4gICAgICAgICAgdGVuc29yRGF0YU9mZnNldCxcbiAgICAgICAgICB0ZW5zb3JEYXRhT2Zmc2V0ICsgcHRyU2l6ZSxcbiAgICAgICAgICB0ZW5zb3JEYXRhT2Zmc2V0ICsgMiAqIHB0clNpemUsXG5cbiAgICAgICAgICB0ZW5zb3JEYXRhT2Zmc2V0ICsgMyAqIHB0clNpemUsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChlcnJvckNvZGUgIT09IDApIHtcbiAgICAgICAgICBjaGVja0xhc3RFcnJvcihgQ2FuJ3QgYWNjZXNzIG91dHB1dCB0ZW5zb3IgZGF0YSBvbiBpbmRleCAke2l9LmApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHB0clNpemUgPT09IDQgPyAnaTMyJyA6ICdpNjQnO1xuICAgICAgICBjb25zdCBkYXRhVHlwZSA9IE51bWJlcih3YXNtLmdldFZhbHVlKHRlbnNvckRhdGFPZmZzZXQsIHZhbHVlVHlwZSkpO1xuICAgICAgICBkYXRhT2Zmc2V0ID0gd2FzbS5nZXRWYWx1ZSh0ZW5zb3JEYXRhT2Zmc2V0ICsgcHRyU2l6ZSwgJyonKTtcbiAgICAgICAgY29uc3QgZGltc09mZnNldCA9IHdhc20uZ2V0VmFsdWUodGVuc29yRGF0YU9mZnNldCArIHB0clNpemUgKiAyLCAnKicpO1xuICAgICAgICBjb25zdCBkaW1zTGVuZ3RoID0gTnVtYmVyKHdhc20uZ2V0VmFsdWUodGVuc29yRGF0YU9mZnNldCArIHB0clNpemUgKiAzLCB2YWx1ZVR5cGUpKTtcbiAgICAgICAgY29uc3QgZGltcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXNMZW5ndGg7IGkrKykge1xuICAgICAgICAgIGRpbXMucHVzaChOdW1iZXIod2FzbS5nZXRWYWx1ZShkaW1zT2Zmc2V0ICsgaSAqIHB0clNpemUsIHZhbHVlVHlwZSkpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAod2FzbS5fT3J0RnJlZShkaW1zT2Zmc2V0KSAhPT0gMCkge1xuICAgICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgZnJlZSBtZW1vcnkgZm9yIHRlbnNvciBkaW1zLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzaXplID0gZGltcy5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiLCAxKTtcbiAgICAgICAgdHlwZSA9IHRlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nKGRhdGFUeXBlKTtcblxuICAgICAgICBjb25zdCBwcmVmZXJyZWRMb2NhdGlvbiA9IGlvQmluZGluZ1N0YXRlPy5vdXRwdXRQcmVmZXJyZWRMb2NhdGlvbnNbb3V0cHV0SW5kaWNlc1tpXV07XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgaWYgKHByZWZlcnJlZExvY2F0aW9uID09PSAnZ3B1LWJ1ZmZlcicgfHwgcHJlZmVycmVkTG9jYXRpb24gPT09ICdtbC10ZW5zb3InKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N0cmluZyB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZCBvbiBHUFUuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHN0cmluZ0RhdGE6IHN0cmluZ1tdID0gW107XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IHdhc20uZ2V0VmFsdWUoZGF0YU9mZnNldCArIGkgKiBwdHJTaXplLCAnKicpO1xuICAgICAgICAgICAgY29uc3QgbmV4dE9mZnNldCA9IHdhc20uZ2V0VmFsdWUoZGF0YU9mZnNldCArIChpICsgMSkgKiBwdHJTaXplLCAnKicpO1xuICAgICAgICAgICAgY29uc3QgbWF4Qnl0ZXNUb1JlYWQgPSBpID09PSBzaXplIC0gMSA/IHVuZGVmaW5lZCA6IG5leHRPZmZzZXQgLSBvZmZzZXQ7XG4gICAgICAgICAgICBzdHJpbmdEYXRhLnB1c2god2FzbS5VVEY4VG9TdHJpbmcob2Zmc2V0LCBtYXhCeXRlc1RvUmVhZCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvdXRwdXQucHVzaChbdHlwZSwgZGltcywgc3RyaW5nRGF0YSwgJ2NwdSddKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBJZiBhIGNlcnRhaW4gb3V0cHV0J3MgcHJlZmVycmVkIGxvY2F0aW9uIGlzIEdQVSBidXQgdGhlIHRlbnNvciBpcyBlbXB0eSwgd2Ugc3RpbGwgbmVlZCB0byBjcmVhdGUgYSBDUFVcbiAgICAgICAgICAvLyB0ZW5zb3IgZm9yIGl0LiBUaGVyZSBpcyBubyBtYXBwaW5nIEdQVSBidWZmZXIgZm9yIGFuIGVtcHR5IHRlbnNvci5cbiAgICAgICAgICBpZiAocHJlZmVycmVkTG9jYXRpb24gPT09ICdncHUtYnVmZmVyJyAmJiBzaXplID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZ2V0QnVmZmVyID0gQlVJTERfREVGUy5VU0VfV0VCR1BVX0VQID8gd2FzbS53ZWJncHVHZXRCdWZmZXIgOiB3YXNtLmpzZXBHZXRCdWZmZXI7XG4gICAgICAgICAgICBpZiAoIWdldEJ1ZmZlcikge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ByZWZlcnJlZExvY2F0aW9uIFwiZ3B1LWJ1ZmZlclwiIGlzIG5vdCBzdXBwb3J0ZWQgd2l0aG91dCB1c2luZyBXZWJHUFUuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBncHVCdWZmZXIgPSBnZXRCdWZmZXIoZGF0YU9mZnNldCk7XG4gICAgICAgICAgICBjb25zdCBidWZmZXJTaXplID0gY2FsY3VsYXRlVGVuc29yU2l6ZUluQnl0ZXMoZGF0YVR5cGUsIHNpemUpO1xuICAgICAgICAgICAgaWYgKGJ1ZmZlclNpemUgPT09IHVuZGVmaW5lZCB8fCAhaXNHcHVCdWZmZXJTdXBwb3J0ZWRUeXBlKHR5cGUpKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZGF0YSB0eXBlOiAke3R5cGV9YCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGRvIG5vdCByZWxlYXNlIHRoZSB0ZW5zb3IgcmlnaHQgbm93LiBpdCB3aWxsIGJlIHJlbGVhc2VkIHdoZW4gdXNlciBjYWxscyB0ZW5zb3IuZGlzcG9zZSgpLlxuICAgICAgICAgICAga2VlcE91dHB1dFRlbnNvciA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmIChCVUlMRF9ERUZTLlVTRV9XRUJHUFVfRVApIHtcbiAgICAgICAgICAgICAgd2FzbS53ZWJncHVSZWdpc3RlckJ1ZmZlciEoZ3B1QnVmZmVyLCBzZXNzaW9uSWQsIGRhdGFPZmZzZXQpO1xuICAgICAgICAgICAgICBjb25zdCBkb3dubG9hZERhdGFGdW5jdGlvbiA9IHdhc20ud2ViZ3B1Q3JlYXRlRG93bmxvYWRlciEoZ3B1QnVmZmVyLCBidWZmZXJTaXplLCBzZXNzaW9uSWQpO1xuICAgICAgICAgICAgICBvdXRwdXQucHVzaChbXG4gICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgICBkaW1zLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGdwdUJ1ZmZlcixcbiAgICAgICAgICAgICAgICAgIGRvd25sb2FkOiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFycmF5QnVmZmVyID0gYXdhaXQgZG93bmxvYWREYXRhRnVuY3Rpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IG5ldyAodGVuc29yVHlwZVRvVHlwZWRBcnJheUNvbnN0cnVjdG9yKHR5cGUhKSkoYXJyYXlCdWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YSBhcyBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlc107XG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgZGlzcG9zZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAod2FzbS5fT3J0UmVsZWFzZVRlbnNvcih0ZW5zb3IpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCByZWxlYXNlIHRlbnNvci5cIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAnZ3B1LWJ1ZmZlcicsXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgb3V0cHV0LnB1c2goW1xuICAgICAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICAgICAgZGltcyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBncHVCdWZmZXIsXG4gICAgICAgICAgICAgICAgICBkb3dubG9hZDogd2FzbS5qc2VwQ3JlYXRlRG93bmxvYWRlciEoZ3B1QnVmZmVyLCBidWZmZXJTaXplLCB0eXBlKSxcbiAgICAgICAgICAgICAgICAgIGRpc3Bvc2U6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdhc20uX09ydFJlbGVhc2VUZW5zb3IodGVuc29yKSAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgcmVsZWFzZSB0ZW5zb3IuXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgJ2dwdS1idWZmZXInLFxuICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKHByZWZlcnJlZExvY2F0aW9uID09PSAnbWwtdGVuc29yJyAmJiBzaXplID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZW5zdXJlVGVuc29yID0gd2FzbS53ZWJubkVuc3VyZVRlbnNvcjtcbiAgICAgICAgICAgIGNvbnN0IGlzR3JhcGhJbnB1dE91dHB1dFR5cGVTdXBwb3J0ZWQgPSB3YXNtLndlYm5uSXNHcmFwaElucHV0T3V0cHV0VHlwZVN1cHBvcnRlZDtcbiAgICAgICAgICAgIGlmICghZW5zdXJlVGVuc29yIHx8ICFpc0dyYXBoSW5wdXRPdXRwdXRUeXBlU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncHJlZmVycmVkTG9jYXRpb24gXCJtbC10ZW5zb3JcIiBpcyBub3Qgc3VwcG9ydGVkIHdpdGhvdXQgdXNpbmcgV2ViTk4uJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB0ZW5zb3JTaXplID0gY2FsY3VsYXRlVGVuc29yU2l6ZUluQnl0ZXMoZGF0YVR5cGUsIHNpemUpO1xuICAgICAgICAgICAgaWYgKHRlbnNvclNpemUgPT09IHVuZGVmaW5lZCB8fCAhaXNNTFRlbnNvclN1cHBvcnRlZFR5cGUodHlwZSkpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7dHlwZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaXNHcmFwaElucHV0T3V0cHV0VHlwZVN1cHBvcnRlZChzZXNzaW9uSWQsIHR5cGUsIGZhbHNlKSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgYHByZWZlcnJlZExvY2F0aW9uIFwibWwtdGVuc29yXCIgZm9yICR7dHlwZX0gb3V0cHV0IGlzIG5vdCBzdXBwb3J0ZWQgYnkgY3VycmVudCBXZWJOTiBDb250ZXh0LmAsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIHRoZSBncmFwaCBoYXMgYmVlbiBwYXJ0aXRpb25lZCwgdGhlIG91dHB1dCB0ZW5zb3IgbWF5IGhhdmUgbm90IGJlZW4gY3JlYXRlZC4gRm9yIHRoaXMgcmVhc29uLCB3ZSB1c2VcbiAgICAgICAgICAgIC8vIGVuc3VyZVRlbnNvciB0byBnZXQvY3JlYXRlIHRoZSBNTFRlbnNvci4gSW4gd2hpY2ggY2FzZSwgd2UgZG9uJ3QgbmVlZCB0byBjb3B5IHRoZSBkYXRhIGlmIGEgbmV3IHRlbnNvclxuICAgICAgICAgICAgLy8gaGFzIGJlZW4gY3JlYXRlZC5cbiAgICAgICAgICAgIGNvbnN0IG1sVGVuc29yID0gYXdhaXQgZW5zdXJlVGVuc29yKHNlc3Npb25JZCwgZGF0YU9mZnNldCwgZGF0YVR5cGUsIGRpbXMsIGZhbHNlKTtcblxuICAgICAgICAgICAgLy8gZG8gbm90IHJlbGVhc2UgdGhlIHRlbnNvciByaWdodCBub3cuIGl0IHdpbGwgYmUgcmVsZWFzZWQgd2hlbiB1c2VyIGNhbGxzIHRlbnNvci5kaXNwb3NlKCkuXG4gICAgICAgICAgICBrZWVwT3V0cHV0VGVuc29yID0gdHJ1ZTtcblxuICAgICAgICAgICAgb3V0cHV0LnB1c2goW1xuICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgICBkaW1zLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbWxUZW5zb3IsXG4gICAgICAgICAgICAgICAgZG93bmxvYWQ6IHdhc20ud2Vibm5DcmVhdGVNTFRlbnNvckRvd25sb2FkZXIhKGRhdGFPZmZzZXQsIHR5cGUpLFxuICAgICAgICAgICAgICAgIGRpc3Bvc2U6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgIHdhc20ud2Vibm5SZWxlYXNlVGVuc29ySWQhKGRhdGFPZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgd2FzbS5fT3J0UmVsZWFzZVRlbnNvcih0ZW5zb3IpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICdtbC10ZW5zb3InLFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChwcmVmZXJyZWRMb2NhdGlvbiA9PT0gJ21sLXRlbnNvci1jcHUtb3V0cHV0JyAmJiBzaXplID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHdhc20ud2Vibm5DcmVhdGVNTFRlbnNvckRvd25sb2FkZXIhKGRhdGFPZmZzZXQsIHR5cGUgYXMgVGVuc29yLk1MVGVuc29yRGF0YVR5cGVzKSgpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBvdXRwdXQubGVuZ3RoO1xuICAgICAgICAgICAgLy8gRGVsYXkgdGhlIGRhdGEgZG93bmxvYWQgYW5kIHJlbGVhc2luZyB0aGUgdGVuc29yIHVudGlsIHdlIGNhbiB3YWl0IGZvciBhbGwgb3V0cHV0IHRlbnNvcnMgdG8gYmUgZG93bmxvYWRlZC5cbiAgICAgICAgICAgIGtlZXBPdXRwdXRUZW5zb3IgPSB0cnVlO1xuICAgICAgICAgICAgb3V0cHV0UHJvbWlzZXMucHVzaChcbiAgICAgICAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQ6IFtudW1iZXIsIFRlbnNvci5EYXRhVHlwZV0gPSBbaW5kZXgsIGF3YWl0IGRhdGFdO1xuICAgICAgICAgICAgICAgIHdhc20ud2Vibm5SZWxlYXNlVGVuc29ySWQhKGRhdGFPZmZzZXQpO1xuICAgICAgICAgICAgICAgIHdhc20uX09ydFJlbGVhc2VUZW5zb3IodGVuc29yKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICB9KSgpLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG91dHB1dC5wdXNoKFt0eXBlLCBkaW1zLCBbXSwgJ2NwdSddKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdHlwZWRBcnJheUNvbnN0cnVjdG9yID0gdGVuc29yVHlwZVRvVHlwZWRBcnJheUNvbnN0cnVjdG9yKHR5cGUpO1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IG5ldyB0eXBlZEFycmF5Q29uc3RydWN0b3Ioc2l6ZSk7XG4gICAgICAgICAgICBuZXcgVWludDhBcnJheShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0LCBkYXRhLmJ5dGVMZW5ndGgpLnNldChcbiAgICAgICAgICAgICAgd2FzbS5IRUFQVTguc3ViYXJyYXkoZGF0YU9mZnNldCwgZGF0YU9mZnNldCArIGRhdGEuYnl0ZUxlbmd0aCksXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb3V0cHV0LnB1c2goW3R5cGUsIGRpbXMsIGRhdGEsICdjcHUnXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB3YXNtLnN0YWNrUmVzdG9yZShiZWZvcmVHZXRUZW5zb3JEYXRhU3RhY2spO1xuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgZGF0YU9mZnNldCkge1xuICAgICAgICAgIHdhc20uX2ZyZWUoZGF0YU9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFrZWVwT3V0cHV0VGVuc29yKSB7XG4gICAgICAgICAgd2FzbS5fT3J0UmVsZWFzZVRlbnNvcih0ZW5zb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlvQmluZGluZ1N0YXRlICYmICFlbmFibGVHcmFwaENhcHR1cmUpIHtcbiAgICAgIGlmICh3YXNtLl9PcnRDbGVhckJvdW5kT3V0cHV0cyhpb0JpbmRpbmdTdGF0ZS5oYW5kbGUpICE9PSAwKSB7XG4gICAgICAgIGNoZWNrTGFzdEVycm9yKFwiQ2FuJ3QgY2xlYXIgYm91bmQgb3V0cHV0cy5cIik7XG4gICAgICB9XG4gICAgICBhY3RpdmVTZXNzaW9ucy5zZXQoc2Vzc2lvbklkLCBbXG4gICAgICAgIHNlc3Npb25IYW5kbGUsXG4gICAgICAgIGlucHV0TmFtZXNVVEY4RW5jb2RlZCxcbiAgICAgICAgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZCxcbiAgICAgICAgaW9CaW5kaW5nU3RhdGUsXG4gICAgICAgIGVuYWJsZUdyYXBoQ2FwdHVyZSxcbiAgICAgICAgZmFsc2UsXG4gICAgICBdKTtcbiAgICB9XG4gICAgLy8gV2FpdCBmb3IgYWxsIG91dHB1dCB0ZW5zb3IgZGF0YSB0byBiZSBkb3dubG9hZGVkLlxuICAgIGZvciAoY29uc3QgW2luZGV4LCBkYXRhXSBvZiBhd2FpdCBQcm9taXNlLmFsbChvdXRwdXRQcm9taXNlcykpIHtcbiAgICAgIG91dHB1dFtpbmRleF1bMl0gPSBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9IGZpbmFsbHkge1xuICAgIHdhc20ud2Vibm5PblJ1bkVuZD8uKHNlc3Npb25IYW5kbGUpO1xuXG4gICAgd2FzbS5zdGFja1Jlc3RvcmUoYmVmb3JlUnVuU3RhY2spO1xuXG4gICAgaWYgKEJVSUxEX0RFRlMuVVNFX1dFQkdQVV9FUCkge1xuICAgICAgaW5wdXRUZW5zb3JzLmZvckVhY2goKHQpID0+IHtcbiAgICAgICAgaWYgKHQgJiYgdFszXSA9PT0gJ2dwdS1idWZmZXInKSB7XG4gICAgICAgICAgd2FzbS53ZWJncHVVbnJlZ2lzdGVyQnVmZmVyISh0WzJdLmdwdUJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgb3V0cHV0VGVuc29ycy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICAgIGlmICh0ICYmIHRbM10gPT09ICdncHUtYnVmZmVyJykge1xuICAgICAgICAgIHdhc20ud2ViZ3B1VW5yZWdpc3RlckJ1ZmZlciEodFsyXS5ncHVCdWZmZXIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgaW5wdXRUZW5zb3JIYW5kbGVzLmZvckVhY2goKHYpID0+IHdhc20uX09ydFJlbGVhc2VUZW5zb3IodikpO1xuICAgIG91dHB1dFRlbnNvckhhbmRsZXMuZm9yRWFjaCgodikgPT4gd2FzbS5fT3J0UmVsZWFzZVRlbnNvcih2KSk7XG4gICAgaW5wdXRPdXRwdXRBbGxvY3MuZm9yRWFjaCgocCkgPT4gd2FzbS5fZnJlZShwKSk7XG5cbiAgICBpZiAocnVuT3B0aW9uc0hhbmRsZSAhPT0gMCkge1xuICAgICAgd2FzbS5fT3J0UmVsZWFzZVJ1bk9wdGlvbnMocnVuT3B0aW9uc0hhbmRsZSk7XG4gICAgfVxuICAgIHJ1bk9wdGlvbnNBbGxvY3MuZm9yRWFjaCgocCkgPT4gd2FzbS5fZnJlZShwKSk7XG4gIH1cbn07XG5cbi8qKlxuICogZW5kIHByb2ZpbGluZ1xuICovXG5leHBvcnQgY29uc3QgZW5kUHJvZmlsaW5nID0gKHNlc3Npb25JZDogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBjb25zdCBzZXNzaW9uID0gYWN0aXZlU2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gIGlmICghc2Vzc2lvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzZXNzaW9uIGlkJyk7XG4gIH1cbiAgY29uc3Qgc2Vzc2lvbkhhbmRsZSA9IHNlc3Npb25bMF07XG5cbiAgLy8gcHJvZmlsZSBmaWxlIG5hbWUgaXMgbm90IHVzZWQgeWV0LCBidXQgaXQgbXVzdCBiZSBmcmVlZC5cbiAgY29uc3QgcHJvZmlsZUZpbGVOYW1lID0gd2FzbS5fT3J0RW5kUHJvZmlsaW5nKHNlc3Npb25IYW5kbGUpO1xuICBpZiAocHJvZmlsZUZpbGVOYW1lID09PSAwKSB7XG4gICAgY2hlY2tMYXN0RXJyb3IoXCJDYW4ndCBnZXQgYW4gcHJvZmlsZSBmaWxlIG5hbWUuXCIpO1xuICB9XG4gIHdhc20uX09ydEZyZWUocHJvZmlsZUZpbGVOYW1lKTtcbn07XG5cbmV4cG9ydCBjb25zdCBleHRyYWN0VHJhbnNmZXJhYmxlQnVmZmVycyA9ICh0ZW5zb3JzOiByZWFkb25seSBTZXJpYWxpemFibGVUZW5zb3JNZXRhZGF0YVtdKTogQXJyYXlCdWZmZXJMaWtlW10gPT4ge1xuICBjb25zdCBidWZmZXJzOiBBcnJheUJ1ZmZlckxpa2VbXSA9IFtdO1xuICBmb3IgKGNvbnN0IHRlbnNvciBvZiB0ZW5zb3JzKSB7XG4gICAgY29uc3QgZGF0YSA9IHRlbnNvclsyXTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkgJiYgJ2J1ZmZlcicgaW4gZGF0YSkge1xuICAgICAgYnVmZmVycy5wdXNoKGRhdGEuYnVmZmVyKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGJ1ZmZlcnM7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQgeyBlbnYsIEluZmVyZW5jZVNlc3Npb24gfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQge1xuICBPcnRXYXNtTWVzc2FnZSxcbiAgU2VyaWFsaXphYmxlSW50ZXJuYWxCdWZmZXIsXG4gIFNlcmlhbGl6YWJsZVNlc3Npb25NZXRhZGF0YSxcbiAgU2VyaWFsaXphYmxlVGVuc29yTWV0YWRhdGEsXG4gIFRlbnNvck1ldGFkYXRhLFxufSBmcm9tICcuL3Byb3h5LW1lc3NhZ2VzJztcbmltcG9ydCAqIGFzIGNvcmUgZnJvbSAnLi93YXNtLWNvcmUtaW1wbCc7XG5pbXBvcnQgeyBpbml0aWFsaXplV2ViQXNzZW1ibHkgfSBmcm9tICcuL3dhc20tZmFjdG9yeSc7XG5pbXBvcnQge1xuICBpbXBvcnRQcm94eVdvcmtlcixcbiAgaW5mZXJXYXNtUGF0aFByZWZpeEZyb21TY3JpcHRTcmMsXG4gIGlzRXNtSW1wb3J0TWV0YVVybEhhcmRjb2RlZEFzRmlsZVVyaSxcbn0gZnJvbSAnLi93YXNtLXV0aWxzLWltcG9ydCc7XG5cbmNvbnN0IGlzUHJveHkgPSAoKTogYm9vbGVhbiA9PiAhIWVudi53YXNtLnByb3h5ICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCc7XG5sZXQgcHJveHlXb3JrZXI6IFdvcmtlciB8IHVuZGVmaW5lZDtcbmxldCBpbml0aWFsaXppbmcgPSBmYWxzZTtcbmxldCBpbml0aWFsaXplZCA9IGZhbHNlO1xubGV0IGFib3J0ZWQgPSBmYWxzZTtcbmxldCB0ZW1wb3JhcnlPYmplY3RVcmw6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxudHlwZSBQcm9taXNlQ2FsbGJhY2tzPFQgPSB2b2lkPiA9IFtyZXNvbHZlOiAocmVzdWx0OiBUKSA9PiB2b2lkLCByZWplY3Q6IChyZWFzb246IHVua25vd24pID0+IHZvaWRdO1xubGV0IGluaXRXYXNtQ2FsbGJhY2tzOiBQcm9taXNlQ2FsbGJhY2tzO1xuY29uc3QgcXVldWVkQ2FsbGJhY2tzOiBNYXA8T3J0V2FzbU1lc3NhZ2VbJ3R5cGUnXSwgQXJyYXk8UHJvbWlzZUNhbGxiYWNrczx1bmtub3duPj4+ID0gbmV3IE1hcCgpO1xuXG5jb25zdCBlbnF1ZXVlQ2FsbGJhY2tzID0gKHR5cGU6IE9ydFdhc21NZXNzYWdlWyd0eXBlJ10sIGNhbGxiYWNrczogUHJvbWlzZUNhbGxiYWNrczx1bmtub3duPik6IHZvaWQgPT4ge1xuICBjb25zdCBxdWV1ZSA9IHF1ZXVlZENhbGxiYWNrcy5nZXQodHlwZSk7XG4gIGlmIChxdWV1ZSkge1xuICAgIHF1ZXVlLnB1c2goY2FsbGJhY2tzKTtcbiAgfSBlbHNlIHtcbiAgICBxdWV1ZWRDYWxsYmFja3Muc2V0KHR5cGUsIFtjYWxsYmFja3NdKTtcbiAgfVxufTtcblxuY29uc3QgZW5zdXJlV29ya2VyID0gKCk6IHZvaWQgPT4ge1xuICBpZiAoaW5pdGlhbGl6aW5nIHx8ICFpbml0aWFsaXplZCB8fCBhYm9ydGVkIHx8ICFwcm94eVdvcmtlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignd29ya2VyIG5vdCByZWFkeScpO1xuICB9XG59O1xuXG5jb25zdCBvblByb3h5V29ya2VyTWVzc2FnZSA9IChldjogTWVzc2FnZUV2ZW50PE9ydFdhc21NZXNzYWdlPik6IHZvaWQgPT4ge1xuICBzd2l0Y2ggKGV2LmRhdGEudHlwZSkge1xuICAgIGNhc2UgJ2luaXQtd2FzbSc6XG4gICAgICBpbml0aWFsaXppbmcgPSBmYWxzZTtcbiAgICAgIGlmIChldi5kYXRhLmVycikge1xuICAgICAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgaW5pdFdhc21DYWxsYmFja3NbMV0oZXYuZGF0YS5lcnIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICBpbml0V2FzbUNhbGxiYWNrc1swXSgpO1xuICAgICAgfVxuICAgICAgaWYgKHRlbXBvcmFyeU9iamVjdFVybCkge1xuICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHRlbXBvcmFyeU9iamVjdFVybCk7XG4gICAgICAgIHRlbXBvcmFyeU9iamVjdFVybCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2luaXQtZXAnOlxuICAgIGNhc2UgJ2NvcHktZnJvbSc6XG4gICAgY2FzZSAnY3JlYXRlJzpcbiAgICBjYXNlICdyZWxlYXNlJzpcbiAgICBjYXNlICdydW4nOlxuICAgIGNhc2UgJ2VuZC1wcm9maWxpbmcnOiB7XG4gICAgICBjb25zdCBjYWxsYmFja3MgPSBxdWV1ZWRDYWxsYmFja3MuZ2V0KGV2LmRhdGEudHlwZSkhO1xuICAgICAgaWYgKGV2LmRhdGEuZXJyKSB7XG4gICAgICAgIGNhbGxiYWNrcy5zaGlmdCgpIVsxXShldi5kYXRhLmVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYWxsYmFja3Muc2hpZnQoKSFbMF0oZXYuZGF0YS5vdXQhKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBkZWZhdWx0OlxuICB9XG59O1xuXG5leHBvcnQgY29uc3QgaW5pdGlhbGl6ZVdlYkFzc2VtYmx5QW5kT3J0UnVudGltZSA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgaWYgKGluaXRpYWxpemVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChpbml0aWFsaXppbmcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJtdWx0aXBsZSBjYWxscyB0byAnaW5pdFdhc20oKScgZGV0ZWN0ZWQuXCIpO1xuICB9XG4gIGlmIChhYm9ydGVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwicHJldmlvdXMgY2FsbCB0byAnaW5pdFdhc20oKScgZmFpbGVkLlwiKTtcbiAgfVxuXG4gIGluaXRpYWxpemluZyA9IHRydWU7XG5cbiAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTV9QUk9YWSAmJiBpc1Byb3h5KCkpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgcHJveHlXb3JrZXI/LnRlcm1pbmF0ZSgpO1xuXG4gICAgICB2b2lkIGltcG9ydFByb3h5V29ya2VyKCkudGhlbigoW29iamVjdFVybCwgd29ya2VyXSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHByb3h5V29ya2VyID0gd29ya2VyO1xuICAgICAgICAgIHByb3h5V29ya2VyLm9uZXJyb3IgPSAoZXY6IEVycm9yRXZlbnQpID0+IHJlamVjdChldik7XG4gICAgICAgICAgcHJveHlXb3JrZXIub25tZXNzYWdlID0gb25Qcm94eVdvcmtlck1lc3NhZ2U7XG4gICAgICAgICAgaW5pdFdhc21DYWxsYmFja3MgPSBbcmVzb2x2ZSwgcmVqZWN0XTtcbiAgICAgICAgICBjb25zdCBtZXNzYWdlOiBPcnRXYXNtTWVzc2FnZSA9IHsgdHlwZTogJ2luaXQtd2FzbScsIGluOiBlbnYgfTtcblxuICAgICAgICAgIC8vIGlmIHRoZSBwcm94eSB3b3JrZXIgaXMgbG9hZGVkIGZyb20gYSBibG9iIFVSTCwgd2UgbmVlZCB0byBtYWtlIHN1cmUgdGhlIHBhdGggaW5mb3JtYXRpb24gaXMgbm90IGxvc3QuXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyB3aGVuIGBlbnYud2FzbS53YXNtUGF0aHNgIGlzIG5vdCBzZXQsIHdlIG5lZWQgdG8gcGFzcyB0aGUgcGF0aCBpbmZvcm1hdGlvbiB0byB0aGUgd29ya2VyLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgaWYgKCFCVUlMRF9ERUZTLkVOQUJMRV9CVU5ETEVfV0FTTV9KUyAmJiAhbWVzc2FnZS5pbiEud2FzbS53YXNtUGF0aHMgJiYgb2JqZWN0VXJsKSB7XG4gICAgICAgICAgICAvLyBmb3IgYSBidWlsZCBub3QgYnVuZGxlZCB0aGUgd2FzbSBKUywgd2UgbmVlZCB0byBwYXNzIHRoZSBwYXRoIHByZWZpeCB0byB0aGUgd29ya2VyLlxuICAgICAgICAgICAgLy8gdGhlIHBhdGggcHJlZml4IHdpbGwgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwYXRoIHRvIGJvdGggdGhlIHdhc20gSlMgYW5kIHRoZSB3YXNtIGZpbGUuXG4gICAgICAgICAgICBjb25zdCBpbmZlcnJlZFdhc21QYXRoUHJlZml4ID0gaW5mZXJXYXNtUGF0aFByZWZpeEZyb21TY3JpcHRTcmMoKTtcbiAgICAgICAgICAgIGlmIChpbmZlcnJlZFdhc21QYXRoUHJlZml4KSB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UuaW4hLndhc20ud2FzbVBhdGhzID0gaW5mZXJyZWRXYXNtUGF0aFByZWZpeDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBCVUlMRF9ERUZTLklTX0VTTSAmJlxuICAgICAgICAgICAgQlVJTERfREVGUy5FTkFCTEVfQlVORExFX1dBU01fSlMgJiZcbiAgICAgICAgICAgICFtZXNzYWdlLmluIS53YXNtLndhc21QYXRocyAmJlxuICAgICAgICAgICAgKG9iamVjdFVybCB8fCBpc0VzbUltcG9ydE1ldGFVcmxIYXJkY29kZWRBc0ZpbGVVcmkpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBmb3IgYSBidWlsZCBidW5kbGVkIHRoZSB3YXNtIEpTLCBpZiBlaXRoZXIgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGlzIG1ldDpcbiAgICAgICAgICAgIC8vIC0gdGhlIHByb3h5IHdvcmtlciBpcyBsb2FkZWQgZnJvbSBhIGJsb2IgVVJMXG4gICAgICAgICAgICAvLyAtIGBpbXBvcnQubWV0YS51cmxgIGlzIGEgZmlsZSBVUkwsIGl0IG1lYW5zIGl0IGlzIG92ZXJ3cml0ZW4gYnkgdGhlIGJ1bmRsZXIuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gaW4gZWl0aGVyIGNhc2UsIHRoZSBwYXRoIGluZm9ybWF0aW9uIGlzIGxvc3QsIHdlIG5lZWQgdG8gcGFzcyB0aGUgcGF0aCBvZiB0aGUgLndhc20gZmlsZSB0byB0aGUgd29ya2VyLlxuICAgICAgICAgICAgLy8gd2UgbmVlZCB0byB1c2UgdGhlIGJ1bmRsZXIgcHJlZmVycmVkIFVSTCBmb3JtYXQ6XG4gICAgICAgICAgICAvLyBuZXcgVVJMKCdmaWxlbmFtZScsIGltcG9ydC5tZXRhLnVybClcbiAgICAgICAgICAgIC8vIHNvIHRoYXQgdGhlIGJ1bmRsZXIgY2FuIGhhbmRsZSB0aGUgZmlsZSB1c2luZyBjb3JyZXNwb25kaW5nIGxvYWRlcnMuXG4gICAgICAgICAgICBtZXNzYWdlLmluIS53YXNtLndhc21QYXRocyA9IHtcbiAgICAgICAgICAgICAgd2FzbTogIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQXG4gICAgICAgICAgICAgICAgPyBuZXcgVVJMKCdvcnQtd2FzbS1zaW1kLXRocmVhZGVkLmpzZXAud2FzbScsIEJVSUxEX0RFRlMuRVNNX0lNUE9SVF9NRVRBX1VSTCkuaHJlZlxuICAgICAgICAgICAgICAgIDogbmV3IFVSTCgnb3J0LXdhc20tc2ltZC10aHJlYWRlZC53YXNtJywgQlVJTERfREVGUy5FU01fSU1QT1JUX01FVEFfVVJMKS5ocmVmLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcHJveHlXb3JrZXIucG9zdE1lc3NhZ2UobWVzc2FnZSk7XG4gICAgICAgICAgdGVtcG9yYXJ5T2JqZWN0VXJsID0gb2JqZWN0VXJsO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICB9XG4gICAgICB9LCByZWplY3QpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBpbml0aWFsaXplV2ViQXNzZW1ibHkoZW52Lndhc20pO1xuICAgICAgYXdhaXQgY29yZS5pbml0UnVudGltZShlbnYpO1xuICAgICAgaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGFib3J0ZWQgPSB0cnVlO1xuICAgICAgdGhyb3cgZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgY29uc3QgaW5pdGlhbGl6ZU9ydEVwID0gYXN5bmMgKGVwTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU01fUFJPWFkgJiYgaXNQcm94eSgpKSB7XG4gICAgZW5zdXJlV29ya2VyKCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGVucXVldWVDYWxsYmFja3MoJ2luaXQtZXAnLCBbcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICBjb25zdCBtZXNzYWdlOiBPcnRXYXNtTWVzc2FnZSA9IHsgdHlwZTogJ2luaXQtZXAnLCBpbjogeyBlcE5hbWUsIGVudiB9IH07XG4gICAgICBwcm94eVdvcmtlciEucG9zdE1lc3NhZ2UobWVzc2FnZSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgY29yZS5pbml0RXAoZW52LCBlcE5hbWUpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY29weUZyb21FeHRlcm5hbEJ1ZmZlciA9IGFzeW5jIChidWZmZXI6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPFNlcmlhbGl6YWJsZUludGVybmFsQnVmZmVyPiA9PiB7XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU01fUFJPWFkgJiYgaXNQcm94eSgpKSB7XG4gICAgZW5zdXJlV29ya2VyKCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFNlcmlhbGl6YWJsZUludGVybmFsQnVmZmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBlbnF1ZXVlQ2FsbGJhY2tzKCdjb3B5LWZyb20nLCBbcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICBjb25zdCBtZXNzYWdlOiBPcnRXYXNtTWVzc2FnZSA9IHsgdHlwZTogJ2NvcHktZnJvbScsIGluOiB7IGJ1ZmZlciB9IH07XG4gICAgICBwcm94eVdvcmtlciEucG9zdE1lc3NhZ2UobWVzc2FnZSwgW2J1ZmZlci5idWZmZXJdKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gY29yZS5jb3B5RnJvbUV4dGVybmFsQnVmZmVyKGJ1ZmZlcik7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVTZXNzaW9uID0gYXN5bmMgKFxuICBtb2RlbDogU2VyaWFsaXphYmxlSW50ZXJuYWxCdWZmZXIgfCBVaW50OEFycmF5LFxuICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyxcbik6IFByb21pc2U8U2VyaWFsaXphYmxlU2Vzc2lvbk1ldGFkYXRhPiA9PiB7XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU01fUFJPWFkgJiYgaXNQcm94eSgpKSB7XG4gICAgLy8gY2hlY2sgdW5zdXBwb3J0ZWQgb3B0aW9uc1xuICAgIGlmIChvcHRpb25zPy5wcmVmZXJyZWRPdXRwdXRMb2NhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzZXNzaW9uIG9wdGlvbiBcInByZWZlcnJlZE91dHB1dExvY2F0aW9uXCIgaXMgbm90IHN1cHBvcnRlZCBmb3IgcHJveHkuJyk7XG4gICAgfVxuICAgIGVuc3VyZVdvcmtlcigpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxTZXJpYWxpemFibGVTZXNzaW9uTWV0YWRhdGE+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGVucXVldWVDYWxsYmFja3MoJ2NyZWF0ZScsIFtyZXNvbHZlLCByZWplY3RdKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2U6IE9ydFdhc21NZXNzYWdlID0geyB0eXBlOiAnY3JlYXRlJywgaW46IHsgbW9kZWwsIG9wdGlvbnM6IHsgLi4ub3B0aW9ucyB9IH0gfTtcbiAgICAgIGNvbnN0IHRyYW5zZmVyYWJsZTogVHJhbnNmZXJhYmxlW10gPSBbXTtcbiAgICAgIGlmIChtb2RlbCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgdHJhbnNmZXJhYmxlLnB1c2gobW9kZWwuYnVmZmVyKTtcbiAgICAgIH1cbiAgICAgIHByb3h5V29ya2VyIS5wb3N0TWVzc2FnZShtZXNzYWdlLCB0cmFuc2ZlcmFibGUpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBjb3JlLmNyZWF0ZVNlc3Npb24obW9kZWwsIG9wdGlvbnMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVsZWFzZVNlc3Npb24gPSBhc3luYyAoc2Vzc2lvbklkOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTV9QUk9YWSAmJiBpc1Byb3h5KCkpIHtcbiAgICBlbnN1cmVXb3JrZXIoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZW5xdWV1ZUNhbGxiYWNrcygncmVsZWFzZScsIFtyZXNvbHZlLCByZWplY3RdKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2U6IE9ydFdhc21NZXNzYWdlID0geyB0eXBlOiAncmVsZWFzZScsIGluOiBzZXNzaW9uSWQgfTtcbiAgICAgIHByb3h5V29ya2VyIS5wb3N0TWVzc2FnZShtZXNzYWdlKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjb3JlLnJlbGVhc2VTZXNzaW9uKHNlc3Npb25JZCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBydW4gPSBhc3luYyAoXG4gIHNlc3Npb25JZDogbnVtYmVyLFxuICBpbnB1dEluZGljZXM6IG51bWJlcltdLFxuICBpbnB1dHM6IFRlbnNvck1ldGFkYXRhW10sXG4gIG91dHB1dEluZGljZXM6IG51bWJlcltdLFxuICBvdXRwdXRzOiBBcnJheTxUZW5zb3JNZXRhZGF0YSB8IG51bGw+LFxuICBvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMsXG4pOiBQcm9taXNlPFRlbnNvck1ldGFkYXRhW10+ID0+IHtcbiAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTV9QUk9YWSAmJiBpc1Byb3h5KCkpIHtcbiAgICAvLyBjaGVjayBpbnB1dHMgbG9jYXRpb25cbiAgICBpZiAoaW5wdXRzLnNvbWUoKHQpID0+IHRbM10gIT09ICdjcHUnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCB0ZW5zb3Igb24gR1BVIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHByb3h5LicpO1xuICAgIH1cbiAgICAvLyBjaGVjayBvdXRwdXRzIGxvY2F0aW9uXG4gICAgaWYgKG91dHB1dHMuc29tZSgodCkgPT4gdCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncHJlLWFsbG9jYXRlZCBvdXRwdXQgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHByb3h5LicpO1xuICAgIH1cbiAgICBlbnN1cmVXb3JrZXIoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8U2VyaWFsaXphYmxlVGVuc29yTWV0YWRhdGFbXT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZW5xdWV1ZUNhbGxiYWNrcygncnVuJywgW3Jlc29sdmUsIHJlamVjdF0pO1xuICAgICAgY29uc3Qgc2VyaWFsaXphYmxlSW5wdXRzID0gaW5wdXRzIGFzIFNlcmlhbGl6YWJsZVRlbnNvck1ldGFkYXRhW107IC8vIGV2ZXJ5IGlucHV0IGlzIG9uIENQVS5cbiAgICAgIGNvbnN0IG1lc3NhZ2U6IE9ydFdhc21NZXNzYWdlID0ge1xuICAgICAgICB0eXBlOiAncnVuJyxcbiAgICAgICAgaW46IHsgc2Vzc2lvbklkLCBpbnB1dEluZGljZXMsIGlucHV0czogc2VyaWFsaXphYmxlSW5wdXRzLCBvdXRwdXRJbmRpY2VzLCBvcHRpb25zIH0sXG4gICAgICB9O1xuICAgICAgcHJveHlXb3JrZXIhLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIGNvcmUuZXh0cmFjdFRyYW5zZmVyYWJsZUJ1ZmZlcnMoc2VyaWFsaXphYmxlSW5wdXRzKSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNvcmUucnVuKHNlc3Npb25JZCwgaW5wdXRJbmRpY2VzLCBpbnB1dHMsIG91dHB1dEluZGljZXMsIG91dHB1dHMsIG9wdGlvbnMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZW5kUHJvZmlsaW5nID0gYXN5bmMgKHNlc3Npb25JZDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU01fUFJPWFkgJiYgaXNQcm94eSgpKSB7XG4gICAgZW5zdXJlV29ya2VyKCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGVucXVldWVDYWxsYmFja3MoJ2VuZC1wcm9maWxpbmcnLCBbcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICBjb25zdCBtZXNzYWdlOiBPcnRXYXNtTWVzc2FnZSA9IHsgdHlwZTogJ2VuZC1wcm9maWxpbmcnLCBpbjogc2Vzc2lvbklkIH07XG4gICAgICBwcm94eVdvcmtlciEucG9zdE1lc3NhZ2UobWVzc2FnZSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29yZS5lbmRQcm9maWxpbmcoc2Vzc2lvbklkKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtcbiAgSW5mZXJlbmNlU2Vzc2lvbixcbiAgSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIsXG4gIFNlc3Npb25IYW5kbGVyLFxuICBUZW5zb3IsXG4gIFRSQUNFX0ZVTkNfQkVHSU4sXG4gIFRSQUNFX0ZVTkNfRU5ELFxufSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQgeyBTZXJpYWxpemFibGVJbnRlcm5hbEJ1ZmZlciwgVGVuc29yTWV0YWRhdGEgfSBmcm9tICcuL3Byb3h5LW1lc3NhZ2VzJztcbmltcG9ydCB7IGNvcHlGcm9tRXh0ZXJuYWxCdWZmZXIsIGNyZWF0ZVNlc3Npb24sIGVuZFByb2ZpbGluZywgcmVsZWFzZVNlc3Npb24sIHJ1biB9IGZyb20gJy4vcHJveHktd3JhcHBlcic7XG5pbXBvcnQgeyBpc0dwdUJ1ZmZlclN1cHBvcnRlZFR5cGUsIGlzTUxUZW5zb3JTdXBwb3J0ZWRUeXBlIH0gZnJvbSAnLi93YXNtLWNvbW1vbic7XG5pbXBvcnQgeyBpc05vZGUgfSBmcm9tICcuL3dhc20tdXRpbHMtZW52JztcbmltcG9ydCB7IGxvYWRGaWxlIH0gZnJvbSAnLi93YXNtLXV0aWxzLWxvYWQtZmlsZSc7XG5cbmV4cG9ydCBjb25zdCBlbmNvZGVUZW5zb3JNZXRhZGF0YSA9ICh0ZW5zb3I6IFRlbnNvciwgZ2V0TmFtZTogKCkgPT4gc3RyaW5nKTogVGVuc29yTWV0YWRhdGEgPT4ge1xuICBzd2l0Y2ggKHRlbnNvci5sb2NhdGlvbikge1xuICAgIGNhc2UgJ2NwdSc6XG4gICAgICByZXR1cm4gW3RlbnNvci50eXBlLCB0ZW5zb3IuZGltcywgdGVuc29yLmRhdGEsICdjcHUnXTtcbiAgICBjYXNlICdncHUtYnVmZmVyJzpcbiAgICAgIHJldHVybiBbdGVuc29yLnR5cGUsIHRlbnNvci5kaW1zLCB7IGdwdUJ1ZmZlcjogdGVuc29yLmdwdUJ1ZmZlciB9LCAnZ3B1LWJ1ZmZlciddO1xuICAgIGNhc2UgJ21sLXRlbnNvcic6XG4gICAgICByZXR1cm4gW3RlbnNvci50eXBlLCB0ZW5zb3IuZGltcywgeyBtbFRlbnNvcjogdGVuc29yLm1sVGVuc29yIH0sICdtbC10ZW5zb3InXTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGRhdGEgbG9jYXRpb246ICR7dGVuc29yLmxvY2F0aW9ufSBmb3IgJHtnZXROYW1lKCl9YCk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBkZWNvZGVUZW5zb3JNZXRhZGF0YSA9ICh0ZW5zb3I6IFRlbnNvck1ldGFkYXRhKTogVGVuc29yID0+IHtcbiAgc3dpdGNoICh0ZW5zb3JbM10pIHtcbiAgICBjYXNlICdjcHUnOlxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3IodGVuc29yWzBdLCB0ZW5zb3JbMl0sIHRlbnNvclsxXSk7XG4gICAgY2FzZSAnZ3B1LWJ1ZmZlcic6IHtcbiAgICAgIGNvbnN0IGRhdGFUeXBlID0gdGVuc29yWzBdO1xuICAgICAgaWYgKCFpc0dwdUJ1ZmZlclN1cHBvcnRlZFR5cGUoZGF0YVR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbm90IHN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7ZGF0YVR5cGV9IGZvciBkZXNlcmlhbGl6aW5nIEdQVSB0ZW5zb3JgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgZ3B1QnVmZmVyLCBkb3dubG9hZCwgZGlzcG9zZSB9ID0gdGVuc29yWzJdO1xuICAgICAgcmV0dXJuIFRlbnNvci5mcm9tR3B1QnVmZmVyKGdwdUJ1ZmZlciwgeyBkYXRhVHlwZSwgZGltczogdGVuc29yWzFdLCBkb3dubG9hZCwgZGlzcG9zZSB9KTtcbiAgICB9XG4gICAgY2FzZSAnbWwtdGVuc29yJzoge1xuICAgICAgY29uc3QgZGF0YVR5cGUgPSB0ZW5zb3JbMF07XG4gICAgICBpZiAoIWlzTUxUZW5zb3JTdXBwb3J0ZWRUeXBlKGRhdGFUeXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG5vdCBzdXBwb3J0ZWQgZGF0YSB0eXBlOiAke2RhdGFUeXBlfSBmb3IgZGVzZXJpYWxpemluZyBNTFRlbnNvciB0ZW5zb3JgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgbWxUZW5zb3IsIGRvd25sb2FkLCBkaXNwb3NlIH0gPSB0ZW5zb3JbMl07XG4gICAgICByZXR1cm4gVGVuc29yLmZyb21NTFRlbnNvcihtbFRlbnNvciwgeyBkYXRhVHlwZSwgZGltczogdGVuc29yWzFdLCBkb3dubG9hZCwgZGlzcG9zZSB9KTtcbiAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBkYXRhIGxvY2F0aW9uOiAke3RlbnNvclszXX1gKTtcbiAgfVxufTtcblxuZXhwb3J0IGNsYXNzIE9ubnhydW50aW1lV2ViQXNzZW1ibHlTZXNzaW9uSGFuZGxlciBpbXBsZW1lbnRzIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyIHtcbiAgcHJpdmF0ZSBzZXNzaW9uSWQ6IG51bWJlcjtcblxuICBpbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgb3V0cHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBpbnB1dE1ldGFkYXRhOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLlZhbHVlTWV0YWRhdGFbXTtcbiAgb3V0cHV0TWV0YWRhdGE6IHJlYWRvbmx5IEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YVtdO1xuXG4gIGFzeW5jIGZldGNoTW9kZWxBbmRDb3B5VG9XYXNtTWVtb3J5KHBhdGg6IHN0cmluZyk6IFByb21pc2U8U2VyaWFsaXphYmxlSW50ZXJuYWxCdWZmZXI+IHtcbiAgICAvLyBmZXRjaCBtb2RlbCBmcm9tIHVybCBhbmQgbW92ZSB0byB3YXNtIGhlYXAuXG4gICAgcmV0dXJuIGNvcHlGcm9tRXh0ZXJuYWxCdWZmZXIoYXdhaXQgbG9hZEZpbGUocGF0aCkpO1xuICB9XG5cbiAgYXN5bmMgbG9hZE1vZGVsKHBhdGhPckJ1ZmZlcjogc3RyaW5nIHwgVWludDhBcnJheSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBUUkFDRV9GVU5DX0JFR0lOKCk7XG4gICAgbGV0IG1vZGVsOiBQYXJhbWV0ZXJzPHR5cGVvZiBjcmVhdGVTZXNzaW9uPlswXTtcblxuICAgIGlmICh0eXBlb2YgcGF0aE9yQnVmZmVyID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKGlzTm9kZSkge1xuICAgICAgICAvLyBub2RlXG4gICAgICAgIG1vZGVsID0gYXdhaXQgbG9hZEZpbGUocGF0aE9yQnVmZmVyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGJyb3dzZXJcbiAgICAgICAgLy8gZmV0Y2ggbW9kZWwgYW5kIGNvcHkgdG8gd2FzbSBoZWFwLlxuICAgICAgICBtb2RlbCA9IGF3YWl0IHRoaXMuZmV0Y2hNb2RlbEFuZENvcHlUb1dhc21NZW1vcnkocGF0aE9yQnVmZmVyKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbW9kZWwgPSBwYXRoT3JCdWZmZXI7XG4gICAgfVxuXG4gICAgW3RoaXMuc2Vzc2lvbklkLCB0aGlzLmlucHV0TmFtZXMsIHRoaXMub3V0cHV0TmFtZXMsIHRoaXMuaW5wdXRNZXRhZGF0YSwgdGhpcy5vdXRwdXRNZXRhZGF0YV0gPSBhd2FpdCBjcmVhdGVTZXNzaW9uKFxuICAgICAgbW9kZWwsXG4gICAgICBvcHRpb25zLFxuICAgICk7XG4gICAgVFJBQ0VfRlVOQ19FTkQoKTtcbiAgfVxuXG4gIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHJlbGVhc2VTZXNzaW9uKHRoaXMuc2Vzc2lvbklkKTtcbiAgfVxuXG4gIGFzeW5jIHJ1bihcbiAgICBmZWVkczogU2Vzc2lvbkhhbmRsZXIuRmVlZHNUeXBlLFxuICAgIGZldGNoZXM6IFNlc3Npb25IYW5kbGVyLkZldGNoZXNUeXBlLFxuICAgIG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPiB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTigpO1xuICAgIGNvbnN0IGlucHV0QXJyYXk6IFRlbnNvcltdID0gW107XG4gICAgY29uc3QgaW5wdXRJbmRpY2VzOiBudW1iZXJbXSA9IFtdO1xuICAgIE9iamVjdC5lbnRyaWVzKGZlZWRzKS5mb3JFYWNoKChrdnApID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSBrdnBbMF07XG4gICAgICBjb25zdCB0ZW5zb3IgPSBrdnBbMV07XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuaW5wdXROYW1lcy5pbmRleE9mKG5hbWUpO1xuICAgICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgaW5wdXQgJyR7bmFtZX0nYCk7XG4gICAgICB9XG4gICAgICBpbnB1dEFycmF5LnB1c2godGVuc29yKTtcbiAgICAgIGlucHV0SW5kaWNlcy5wdXNoKGluZGV4KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG91dHB1dEFycmF5OiBBcnJheTxUZW5zb3IgfCBudWxsPiA9IFtdO1xuICAgIGNvbnN0IG91dHB1dEluZGljZXM6IG51bWJlcltdID0gW107XG4gICAgT2JqZWN0LmVudHJpZXMoZmV0Y2hlcykuZm9yRWFjaCgoa3ZwKSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0ga3ZwWzBdO1xuICAgICAgY29uc3QgdGVuc29yID0ga3ZwWzFdO1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLm91dHB1dE5hbWVzLmluZGV4T2YobmFtZSk7XG4gICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBvdXRwdXQgJyR7bmFtZX0nYCk7XG4gICAgICB9XG4gICAgICBvdXRwdXRBcnJheS5wdXNoKHRlbnNvcik7XG4gICAgICBvdXRwdXRJbmRpY2VzLnB1c2goaW5kZXgpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgaW5wdXRzID0gaW5wdXRBcnJheS5tYXAoKHQsIGkpID0+XG4gICAgICBlbmNvZGVUZW5zb3JNZXRhZGF0YSh0LCAoKSA9PiBgaW5wdXQgXCIke3RoaXMuaW5wdXROYW1lc1tpbnB1dEluZGljZXNbaV1dfVwiYCksXG4gICAgKTtcbiAgICBjb25zdCBvdXRwdXRzID0gb3V0cHV0QXJyYXkubWFwKCh0LCBpKSA9PlxuICAgICAgdCA/IGVuY29kZVRlbnNvck1ldGFkYXRhKHQsICgpID0+IGBvdXRwdXQgXCIke3RoaXMub3V0cHV0TmFtZXNbb3V0cHV0SW5kaWNlc1tpXV19XCJgKSA6IG51bGwsXG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBydW4odGhpcy5zZXNzaW9uSWQsIGlucHV0SW5kaWNlcywgaW5wdXRzLCBvdXRwdXRJbmRpY2VzLCBvdXRwdXRzLCBvcHRpb25zKTtcblxuICAgIGNvbnN0IHJlc3VsdE1hcDogU2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZSA9IHt9O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVzdWx0cy5sZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0TWFwW3RoaXMub3V0cHV0TmFtZXNbb3V0cHV0SW5kaWNlc1tpXV1dID0gb3V0cHV0QXJyYXlbaV0gPz8gZGVjb2RlVGVuc29yTWV0YWRhdGEocmVzdWx0c1tpXSk7XG4gICAgfVxuICAgIFRSQUNFX0ZVTkNfRU5EKCk7XG4gICAgcmV0dXJuIHJlc3VsdE1hcDtcbiAgfVxuXG4gIHN0YXJ0UHJvZmlsaW5nKCk6IHZvaWQge1xuICAgIC8vIFRPRE86IGltcGxlbWVudCBwcm9maWxpbmdcbiAgfVxuXG4gIGVuZFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB2b2lkIGVuZFByb2ZpbGluZyh0aGlzLnNlc3Npb25JZCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHsgQmFja2VuZCwgZW52LCBJbmZlcmVuY2VTZXNzaW9uLCBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciB9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7IGluaXRpYWxpemVPcnRFcCwgaW5pdGlhbGl6ZVdlYkFzc2VtYmx5QW5kT3J0UnVudGltZSB9IGZyb20gJy4vd2FzbS9wcm94eS13cmFwcGVyJztcbmltcG9ydCB7IE9ubnhydW50aW1lV2ViQXNzZW1ibHlTZXNzaW9uSGFuZGxlciB9IGZyb20gJy4vd2FzbS9zZXNzaW9uLWhhbmRsZXItaW5mZXJlbmNlJztcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGluaXRpYWxpemVzIGFsbCBmbGFncyBmb3IgV2ViQXNzZW1ibHkuXG4gKlxuICogVGhvc2UgZmxhZ3MgYXJlIGFjY2Vzc2libGUgZnJvbSBgb3J0LmVudi53YXNtYC4gVXNlcnMgYXJlIGFsbG93IHRvIHNldCB0aG9zZSBmbGFncyBiZWZvcmUgdGhlIGZpcnN0IGluZmVyZW5jZSBzZXNzaW9uXG4gKiBiZWluZyBjcmVhdGVkLCB0byBvdmVycmlkZSBkZWZhdWx0IHZhbHVlLlxuICovXG5leHBvcnQgY29uc3QgaW5pdGlhbGl6ZUZsYWdzID0gKCk6IHZvaWQgPT4ge1xuICBpZiAodHlwZW9mIGVudi53YXNtLmluaXRUaW1lb3V0ICE9PSAnbnVtYmVyJyB8fCBlbnYud2FzbS5pbml0VGltZW91dCA8IDApIHtcbiAgICBlbnYud2FzbS5pbml0VGltZW91dCA9IDA7XG4gIH1cblxuICBjb25zdCBzaW1kID0gZW52Lndhc20uc2ltZDtcbiAgaWYgKHR5cGVvZiBzaW1kICE9PSAnYm9vbGVhbicgJiYgc2ltZCAhPT0gdW5kZWZpbmVkICYmIHNpbWQgIT09ICdmaXhlZCcgJiYgc2ltZCAhPT0gJ3JlbGF4ZWQnKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgUHJvcGVydHkgXCJlbnYud2FzbS5zaW1kXCIgaXMgc2V0IHRvIHVua25vd24gdmFsdWUgXCIke3NpbWR9XCIuIFJlc2V0IGl0IHRvIFxcYGZhbHNlXFxgIGFuZCBpZ25vcmUgU0lNRCBmZWF0dXJlIGNoZWNraW5nLmAsXG4gICAgKTtcbiAgICBlbnYud2FzbS5zaW1kID0gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIGVudi53YXNtLnByb3h5ICE9PSAnYm9vbGVhbicpIHtcbiAgICBlbnYud2FzbS5wcm94eSA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBlbnYud2FzbS50cmFjZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgZW52Lndhc20udHJhY2UgPSBmYWxzZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZW52Lndhc20ubnVtVGhyZWFkcyAhPT0gJ251bWJlcicgfHwgIU51bWJlci5pc0ludGVnZXIoZW52Lndhc20ubnVtVGhyZWFkcykgfHwgZW52Lndhc20ubnVtVGhyZWFkcyA8PSAwKSB7XG4gICAgLy8gVGhlIGZvbGxvd2luZyBsb2dpYyBvbmx5IGFwcGxpZXMgd2hlbiBgb3J0LmVudi53YXNtLm51bVRocmVhZHNgIGlzIG5vdCBzZXQgYnkgdXNlci4gV2Ugd2lsbCBhbHdheXMgaG9ub3IgdXNlcidzXG4gICAgLy8gc2V0dGluZyBpZiBpdCBpcyBwcm92aWRlZC5cblxuICAgIC8vIEJyb3dzZXI6IHdoZW4gY3Jvc3NPcmlnaW5Jc29sYXRlZCBpcyBmYWxzZSwgU2hhcmVkQXJyYXlCdWZmZXIgaXMgbm90IGF2YWlsYWJsZSBzbyBXZWJBc3NlbWJseSB0aHJlYWRzIHdpbGwgbm90XG4gICAgLy8gd29yay4gSW4gdGhpcyBjYXNlLCB3ZSB3aWxsIHNldCBudW1UaHJlYWRzIHRvIDEuXG4gICAgLy9cbiAgICAvLyBUaGVyZSBpcyBhbiBleGNlcHRpb246IHdoZW4gdGhlIGJyb3dzZXIgaXMgY29uZmlndXJlZCB0byBmb3JjZS1lbmFibGUgU2hhcmVkQXJyYXlCdWZmZXIgKGUuZy4gQ2hyb211aW0gd2l0aFxuICAgIC8vIC0tZW5hYmxlLWZlYXR1cmVzPVNoYXJlZEFycmF5QnVmZmVyKSwgaXQgaXMgcG9zc2libGUgdGhhdCBgc2VsZi5jcm9zc09yaWdpbklzb2xhdGVkYCBpcyBmYWxzZSBhbmRcbiAgICAvLyBTaGFyZWRBcnJheUJ1ZmZlciBpcyBhdmFpbGFibGUgYXQgdGhlIHNhbWUgdGltZS4gVGhpcyBpcyB1c3VhbGx5IGZvciB0ZXN0aW5nLiBJbiB0aGlzIGNhc2UsICB3ZSB3aWxsIHN0aWxsIHNldFxuICAgIC8vIG51bVRocmVhZHMgdG8gMSBoZXJlLiBJZiB3ZSB3YW50IHRvIGVuYWJsZSBtdWx0aS10aHJlYWRpbmcgaW4gdGVzdCwgd2Ugc2hvdWxkIHNldCBgb3J0LmVudi53YXNtLm51bVRocmVhZHNgIHRvIGFcbiAgICAvLyB2YWx1ZSBncmVhdGVyIHRoYW4gMS5cbiAgICBpZiAodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnICYmICFzZWxmLmNyb3NzT3JpZ2luSXNvbGF0ZWQpIHtcbiAgICAgIGVudi53YXNtLm51bVRocmVhZHMgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBudW1DcHVMb2dpY2FsQ29yZXMgPVxuICAgICAgICB0eXBlb2YgbmF2aWdhdG9yID09PSAndW5kZWZpbmVkJyA/IHJlcXVpcmUoJ25vZGU6b3MnKS5jcHVzKCkubGVuZ3RoIDogbmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3k7XG4gICAgICBlbnYud2FzbS5udW1UaHJlYWRzID0gTWF0aC5taW4oNCwgTWF0aC5jZWlsKChudW1DcHVMb2dpY2FsQ29yZXMgfHwgMSkgLyAyKSk7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgY2xhc3MgT25ueHJ1bnRpbWVXZWJBc3NlbWJseUJhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHtcbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gaW5pdGlhbGl6ZXMgdGhlIFdlYkFzc2VtYmx5IGJhY2tlbmQuXG4gICAqXG4gICAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlIGZvciBlYWNoIGJhY2tlbmQgbmFtZS4gSXQgd2lsbCBiZSBjYWxsZWQgdGhlIGZpcnN0IHRpbWUgd2hlblxuICAgKiBgb3J0LkluZmVyZW5jZVNlc3Npb24uY3JlYXRlKClgIGlzIGNhbGxlZCB3aXRoIGEgcmVnaXN0ZXJlZCBiYWNrZW5kIG5hbWUuXG4gICAqXG4gICAqIEBwYXJhbSBiYWNrZW5kTmFtZSAtIHRoZSByZWdpc3RlcmVkIGJhY2tlbmQgbmFtZS5cbiAgICovXG4gIGFzeW5jIGluaXQoYmFja2VuZE5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIHBvcHVsYXRlIHdhc20gZmxhZ3NcbiAgICBpbml0aWFsaXplRmxhZ3MoKTtcblxuICAgIC8vIGluaXQgd2FzbVxuICAgIGF3YWl0IGluaXRpYWxpemVXZWJBc3NlbWJseUFuZE9ydFJ1bnRpbWUoKTtcblxuICAgIC8vIHBlcmZvcm1lIEVQIHNwZWNpZmljIGluaXRpYWxpemF0aW9uXG4gICAgYXdhaXQgaW5pdGlhbGl6ZU9ydEVwKGJhY2tlbmROYW1lKTtcbiAgfVxuICBjcmVhdGVJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcihcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXI+O1xuICBjcmVhdGVJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcihcbiAgICBidWZmZXI6IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXI+O1xuICBhc3luYyBjcmVhdGVJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcihcbiAgICBwYXRoT3JCdWZmZXI6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMsXG4gICk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXI+IHtcbiAgICBjb25zdCBoYW5kbGVyID0gbmV3IE9ubnhydW50aW1lV2ViQXNzZW1ibHlTZXNzaW9uSGFuZGxlcigpO1xuICAgIGF3YWl0IGhhbmRsZXIubG9hZE1vZGVsKHBhdGhPckJ1ZmZlciwgb3B0aW9ucyk7XG4gICAgcmV0dXJuIGhhbmRsZXI7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHdhc21CYWNrZW5kID0gbmV3IE9ubnhydW50aW1lV2ViQXNzZW1ibHlCYWNrZW5kKCk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMgKi9cblxuLy8gV2UgdXNlIFwicmVxdWlyZVwiIGluc3RlYWQgb2YgXCJpbXBvcnRcIiBoZXJlIGJlY2F1c2UgaW1wb3J0IHN0YXRlbWVudCBtdXN0IGJlIHB1dCBpbiB0b3AgbGV2ZWwuIE91ciBjdXJyZW50IGNvZGUgZG9lc1xuLy8gbm90IGFsbG93IGJ1bmRsZXIgdG8gdHJlZS1zaGFraW5nIGNvZGUgYXMgZXhwZWN0ZWQgYmVjYXVzZSBzb21lIGNvZGVzIGFyZSB0cmVhdGVkIGFzIGhhdmluZyBzaWRlIGVmZmVjdHMuXG4vLyBTbyB3ZSBpbXBvcnQgY29kZSBpbnNpZGUgdGhlIGlmLWNsYXVzZSB0byBhbGxvdyBidW5kbGVyIHJlbW92ZSB0aGUgY29kZSBzYWZlbHkuXG5cbmV4cG9ydCAqIGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5pbXBvcnQgKiBhcyBvcnQgZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcbmV4cG9ydCBkZWZhdWx0IG9ydDtcblxuaW1wb3J0IHsgcmVnaXN0ZXJCYWNrZW5kLCBlbnYgfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4vdmVyc2lvbic7XG5cbmlmICghQlVJTERfREVGUy5ESVNBQkxFX1dFQkdMKSB7XG4gIGNvbnN0IG9ubnhqc0JhY2tlbmQgPSByZXF1aXJlKCcuL2JhY2tlbmQtb25ueGpzJykub25ueGpzQmFja2VuZDtcbiAgcmVnaXN0ZXJCYWNrZW5kKCd3ZWJnbCcsIG9ubnhqc0JhY2tlbmQsIC0xMCk7XG59XG5cbmlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU00pIHtcbiAgY29uc3Qgd2FzbUJhY2tlbmQgPSByZXF1aXJlKCcuL2JhY2tlbmQtd2FzbScpLndhc21CYWNrZW5kO1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9KU0VQKSB7XG4gICAgcmVnaXN0ZXJCYWNrZW5kKCd3ZWJncHUnLCB3YXNtQmFja2VuZCwgNSk7XG4gICAgcmVnaXN0ZXJCYWNrZW5kKCd3ZWJubicsIHdhc21CYWNrZW5kLCA1KTtcbiAgfVxuICByZWdpc3RlckJhY2tlbmQoJ2NwdScsIHdhc21CYWNrZW5kLCAxMCk7XG4gIHJlZ2lzdGVyQmFja2VuZCgnd2FzbScsIHdhc21CYWNrZW5kLCAxMCk7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbnYudmVyc2lvbnMsICd3ZWInLCB7IHZhbHVlOiB2ZXJzaW9uLCBlbnVtZXJhYmxlOiB0cnVlIH0pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGJ5IC9qcy9zY3JpcHRzL3VwZGF0ZS12ZXJzaW9uLnRzXG4vLyBEbyBub3QgbW9kaWZ5IGZpbGUgY29udGVudCBtYW51YWxseS5cblxuZXhwb3J0IGNvbnN0IHZlcnNpb24gPSAnMS4yMy4wJztcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE1BZ0JNLFVBQ0EsMEJBWU8saUJBd0NQLGdDQXdDTztBQTdHYjs7QUFnQkEsTUFBTSxXQUFxQyxvQkFBSSxJQUFHO0FBQ2xELE1BQU0sMkJBQXFDLENBQUE7QUFZcEMsTUFBTSxrQkFBa0IsQ0FBQ0EsT0FBY0MsVUFBa0IsYUFBMEI7QUFDeEYsWUFBSUEsWUFBVyxPQUFPQSxTQUFRLFNBQVMsY0FBYyxPQUFPQSxTQUFRLGtDQUFrQyxZQUFZO0FBQ2hILGdCQUFNLGlCQUFpQixTQUFTLElBQUlELEtBQUk7QUFDeEMsY0FBSSxtQkFBbUIsUUFBVztBQUNoQyxxQkFBUyxJQUFJQSxPQUFNLEVBQUUsU0FBQUMsVUFBUyxTQUFRLENBQUU7cUJBQy9CLGVBQWUsV0FBVyxVQUFVO0FBRTdDO3FCQUNTLGVBQWUsYUFBYSxVQUFVO0FBQy9DLGdCQUFJLGVBQWUsWUFBWUEsVUFBUztBQUN0QyxvQkFBTSxJQUFJLE1BQU0sNEJBQTRCRCxLQUFJLG9CQUFvQixRQUFRLEVBQUU7OztBQUlsRixjQUFJLFlBQVksR0FBRztBQUNqQixrQkFBTSxJQUFJLHlCQUF5QixRQUFRQSxLQUFJO0FBQy9DLGdCQUFJLE1BQU0sSUFBSTtBQUNaLHVDQUF5QixPQUFPLEdBQUcsQ0FBQzs7QUFHdEMs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O0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFJO0FBQUEsVUFBSztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBRztBQUFBLFVBQUs7QUFBQSxVQUFJO0FBQUEsVUFBSTtBQUFBLFVBQUs7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUk7QUFBQSxVQUFLO0FBQUEsVUFBSztBQUFBLFVBQUk7QUFBQSxVQUFHO0FBQUEsVUFBSTtBQUFBLFVBQUc7QUFBQSxVQUFLO0FBQUEsUUFDNW5DLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFO0FBQUEsTUFDWCxTQUFTLEdBQUc7QUFBQSxNQUVaO0FBd0RBLFdBQUssVUFBVTtBQUVmLGFBQU8sZUFBZSxLQUFLLFdBQVcsY0FBYyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBNkJuRSxXQUFL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Q0osY0FDQSxTQUNrQztBQUNsQyxnQkFBTSxVQUFVLElBQUkscUNBQXFDO0FBQ3pELGdCQUFNLFFBQVEsVUFBVSxjQUFjLE9BQU87QUFDN0MsaUJBQU87QUFBQSxRQUNUO0FBQUEsTUFDRjtBQUVPLE1BQU0sY0FBYyxJQUFJLDhCQUE4QjtBQUFBO0FBQUE7OztBQy9GN0Q7QUFBQTtBQUFBLDRCQUFBQztBQUFBLElBQUE7QUFBQTtBQUFBO0FBQUEsa0JBQUFDO0FBQUEsSUFBQTtBQUFBLGVBQUFDO0FBQUEsSUFBQTtBQUFBO0FBU0E7QUFDQTtBQUdBOzs7QUNQTyxNQUFNQyxXQUFVOzs7QURLdkIsTUFBTyxnQkFBUTtBQUtmLE1BQUksTUFBMkI7QUFDN0IsVUFBTUMsaUJBQWdCLDhEQUE0QjtBQUNsRCxvQkFBZ0IsU0FBU0EsZ0JBQWUsR0FBRztBQUFBLEVBQzdDO0FBRUEsTUFBSSxNQUEwQjtBQUM1QixVQUFNQyxlQUFjLDBEQUEwQjtBQUM5QyxRQUFJLE1BQTBCO0FBQzVCLHNCQUFnQixVQUFVQSxjQUFhLENBQUM7QUFDeEMsc0JBQWdCLFNBQVNBLGNBQWEsQ0FBQztBQUFBLElBQ3pDO0FBQ0Esb0JBQWdCLE9BQU9BLGNBQWEsRUFBRTtBQUN0QyxvQkFBZ0IsUUFBUUEsY0FBYSxFQUFFO0FBQUEsRUFDekM7QUFFQSxTQUFPLGVBQWVDLEtBQUksVUFBVSxPQUFPLEVBQUUsT0FBT0MsVUFBUyxZQUFZLEtBQUssQ0FBQzsiLAogICJuYW1lcyI6IFsibmFtZSIsICJiYWNrZW5kIiwgImkiLCAiZW52IiwgImNyZWF0ZUNhbnZhcyIsICJGbG9hdDE2QXJyYXkiLCAiVGVuc29yIiwgIlRlbnNvciIsICJuYW1lIiwgImJhY2tlbmQiLCAiSW5mZXJlbmNlU2Vzc2lvbiIsICJJbmZlcmVuY2VTZXNzaW9uIiwgIlRlbnNvciIsICJlbnYiLCAibG9nIiwgImVudiIsICJuYW1lIiwgInZlcnNpb24iLCAiZXhwb3J0cyIsICJHdWlkIiwgImd1aWQiLCAiY2FjaGUiLCAiZGl2IiwgImxvZzIiLCAiQXJnVHlwZSIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIkVuY29kaW5nIiwgImV4cG9ydHMiLCAiQnl0ZUJ1ZmZlciIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiQXJnVHlwZUFuZEluZGV4IiwgImV4cG9ydHMiLCAiQXR0cmlidXRlVHlwZSIsICJleHBvcnRzIiwgIk5vZGVUeXBlIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiTm9kZSIsICJleHBvcnRzIiwgIkVkZ2VFbmQiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJOb2RlRWRnZSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIk5vZGVzVG9PcHRpbWl6ZUluZGljZXMiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJSdW50aW1lT3B0aW1pemF0aW9uUmVjb3JkIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiUnVudGltZU9wdGltaXphdGlvblJlY29yZENvbnRhaW5lckVudHJ5IiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiUnVudGltZU9wdGltaXphdGlvbnMiLCAiZXhwb3J0cyIsICJUZW5zb3JEYXRhVHlwZSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIlRlbnNvciIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIlNwYXJzZVRlbnNvciIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIk1hcFR5cGUiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJTZXF1ZW5jZVR5cGUiLCAiZXhwb3J0cyIsICJEaW1lbnNpb25WYWx1ZVR5cGUiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJEaW1lbnNpb25WYWx1ZSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIkRpbWVuc2lvbiIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIlNoYXBlIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiVGVuc29yVHlwZUFuZFNoYXBlIiwgImV4cG9ydHMiLCAiVHlwZUluZm9WYWx1ZSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIlR5cGVJbmZvIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiVmFsdWVJbmZvIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiR3JhcGgiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJBdHRyaWJ1dGUiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJEZXByZWNhdGVkS2VybmVsQ3JlYXRlSW5mb3MiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJEZXByZWNhdGVkTm9kZUluZGV4QW5kS2VybmVsRGVmSGFzaCIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIkRlcHJlY2F0ZWRTdWJHcmFwaFNlc3Npb25TdGF0ZSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIkRlcHJlY2F0ZWRTZXNzaW9uU3RhdGUiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJLZXJuZWxUeXBlU3RyQXJnc0VudHJ5IiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiT3BJZEtlcm5lbFR5cGVTdHJBcmdzRW50cnkiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJLZXJuZWxUeXBlU3RyUmVzb2x2ZXIiLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJPcGVyYXRvclNldElkIiwgInZlcnNpb24iLCAiZXhwb3J0cyIsICJmbGF0YnVmZmVycyIsICJTdHJpbmdTdHJpbmdFbnRyeSIsICJleHBvcnRzIiwgImZsYXRidWZmZXJzIiwgIk1vZGVsIiwgImV4cG9ydHMiLCAiZmxhdGJ1ZmZlcnMiLCAiSW5mZXJlbmNlU2Vzc2lvbiIsICJleHBvcnRzIiwgImltcG9ydF90ZW5zb3IiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAicGFyYW1zIiwgIm9mZnNldCIsICJleHBvcnRzIiwgImkiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJzbGljZSIsICJzaXplIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImZyb21OdW1iZXIiLCAidG9OdW1iZXIiLCAiZXhwb3J0cyIsICJCdWZmZXIiLCAibmFtZSIsICJpIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImNyZWF0ZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJjcmVhdGVfYXJyYXkiLCAiY3JlYXRlIiwgImJ1ZmZlciIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJzZWxmIiwgImVyciIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAicmVxdWlyZV9taW5pbWFsIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgIm9ubngiLCAiRGltZW5zaW9uIiwgIlRlbnNvciIsICJNYXAiLCAiU3BhcnNlVGVuc29yIiwgImluaXRfdGVuc29yIiwgIlRlbnNvciIsICJzaGFwZSIsICJwYWQiLCAic3BsaXQiLCAiaW1wb3J0X29ubngiLCAiVGVuc29yIiwgImluaXRfdGVuc29yIiwgImNhY2hlIiwgInZlcnNpb24iLCAibmFtZSIsICJzaGFwZSIsICJzaGFwZSIsICJzaGFwZSIsICJpbml0X3RlbnNvciIsICJzaGFwZSIsICJUZW5zb3IiLCAibmFtZSIsICJuYW1lIiwgIm5hbWUiLCAiYWRkIiwgImFuZCIsICJvciIsICJ4b3IiLCAiZ2xzbCIsICJzaGFkZXJTb3VyY2UiLCAidmFsaWRhdGVJbnB1dHMiLCAic2hpZnQiLCAidmFsaWRhdGVJbnB1dHMiLCAibmFtZSIsICJsb2ciLCAibm90IiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgIm5hbWUiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAic2hhcGUiLCAidmFsaWRhdGVJbnB1dHMiLCAic3VtIiwgInZhbGlkYXRlSW5wdXRzIiwgIm5hbWUiLCAicmVkdWNlT3BzIiwgImlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJkaW0iLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF90ZW5zb3IiLCAiVGVuc29yIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInNwbGl0IiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzVjEzIiwgImFkZCIsICJhbmQiLCAibG9nIiwgIm5vdCIsICJvciIsICJ4b3IiLCAibmFtZSIsICJzaGFwZSIsICJzaGFwZSIsICJuYW1lIiwgInNvdXJjZSIsICJwYWNrZWRTYW1wbGVyIiwgInRleE51bVIiLCAidGV4TnVtQyIsICJ0cmFuc3Bvc2UiLCAibmFtZSIsICJzaGFwZSIsICJpIiwgIm5hbWUiLCAibmFtZSIsICJlbnYiLCAibmFtZSIsICJsb2NhdGlvbiIsICJ0ZXh0dXJlIiwgImJhY2tlbmQiLCAidmVyc2lvbiIsICJlbnYiLCAiZW52IiwgImNhY2hlIiwgImJhY2tlbmQiLCAiaW5pdCIsICJpbml0X2JhY2tlbmQiLCAib3V0cHV0IiwgImltcG9ydF9vbm54IiwgIkF0dHJpYnV0ZSIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAidmFsdWUiLCAiaW1wb3J0X29ubngiLCAiR3JhcGgiLCAiTm9kZSIsICJpbml0X3RlbnNvciIsICJuYW1lIiwgIkF0dHJpYnV0ZSIsICJUZW5zb3IiLCAic2hhcGUiLCAibm9kZUluZGV4IiwgImltcG9ydF9vbm54IiwgIk1vZGVsIiwgIkdyYXBoIiwgImluaXRfYmFja2VuZCIsICJiYWNrZW5kIiwgIk1vZGVsIiwgImluaXRfdGVuc29yIiwgIm5hbWUiLCAiVGVuc29yIiwgImVudiIsICJ3YXNtIiwgIm1vZHVsZSIsICJ3YXNtIiwgIm5hbWUiLCAid2FzbSIsICJ3YXNtIiwgIm5hbWUiLCAibG9jYXRpb24iLCAiTWF0TXVsVXRpbCIsICJCcm9hZGNhc3RVdGlsIiwgIlNoYXBlVXRpbCIsICJQb29sQ29udlV0aWwiLCAiR2VtbVV0aWwiLCAiTUlOX0NMSVAiLCAiTUFYX0NMSVAiLCAiaW5pdF91dGlsIiwgInNoYXBlIiwgInBhZCIsICJjcmVhdGVWaWV3IiwgInNoYXBlIiwgImJhY2tlbmQiLCAidGVuc29yIiwgImVudiIsICJtbENvbnRleHRJbmRleCIsICJzaGFwZSIsICJ3YXNtIiwgImNyZWF0ZVZpZXciLCAiaW5pdF90eXBlcyIsICJpbml0X3R5cGVzIiwgImJhY2tlbmQiLCAiQXR0cmlidXRlV2l0aENhY2hlS2V5SW1wbCIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAibmFtZSIsICJpbml0X3V0aWwiLCAiU2hhcGVVdGlsIiwgIm5hbWUiLCAic2hhcGUiLCAib2Zmc2V0VG9JbmRpY2VzIiwgImluaXQiLCAib2Zmc2V0cyIsICJpbmRpY2VzIiwgImltcGwiLCAidmFsaWRhdGVJbnB1dHMiLCAiZ2V0QWRqdXN0ZWRQZXJtIiwgImdldE91dHB1dFNoYXBlIiwgInNxdWVlemVTaGFwZSIsICJjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyIsICJ0cmFuc3Bvc2UiLCAicGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzIiwgImluaXRfdHJhbnNwb3NlIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJTaGFwZVV0aWwiLCAic2hhcGUiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgImluaXRfdXRpbCIsICJpbml0X3JlZHVjZSIsICJpbml0X3RyYW5zcG9zZSIsICJzaGFwZSIsICJuYW1lIiwgIlNoYXBlVXRpbCIsICJjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyIsICJ2YWxpZGF0ZUlucHV0cyIsICJjcmVhdGVSZWR1Y2VQcm9ncmFtSW5mbyIsICJyZWR1Y2VNZWFuIiwgInJlZHVjZU1heCIsICJyZWR1Y2VNaW4iLCAicmVkdWNlUHJvZCIsICJyZWR1Y2VTdW0iLCAicmVkdWNlTG9nU3VtIiwgImluaXRfcmVkdWNlIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJuYW1lIiwgIlNoYXBlVXRpbCIsICJyZWR1Y2VPcHMiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInNoYXBlIiwgInZhbGlkYXRlSW5wdXRzIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgImluaXRfcmVkdWNlIiwgImNyZWF0ZVJlZHVjZVByb2dyYW1JbmZvIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJpbml0X3V0aWwiLCAiaW5pdF90eXBlcyIsICJTaGFwZVV0aWwiLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgInNoYXBlIiwgIlNoYXBlVXRpbCIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAiZW52IiwgInZhbGlkYXRlSW5wdXRzIiwgImluaXRfdXRpbCIsICJTaGFwZVV0aWwiLCAiY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyIsICJhYnMiLCAiYWNvcyIsICJhc2luIiwgImF0YW4iLCAicGFyc2VDYXN0QXR0cmlidXRlcyIsICJjYXN0IiwgImdlbmVyYXRlQ2xpcEF0dHJpYnV0ZXNGcm9tSW5wdXRzIiwgImNsaXAiLCAiY2VpbCIsICJjb3MiLCAiZWx1IiwgImV4cCIsICJmbG9vciIsICJsZWFreVJlbHUiLCAibm90IiwgIm5lZyIsICJyZWx1IiwgInNpZ21vaWQiLCAic2luIiwgInNxcnQiLCAidGFuIiwgInRhbmgiLCAibG9nIiwgImluaXRfdW5hcnlfb3AiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIm5hbWUiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3V0aWwiLCAiaW5pdF91bmFyeV9vcCIsICJTaGFwZVV0aWwiLCAiYWRkIiwgImRpdiIsICJlcXVhbCIsICJtdWwiLCAicG93IiwgInN1YiIsICJncmVhdGVyIiwgImxlc3MiLCAiaW5pdF9iaW5hcnlfb3AiLCAiaW5pdF91dGlsIiwgImEiLCAiYiIsICJTaGFwZVV0aWwiLCAibmFtZSIsICJCcm9hZGNhc3RVdGlsIiwgInZhbGlkYXRlSW5wdXRzIiwgImNvbmNhdCIsICJwYXJzZUNvbmNhdEF0dHJpYnV0ZXMiLCAiaW5pdF9jb25jYXQiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgImkiLCAiU2hhcGVVdGlsIiwgInN1bSIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAiZ2V0QWN0aXZhdGlvblNuaXBwZXQiLCAicGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIiwgImluaXRfZnVzZV91dGlscyIsICJpbml0X3V0aWwiLCAiTUlOX0NMSVAiLCAiTUFYX0NMSVAiLCAiaW5pdF91dGlsIiwgImluaXRfZnVzZV91dGlscyIsICJpbnB1dFZhcmlhYmxlIiwgIlNoYXBlVXRpbCIsICJnZXRBY3RpdmF0aW9uU25pcHBldCIsICJjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyIsICJpbml0X3V0aWwiLCAiaW5pdF9mdXNlX3V0aWxzIiwgInRyYW5zcG9zZSIsICJvdXRwdXRWYXJpYWJsZSIsICJTaGFwZVV0aWwiLCAiZ2V0QWN0aXZhdGlvblNuaXBwZXQiLCAiaW5pdF9mdXNlX3V0aWxzIiwgImlubmVyRWxlbWVudFNpemUiLCAiZ2V0QWN0aXZhdGlvblNuaXBwZXQiLCAiaW5pdF91dGlsIiwgImluaXRfZnVzZV91dGlscyIsICJwYWQiLCAiU2hhcGVVdGlsIiwgImdldEFjdGl2YXRpb25TbmlwcGV0IiwgImluaXRfY29udl9ncm91cGVkIiwgImluaXRfdXRpbCIsICJpbml0X2Z1c2VfdXRpbHMiLCAiU2hhcGVVdGlsIiwgImdldEFjdGl2YXRpb25TbmlwcGV0IiwgImNhbGN1bGF0ZU91dHB1dFNoYXBlIiwgInZhbGlkYXRlSW5wdXRzIiwgImdldEFkanVzdGVkQ29udkF0dHJpYnV0ZXMiLCAicGFyc2VDb252QXR0cmlidXRlcyIsICJjb252MmQiLCAiY29udiIsICJpbml0X2NvbnYiLCAiaW5pdF91dGlsIiwgImluaXRfY29udl9ncm91cGVkIiwgImluaXRfZnVzZV91dGlscyIsICJpbml0X3RyYW5zcG9zZSIsICJQb29sQ29udlV0aWwiLCAicGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzIiwgImNvbnZJbnB1dHMiLCAidHJhbnNwb3NlZFdlaWdodCIsICJjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyIsICJjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyIsICJpbml0X3V0aWwiLCAiU2hhcGVVdGlsIiwgImNvbXB1dGVUb3RhbFBhZCIsICJkaXN0cmlidXRlUGFkZGluZyIsICJjYWxjdWxhdGVPdXRwdXRTaGFwZUFuZFBhZHMiLCAiZ2V0QWRqdXN0ZWRDb252VHJhbnNwb3NlQXR0cmlidXRlcyIsICJwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzIiwgInZhbGlkYXRlSW5wdXRzIiwgImNvbnZUcmFuc3Bvc2UyZCIsICJjb252VHJhbnNwb3NlIiwgImluaXRfY29udl90cmFuc3Bvc2UiLCAiaW5pdF9mdXNlX3V0aWxzIiwgImluaXRfdHJhbnNwb3NlIiwgInBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyIsICJjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJ2YWxpZGF0ZUlucHV0cyIsICJwZXJtRnVuY3Rpb25Cb2R5IiwgImRlcHRoVG9TcGFjZSIsICJwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXMiLCAiaW5pdF9kZXB0aF90b19zcGFjZSIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAic2hhcGUiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAic3ltYm9sIiwgIm5hbWUiLCAiU2hhcGVVdGlsIiwgInJlZHVjZU9wcyIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAidmFsaWRhdGVJbnB1dHMiLCAiY2FsY3VsYXRlT3V0cHV0U2hhcGUiLCAiaW5pdF91dGlsIiwgInNoYXBlIiwgIlNoYXBlVXRpbCIsICJmYXN0R2VsdSIsICJpbml0X3V0aWwiLCAiaW5pdF91bmFyeV9vcCIsICJTaGFwZVV0aWwiLCAidmFsaWRhdGVJbnB1dHMiLCAiY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm8iLCAicGFyc2VHYXRoZXJBdHRyaWJ1dGVzIiwgImdhdGhlciIsICJpbml0X2dhdGhlciIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJpbml0X3V0aWwiLCAiU2hhcGVVdGlsIiwgInZhbGlkYXRlSW5wdXRzIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInZhbGlkYXRlSW5wdXRzIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInZhbGlkYXRlSW5wdXRzIiwgImNyZWF0ZUdlbW1Qcm9ncmFtSW5mbyIsICJwYXJzZUdlbW1BdHRyaWJ1dGVzIiwgImdlbW0iLCAiaW5pdF9nZW1tIiwgImluaXRfdXRpbCIsICJHZW1tVXRpbCIsICJTaGFwZVV0aWwiLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIlNoYXBlVXRpbCIsICJpbnB1dHMiLCAib3V0cHV0U2l6ZSIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAidmFsaWRhdGVJbnB1dHMiLCAid2VpZ2h0VHJhbnNwb3NlQXR0cmlidXRlIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJpbml0X3R5cGVzIiwgImluaXRfdHJhbnNwb3NlIiwgIlNoYXBlVXRpbCIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAiY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8iLCAidmFsaWRhdGVJbnB1dHMiLCAiY3JlYXRlU3BsaXRQcm9ncmFtSW5mbyIsICJzcGxpdCIsICJwYXJzZVNwbGl0QXR0cmlidXRlcyIsICJpbml0X3NwbGl0IiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAiU2hhcGVVdGlsIiwgInZhbGlkYXRlSW5wdXRzIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInZhbGlkYXRlSW5wdXRzIiwgIndlaWdodFRyYW5zcG9zZUF0dHJpYnV0ZSIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJpbml0X3NwbGl0IiwgImluaXRfdHJhbnNwb3NlIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyIsICJjcmVhdGVTcGxpdFByb2dyYW1JbmZvIiwgImluaXRfdXRpbCIsICJpbml0X3RyYW5zcG9zZSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8iLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF91dGlsIiwgIlNoYXBlVXRpbCIsICJ2YWxpZGF0ZUlucHV0cyIsICJtYXRNdWwiLCAiaW5pdF9tYXRtdWwiLCAiaW5pdF91dGlsIiwgIkJyb2FkY2FzdFV0aWwiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZU1hdG11bFByb2dyYW1JbmZvIiwgInZhbGlkYXRlSW5wdXRzIiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJTaGFwZVV0aWwiLCAiZGF0YVR5cGUiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInZhbGlkYXRlSW5wdXRzIiwgImdldFBhZENvbnN0YW50IiwgImdldFBhZFJlZmxlY3QiLCAiZ2V0UGFkRWRnZSIsICJjcmVhdGVQYWRQcm9ncmFtSW5mbyIsICJpbml0X3BhZCIsICJpbml0X3V0aWwiLCAiU2hhcGVVdGlsIiwgInZhbGlkYXRlSW5wdXRzIiwgImdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZSIsICJnZW5lcmF0ZVBvb2xpbmdDb2RlIiwgImNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8iLCAicGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXMiLCAiYXZlcmFnZVBvb2wiLCAicGFyc2VHbG9iYWxBdmVyYWdlUG9vbEF0dHJpYnV0ZXMiLCAiZ2xvYmFsQXZlcmFnZVBvb2wiLCAiY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvIiwgIm1heFBvb2wiLCAicGFyc2VNYXhQb29sQXR0cmlidXRlcyIsICJnbG9iYWxNYXhQb29sIiwgImluaXRfcG9vbCIsICJpbml0X3V0aWwiLCAiZW52IiwgIlBvb2xDb252VXRpbCIsICJTaGFwZVV0aWwiLCAic3VtIiwgIm5hbWUiLCAidmFsaWRhdGVJbnB1dHMiLCAiaW5pdF91dGlsIiwgImluaXRfYXR0cmlidXRlX3dpdGhfY2FjaGVfa2V5IiwgIlNoYXBlVXRpbCIsICJjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkiLCAiZW52IiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgInZhbGlkYXRlSW5wdXRzIiwgInJlc2l6ZSIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAiU2hhcGVVdGlsIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3V0aWwiLCAiU2hhcGVVdGlsIiwgInZhbGlkYXRlSW5wdXRzIiwgImNyZWF0ZVNsaWNlUHJvZ3JhbUluZm8iLCAic2xpY2UiLCAicGFyc2VTbGljZUF0dHJpYnV0ZXMiLCAiaW5pdF9zbGljZSIsICJpbml0X3V0aWwiLCAiaW5pdF9hdHRyaWJ1dGVfd2l0aF9jYWNoZV9rZXkiLCAiY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5IiwgIlNoYXBlVXRpbCIsICJ2YWxpZGF0ZUlucHV0cyIsICJzb2Z0bWF4IiwgInBhcnNlU29mdG1heEF0dHJpYnV0ZXMiLCAiaW5pdF9zb2Z0bWF4IiwgImluaXRfdXRpbCIsICJpbml0X2F0dHJpYnV0ZV93aXRoX2NhY2hlX2tleSIsICJpbml0X3RyYW5zcG9zZSIsICJTaGFwZVV0aWwiLCAiY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8iLCAibmFtZSIsICJjb21wb25lbnRzIiwgImNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSIsICJ2YWxpZGF0ZUlucHV0cyIsICJnZXRPdXRwdXRTaGFwZSIsICJjcmVhdGVUaWxlUHJvZ3JhbUluZm8iLCAidGlsZSIsICJpbml0X3RpbGUiLCAiaW5pdF91dGlsIiwgInNoYXBlIiwgIlNoYXBlVXRpbCIsICJpbml0X3V0aWwiLCAiYSIsICJiIiwgImMiLCAiU2hhcGVVdGlsIiwgIkJyb2FkY2FzdFV0aWwiLCAiaW5pdF9vcF9yZXNvbHZlX3J1bGVzIiwgImluaXRfYmluYXJ5X29wIiwgImluaXRfY29uY2F0IiwgImluaXRfY29udiIsICJpbml0X2NvbnZfdHJhbnNwb3NlIiwgImluaXRfZGVwdGhfdG9fc3BhY2UiLCAiaW5pdF9nYXRoZXIiLCAiaW5pdF9nZW1tIiwgImluaXRfbWF0bXVsIiwgImluaXRfcGFkIiwgImluaXRfcG9vbCIsICJpbml0X3JlZHVjZSIsICJpbml0X3NsaWNlIiwgImluaXRfc29mdG1heCIsICJpbml0X3NwbGl0IiwgImluaXRfdGlsZSIsICJpbml0X3RyYW5zcG9zZSIsICJpbml0X3VuYXJ5X29wIiwgImFicyIsICJhY29zIiwgImFkZCIsICJhc2luIiwgImF0YW4iLCAiYXZlcmFnZVBvb2wiLCAicGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXMiLCAiY2FzdCIsICJwYXJzZUNhc3RBdHRyaWJ1dGVzIiwgImNlaWwiLCAiY2xpcCIsICJjb25jYXQiLCAicGFyc2VDb25jYXRBdHRyaWJ1dGVzIiwgImNvbnYiLCAicGFyc2VDb252QXR0cmlidXRlcyIsICJjb252VHJhbnNwb3NlIiwgInBhcnNlQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMiLCAiY29zIiwgImRlcHRoVG9TcGFjZSIsICJwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXMiLCAiZGl2IiwgImVsdSIsICJlcXVhbCIsICJleHAiLCAiZmFzdEdlbHUiLCAiZmxvb3IiLCAiZ2F0aGVyIiwgInBhcnNlR2F0aGVyQXR0cmlidXRlcyIsICJnZW1tIiwgInBhcnNlR2VtbUF0dHJpYnV0ZXMiLCAiZ2xvYmFsQXZlcmFnZVBvb2wiLCAicGFyc2VHbG9iYWxBdmVyYWdlUG9vbEF0dHJpYnV0ZXMiLCAiZ2xvYmFsTWF4UG9vbCIsICJncmVhdGVyIiwgImxlYWt5UmVsdSIsICJsZXNzIiwgImxvZyIsICJtYXRNdWwiLCAibWF4UG9vbCIsICJwYXJzZU1heFBvb2xBdHRyaWJ1dGVzIiwgIm11bCIsICJuZWciLCAibm90IiwgInBvdyIsICJyZWR1Y2VNaW4iLCAicmVkdWNlTWVhbiIsICJyZWR1Y2VNYXgiLCAicmVkdWNlU3VtIiwgInJlZHVjZVByb2QiLCAicmVkdWNlTG9nU3VtIiwgInJlbHUiLCAicmVzaXplIiwgInNpZ21vaWQiLCAic2luIiwgInNsaWNlIiwgInBhcnNlU2xpY2VBdHRyaWJ1dGVzIiwgInNwbGl0IiwgInBhcnNlU3BsaXRBdHRyaWJ1dGVzIiwgInNxcnQiLCAic29mdG1heCIsICJwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzIiwgInN1YiIsICJ0YW4iLCAidGFuaCIsICJ0aWxlIiwgInRyYW5zcG9zZSIsICJwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXMiLCAiUHJvZ3JhbU1hbmFnZXIiLCAiaW5pdF9wcm9ncmFtX21hbmFnZXIiLCAiYmFja2VuZCIsICJnZXRQcm9ncmFtSW5mb1VuaXF1ZUtleSIsICJpbml0X29wX3Jlc29sdmVfcnVsZXMiLCAiaW5pdF9wcm9ncmFtX21hbmFnZXIiLCAiZW52IiwgIlByb2dyYW1NYW5hZ2VyIiwgImkiLCAiY3JlYXRlVmlldyIsICJpbml0X3V0aWwiLCAibW9kdWxlIiwgIlNoYXBlVXRpbCIsICJiYWNrZW5kIiwgIm5hbWUiLCAiZW52IiwgInNoYXBlIiwgImVudiIsICJ3YXNtIiwgInNoYXBlIiwgIm5hbWUiLCAibG9jYXRpb24iLCAiaW5kZXgiLCAidGVuc29yIiwgImVycm9yQ29kZSIsICJpIiwgImluaXRpYWxpemluZyIsICJpbml0aWFsaXplZCIsICJhYm9ydGVkIiwgImNvcHlGcm9tRXh0ZXJuYWxCdWZmZXIiLCAiY3JlYXRlU2Vzc2lvbiIsICJyZWxlYXNlU2Vzc2lvbiIsICJydW4iLCAiZW5kUHJvZmlsaW5nIiwgImVudiIsICJpbml0X3Nlc3Npb25faGFuZGxlcl9pbmZlcmVuY2UiLCAiVGVuc29yIiwgImNvcHlGcm9tRXh0ZXJuYWxCdWZmZXIiLCAiY3JlYXRlU2Vzc2lvbiIsICJyZWxlYXNlU2Vzc2lvbiIsICJuYW1lIiwgInJ1biIsICJlbmRQcm9maWxpbmciLCAiaW5pdF9zZXNzaW9uX2hhbmRsZXJfaW5mZXJlbmNlIiwgImVudiIsICJJbmZlcmVuY2VTZXNzaW9uIiwgIlRlbnNvciIsICJlbnYiLCAidmVyc2lvbiIsICJvbm54anNCYWNrZW5kIiwgIndhc21CYWNrZW5kIiwgImVudiIsICJ2ZXJzaW9uIl0KfQo=