diff --git "a/.next/server/vendor-chunks/@google.js" "b/.next/server/vendor-chunks/@google.js" new file mode 100644--- /dev/null +++ "b/.next/server/vendor-chunks/@google.js" @@ -0,0 +1,35 @@ +"use strict"; +/* + * ATTENTION: An "eval-source-map" devtool has been used. + * This devtool is neither made for production nor for readable output files. + * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. + * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) + * or disable the default devtool with "devtool: false". + * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). + */ +exports.id = "vendor-chunks/@google"; +exports.ids = ["vendor-chunks/@google"]; +exports.modules = { + +/***/ "(action-browser)/./node_modules/@google/generative-ai/dist/index.js": +/*!**********************************************************!*\ + !*** ./node_modules/@google/generative-ai/dist/index.js ***! + \**********************************************************/ +/***/ ((__unused_webpack_module, exports) => { + +eval("\n\n/**\n * Contains the list of OpenAPI data types\n * as defined by https://swagger.io/docs/specification/data-models/data-types/\n * @public\n */\nexports.SchemaType = void 0;\n(function (SchemaType) {\n /** String type. */\n SchemaType[\"STRING\"] = \"string\";\n /** Number type. */\n SchemaType[\"NUMBER\"] = \"number\";\n /** Integer type. */\n SchemaType[\"INTEGER\"] = \"integer\";\n /** Boolean type. */\n SchemaType[\"BOOLEAN\"] = \"boolean\";\n /** Array type. */\n SchemaType[\"ARRAY\"] = \"array\";\n /** Object type. */\n SchemaType[\"OBJECT\"] = \"object\";\n})(exports.SchemaType || (exports.SchemaType = {}));\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @public\n */\nexports.ExecutableCodeLanguage = void 0;\n(function (ExecutableCodeLanguage) {\n ExecutableCodeLanguage[\"LANGUAGE_UNSPECIFIED\"] = \"language_unspecified\";\n ExecutableCodeLanguage[\"PYTHON\"] = \"python\";\n})(exports.ExecutableCodeLanguage || (exports.ExecutableCodeLanguage = {}));\n/**\n * Possible outcomes of code execution.\n * @public\n */\nexports.Outcome = void 0;\n(function (Outcome) {\n /**\n * Unspecified status. This value should not be used.\n */\n Outcome[\"OUTCOME_UNSPECIFIED\"] = \"outcome_unspecified\";\n /**\n * Code execution completed successfully.\n */\n Outcome[\"OUTCOME_OK\"] = \"outcome_ok\";\n /**\n * Code execution finished but with a failure. `stderr` should contain the\n * reason.\n */\n Outcome[\"OUTCOME_FAILED\"] = \"outcome_failed\";\n /**\n * Code execution ran for too long, and was cancelled. There may or may not\n * be a partial output present.\n */\n Outcome[\"OUTCOME_DEADLINE_EXCEEDED\"] = \"outcome_deadline_exceeded\";\n})(exports.Outcome || (exports.Outcome = {}));\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Possible roles.\n * @public\n */\nconst POSSIBLE_ROLES = [\"user\", \"model\", \"function\", \"system\"];\n/**\n * Harm categories that would cause prompts or candidates to be blocked.\n * @public\n */\nexports.HarmCategory = void 0;\n(function (HarmCategory) {\n HarmCategory[\"HARM_CATEGORY_UNSPECIFIED\"] = \"HARM_CATEGORY_UNSPECIFIED\";\n HarmCategory[\"HARM_CATEGORY_HATE_SPEECH\"] = \"HARM_CATEGORY_HATE_SPEECH\";\n HarmCategory[\"HARM_CATEGORY_SEXUALLY_EXPLICIT\"] = \"HARM_CATEGORY_SEXUALLY_EXPLICIT\";\n HarmCategory[\"HARM_CATEGORY_HARASSMENT\"] = \"HARM_CATEGORY_HARASSMENT\";\n HarmCategory[\"HARM_CATEGORY_DANGEROUS_CONTENT\"] = \"HARM_CATEGORY_DANGEROUS_CONTENT\";\n HarmCategory[\"HARM_CATEGORY_CIVIC_INTEGRITY\"] = \"HARM_CATEGORY_CIVIC_INTEGRITY\";\n})(exports.HarmCategory || (exports.HarmCategory = {}));\n/**\n * Threshold above which a prompt or candidate will be blocked.\n * @public\n */\nexports.HarmBlockThreshold = void 0;\n(function (HarmBlockThreshold) {\n /** Threshold is unspecified. */\n HarmBlockThreshold[\"HARM_BLOCK_THRESHOLD_UNSPECIFIED\"] = \"HARM_BLOCK_THRESHOLD_UNSPECIFIED\";\n /** Content with NEGLIGIBLE will be allowed. */\n HarmBlockThreshold[\"BLOCK_LOW_AND_ABOVE\"] = \"BLOCK_LOW_AND_ABOVE\";\n /** Content with NEGLIGIBLE and LOW will be allowed. */\n HarmBlockThreshold[\"BLOCK_MEDIUM_AND_ABOVE\"] = \"BLOCK_MEDIUM_AND_ABOVE\";\n /** Content with NEGLIGIBLE, LOW, and MEDIUM will be allowed. */\n HarmBlockThreshold[\"BLOCK_ONLY_HIGH\"] = \"BLOCK_ONLY_HIGH\";\n /** All content will be allowed. */\n HarmBlockThreshold[\"BLOCK_NONE\"] = \"BLOCK_NONE\";\n})(exports.HarmBlockThreshold || (exports.HarmBlockThreshold = {}));\n/**\n * Probability that a prompt or candidate matches a harm category.\n * @public\n */\nexports.HarmProbability = void 0;\n(function (HarmProbability) {\n /** Probability is unspecified. */\n HarmProbability[\"HARM_PROBABILITY_UNSPECIFIED\"] = \"HARM_PROBABILITY_UNSPECIFIED\";\n /** Content has a negligible chance of being unsafe. */\n HarmProbability[\"NEGLIGIBLE\"] = \"NEGLIGIBLE\";\n /** Content has a low chance of being unsafe. */\n HarmProbability[\"LOW\"] = \"LOW\";\n /** Content has a medium chance of being unsafe. */\n HarmProbability[\"MEDIUM\"] = \"MEDIUM\";\n /** Content has a high chance of being unsafe. */\n HarmProbability[\"HIGH\"] = \"HIGH\";\n})(exports.HarmProbability || (exports.HarmProbability = {}));\n/**\n * Reason that a prompt was blocked.\n * @public\n */\nexports.BlockReason = void 0;\n(function (BlockReason) {\n // A blocked reason was not specified.\n BlockReason[\"BLOCKED_REASON_UNSPECIFIED\"] = \"BLOCKED_REASON_UNSPECIFIED\";\n // Content was blocked by safety settings.\n BlockReason[\"SAFETY\"] = \"SAFETY\";\n // Content was blocked, but the reason is uncategorized.\n BlockReason[\"OTHER\"] = \"OTHER\";\n})(exports.BlockReason || (exports.BlockReason = {}));\n/**\n * Reason that a candidate finished.\n * @public\n */\nexports.FinishReason = void 0;\n(function (FinishReason) {\n // Default value. This value is unused.\n FinishReason[\"FINISH_REASON_UNSPECIFIED\"] = \"FINISH_REASON_UNSPECIFIED\";\n // Natural stop point of the model or provided stop sequence.\n FinishReason[\"STOP\"] = \"STOP\";\n // The maximum number of tokens as specified in the request was reached.\n FinishReason[\"MAX_TOKENS\"] = \"MAX_TOKENS\";\n // The candidate content was flagged for safety reasons.\n FinishReason[\"SAFETY\"] = \"SAFETY\";\n // The candidate content was flagged for recitation reasons.\n FinishReason[\"RECITATION\"] = \"RECITATION\";\n // The candidate content was flagged for using an unsupported language.\n FinishReason[\"LANGUAGE\"] = \"LANGUAGE\";\n // Token generation stopped because the content contains forbidden terms.\n FinishReason[\"BLOCKLIST\"] = \"BLOCKLIST\";\n // Token generation stopped for potentially containing prohibited content.\n FinishReason[\"PROHIBITED_CONTENT\"] = \"PROHIBITED_CONTENT\";\n // Token generation stopped because the content potentially contains Sensitive Personally Identifiable Information (SPII).\n FinishReason[\"SPII\"] = \"SPII\";\n // The function call generated by the model is invalid.\n FinishReason[\"MALFORMED_FUNCTION_CALL\"] = \"MALFORMED_FUNCTION_CALL\";\n // Unknown reason.\n FinishReason[\"OTHER\"] = \"OTHER\";\n})(exports.FinishReason || (exports.FinishReason = {}));\n/**\n * Task type for embedding content.\n * @public\n */\nexports.TaskType = void 0;\n(function (TaskType) {\n TaskType[\"TASK_TYPE_UNSPECIFIED\"] = \"TASK_TYPE_UNSPECIFIED\";\n TaskType[\"RETRIEVAL_QUERY\"] = \"RETRIEVAL_QUERY\";\n TaskType[\"RETRIEVAL_DOCUMENT\"] = \"RETRIEVAL_DOCUMENT\";\n TaskType[\"SEMANTIC_SIMILARITY\"] = \"SEMANTIC_SIMILARITY\";\n TaskType[\"CLASSIFICATION\"] = \"CLASSIFICATION\";\n TaskType[\"CLUSTERING\"] = \"CLUSTERING\";\n})(exports.TaskType || (exports.TaskType = {}));\n/**\n * @public\n */\nexports.FunctionCallingMode = void 0;\n(function (FunctionCallingMode) {\n // Unspecified function calling mode. This value should not be used.\n FunctionCallingMode[\"MODE_UNSPECIFIED\"] = \"MODE_UNSPECIFIED\";\n // Default model behavior, model decides to predict either a function call\n // or a natural language repspose.\n FunctionCallingMode[\"AUTO\"] = \"AUTO\";\n // Model is constrained to always predicting a function call only.\n // If \"allowed_function_names\" are set, the predicted function call will be\n // limited to any one of \"allowed_function_names\", else the predicted\n // function call will be any one of the provided \"function_declarations\".\n FunctionCallingMode[\"ANY\"] = \"ANY\";\n // Model will not predict any function call. Model behavior is same as when\n // not passing any function declarations.\n FunctionCallingMode[\"NONE\"] = \"NONE\";\n})(exports.FunctionCallingMode || (exports.FunctionCallingMode = {}));\n/**\n * The mode of the predictor to be used in dynamic retrieval.\n * @public\n */\nexports.DynamicRetrievalMode = void 0;\n(function (DynamicRetrievalMode) {\n // Unspecified function calling mode. This value should not be used.\n DynamicRetrievalMode[\"MODE_UNSPECIFIED\"] = \"MODE_UNSPECIFIED\";\n // Run retrieval only when system decides it is necessary.\n DynamicRetrievalMode[\"MODE_DYNAMIC\"] = \"MODE_DYNAMIC\";\n})(exports.DynamicRetrievalMode || (exports.DynamicRetrievalMode = {}));\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Basic error type for this SDK.\n * @public\n */\nclass GoogleGenerativeAIError extends Error {\n constructor(message) {\n super(`[GoogleGenerativeAI Error]: ${message}`);\n }\n}\n/**\n * Errors in the contents of a response from the model. This includes parsing\n * errors, or responses including a safety block reason.\n * @public\n */\nclass GoogleGenerativeAIResponseError extends GoogleGenerativeAIError {\n constructor(message, response) {\n super(message);\n this.response = response;\n }\n}\n/**\n * Error class covering HTTP errors when calling the server. Includes HTTP\n * status, statusText, and optional details, if provided in the server response.\n * @public\n */\nclass GoogleGenerativeAIFetchError extends GoogleGenerativeAIError {\n constructor(message, status, statusText, errorDetails) {\n super(message);\n this.status = status;\n this.statusText = statusText;\n this.errorDetails = errorDetails;\n }\n}\n/**\n * Errors in the contents of a request originating from user input.\n * @public\n */\nclass GoogleGenerativeAIRequestInputError extends GoogleGenerativeAIError {\n}\n/**\n * Error thrown when a request is aborted, either due to a timeout or\n * intentional cancellation by the user.\n * @public\n */\nclass GoogleGenerativeAIAbortError extends GoogleGenerativeAIError {\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst DEFAULT_BASE_URL = \"https://generativelanguage.googleapis.com\";\nconst DEFAULT_API_VERSION = \"v1beta\";\n/**\n * We can't `require` package.json if this runs on web. We will use rollup to\n * swap in the version number here at build time.\n */\nconst PACKAGE_VERSION = \"0.24.0\";\nconst PACKAGE_LOG_HEADER = \"genai-js\";\nvar Task;\n(function (Task) {\n Task[\"GENERATE_CONTENT\"] = \"generateContent\";\n Task[\"STREAM_GENERATE_CONTENT\"] = \"streamGenerateContent\";\n Task[\"COUNT_TOKENS\"] = \"countTokens\";\n Task[\"EMBED_CONTENT\"] = \"embedContent\";\n Task[\"BATCH_EMBED_CONTENTS\"] = \"batchEmbedContents\";\n})(Task || (Task = {}));\nclass RequestUrl {\n constructor(model, task, apiKey, stream, requestOptions) {\n this.model = model;\n this.task = task;\n this.apiKey = apiKey;\n this.stream = stream;\n this.requestOptions = requestOptions;\n }\n toString() {\n var _a, _b;\n const apiVersion = ((_a = this.requestOptions) === null || _a === void 0 ? void 0 : _a.apiVersion) || DEFAULT_API_VERSION;\n const baseUrl = ((_b = this.requestOptions) === null || _b === void 0 ? void 0 : _b.baseUrl) || DEFAULT_BASE_URL;\n let url = `${baseUrl}/${apiVersion}/${this.model}:${this.task}`;\n if (this.stream) {\n url += \"?alt=sse\";\n }\n return url;\n }\n}\n/**\n * Simple, but may become more complex if we add more versions to log.\n */\nfunction getClientHeaders(requestOptions) {\n const clientHeaders = [];\n if (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.apiClient) {\n clientHeaders.push(requestOptions.apiClient);\n }\n clientHeaders.push(`${PACKAGE_LOG_HEADER}/${PACKAGE_VERSION}`);\n return clientHeaders.join(\" \");\n}\nasync function getHeaders(url) {\n var _a;\n const headers = new Headers();\n headers.append(\"Content-Type\", \"application/json\");\n headers.append(\"x-goog-api-client\", getClientHeaders(url.requestOptions));\n headers.append(\"x-goog-api-key\", url.apiKey);\n let customHeaders = (_a = url.requestOptions) === null || _a === void 0 ? void 0 : _a.customHeaders;\n if (customHeaders) {\n if (!(customHeaders instanceof Headers)) {\n try {\n customHeaders = new Headers(customHeaders);\n }\n catch (e) {\n throw new GoogleGenerativeAIRequestInputError(`unable to convert customHeaders value ${JSON.stringify(customHeaders)} to Headers: ${e.message}`);\n }\n }\n for (const [headerName, headerValue] of customHeaders.entries()) {\n if (headerName === \"x-goog-api-key\") {\n throw new GoogleGenerativeAIRequestInputError(`Cannot set reserved header name ${headerName}`);\n }\n else if (headerName === \"x-goog-api-client\") {\n throw new GoogleGenerativeAIRequestInputError(`Header name ${headerName} can only be set using the apiClient field`);\n }\n headers.append(headerName, headerValue);\n }\n }\n return headers;\n}\nasync function constructModelRequest(model, task, apiKey, stream, body, requestOptions) {\n const url = new RequestUrl(model, task, apiKey, stream, requestOptions);\n return {\n url: url.toString(),\n fetchOptions: Object.assign(Object.assign({}, buildFetchOptions(requestOptions)), { method: \"POST\", headers: await getHeaders(url), body }),\n };\n}\nasync function makeModelRequest(model, task, apiKey, stream, body, requestOptions = {}, \n// Allows this to be stubbed for tests\nfetchFn = fetch) {\n const { url, fetchOptions } = await constructModelRequest(model, task, apiKey, stream, body, requestOptions);\n return makeRequest(url, fetchOptions, fetchFn);\n}\nasync function makeRequest(url, fetchOptions, fetchFn = fetch) {\n let response;\n try {\n response = await fetchFn(url, fetchOptions);\n }\n catch (e) {\n handleResponseError(e, url);\n }\n if (!response.ok) {\n await handleResponseNotOk(response, url);\n }\n return response;\n}\nfunction handleResponseError(e, url) {\n let err = e;\n if (err.name === \"AbortError\") {\n err = new GoogleGenerativeAIAbortError(`Request aborted when fetching ${url.toString()}: ${e.message}`);\n err.stack = e.stack;\n }\n else if (!(e instanceof GoogleGenerativeAIFetchError ||\n e instanceof GoogleGenerativeAIRequestInputError)) {\n err = new GoogleGenerativeAIError(`Error fetching from ${url.toString()}: ${e.message}`);\n err.stack = e.stack;\n }\n throw err;\n}\nasync function handleResponseNotOk(response, url) {\n let message = \"\";\n let errorDetails;\n try {\n const json = await response.json();\n message = json.error.message;\n if (json.error.details) {\n message += ` ${JSON.stringify(json.error.details)}`;\n errorDetails = json.error.details;\n }\n }\n catch (e) {\n // ignored\n }\n throw new GoogleGenerativeAIFetchError(`Error fetching from ${url.toString()}: [${response.status} ${response.statusText}] ${message}`, response.status, response.statusText, errorDetails);\n}\n/**\n * Generates the request options to be passed to the fetch API.\n * @param requestOptions - The user-defined request options.\n * @returns The generated request options.\n */\nfunction buildFetchOptions(requestOptions) {\n const fetchOptions = {};\n if ((requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.signal) !== undefined || (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.timeout) >= 0) {\n const controller = new AbortController();\n if ((requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.timeout) >= 0) {\n setTimeout(() => controller.abort(), requestOptions.timeout);\n }\n if (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.signal) {\n requestOptions.signal.addEventListener(\"abort\", () => {\n controller.abort();\n });\n }\n fetchOptions.signal = controller.signal;\n }\n return fetchOptions;\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Adds convenience helper methods to a response object, including stream\n * chunks (as long as each chunk is a complete GenerateContentResponse JSON).\n */\nfunction addHelpers(response) {\n response.text = () => {\n if (response.candidates && response.candidates.length > 0) {\n if (response.candidates.length > 1) {\n console.warn(`This response had ${response.candidates.length} ` +\n `candidates. Returning text from the first candidate only. ` +\n `Access response.candidates directly to use the other candidates.`);\n }\n if (hadBadFinishReason(response.candidates[0])) {\n throw new GoogleGenerativeAIResponseError(`${formatBlockErrorMessage(response)}`, response);\n }\n return getText(response);\n }\n else if (response.promptFeedback) {\n throw new GoogleGenerativeAIResponseError(`Text not available. ${formatBlockErrorMessage(response)}`, response);\n }\n return \"\";\n };\n /**\n * TODO: remove at next major version\n */\n response.functionCall = () => {\n if (response.candidates && response.candidates.length > 0) {\n if (response.candidates.length > 1) {\n console.warn(`This response had ${response.candidates.length} ` +\n `candidates. Returning function calls from the first candidate only. ` +\n `Access response.candidates directly to use the other candidates.`);\n }\n if (hadBadFinishReason(response.candidates[0])) {\n throw new GoogleGenerativeAIResponseError(`${formatBlockErrorMessage(response)}`, response);\n }\n console.warn(`response.functionCall() is deprecated. ` +\n `Use response.functionCalls() instead.`);\n return getFunctionCalls(response)[0];\n }\n else if (response.promptFeedback) {\n throw new GoogleGenerativeAIResponseError(`Function call not available. ${formatBlockErrorMessage(response)}`, response);\n }\n return undefined;\n };\n response.functionCalls = () => {\n if (response.candidates && response.candidates.length > 0) {\n if (response.candidates.length > 1) {\n console.warn(`This response had ${response.candidates.length} ` +\n `candidates. Returning function calls from the first candidate only. ` +\n `Access response.candidates directly to use the other candidates.`);\n }\n if (hadBadFinishReason(response.candidates[0])) {\n throw new GoogleGenerativeAIResponseError(`${formatBlockErrorMessage(response)}`, response);\n }\n return getFunctionCalls(response);\n }\n else if (response.promptFeedback) {\n throw new GoogleGenerativeAIResponseError(`Function call not available. ${formatBlockErrorMessage(response)}`, response);\n }\n return undefined;\n };\n return response;\n}\n/**\n * Returns all text found in all parts of first candidate.\n */\nfunction getText(response) {\n var _a, _b, _c, _d;\n const textStrings = [];\n if ((_b = (_a = response.candidates) === null || _a === void 0 ? void 0 : _a[0].content) === null || _b === void 0 ? void 0 : _b.parts) {\n for (const part of (_d = (_c = response.candidates) === null || _c === void 0 ? void 0 : _c[0].content) === null || _d === void 0 ? void 0 : _d.parts) {\n if (part.text) {\n textStrings.push(part.text);\n }\n if (part.executableCode) {\n textStrings.push(\"\\n```\" +\n part.executableCode.language +\n \"\\n\" +\n part.executableCode.code +\n \"\\n```\\n\");\n }\n if (part.codeExecutionResult) {\n textStrings.push(\"\\n```\\n\" + part.codeExecutionResult.output + \"\\n```\\n\");\n }\n }\n }\n if (textStrings.length > 0) {\n return textStrings.join(\"\");\n }\n else {\n return \"\";\n }\n}\n/**\n * Returns functionCall of first candidate.\n */\nfunction getFunctionCalls(response) {\n var _a, _b, _c, _d;\n const functionCalls = [];\n if ((_b = (_a = response.candidates) === null || _a === void 0 ? void 0 : _a[0].content) === null || _b === void 0 ? void 0 : _b.parts) {\n for (const part of (_d = (_c = response.candidates) === null || _c === void 0 ? void 0 : _c[0].content) === null || _d === void 0 ? void 0 : _d.parts) {\n if (part.functionCall) {\n functionCalls.push(part.functionCall);\n }\n }\n }\n if (functionCalls.length > 0) {\n return functionCalls;\n }\n else {\n return undefined;\n }\n}\nconst badFinishReasons = [\n exports.FinishReason.RECITATION,\n exports.FinishReason.SAFETY,\n exports.FinishReason.LANGUAGE,\n];\nfunction hadBadFinishReason(candidate) {\n return (!!candidate.finishReason &&\n badFinishReasons.includes(candidate.finishReason));\n}\nfunction formatBlockErrorMessage(response) {\n var _a, _b, _c;\n let message = \"\";\n if ((!response.candidates || response.candidates.length === 0) &&\n response.promptFeedback) {\n message += \"Response was blocked\";\n if ((_a = response.promptFeedback) === null || _a === void 0 ? void 0 : _a.blockReason) {\n message += ` due to ${response.promptFeedback.blockReason}`;\n }\n if ((_b = response.promptFeedback) === null || _b === void 0 ? void 0 : _b.blockReasonMessage) {\n message += `: ${response.promptFeedback.blockReasonMessage}`;\n }\n }\n else if ((_c = response.candidates) === null || _c === void 0 ? void 0 : _c[0]) {\n const firstCandidate = response.candidates[0];\n if (hadBadFinishReason(firstCandidate)) {\n message += `Candidate was blocked due to ${firstCandidate.finishReason}`;\n if (firstCandidate.finishMessage) {\n message += `: ${firstCandidate.finishMessage}`;\n }\n }\n }\n return message;\n}\n\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\n\r\nfunction __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nfunction __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\ntypeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst responseLineRE = /^data\\: (.*)(?:\\n\\n|\\r\\r|\\r\\n\\r\\n)/;\n/**\n * Process a response.body stream from the backend and return an\n * iterator that provides one complete GenerateContentResponse at a time\n * and a promise that resolves with a single aggregated\n * GenerateContentResponse.\n *\n * @param response - Response from a fetch call\n */\nfunction processStream(response) {\n const inputStream = response.body.pipeThrough(new TextDecoderStream(\"utf8\", { fatal: true }));\n const responseStream = getResponseStream(inputStream);\n const [stream1, stream2] = responseStream.tee();\n return {\n stream: generateResponseSequence(stream1),\n response: getResponsePromise(stream2),\n };\n}\nasync function getResponsePromise(stream) {\n const allResponses = [];\n const reader = stream.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n return addHelpers(aggregateResponses(allResponses));\n }\n allResponses.push(value);\n }\n}\nfunction generateResponseSequence(stream) {\n return __asyncGenerator(this, arguments, function* generateResponseSequence_1() {\n const reader = stream.getReader();\n while (true) {\n const { value, done } = yield __await(reader.read());\n if (done) {\n break;\n }\n yield yield __await(addHelpers(value));\n }\n });\n}\n/**\n * Reads a raw stream from the fetch response and join incomplete\n * chunks, returning a new stream that provides a single complete\n * GenerateContentResponse in each iteration.\n */\nfunction getResponseStream(inputStream) {\n const reader = inputStream.getReader();\n const stream = new ReadableStream({\n start(controller) {\n let currentText = \"\";\n return pump();\n function pump() {\n return reader\n .read()\n .then(({ value, done }) => {\n if (done) {\n if (currentText.trim()) {\n controller.error(new GoogleGenerativeAIError(\"Failed to parse stream\"));\n return;\n }\n controller.close();\n return;\n }\n currentText += value;\n let match = currentText.match(responseLineRE);\n let parsedResponse;\n while (match) {\n try {\n parsedResponse = JSON.parse(match[1]);\n }\n catch (e) {\n controller.error(new GoogleGenerativeAIError(`Error parsing JSON response: \"${match[1]}\"`));\n return;\n }\n controller.enqueue(parsedResponse);\n currentText = currentText.substring(match[0].length);\n match = currentText.match(responseLineRE);\n }\n return pump();\n })\n .catch((e) => {\n let err = e;\n err.stack = e.stack;\n if (err.name === \"AbortError\") {\n err = new GoogleGenerativeAIAbortError(\"Request aborted when reading from the stream\");\n }\n else {\n err = new GoogleGenerativeAIError(\"Error reading from the stream\");\n }\n throw err;\n });\n }\n },\n });\n return stream;\n}\n/**\n * Aggregates an array of `GenerateContentResponse`s into a single\n * GenerateContentResponse.\n */\nfunction aggregateResponses(responses) {\n const lastResponse = responses[responses.length - 1];\n const aggregatedResponse = {\n promptFeedback: lastResponse === null || lastResponse === void 0 ? void 0 : lastResponse.promptFeedback,\n };\n for (const response of responses) {\n if (response.candidates) {\n let candidateIndex = 0;\n for (const candidate of response.candidates) {\n if (!aggregatedResponse.candidates) {\n aggregatedResponse.candidates = [];\n }\n if (!aggregatedResponse.candidates[candidateIndex]) {\n aggregatedResponse.candidates[candidateIndex] = {\n index: candidateIndex,\n };\n }\n // Keep overwriting, the last one will be final\n aggregatedResponse.candidates[candidateIndex].citationMetadata =\n candidate.citationMetadata;\n aggregatedResponse.candidates[candidateIndex].groundingMetadata =\n candidate.groundingMetadata;\n aggregatedResponse.candidates[candidateIndex].finishReason =\n candidate.finishReason;\n aggregatedResponse.candidates[candidateIndex].finishMessage =\n candidate.finishMessage;\n aggregatedResponse.candidates[candidateIndex].safetyRatings =\n candidate.safetyRatings;\n /**\n * Candidates should always have content and parts, but this handles\n * possible malformed responses.\n */\n if (candidate.content && candidate.content.parts) {\n if (!aggregatedResponse.candidates[candidateIndex].content) {\n aggregatedResponse.candidates[candidateIndex].content = {\n role: candidate.content.role || \"user\",\n parts: [],\n };\n }\n const newPart = {};\n for (const part of candidate.content.parts) {\n if (part.text) {\n newPart.text = part.text;\n }\n if (part.functionCall) {\n newPart.functionCall = part.functionCall;\n }\n if (part.executableCode) {\n newPart.executableCode = part.executableCode;\n }\n if (part.codeExecutionResult) {\n newPart.codeExecutionResult = part.codeExecutionResult;\n }\n if (Object.keys(newPart).length === 0) {\n newPart.text = \"\";\n }\n aggregatedResponse.candidates[candidateIndex].content.parts.push(newPart);\n }\n }\n }\n candidateIndex++;\n }\n if (response.usageMetadata) {\n aggregatedResponse.usageMetadata = response.usageMetadata;\n }\n }\n return aggregatedResponse;\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nasync function generateContentStream(apiKey, model, params, requestOptions) {\n const response = await makeModelRequest(model, Task.STREAM_GENERATE_CONTENT, apiKey, \n /* stream */ true, JSON.stringify(params), requestOptions);\n return processStream(response);\n}\nasync function generateContent(apiKey, model, params, requestOptions) {\n const response = await makeModelRequest(model, Task.GENERATE_CONTENT, apiKey, \n /* stream */ false, JSON.stringify(params), requestOptions);\n const responseJson = await response.json();\n const enhancedResponse = addHelpers(responseJson);\n return {\n response: enhancedResponse,\n };\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nfunction formatSystemInstruction(input) {\n // null or undefined\n if (input == null) {\n return undefined;\n }\n else if (typeof input === \"string\") {\n return { role: \"system\", parts: [{ text: input }] };\n }\n else if (input.text) {\n return { role: \"system\", parts: [input] };\n }\n else if (input.parts) {\n if (!input.role) {\n return { role: \"system\", parts: input.parts };\n }\n else {\n return input;\n }\n }\n}\nfunction formatNewContent(request) {\n let newParts = [];\n if (typeof request === \"string\") {\n newParts = [{ text: request }];\n }\n else {\n for (const partOrString of request) {\n if (typeof partOrString === \"string\") {\n newParts.push({ text: partOrString });\n }\n else {\n newParts.push(partOrString);\n }\n }\n }\n return assignRoleToPartsAndValidateSendMessageRequest(newParts);\n}\n/**\n * When multiple Part types (i.e. FunctionResponsePart and TextPart) are\n * passed in a single Part array, we may need to assign different roles to each\n * part. Currently only FunctionResponsePart requires a role other than 'user'.\n * @private\n * @param parts Array of parts to pass to the model\n * @returns Array of content items\n */\nfunction assignRoleToPartsAndValidateSendMessageRequest(parts) {\n const userContent = { role: \"user\", parts: [] };\n const functionContent = { role: \"function\", parts: [] };\n let hasUserContent = false;\n let hasFunctionContent = false;\n for (const part of parts) {\n if (\"functionResponse\" in part) {\n functionContent.parts.push(part);\n hasFunctionContent = true;\n }\n else {\n userContent.parts.push(part);\n hasUserContent = true;\n }\n }\n if (hasUserContent && hasFunctionContent) {\n throw new GoogleGenerativeAIError(\"Within a single message, FunctionResponse cannot be mixed with other type of part in the request for sending chat message.\");\n }\n if (!hasUserContent && !hasFunctionContent) {\n throw new GoogleGenerativeAIError(\"No content is provided for sending chat message.\");\n }\n if (hasUserContent) {\n return userContent;\n }\n return functionContent;\n}\nfunction formatCountTokensInput(params, modelParams) {\n var _a;\n let formattedGenerateContentRequest = {\n model: modelParams === null || modelParams === void 0 ? void 0 : modelParams.model,\n generationConfig: modelParams === null || modelParams === void 0 ? void 0 : modelParams.generationConfig,\n safetySettings: modelParams === null || modelParams === void 0 ? void 0 : modelParams.safetySettings,\n tools: modelParams === null || modelParams === void 0 ? void 0 : modelParams.tools,\n toolConfig: modelParams === null || modelParams === void 0 ? void 0 : modelParams.toolConfig,\n systemInstruction: modelParams === null || modelParams === void 0 ? void 0 : modelParams.systemInstruction,\n cachedContent: (_a = modelParams === null || modelParams === void 0 ? void 0 : modelParams.cachedContent) === null || _a === void 0 ? void 0 : _a.name,\n contents: [],\n };\n const containsGenerateContentRequest = params.generateContentRequest != null;\n if (params.contents) {\n if (containsGenerateContentRequest) {\n throw new GoogleGenerativeAIRequestInputError(\"CountTokensRequest must have one of contents or generateContentRequest, not both.\");\n }\n formattedGenerateContentRequest.contents = params.contents;\n }\n else if (containsGenerateContentRequest) {\n formattedGenerateContentRequest = Object.assign(Object.assign({}, formattedGenerateContentRequest), params.generateContentRequest);\n }\n else {\n // Array or string\n const content = formatNewContent(params);\n formattedGenerateContentRequest.contents = [content];\n }\n return { generateContentRequest: formattedGenerateContentRequest };\n}\nfunction formatGenerateContentInput(params) {\n let formattedRequest;\n if (params.contents) {\n formattedRequest = params;\n }\n else {\n // Array or string\n const content = formatNewContent(params);\n formattedRequest = { contents: [content] };\n }\n if (params.systemInstruction) {\n formattedRequest.systemInstruction = formatSystemInstruction(params.systemInstruction);\n }\n return formattedRequest;\n}\nfunction formatEmbedContentInput(params) {\n if (typeof params === \"string\" || Array.isArray(params)) {\n const content = formatNewContent(params);\n return { content };\n }\n return params;\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// https://ai.google.dev/api/rest/v1beta/Content#part\nconst VALID_PART_FIELDS = [\n \"text\",\n \"inlineData\",\n \"functionCall\",\n \"functionResponse\",\n \"executableCode\",\n \"codeExecutionResult\",\n];\nconst VALID_PARTS_PER_ROLE = {\n user: [\"text\", \"inlineData\"],\n function: [\"functionResponse\"],\n model: [\"text\", \"functionCall\", \"executableCode\", \"codeExecutionResult\"],\n // System instructions shouldn't be in history anyway.\n system: [\"text\"],\n};\nfunction validateChatHistory(history) {\n let prevContent = false;\n for (const currContent of history) {\n const { role, parts } = currContent;\n if (!prevContent && role !== \"user\") {\n throw new GoogleGenerativeAIError(`First content should be with role 'user', got ${role}`);\n }\n if (!POSSIBLE_ROLES.includes(role)) {\n throw new GoogleGenerativeAIError(`Each item should include role field. Got ${role} but valid roles are: ${JSON.stringify(POSSIBLE_ROLES)}`);\n }\n if (!Array.isArray(parts)) {\n throw new GoogleGenerativeAIError(\"Content should have 'parts' property with an array of Parts\");\n }\n if (parts.length === 0) {\n throw new GoogleGenerativeAIError(\"Each Content should have at least one part\");\n }\n const countFields = {\n text: 0,\n inlineData: 0,\n functionCall: 0,\n functionResponse: 0,\n fileData: 0,\n executableCode: 0,\n codeExecutionResult: 0,\n };\n for (const part of parts) {\n for (const key of VALID_PART_FIELDS) {\n if (key in part) {\n countFields[key] += 1;\n }\n }\n }\n const validParts = VALID_PARTS_PER_ROLE[role];\n for (const key of VALID_PART_FIELDS) {\n if (!validParts.includes(key) && countFields[key] > 0) {\n throw new GoogleGenerativeAIError(`Content with role '${role}' can't contain '${key}' part`);\n }\n }\n prevContent = true;\n }\n}\n/**\n * Returns true if the response is valid (could be appended to the history), flase otherwise.\n */\nfunction isValidResponse(response) {\n var _a;\n if (response.candidates === undefined || response.candidates.length === 0) {\n return false;\n }\n const content = (_a = response.candidates[0]) === null || _a === void 0 ? void 0 : _a.content;\n if (content === undefined) {\n return false;\n }\n if (content.parts === undefined || content.parts.length === 0) {\n return false;\n }\n for (const part of content.parts) {\n if (part === undefined || Object.keys(part).length === 0) {\n return false;\n }\n if (part.text !== undefined && part.text === \"\") {\n return false;\n }\n }\n return true;\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Do not log a message for this error.\n */\nconst SILENT_ERROR = \"SILENT_ERROR\";\n/**\n * ChatSession class that enables sending chat messages and stores\n * history of sent and received messages so far.\n *\n * @public\n */\nclass ChatSession {\n constructor(apiKey, model, params, _requestOptions = {}) {\n this.model = model;\n this.params = params;\n this._requestOptions = _requestOptions;\n this._history = [];\n this._sendPromise = Promise.resolve();\n this._apiKey = apiKey;\n if (params === null || params === void 0 ? void 0 : params.history) {\n validateChatHistory(params.history);\n this._history = params.history;\n }\n }\n /**\n * Gets the chat history so far. Blocked prompts are not added to history.\n * Blocked candidates are not added to history, nor are the prompts that\n * generated them.\n */\n async getHistory() {\n await this._sendPromise;\n return this._history;\n }\n /**\n * Sends a chat message and receives a non-streaming\n * {@link GenerateContentResult}.\n *\n * Fields set in the optional {@link SingleRequestOptions} parameter will\n * take precedence over the {@link RequestOptions} values provided to\n * {@link GoogleGenerativeAI.getGenerativeModel }.\n */\n async sendMessage(request, requestOptions = {}) {\n var _a, _b, _c, _d, _e, _f;\n await this._sendPromise;\n const newContent = formatNewContent(request);\n const generateContentRequest = {\n safetySettings: (_a = this.params) === null || _a === void 0 ? void 0 : _a.safetySettings,\n generationConfig: (_b = this.params) === null || _b === void 0 ? void 0 : _b.generationConfig,\n tools: (_c = this.params) === null || _c === void 0 ? void 0 : _c.tools,\n toolConfig: (_d = this.params) === null || _d === void 0 ? void 0 : _d.toolConfig,\n systemInstruction: (_e = this.params) === null || _e === void 0 ? void 0 : _e.systemInstruction,\n cachedContent: (_f = this.params) === null || _f === void 0 ? void 0 : _f.cachedContent,\n contents: [...this._history, newContent],\n };\n const chatSessionRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);\n let finalResult;\n // Add onto the chain.\n this._sendPromise = this._sendPromise\n .then(() => generateContent(this._apiKey, this.model, generateContentRequest, chatSessionRequestOptions))\n .then((result) => {\n var _a;\n if (isValidResponse(result.response)) {\n this._history.push(newContent);\n const responseContent = Object.assign({ parts: [], \n // Response seems to come back without a role set.\n role: \"model\" }, (_a = result.response.candidates) === null || _a === void 0 ? void 0 : _a[0].content);\n this._history.push(responseContent);\n }\n else {\n const blockErrorMessage = formatBlockErrorMessage(result.response);\n if (blockErrorMessage) {\n console.warn(`sendMessage() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`);\n }\n }\n finalResult = result;\n });\n await this._sendPromise;\n return finalResult;\n }\n /**\n * Sends a chat message and receives the response as a\n * {@link GenerateContentStreamResult} containing an iterable stream\n * and a response promise.\n *\n * Fields set in the optional {@link SingleRequestOptions} parameter will\n * take precedence over the {@link RequestOptions} values provided to\n * {@link GoogleGenerativeAI.getGenerativeModel }.\n */\n async sendMessageStream(request, requestOptions = {}) {\n var _a, _b, _c, _d, _e, _f;\n await this._sendPromise;\n const newContent = formatNewContent(request);\n const generateContentRequest = {\n safetySettings: (_a = this.params) === null || _a === void 0 ? void 0 : _a.safetySettings,\n generationConfig: (_b = this.params) === null || _b === void 0 ? void 0 : _b.generationConfig,\n tools: (_c = this.params) === null || _c === void 0 ? void 0 : _c.tools,\n toolConfig: (_d = this.params) === null || _d === void 0 ? void 0 : _d.toolConfig,\n systemInstruction: (_e = this.params) === null || _e === void 0 ? void 0 : _e.systemInstruction,\n cachedContent: (_f = this.params) === null || _f === void 0 ? void 0 : _f.cachedContent,\n contents: [...this._history, newContent],\n };\n const chatSessionRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);\n const streamPromise = generateContentStream(this._apiKey, this.model, generateContentRequest, chatSessionRequestOptions);\n // Add onto the chain.\n this._sendPromise = this._sendPromise\n .then(() => streamPromise)\n // This must be handled to avoid unhandled rejection, but jump\n // to the final catch block with a label to not log this error.\n .catch((_ignored) => {\n throw new Error(SILENT_ERROR);\n })\n .then((streamResult) => streamResult.response)\n .then((response) => {\n if (isValidResponse(response)) {\n this._history.push(newContent);\n const responseContent = Object.assign({}, response.candidates[0].content);\n // Response seems to come back without a role set.\n if (!responseContent.role) {\n responseContent.role = \"model\";\n }\n this._history.push(responseContent);\n }\n else {\n const blockErrorMessage = formatBlockErrorMessage(response);\n if (blockErrorMessage) {\n console.warn(`sendMessageStream() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`);\n }\n }\n })\n .catch((e) => {\n // Errors in streamPromise are already catchable by the user as\n // streamPromise is returned.\n // Avoid duplicating the error message in logs.\n if (e.message !== SILENT_ERROR) {\n // Users do not have access to _sendPromise to catch errors\n // downstream from streamPromise, so they should not throw.\n console.error(e);\n }\n });\n return streamPromise;\n }\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nasync function countTokens(apiKey, model, params, singleRequestOptions) {\n const response = await makeModelRequest(model, Task.COUNT_TOKENS, apiKey, false, JSON.stringify(params), singleRequestOptions);\n return response.json();\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nasync function embedContent(apiKey, model, params, requestOptions) {\n const response = await makeModelRequest(model, Task.EMBED_CONTENT, apiKey, false, JSON.stringify(params), requestOptions);\n return response.json();\n}\nasync function batchEmbedContents(apiKey, model, params, requestOptions) {\n const requestsWithModel = params.requests.map((request) => {\n return Object.assign(Object.assign({}, request), { model });\n });\n const response = await makeModelRequest(model, Task.BATCH_EMBED_CONTENTS, apiKey, false, JSON.stringify({ requests: requestsWithModel }), requestOptions);\n return response.json();\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class for generative model APIs.\n * @public\n */\nclass GenerativeModel {\n constructor(apiKey, modelParams, _requestOptions = {}) {\n this.apiKey = apiKey;\n this._requestOptions = _requestOptions;\n if (modelParams.model.includes(\"/\")) {\n // Models may be named \"models/model-name\" or \"tunedModels/model-name\"\n this.model = modelParams.model;\n }\n else {\n // If path is not included, assume it's a non-tuned model.\n this.model = `models/${modelParams.model}`;\n }\n this.generationConfig = modelParams.generationConfig || {};\n this.safetySettings = modelParams.safetySettings || [];\n this.tools = modelParams.tools;\n this.toolConfig = modelParams.toolConfig;\n this.systemInstruction = formatSystemInstruction(modelParams.systemInstruction);\n this.cachedContent = modelParams.cachedContent;\n }\n /**\n * Makes a single non-streaming call to the model\n * and returns an object containing a single {@link GenerateContentResponse}.\n *\n * Fields set in the optional {@link SingleRequestOptions} parameter will\n * take precedence over the {@link RequestOptions} values provided to\n * {@link GoogleGenerativeAI.getGenerativeModel }.\n */\n async generateContent(request, requestOptions = {}) {\n var _a;\n const formattedParams = formatGenerateContentInput(request);\n const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);\n return generateContent(this.apiKey, this.model, Object.assign({ generationConfig: this.generationConfig, safetySettings: this.safetySettings, tools: this.tools, toolConfig: this.toolConfig, systemInstruction: this.systemInstruction, cachedContent: (_a = this.cachedContent) === null || _a === void 0 ? void 0 : _a.name }, formattedParams), generativeModelRequestOptions);\n }\n /**\n * Makes a single streaming call to the model and returns an object\n * containing an iterable stream that iterates over all chunks in the\n * streaming response as well as a promise that returns the final\n * aggregated response.\n *\n * Fields set in the optional {@link SingleRequestOptions} parameter will\n * take precedence over the {@link RequestOptions} values provided to\n * {@link GoogleGenerativeAI.getGenerativeModel }.\n */\n async generateContentStream(request, requestOptions = {}) {\n var _a;\n const formattedParams = formatGenerateContentInput(request);\n const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);\n return generateContentStream(this.apiKey, this.model, Object.assign({ generationConfig: this.generationConfig, safetySettings: this.safetySettings, tools: this.tools, toolConfig: this.toolConfig, systemInstruction: this.systemInstruction, cachedContent: (_a = this.cachedContent) === null || _a === void 0 ? void 0 : _a.name }, formattedParams), generativeModelRequestOptions);\n }\n /**\n * Gets a new {@link ChatSession} instance which can be used for\n * multi-turn chats.\n */\n startChat(startChatParams) {\n var _a;\n return new ChatSession(this.apiKey, this.model, Object.assign({ generationConfig: this.generationConfig, safetySettings: this.safetySettings, tools: this.tools, toolConfig: this.toolConfig, systemInstruction: this.systemInstruction, cachedContent: (_a = this.cachedContent) === null || _a === void 0 ? void 0 : _a.name }, startChatParams), this._requestOptions);\n }\n /**\n * Counts the tokens in the provided request.\n *\n * Fields set in the optional {@link SingleRequestOptions} parameter will\n * take precedence over the {@link RequestOptions} values provided to\n * {@link GoogleGenerativeAI.getGenerativeModel }.\n */\n async countTokens(request, requestOptions = {}) {\n const formattedParams = formatCountTokensInput(request, {\n model: this.model,\n generationConfig: this.generationConfig,\n safetySettings: this.safetySettings,\n tools: this.tools,\n toolConfig: this.toolConfig,\n systemInstruction: this.systemInstruction,\n cachedContent: this.cachedContent,\n });\n const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);\n return countTokens(this.apiKey, this.model, formattedParams, generativeModelRequestOptions);\n }\n /**\n * Embeds the provided content.\n *\n * Fields set in the optional {@link SingleRequestOptions} parameter will\n * take precedence over the {@link RequestOptions} values provided to\n * {@link GoogleGenerativeAI.getGenerativeModel }.\n */\n async embedContent(request, requestOptions = {}) {\n const formattedParams = formatEmbedContentInput(request);\n const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);\n return embedContent(this.apiKey, this.model, formattedParams, generativeModelRequestOptions);\n }\n /**\n * Embeds an array of {@link EmbedContentRequest}s.\n *\n * Fields set in the optional {@link SingleRequestOptions} parameter will\n * take precedence over the {@link RequestOptions} values provided to\n * {@link GoogleGenerativeAI.getGenerativeModel }.\n */\n async batchEmbedContents(batchEmbedContentRequest, requestOptions = {}) {\n const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);\n return batchEmbedContents(this.apiKey, this.model, batchEmbedContentRequest, generativeModelRequestOptions);\n }\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Top-level class for this SDK\n * @public\n */\nclass GoogleGenerativeAI {\n constructor(apiKey) {\n this.apiKey = apiKey;\n }\n /**\n * Gets a {@link GenerativeModel} instance for the provided model name.\n */\n getGenerativeModel(modelParams, requestOptions) {\n if (!modelParams.model) {\n throw new GoogleGenerativeAIError(`Must provide a model name. ` +\n `Example: genai.getGenerativeModel({ model: 'my-model-name' })`);\n }\n return new GenerativeModel(this.apiKey, modelParams, requestOptions);\n }\n /**\n * Creates a {@link GenerativeModel} instance from provided content cache.\n */\n getGenerativeModelFromCachedContent(cachedContent, modelParams, requestOptions) {\n if (!cachedContent.name) {\n throw new GoogleGenerativeAIRequestInputError(\"Cached content must contain a `name` field.\");\n }\n if (!cachedContent.model) {\n throw new GoogleGenerativeAIRequestInputError(\"Cached content must contain a `model` field.\");\n }\n /**\n * Not checking tools and toolConfig for now as it would require a deep\n * equality comparison and isn't likely to be a common case.\n */\n const disallowedDuplicates = [\"model\", \"systemInstruction\"];\n for (const key of disallowedDuplicates) {\n if ((modelParams === null || modelParams === void 0 ? void 0 : modelParams[key]) &&\n cachedContent[key] &&\n (modelParams === null || modelParams === void 0 ? void 0 : modelParams[key]) !== cachedContent[key]) {\n if (key === \"model\") {\n const modelParamsComp = modelParams.model.startsWith(\"models/\")\n ? modelParams.model.replace(\"models/\", \"\")\n : modelParams.model;\n const cachedContentComp = cachedContent.model.startsWith(\"models/\")\n ? cachedContent.model.replace(\"models/\", \"\")\n : cachedContent.model;\n if (modelParamsComp === cachedContentComp) {\n continue;\n }\n }\n throw new GoogleGenerativeAIRequestInputError(`Different value for \"${key}\" specified in modelParams` +\n ` (${modelParams[key]}) and cachedContent (${cachedContent[key]})`);\n }\n }\n const modelParamsFromCache = Object.assign(Object.assign({}, modelParams), { model: cachedContent.model, tools: cachedContent.tools, toolConfig: cachedContent.toolConfig, systemInstruction: cachedContent.systemInstruction, cachedContent });\n return new GenerativeModel(this.apiKey, modelParamsFromCache, requestOptions);\n }\n}\n\nexports.ChatSession = ChatSession;\nexports.GenerativeModel = GenerativeModel;\nexports.GoogleGenerativeAI = GoogleGenerativeAI;\nexports.GoogleGenerativeAIAbortError = GoogleGenerativeAIAbortError;\nexports.GoogleGenerativeAIError = GoogleGenerativeAIError;\nexports.GoogleGenerativeAIFetchError = GoogleGenerativeAIFetchError;\nexports.GoogleGenerativeAIRequestInputError = GoogleGenerativeAIRequestInputError;\nexports.GoogleGenerativeAIResponseError = GoogleGenerativeAIResponseError;\nexports.POSSIBLE_ROLES = POSSIBLE_ROLES;\n//# sourceMappingURL=index.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFjdGlvbi1icm93c2VyKS8uL25vZGVfbW9kdWxlcy9AZ29vZ2xlL2dlbmVyYXRpdmUtYWkvZGlzdC9pbmRleC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyx5QkFBeUIsa0JBQWtCLEtBQUs7O0FBRWpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBLENBQUMscUNBQXFDLDhCQUE4QixLQUFLO0FBQ3pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxzQkFBc0IsZUFBZSxLQUFLOztBQUUzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsMkJBQTJCLG9CQUFvQixLQUFLO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLGlDQUFpQywwQkFBMEIsS0FBSztBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGNBQWM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsY0FBYztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixhQUFhO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEdBQTBHLFNBQVM7QUFDbkg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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REFBbUQ7QUFDbkQ7QUFDQSw0RUFBNEU7QUFDNUU7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLDBCQUEwQjtBQUNyRDtBQUNBLG1DQUFtQyw0QkFBNEI7QUFDL0QsaUNBQWlDLHNCQUFzQjtBQUN2RCxRQUFRLDZDQUE2QztBQUNyRDtBQUNBLDBFQUEwRTtBQUMxRSw0RUFBNEU7QUFDNUU7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSx1QkFBdUI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQsd0JBQXdCO0FBQzdFO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLHVCQUF1QjtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNGQUFzRixJQUFJO0FBQzFGLHlCQUF5QixpQkFBaUIsdUJBQXVCLG1CQUFtQjtBQUNwRjtBQUNBO0FBQ0EsbUVBQW1FLGtCQUFrQixpS0FBaUs7QUFDdFA7QUFDQTtBQUNBOztBQUVBLG1CQUFtQjtBQUNuQix1QkFBdUI7QUFDdkIsMEJBQTBCO0FBQzFCLG9DQUFvQztBQUNwQywrQkFBK0I7QUFDL0Isb0NBQW9DO0FBQ3BDLDJDQUEyQztBQUMzQyx1Q0FBdUM7QUFDdkMsc0JBQXNCO0FBQ3RCIiwic291cmNlcyI6WyIvaG9tZS91c2VyL3N0dWRpby9ub2RlX21vZHVsZXMvQGdvb2dsZS9nZW5lcmF0aXZlLWFpL2Rpc3QvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIENvbnRhaW5zIHRoZSBsaXN0IG9mIE9wZW5BUEkgZGF0YSB0eXBlc1xuICogYXMgZGVmaW5lZCBieSBodHRwczovL3N3YWdnZXIuaW8vZG9jcy9zcGVjaWZpY2F0aW9uL2RhdGEtbW9kZWxzL2RhdGEtdHlwZXMvXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydHMuU2NoZW1hVHlwZSA9IHZvaWQgMDtcbihmdW5jdGlvbiAoU2NoZW1hVHlwZSkge1xuICAgIC8qKiBTdHJpbmcgdHlwZS4gKi9cbiAgICBTY2hlbWFUeXBlW1wiU1RSSU5HXCJdID0gXCJzdHJpbmdcIjtcbiAgICAvKiogTnVtYmVyIHR5cGUuICovXG4gICAgU2NoZW1hVHlwZVtcIk5VTUJFUlwiXSA9IFwibnVtYmVyXCI7XG4gICAgLyoqIEludGVnZXIgdHlwZS4gKi9cbiAgICBTY2hlbWFUeXBlW1wiSU5URUdFUlwiXSA9IFwiaW50ZWdlclwiO1xuICAgIC8qKiBCb29sZWFuIHR5cGUuICovXG4gICAgU2NoZW1hVHlwZVtcIkJPT0xFQU5cIl0gPSBcImJvb2xlYW5cIjtcbiAgICAvKiogQXJyYXkgdHlwZS4gKi9cbiAgICBTY2hlbWFUeXBlW1wiQVJSQVlcIl0gPSBcImFycmF5XCI7XG4gICAgLyoqIE9iamVjdCB0eXBlLiAqL1xuICAgIFNjaGVtYVR5cGVbXCJPQkpFQ1RcIl0gPSBcIm9iamVjdFwiO1xufSkoZXhwb3J0cy5TY2hlbWFUeXBlIHx8IChleHBvcnRzLlNjaGVtYVR5cGUgPSB7fSkpO1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydHMuRXhlY3V0YWJsZUNvZGVMYW5ndWFnZSA9IHZvaWQgMDtcbihmdW5jdGlvbiAoRXhlY3V0YWJsZUNvZGVMYW5ndWFnZSkge1xuICAgIEV4ZWN1dGFibGVDb2RlTGFuZ3VhZ2VbXCJMQU5HVUFHRV9VTlNQRUNJRklFRFwiXSA9IFwibGFuZ3VhZ2VfdW5zcGVjaWZpZWRcIjtcbiAgICBFeGVjdXRhYmxlQ29kZUxhbmd1YWdlW1wiUFlUSE9OXCJdID0gXCJweXRob25cIjtcbn0pKGV4cG9ydHMuRXhlY3V0YWJsZUNvZGVMYW5ndWFnZSB8fCAoZXhwb3J0cy5FeGVjdXRhYmxlQ29kZUxhbmd1YWdlID0ge30pKTtcbi8qKlxuICogUG9zc2libGUgb3V0Y29tZXMgb2YgY29kZSBleGVjdXRpb24uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydHMuT3V0Y29tZSA9IHZvaWQgMDtcbihmdW5jdGlvbiAoT3V0Y29tZSkge1xuICAgIC8qKlxuICAgICAqIFVuc3BlY2lmaWVkIHN0YXR1cy4gVGhpcyB2YWx1ZSBzaG91bGQgbm90IGJlIHVzZWQuXG4gICAgICovXG4gICAgT3V0Y29tZVtcIk9VVENPTUVfVU5TUEVDSUZJRURcIl0gPSBcIm91dGNvbWVfdW5zcGVjaWZpZWRcIjtcbiAgICAvKipcbiAgICAgKiBDb2RlIGV4ZWN1dGlvbiBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LlxuICAgICAqL1xuICAgIE91dGNvbWVbXCJPVVRDT01FX09LXCJdID0gXCJvdXRjb21lX29rXCI7XG4gICAgLyoqXG4gICAgICogQ29kZSBleGVjdXRpb24gZmluaXNoZWQgYnV0IHdpdGggYSBmYWlsdXJlLiBgc3RkZXJyYCBzaG91bGQgY29udGFpbiB0aGVcbiAgICAgKiByZWFzb24uXG4gICAgICovXG4gICAgT3V0Y29tZVtcIk9VVENPTUVfRkFJTEVEXCJdID0gXCJvdXRjb21lX2ZhaWxlZFwiO1xuICAgIC8qKlxuICAgICAqIENvZGUgZXhlY3V0aW9uIHJhbiBmb3IgdG9vIGxvbmcsIGFuZCB3YXMgY2FuY2VsbGVkLiBUaGVyZSBtYXkgb3IgbWF5IG5vdFxuICAgICAqIGJlIGEgcGFydGlhbCBvdXRwdXQgcHJlc2VudC5cbiAgICAgKi9cbiAgICBPdXRjb21lW1wiT1VUQ09NRV9ERUFETElORV9FWENFRURFRFwiXSA9IFwib3V0Y29tZV9kZWFkbGluZV9leGNlZWRlZFwiO1xufSkoZXhwb3J0cy5PdXRjb21lIHx8IChleHBvcnRzLk91dGNvbWUgPSB7fSkpO1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBQb3NzaWJsZSByb2xlcy5cbiAqIEBwdWJsaWNcbiAqL1xuY29uc3QgUE9TU0lCTEVfUk9MRVMgPSBbXCJ1c2VyXCIsIFwibW9kZWxcIiwgXCJmdW5jdGlvblwiLCBcInN5c3RlbVwiXTtcbi8qKlxuICogSGFybSBjYXRlZ29yaWVzIHRoYXQgd291bGQgY2F1c2UgcHJvbXB0cyBvciBjYW5kaWRhdGVzIHRvIGJlIGJsb2NrZWQuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydHMuSGFybUNhdGVnb3J5ID0gdm9pZCAwO1xuKGZ1bmN0aW9uIChIYXJtQ2F0ZWdvcnkpIHtcbiAgICBIYXJtQ2F0ZWdvcnlbXCJIQVJNX0NBVEVHT1JZX1VOU1BFQ0lGSUVEXCJdID0gXCJIQVJNX0NBVEVHT1JZX1VOU1BFQ0lGSUVEXCI7XG4gICAgSGFybUNhdGVnb3J5W1wiSEFSTV9DQVRFR09SWV9IQVRFX1NQRUVDSFwiXSA9IFwiSEFSTV9DQVRFR09SWV9IQVRFX1NQRUVDSFwiO1xuICAgIEhhcm1DYXRlZ29yeVtcIkhBUk1fQ0FURUdPUllfU0VYVUFMTFlfRVhQTElDSVRcIl0gPSBcIkhBUk1fQ0FURUdPUllfU0VYVUFMTFlfRVhQTElDSVRcIjtcbiAgICBIYXJtQ2F0ZWdvcnlbXCJIQVJNX0NBVEVHT1JZX0hBUkFTU01FTlRcIl0gPSBcIkhBUk1fQ0FURUdPUllfSEFSQVNTTUVOVFwiO1xuICAgIEhhcm1DYXRlZ29yeVtcIkhBUk1fQ0FURUdPUllfREFOR0VST1VTX0NPTlRFTlRcIl0gPSBcIkhBUk1fQ0FURUdPUllfREFOR0VST1VTX0NPTlRFTlRcIjtcbiAgICBIYXJtQ2F0ZWdvcnlbXCJIQVJNX0NBVEVHT1JZX0NJVklDX0lOVEVHUklUWVwiXSA9IFwiSEFSTV9DQVRFR09SWV9DSVZJQ19JTlRFR1JJVFlcIjtcbn0pKGV4cG9ydHMuSGFybUNhdGVnb3J5IHx8IChleHBvcnRzLkhhcm1DYXRlZ29yeSA9IHt9KSk7XG4vKipcbiAqIFRocmVzaG9sZCBhYm92ZSB3aGljaCBhIHByb21wdCBvciBjYW5kaWRhdGUgd2lsbCBiZSBibG9ja2VkLlxuICogQHB1YmxpY1xuICovXG5leHBvcnRzLkhhcm1CbG9ja1RocmVzaG9sZCA9IHZvaWQgMDtcbihmdW5jdGlvbiAoSGFybUJsb2NrVGhyZXNob2xkKSB7XG4gICAgLyoqIFRocmVzaG9sZCBpcyB1bnNwZWNpZmllZC4gKi9cbiAgICBIYXJtQmxvY2tUaHJlc2hvbGRbXCJIQVJNX0JMT0NLX1RIUkVTSE9MRF9VTlNQRUNJRklFRFwiXSA9IFwiSEFSTV9CTE9DS19USFJFU0hPTERfVU5TUEVDSUZJRURcIjtcbiAgICAvKiogQ29udGVudCB3aXRoIE5FR0xJR0lCTEUgd2lsbCBiZSBhbGxvd2VkLiAqL1xuICAgIEhhcm1CbG9ja1RocmVzaG9sZFtcIkJMT0NLX0xPV19BTkRfQUJPVkVcIl0gPSBcIkJMT0NLX0xPV19BTkRfQUJPVkVcIjtcbiAgICAvKiogQ29udGVudCB3aXRoIE5FR0xJR0lCTEUgYW5kIExPVyB3aWxsIGJlIGFsbG93ZWQuICovXG4gICAgSGFybUJsb2NrVGhyZXNob2xkW1wiQkxPQ0tfTUVESVVNX0FORF9BQk9WRVwiXSA9IFwiQkxPQ0tfTUVESVVNX0FORF9BQk9WRVwiO1xuICAgIC8qKiBDb250ZW50IHdpdGggTkVHTElHSUJMRSwgTE9XLCBhbmQgTUVESVVNIHdpbGwgYmUgYWxsb3dlZC4gKi9cbiAgICBIYXJtQmxvY2tUaHJlc2hvbGRbXCJCTE9DS19PTkxZX0hJR0hcIl0gPSBcIkJMT0NLX09OTFlfSElHSFwiO1xuICAgIC8qKiBBbGwgY29udGVudCB3aWxsIGJlIGFsbG93ZWQuICovXG4gICAgSGFybUJsb2NrVGhyZXNob2xkW1wiQkxPQ0tfTk9ORVwiXSA9IFwiQkxPQ0tfTk9ORVwiO1xufSkoZXhwb3J0cy5IYXJtQmxvY2tUaHJlc2hvbGQgfHwgKGV4cG9ydHMuSGFybUJsb2NrVGhyZXNob2xkID0ge30pKTtcbi8qKlxuICogUHJvYmFiaWxpdHkgdGhhdCBhIHByb21wdCBvciBjYW5kaWRhdGUgbWF0Y2hlcyBhIGhhcm0gY2F0ZWdvcnkuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydHMuSGFybVByb2JhYmlsaXR5ID0gdm9pZCAwO1xuKGZ1bmN0aW9uIChIYXJtUHJvYmFiaWxpdHkpIHtcbiAgICAvKiogUHJvYmFiaWxpdHkgaXMgdW5zcGVjaWZpZWQuICovXG4gICAgSGFybVByb2JhYmlsaXR5W1wiSEFSTV9QUk9CQUJJTElUWV9VTlNQRUNJRklFRFwiXSA9IFwiSEFSTV9QUk9CQUJJTElUWV9VTlNQRUNJRklFRFwiO1xuICAgIC8qKiBDb250ZW50IGhhcyBhIG5lZ2xpZ2libGUgY2hhbmNlIG9mIGJlaW5nIHVuc2FmZS4gKi9cbiAgICBIYXJtUHJvYmFiaWxpdHlbXCJORUdMSUdJQkxFXCJdID0gXCJORUdMSUdJQkxFXCI7XG4gICAgLyoqIENvbnRlbnQgaGFzIGEgbG93IGNoYW5jZSBvZiBiZWluZyB1bnNhZmUuICovXG4gICAgSGFybVByb2JhYmlsaXR5W1wiTE9XXCJdID0gXCJMT1dcIjtcbiAgICAvKiogQ29udGVudCBoYXMgYSBtZWRpdW0gY2hhbmNlIG9mIGJlaW5nIHVuc2FmZS4gKi9cbiAgICBIYXJtUHJvYmFiaWxpdHlbXCJNRURJVU1cIl0gPSBcIk1FRElVTVwiO1xuICAgIC8qKiBDb250ZW50IGhhcyBhIGhpZ2ggY2hhbmNlIG9mIGJlaW5nIHVuc2FmZS4gKi9cbiAgICBIYXJtUHJvYmFiaWxpdHlbXCJISUdIXCJdID0gXCJISUdIXCI7XG59KShleHBvcnRzLkhhcm1Qcm9iYWJpbGl0eSB8fCAoZXhwb3J0cy5IYXJtUHJvYmFiaWxpdHkgPSB7fSkpO1xuLyoqXG4gKiBSZWFzb24gdGhhdCBhIHByb21wdCB3YXMgYmxvY2tlZC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0cy5CbG9ja1JlYXNvbiA9IHZvaWQgMDtcbihmdW5jdGlvbiAoQmxvY2tSZWFzb24pIHtcbiAgICAvLyBBIGJsb2NrZWQgcmVhc29uIHdhcyBub3Qgc3BlY2lmaWVkLlxuICAgIEJsb2NrUmVhc29uW1wiQkxPQ0tFRF9SRUFTT05fVU5TUEVDSUZJRURcIl0gPSBcIkJMT0NLRURfUkVBU09OX1VOU1BFQ0lGSUVEXCI7XG4gICAgLy8gQ29udGVudCB3YXMgYmxvY2tlZCBieSBzYWZldHkgc2V0dGluZ3MuXG4gICAgQmxvY2tSZWFzb25bXCJTQUZFVFlcIl0gPSBcIlNBRkVUWVwiO1xuICAgIC8vIENvbnRlbnQgd2FzIGJsb2NrZWQsIGJ1dCB0aGUgcmVhc29uIGlzIHVuY2F0ZWdvcml6ZWQuXG4gICAgQmxvY2tSZWFzb25bXCJPVEhFUlwiXSA9IFwiT1RIRVJcIjtcbn0pKGV4cG9ydHMuQmxvY2tSZWFzb24gfHwgKGV4cG9ydHMuQmxvY2tSZWFzb24gPSB7fSkpO1xuLyoqXG4gKiBSZWFzb24gdGhhdCBhIGNhbmRpZGF0ZSBmaW5pc2hlZC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0cy5GaW5pc2hSZWFzb24gPSB2b2lkIDA7XG4oZnVuY3Rpb24gKEZpbmlzaFJlYXNvbikge1xuICAgIC8vIERlZmF1bHQgdmFsdWUuIFRoaXMgdmFsdWUgaXMgdW51c2VkLlxuICAgIEZpbmlzaFJlYXNvbltcIkZJTklTSF9SRUFTT05fVU5TUEVDSUZJRURcIl0gPSBcIkZJTklTSF9SRUFTT05fVU5TUEVDSUZJRURcIjtcbiAgICAvLyBOYXR1cmFsIHN0b3AgcG9pbnQgb2YgdGhlIG1vZGVsIG9yIHByb3ZpZGVkIHN0b3Agc2VxdWVuY2UuXG4gICAgRmluaXNoUmVhc29uW1wiU1RPUFwiXSA9IFwiU1RPUFwiO1xuICAgIC8vIFRoZSBtYXhpbXVtIG51bWJlciBvZiB0b2tlbnMgYXMgc3BlY2lmaWVkIGluIHRoZSByZXF1ZXN0IHdhcyByZWFjaGVkLlxuICAgIEZpbmlzaFJlYXNvbltcIk1BWF9UT0tFTlNcIl0gPSBcIk1BWF9UT0tFTlNcIjtcbiAgICAvLyBUaGUgY2FuZGlkYXRlIGNvbnRlbnQgd2FzIGZsYWdnZWQgZm9yIHNhZmV0eSByZWFzb25zLlxuICAgIEZpbmlzaFJlYXNvbltcIlNBRkVUWVwiXSA9IFwiU0FGRVRZXCI7XG4gICAgLy8gVGhlIGNhbmRpZGF0ZSBjb250ZW50IHdhcyBmbGFnZ2VkIGZvciByZWNpdGF0aW9uIHJlYXNvbnMuXG4gICAgRmluaXNoUmVhc29uW1wiUkVDSVRBVElPTlwiXSA9IFwiUkVDSVRBVElPTlwiO1xuICAgIC8vIFRoZSBjYW5kaWRhdGUgY29udGVudCB3YXMgZmxhZ2dlZCBmb3IgdXNpbmcgYW4gdW5zdXBwb3J0ZWQgbGFuZ3VhZ2UuXG4gICAgRmluaXNoUmVhc29uW1wiTEFOR1VBR0VcIl0gPSBcIkxBTkdVQUdFXCI7XG4gICAgLy8gVG9rZW4gZ2VuZXJhdGlvbiBzdG9wcGVkIGJlY2F1c2UgdGhlIGNvbnRlbnQgY29udGFpbnMgZm9yYmlkZGVuIHRlcm1zLlxuICAgIEZpbmlzaFJlYXNvbltcIkJMT0NLTElTVFwiXSA9IFwiQkxPQ0tMSVNUXCI7XG4gICAgLy8gVG9rZW4gZ2VuZXJhdGlvbiBzdG9wcGVkIGZvciBwb3RlbnRpYWxseSBjb250YWluaW5nIHByb2hpYml0ZWQgY29udGVudC5cbiAgICBGaW5pc2hSZWFzb25bXCJQUk9ISUJJVEVEX0NPTlRFTlRcIl0gPSBcIlBST0hJQklURURfQ09OVEVOVFwiO1xuICAgIC8vIFRva2VuIGdlbmVyYXRpb24gc3RvcHBlZCBiZWNhdXNlIHRoZSBjb250ZW50IHBvdGVudGlhbGx5IGNvbnRhaW5zIFNlbnNpdGl2ZSBQZXJzb25hbGx5IElkZW50aWZpYWJsZSBJbmZvcm1hdGlvbiAoU1BJSSkuXG4gICAgRmluaXNoUmVhc29uW1wiU1BJSVwiXSA9IFwiU1BJSVwiO1xuICAgIC8vIFRoZSBmdW5jdGlvbiBjYWxsIGdlbmVyYXRlZCBieSB0aGUgbW9kZWwgaXMgaW52YWxpZC5cbiAgICBGaW5pc2hSZWFzb25bXCJNQUxGT1JNRURfRlVOQ1RJT05fQ0FMTFwiXSA9IFwiTUFMRk9STUVEX0ZVTkNUSU9OX0NBTExcIjtcbiAgICAvLyBVbmtub3duIHJlYXNvbi5cbiAgICBGaW5pc2hSZWFzb25bXCJPVEhFUlwiXSA9IFwiT1RIRVJcIjtcbn0pKGV4cG9ydHMuRmluaXNoUmVhc29uIHx8IChleHBvcnRzLkZpbmlzaFJlYXNvbiA9IHt9KSk7XG4vKipcbiAqIFRhc2sgdHlwZSBmb3IgZW1iZWRkaW5nIGNvbnRlbnQuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydHMuVGFza1R5cGUgPSB2b2lkIDA7XG4oZnVuY3Rpb24gKFRhc2tUeXBlKSB7XG4gICAgVGFza1R5cGVbXCJUQVNLX1RZUEVfVU5TUEVDSUZJRURcIl0gPSBcIlRBU0tfVFlQRV9VTlNQRUNJRklFRFwiO1xuICAgIFRhc2tUeXBlW1wiUkVUUklFVkFMX1FVRVJZXCJdID0gXCJSRVRSSUVWQUxfUVVFUllcIjtcbiAgICBUYXNrVHlwZVtcIlJFVFJJRVZBTF9ET0NVTUVOVFwiXSA9IFwiUkVUUklFVkFMX0RPQ1VNRU5UXCI7XG4gICAgVGFza1R5cGVbXCJTRU1BTlRJQ19TSU1JTEFSSVRZXCJdID0gXCJTRU1BTlRJQ19TSU1JTEFSSVRZXCI7XG4gICAgVGFza1R5cGVbXCJDTEFTU0lGSUNBVElPTlwiXSA9IFwiQ0xBU1NJRklDQVRJT05cIjtcbiAgICBUYXNrVHlwZVtcIkNMVVNURVJJTkdcIl0gPSBcIkNMVVNURVJJTkdcIjtcbn0pKGV4cG9ydHMuVGFza1R5cGUgfHwgKGV4cG9ydHMuVGFza1R5cGUgPSB7fSkpO1xuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydHMuRnVuY3Rpb25DYWxsaW5nTW9kZSA9IHZvaWQgMDtcbihmdW5jdGlvbiAoRnVuY3Rpb25DYWxsaW5nTW9kZSkge1xuICAgIC8vIFVuc3BlY2lmaWVkIGZ1bmN0aW9uIGNhbGxpbmcgbW9kZS4gVGhpcyB2YWx1ZSBzaG91bGQgbm90IGJlIHVzZWQuXG4gICAgRnVuY3Rpb25DYWxsaW5nTW9kZVtcIk1PREVfVU5TUEVDSUZJRURcIl0gPSBcIk1PREVfVU5TUEVDSUZJRURcIjtcbiAgICAvLyBEZWZhdWx0IG1vZGVsIGJlaGF2aW9yLCBtb2RlbCBkZWNpZGVzIHRvIHByZWRpY3QgZWl0aGVyIGEgZnVuY3Rpb24gY2FsbFxuICAgIC8vIG9yIGEgbmF0dXJhbCBsYW5ndWFnZSByZXBzcG9zZS5cbiAgICBGdW5jdGlvbkNhbGxpbmdNb2RlW1wiQVVUT1wiXSA9IFwiQVVUT1wiO1xuICAgIC8vIE1vZGVsIGlzIGNvbnN0cmFpbmVkIHRvIGFsd2F5cyBwcmVkaWN0aW5nIGEgZnVuY3Rpb24gY2FsbCBvbmx5LlxuICAgIC8vIElmIFwiYWxsb3dlZF9mdW5jdGlvbl9uYW1lc1wiIGFyZSBzZXQsIHRoZSBwcmVkaWN0ZWQgZnVuY3Rpb24gY2FsbCB3aWxsIGJlXG4gICAgLy8gbGltaXRlZCB0byBhbnkgb25lIG9mIFwiYWxsb3dlZF9mdW5jdGlvbl9uYW1lc1wiLCBlbHNlIHRoZSBwcmVkaWN0ZWRcbiAgICAvLyBmdW5jdGlvbiBjYWxsIHdpbGwgYmUgYW55IG9uZSBvZiB0aGUgcHJvdmlkZWQgXCJmdW5jdGlvbl9kZWNsYXJhdGlvbnNcIi5cbiAgICBGdW5jdGlvbkNhbGxpbmdNb2RlW1wiQU5ZXCJdID0gXCJBTllcIjtcbiAgICAvLyBNb2RlbCB3aWxsIG5vdCBwcmVkaWN0IGFueSBmdW5jdGlvbiBjYWxsLiBNb2RlbCBiZWhhdmlvciBpcyBzYW1lIGFzIHdoZW5cbiAgICAvLyBub3QgcGFzc2luZyBhbnkgZnVuY3Rpb24gZGVjbGFyYXRpb25zLlxuICAgIEZ1bmN0aW9uQ2FsbGluZ01vZGVbXCJOT05FXCJdID0gXCJOT05FXCI7XG59KShleHBvcnRzLkZ1bmN0aW9uQ2FsbGluZ01vZGUgfHwgKGV4cG9ydHMuRnVuY3Rpb25DYWxsaW5nTW9kZSA9IHt9KSk7XG4vKipcbiAqIFRoZSBtb2RlIG9mIHRoZSBwcmVkaWN0b3IgdG8gYmUgdXNlZCBpbiBkeW5hbWljIHJldHJpZXZhbC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0cy5EeW5hbWljUmV0cmlldmFsTW9kZSA9IHZvaWQgMDtcbihmdW5jdGlvbiAoRHluYW1pY1JldHJpZXZhbE1vZGUpIHtcbiAgICAvLyBVbnNwZWNpZmllZCBmdW5jdGlvbiBjYWxsaW5nIG1vZGUuIFRoaXMgdmFsdWUgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICAgIER5bmFtaWNSZXRyaWV2YWxNb2RlW1wiTU9ERV9VTlNQRUNJRklFRFwiXSA9IFwiTU9ERV9VTlNQRUNJRklFRFwiO1xuICAgIC8vIFJ1biByZXRyaWV2YWwgb25seSB3aGVuIHN5c3RlbSBkZWNpZGVzIGl0IGlzIG5lY2Vzc2FyeS5cbiAgICBEeW5hbWljUmV0cmlldmFsTW9kZVtcIk1PREVfRFlOQU1JQ1wiXSA9IFwiTU9ERV9EWU5BTUlDXCI7XG59KShleHBvcnRzLkR5bmFtaWNSZXRyaWV2YWxNb2RlIHx8IChleHBvcnRzLkR5bmFtaWNSZXRyaWV2YWxNb2RlID0ge30pKTtcblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbi8qKlxuICogQmFzaWMgZXJyb3IgdHlwZSBmb3IgdGhpcyBTREsuXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIEdvb2dsZUdlbmVyYXRpdmVBSUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UpIHtcbiAgICAgICAgc3VwZXIoYFtHb29nbGVHZW5lcmF0aXZlQUkgRXJyb3JdOiAke21lc3NhZ2V9YCk7XG4gICAgfVxufVxuLyoqXG4gKiBFcnJvcnMgaW4gdGhlIGNvbnRlbnRzIG9mIGEgcmVzcG9uc2UgZnJvbSB0aGUgbW9kZWwuIFRoaXMgaW5jbHVkZXMgcGFyc2luZ1xuICogZXJyb3JzLCBvciByZXNwb25zZXMgaW5jbHVkaW5nIGEgc2FmZXR5IGJsb2NrIHJlYXNvbi5cbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgR29vZ2xlR2VuZXJhdGl2ZUFJUmVzcG9uc2VFcnJvciBleHRlbmRzIEdvb2dsZUdlbmVyYXRpdmVBSUVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlLCByZXNwb25zZSkge1xuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICAgIH1cbn1cbi8qKlxuICogRXJyb3IgY2xhc3MgY292ZXJpbmcgSFRUUCBlcnJvcnMgd2hlbiBjYWxsaW5nIHRoZSBzZXJ2ZXIuIEluY2x1ZGVzIEhUVFBcbiAqIHN0YXR1cywgc3RhdHVzVGV4dCwgYW5kIG9wdGlvbmFsIGRldGFpbHMsIGlmIHByb3ZpZGVkIGluIHRoZSBzZXJ2ZXIgcmVzcG9uc2UuXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIEdvb2dsZUdlbmVyYXRpdmVBSUZldGNoRXJyb3IgZXh0ZW5kcyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvciB7XG4gICAgY29uc3RydWN0b3IobWVzc2FnZSwgc3RhdHVzLCBzdGF0dXNUZXh0LCBlcnJvckRldGFpbHMpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSBzdGF0dXNUZXh0O1xuICAgICAgICB0aGlzLmVycm9yRGV0YWlscyA9IGVycm9yRGV0YWlscztcbiAgICB9XG59XG4vKipcbiAqIEVycm9ycyBpbiB0aGUgY29udGVudHMgb2YgYSByZXF1ZXN0IG9yaWdpbmF0aW5nIGZyb20gdXNlciBpbnB1dC5cbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3IgZXh0ZW5kcyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvciB7XG59XG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGEgcmVxdWVzdCBpcyBhYm9ydGVkLCBlaXRoZXIgZHVlIHRvIGEgdGltZW91dCBvclxuICogaW50ZW50aW9uYWwgY2FuY2VsbGF0aW9uIGJ5IHRoZSB1c2VyLlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBHb29nbGVHZW5lcmF0aXZlQUlBYm9ydEVycm9yIGV4dGVuZHMgR29vZ2xlR2VuZXJhdGl2ZUFJRXJyb3Ige1xufVxuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuY29uc3QgREVGQVVMVF9CQVNFX1VSTCA9IFwiaHR0cHM6Ly9nZW5lcmF0aXZlbGFuZ3VhZ2UuZ29vZ2xlYXBpcy5jb21cIjtcbmNvbnN0IERFRkFVTFRfQVBJX1ZFUlNJT04gPSBcInYxYmV0YVwiO1xuLyoqXG4gKiBXZSBjYW4ndCBgcmVxdWlyZWAgcGFja2FnZS5qc29uIGlmIHRoaXMgcnVucyBvbiB3ZWIuIFdlIHdpbGwgdXNlIHJvbGx1cCB0b1xuICogc3dhcCBpbiB0aGUgdmVyc2lvbiBudW1iZXIgaGVyZSBhdCBidWlsZCB0aW1lLlxuICovXG5jb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuMjQuMFwiO1xuY29uc3QgUEFDS0FHRV9MT0dfSEVBREVSID0gXCJnZW5haS1qc1wiO1xudmFyIFRhc2s7XG4oZnVuY3Rpb24gKFRhc2spIHtcbiAgICBUYXNrW1wiR0VORVJBVEVfQ09OVEVOVFwiXSA9IFwiZ2VuZXJhdGVDb250ZW50XCI7XG4gICAgVGFza1tcIlNUUkVBTV9HRU5FUkFURV9DT05URU5UXCJdID0gXCJzdHJlYW1HZW5lcmF0ZUNvbnRlbnRcIjtcbiAgICBUYXNrW1wiQ09VTlRfVE9LRU5TXCJdID0gXCJjb3VudFRva2Vuc1wiO1xuICAgIFRhc2tbXCJFTUJFRF9DT05URU5UXCJdID0gXCJlbWJlZENvbnRlbnRcIjtcbiAgICBUYXNrW1wiQkFUQ0hfRU1CRURfQ09OVEVOVFNcIl0gPSBcImJhdGNoRW1iZWRDb250ZW50c1wiO1xufSkoVGFzayB8fCAoVGFzayA9IHt9KSk7XG5jbGFzcyBSZXF1ZXN0VXJsIHtcbiAgICBjb25zdHJ1Y3Rvcihtb2RlbCwgdGFzaywgYXBpS2V5LCBzdHJlYW0sIHJlcXVlc3RPcHRpb25zKSB7XG4gICAgICAgIHRoaXMubW9kZWwgPSBtb2RlbDtcbiAgICAgICAgdGhpcy50YXNrID0gdGFzaztcbiAgICAgICAgdGhpcy5hcGlLZXkgPSBhcGlLZXk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnJlcXVlc3RPcHRpb25zID0gcmVxdWVzdE9wdGlvbnM7XG4gICAgfVxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICBjb25zdCBhcGlWZXJzaW9uID0gKChfYSA9IHRoaXMucmVxdWVzdE9wdGlvbnMpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5hcGlWZXJzaW9uKSB8fCBERUZBVUxUX0FQSV9WRVJTSU9OO1xuICAgICAgICBjb25zdCBiYXNlVXJsID0gKChfYiA9IHRoaXMucmVxdWVzdE9wdGlvbnMpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5iYXNlVXJsKSB8fCBERUZBVUxUX0JBU0VfVVJMO1xuICAgICAgICBsZXQgdXJsID0gYCR7YmFzZVVybH0vJHthcGlWZXJzaW9ufS8ke3RoaXMubW9kZWx9OiR7dGhpcy50YXNrfWA7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbSkge1xuICAgICAgICAgICAgdXJsICs9IFwiP2FsdD1zc2VcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXJsO1xuICAgIH1cbn1cbi8qKlxuICogU2ltcGxlLCBidXQgbWF5IGJlY29tZSBtb3JlIGNvbXBsZXggaWYgd2UgYWRkIG1vcmUgdmVyc2lvbnMgdG8gbG9nLlxuICovXG5mdW5jdGlvbiBnZXRDbGllbnRIZWFkZXJzKHJlcXVlc3RPcHRpb25zKSB7XG4gICAgY29uc3QgY2xpZW50SGVhZGVycyA9IFtdO1xuICAgIGlmIChyZXF1ZXN0T3B0aW9ucyA9PT0gbnVsbCB8fCByZXF1ZXN0T3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcmVxdWVzdE9wdGlvbnMuYXBpQ2xpZW50KSB7XG4gICAgICAgIGNsaWVudEhlYWRlcnMucHVzaChyZXF1ZXN0T3B0aW9ucy5hcGlDbGllbnQpO1xuICAgIH1cbiAgICBjbGllbnRIZWFkZXJzLnB1c2goYCR7UEFDS0FHRV9MT0dfSEVBREVSfS8ke1BBQ0tBR0VfVkVSU0lPTn1gKTtcbiAgICByZXR1cm4gY2xpZW50SGVhZGVycy5qb2luKFwiIFwiKTtcbn1cbmFzeW5jIGZ1bmN0aW9uIGdldEhlYWRlcnModXJsKSB7XG4gICAgdmFyIF9hO1xuICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICAgIGhlYWRlcnMuYXBwZW5kKFwiQ29udGVudC1UeXBlXCIsIFwiYXBwbGljYXRpb24vanNvblwiKTtcbiAgICBoZWFkZXJzLmFwcGVuZChcIngtZ29vZy1hcGktY2xpZW50XCIsIGdldENsaWVudEhlYWRlcnModXJsLnJlcXVlc3RPcHRpb25zKSk7XG4gICAgaGVhZGVycy5hcHBlbmQoXCJ4LWdvb2ctYXBpLWtleVwiLCB1cmwuYXBpS2V5KTtcbiAgICBsZXQgY3VzdG9tSGVhZGVycyA9IChfYSA9IHVybC5yZXF1ZXN0T3B0aW9ucykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmN1c3RvbUhlYWRlcnM7XG4gICAgaWYgKGN1c3RvbUhlYWRlcnMpIHtcbiAgICAgICAgaWYgKCEoY3VzdG9tSGVhZGVycyBpbnN0YW5jZW9mIEhlYWRlcnMpKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGN1c3RvbUhlYWRlcnMgPSBuZXcgSGVhZGVycyhjdXN0b21IZWFkZXJzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEdvb2dsZUdlbmVyYXRpdmVBSVJlcXVlc3RJbnB1dEVycm9yKGB1bmFibGUgdG8gY29udmVydCBjdXN0b21IZWFkZXJzIHZhbHVlICR7SlNPTi5zdHJpbmdpZnkoY3VzdG9tSGVhZGVycyl9IHRvIEhlYWRlcnM6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgW2hlYWRlck5hbWUsIGhlYWRlclZhbHVlXSBvZiBjdXN0b21IZWFkZXJzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgaWYgKGhlYWRlck5hbWUgPT09IFwieC1nb29nLWFwaS1rZXlcIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlSZXF1ZXN0SW5wdXRFcnJvcihgQ2Fubm90IHNldCByZXNlcnZlZCBoZWFkZXIgbmFtZSAke2hlYWRlck5hbWV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChoZWFkZXJOYW1lID09PSBcIngtZ29vZy1hcGktY2xpZW50XCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3IoYEhlYWRlciBuYW1lICR7aGVhZGVyTmFtZX0gY2FuIG9ubHkgYmUgc2V0IHVzaW5nIHRoZSBhcGlDbGllbnQgZmllbGRgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhlYWRlcnMuYXBwZW5kKGhlYWRlck5hbWUsIGhlYWRlclZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaGVhZGVycztcbn1cbmFzeW5jIGZ1bmN0aW9uIGNvbnN0cnVjdE1vZGVsUmVxdWVzdChtb2RlbCwgdGFzaywgYXBpS2V5LCBzdHJlYW0sIGJvZHksIHJlcXVlc3RPcHRpb25zKSB7XG4gICAgY29uc3QgdXJsID0gbmV3IFJlcXVlc3RVcmwobW9kZWwsIHRhc2ssIGFwaUtleSwgc3RyZWFtLCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdXJsOiB1cmwudG9TdHJpbmcoKSxcbiAgICAgICAgZmV0Y2hPcHRpb25zOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGJ1aWxkRmV0Y2hPcHRpb25zKHJlcXVlc3RPcHRpb25zKSksIHsgbWV0aG9kOiBcIlBPU1RcIiwgaGVhZGVyczogYXdhaXQgZ2V0SGVhZGVycyh1cmwpLCBib2R5IH0pLFxuICAgIH07XG59XG5hc3luYyBmdW5jdGlvbiBtYWtlTW9kZWxSZXF1ZXN0KG1vZGVsLCB0YXNrLCBhcGlLZXksIHN0cmVhbSwgYm9keSwgcmVxdWVzdE9wdGlvbnMgPSB7fSwgXG4vLyBBbGxvd3MgdGhpcyB0byBiZSBzdHViYmVkIGZvciB0ZXN0c1xuZmV0Y2hGbiA9IGZldGNoKSB7XG4gICAgY29uc3QgeyB1cmwsIGZldGNoT3B0aW9ucyB9ID0gYXdhaXQgY29uc3RydWN0TW9kZWxSZXF1ZXN0KG1vZGVsLCB0YXNrLCBhcGlLZXksIHN0cmVhbSwgYm9keSwgcmVxdWVzdE9wdGlvbnMpO1xuICAgIHJldHVybiBtYWtlUmVxdWVzdCh1cmwsIGZldGNoT3B0aW9ucywgZmV0Y2hGbik7XG59XG5hc3luYyBmdW5jdGlvbiBtYWtlUmVxdWVzdCh1cmwsIGZldGNoT3B0aW9ucywgZmV0Y2hGbiA9IGZldGNoKSB7XG4gICAgbGV0IHJlc3BvbnNlO1xuICAgIHRyeSB7XG4gICAgICAgIHJlc3BvbnNlID0gYXdhaXQgZmV0Y2hGbih1cmwsIGZldGNoT3B0aW9ucyk7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIGhhbmRsZVJlc3BvbnNlRXJyb3IoZSwgdXJsKTtcbiAgICB9XG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICBhd2FpdCBoYW5kbGVSZXNwb25zZU5vdE9rKHJlc3BvbnNlLCB1cmwpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2U7XG59XG5mdW5jdGlvbiBoYW5kbGVSZXNwb25zZUVycm9yKGUsIHVybCkge1xuICAgIGxldCBlcnIgPSBlO1xuICAgIGlmIChlcnIubmFtZSA9PT0gXCJBYm9ydEVycm9yXCIpIHtcbiAgICAgICAgZXJyID0gbmV3IEdvb2dsZUdlbmVyYXRpdmVBSUFib3J0RXJyb3IoYFJlcXVlc3QgYWJvcnRlZCB3aGVuIGZldGNoaW5nICR7dXJsLnRvU3RyaW5nKCl9OiAke2UubWVzc2FnZX1gKTtcbiAgICAgICAgZXJyLnN0YWNrID0gZS5zdGFjaztcbiAgICB9XG4gICAgZWxzZSBpZiAoIShlIGluc3RhbmNlb2YgR29vZ2xlR2VuZXJhdGl2ZUFJRmV0Y2hFcnJvciB8fFxuICAgICAgICBlIGluc3RhbmNlb2YgR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3IpKSB7XG4gICAgICAgIGVyciA9IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihgRXJyb3IgZmV0Y2hpbmcgZnJvbSAke3VybC50b1N0cmluZygpfTogJHtlLm1lc3NhZ2V9YCk7XG4gICAgICAgIGVyci5zdGFjayA9IGUuc3RhY2s7XG4gICAgfVxuICAgIHRocm93IGVycjtcbn1cbmFzeW5jIGZ1bmN0aW9uIGhhbmRsZVJlc3BvbnNlTm90T2socmVzcG9uc2UsIHVybCkge1xuICAgIGxldCBtZXNzYWdlID0gXCJcIjtcbiAgICBsZXQgZXJyb3JEZXRhaWxzO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGpzb24gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIG1lc3NhZ2UgPSBqc29uLmVycm9yLm1lc3NhZ2U7XG4gICAgICAgIGlmIChqc29uLmVycm9yLmRldGFpbHMpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgKz0gYCAke0pTT04uc3RyaW5naWZ5KGpzb24uZXJyb3IuZGV0YWlscyl9YDtcbiAgICAgICAgICAgIGVycm9yRGV0YWlscyA9IGpzb24uZXJyb3IuZGV0YWlscztcbiAgICAgICAgfVxuICAgIH1cbiAgICBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpZ25vcmVkXG4gICAgfVxuICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlGZXRjaEVycm9yKGBFcnJvciBmZXRjaGluZyBmcm9tICR7dXJsLnRvU3RyaW5nKCl9OiBbJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1dICR7bWVzc2FnZX1gLCByZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlLnN0YXR1c1RleHQsIGVycm9yRGV0YWlscyk7XG59XG4vKipcbiAqIEdlbmVyYXRlcyB0aGUgcmVxdWVzdCBvcHRpb25zIHRvIGJlIHBhc3NlZCB0byB0aGUgZmV0Y2ggQVBJLlxuICogQHBhcmFtIHJlcXVlc3RPcHRpb25zIC0gVGhlIHVzZXItZGVmaW5lZCByZXF1ZXN0IG9wdGlvbnMuXG4gKiBAcmV0dXJucyBUaGUgZ2VuZXJhdGVkIHJlcXVlc3Qgb3B0aW9ucy5cbiAqL1xuZnVuY3Rpb24gYnVpbGRGZXRjaE9wdGlvbnMocmVxdWVzdE9wdGlvbnMpIHtcbiAgICBjb25zdCBmZXRjaE9wdGlvbnMgPSB7fTtcbiAgICBpZiAoKHJlcXVlc3RPcHRpb25zID09PSBudWxsIHx8IHJlcXVlc3RPcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiByZXF1ZXN0T3B0aW9ucy5zaWduYWwpICE9PSB1bmRlZmluZWQgfHwgKHJlcXVlc3RPcHRpb25zID09PSBudWxsIHx8IHJlcXVlc3RPcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiByZXF1ZXN0T3B0aW9ucy50aW1lb3V0KSA+PSAwKSB7XG4gICAgICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICAgIGlmICgocmVxdWVzdE9wdGlvbnMgPT09IG51bGwgfHwgcmVxdWVzdE9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHJlcXVlc3RPcHRpb25zLnRpbWVvdXQpID49IDApIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gY29udHJvbGxlci5hYm9ydCgpLCByZXF1ZXN0T3B0aW9ucy50aW1lb3V0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMgPT09IG51bGwgfHwgcmVxdWVzdE9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHJlcXVlc3RPcHRpb25zLnNpZ25hbCkge1xuICAgICAgICAgICAgcmVxdWVzdE9wdGlvbnMuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5hYm9ydCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZmV0Y2hPcHRpb25zLnNpZ25hbCA9IGNvbnRyb2xsZXIuc2lnbmFsO1xuICAgIH1cbiAgICByZXR1cm4gZmV0Y2hPcHRpb25zO1xufVxuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBBZGRzIGNvbnZlbmllbmNlIGhlbHBlciBtZXRob2RzIHRvIGEgcmVzcG9uc2Ugb2JqZWN0LCBpbmNsdWRpbmcgc3RyZWFtXG4gKiBjaHVua3MgKGFzIGxvbmcgYXMgZWFjaCBjaHVuayBpcyBhIGNvbXBsZXRlIEdlbmVyYXRlQ29udGVudFJlc3BvbnNlIEpTT04pLlxuICovXG5mdW5jdGlvbiBhZGRIZWxwZXJzKHJlc3BvbnNlKSB7XG4gICAgcmVzcG9uc2UudGV4dCA9ICgpID0+IHtcbiAgICAgICAgaWYgKHJlc3BvbnNlLmNhbmRpZGF0ZXMgJiYgcmVzcG9uc2UuY2FuZGlkYXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2UuY2FuZGlkYXRlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBUaGlzIHJlc3BvbnNlIGhhZCAke3Jlc3BvbnNlLmNhbmRpZGF0ZXMubGVuZ3RofSBgICtcbiAgICAgICAgICAgICAgICAgICAgYGNhbmRpZGF0ZXMuIFJldHVybmluZyB0ZXh0IGZyb20gdGhlIGZpcnN0IGNhbmRpZGF0ZSBvbmx5LiBgICtcbiAgICAgICAgICAgICAgICAgICAgYEFjY2VzcyByZXNwb25zZS5jYW5kaWRhdGVzIGRpcmVjdGx5IHRvIHVzZSB0aGUgb3RoZXIgY2FuZGlkYXRlcy5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChoYWRCYWRGaW5pc2hSZWFzb24ocmVzcG9uc2UuY2FuZGlkYXRlc1swXSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJUmVzcG9uc2VFcnJvcihgJHtmb3JtYXRCbG9ja0Vycm9yTWVzc2FnZShyZXNwb25zZSl9YCwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGdldFRleHQocmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJlc3BvbnNlLnByb21wdEZlZWRiYWNrKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJUmVzcG9uc2VFcnJvcihgVGV4dCBub3QgYXZhaWxhYmxlLiAke2Zvcm1hdEJsb2NrRXJyb3JNZXNzYWdlKHJlc3BvbnNlKX1gLCByZXNwb25zZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBUT0RPOiByZW1vdmUgYXQgbmV4dCBtYWpvciB2ZXJzaW9uXG4gICAgICovXG4gICAgcmVzcG9uc2UuZnVuY3Rpb25DYWxsID0gKCkgPT4ge1xuICAgICAgICBpZiAocmVzcG9uc2UuY2FuZGlkYXRlcyAmJiByZXNwb25zZS5jYW5kaWRhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5jYW5kaWRhdGVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFRoaXMgcmVzcG9uc2UgaGFkICR7cmVzcG9uc2UuY2FuZGlkYXRlcy5sZW5ndGh9IGAgK1xuICAgICAgICAgICAgICAgICAgICBgY2FuZGlkYXRlcy4gUmV0dXJuaW5nIGZ1bmN0aW9uIGNhbGxzIGZyb20gdGhlIGZpcnN0IGNhbmRpZGF0ZSBvbmx5LiBgICtcbiAgICAgICAgICAgICAgICAgICAgYEFjY2VzcyByZXNwb25zZS5jYW5kaWRhdGVzIGRpcmVjdGx5IHRvIHVzZSB0aGUgb3RoZXIgY2FuZGlkYXRlcy5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChoYWRCYWRGaW5pc2hSZWFzb24ocmVzcG9uc2UuY2FuZGlkYXRlc1swXSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJUmVzcG9uc2VFcnJvcihgJHtmb3JtYXRCbG9ja0Vycm9yTWVzc2FnZShyZXNwb25zZSl9YCwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS53YXJuKGByZXNwb25zZS5mdW5jdGlvbkNhbGwoKSBpcyBkZXByZWNhdGVkLiBgICtcbiAgICAgICAgICAgICAgICBgVXNlIHJlc3BvbnNlLmZ1bmN0aW9uQ2FsbHMoKSBpbnN0ZWFkLmApO1xuICAgICAgICAgICAgcmV0dXJuIGdldEZ1bmN0aW9uQ2FsbHMocmVzcG9uc2UpWzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJlc3BvbnNlLnByb21wdEZlZWRiYWNrKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJUmVzcG9uc2VFcnJvcihgRnVuY3Rpb24gY2FsbCBub3QgYXZhaWxhYmxlLiAke2Zvcm1hdEJsb2NrRXJyb3JNZXNzYWdlKHJlc3BvbnNlKX1gLCByZXNwb25zZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9O1xuICAgIHJlc3BvbnNlLmZ1bmN0aW9uQ2FsbHMgPSAoKSA9PiB7XG4gICAgICAgIGlmIChyZXNwb25zZS5jYW5kaWRhdGVzICYmIHJlc3BvbnNlLmNhbmRpZGF0ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmNhbmRpZGF0ZXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgVGhpcyByZXNwb25zZSBoYWQgJHtyZXNwb25zZS5jYW5kaWRhdGVzLmxlbmd0aH0gYCArXG4gICAgICAgICAgICAgICAgICAgIGBjYW5kaWRhdGVzLiBSZXR1cm5pbmcgZnVuY3Rpb24gY2FsbHMgZnJvbSB0aGUgZmlyc3QgY2FuZGlkYXRlIG9ubHkuIGAgK1xuICAgICAgICAgICAgICAgICAgICBgQWNjZXNzIHJlc3BvbnNlLmNhbmRpZGF0ZXMgZGlyZWN0bHkgdG8gdXNlIHRoZSBvdGhlciBjYW5kaWRhdGVzLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGhhZEJhZEZpbmlzaFJlYXNvbihyZXNwb25zZS5jYW5kaWRhdGVzWzBdKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlSZXNwb25zZUVycm9yKGAke2Zvcm1hdEJsb2NrRXJyb3JNZXNzYWdlKHJlc3BvbnNlKX1gLCByZXNwb25zZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZ2V0RnVuY3Rpb25DYWxscyhyZXNwb25zZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocmVzcG9uc2UucHJvbXB0RmVlZGJhY2spIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlSZXNwb25zZUVycm9yKGBGdW5jdGlvbiBjYWxsIG5vdCBhdmFpbGFibGUuICR7Zm9ybWF0QmxvY2tFcnJvck1lc3NhZ2UocmVzcG9uc2UpfWAsIHJlc3BvbnNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH07XG4gICAgcmV0dXJuIHJlc3BvbnNlO1xufVxuLyoqXG4gKiBSZXR1cm5zIGFsbCB0ZXh0IGZvdW5kIGluIGFsbCBwYXJ0cyBvZiBmaXJzdCBjYW5kaWRhdGUuXG4gKi9cbmZ1bmN0aW9uIGdldFRleHQocmVzcG9uc2UpIHtcbiAgICB2YXIgX2EsIF9iLCBfYywgX2Q7XG4gICAgY29uc3QgdGV4dFN0cmluZ3MgPSBbXTtcbiAgICBpZiAoKF9iID0gKF9hID0gcmVzcG9uc2UuY2FuZGlkYXRlcykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hWzBdLmNvbnRlbnQpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5wYXJ0cykge1xuICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgKF9kID0gKF9jID0gcmVzcG9uc2UuY2FuZGlkYXRlcykgPT09IG51bGwgfHwgX2MgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9jWzBdLmNvbnRlbnQpID09PSBudWxsIHx8IF9kID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZC5wYXJ0cykge1xuICAgICAgICAgICAgaWYgKHBhcnQudGV4dCkge1xuICAgICAgICAgICAgICAgIHRleHRTdHJpbmdzLnB1c2gocGFydC50ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXJ0LmV4ZWN1dGFibGVDb2RlKSB7XG4gICAgICAgICAgICAgICAgdGV4dFN0cmluZ3MucHVzaChcIlxcbmBgYFwiICtcbiAgICAgICAgICAgICAgICAgICAgcGFydC5leGVjdXRhYmxlQ29kZS5sYW5ndWFnZSArXG4gICAgICAgICAgICAgICAgICAgIFwiXFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICBwYXJ0LmV4ZWN1dGFibGVDb2RlLmNvZGUgK1xuICAgICAgICAgICAgICAgICAgICBcIlxcbmBgYFxcblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXJ0LmNvZGVFeGVjdXRpb25SZXN1bHQpIHtcbiAgICAgICAgICAgICAgICB0ZXh0U3RyaW5ncy5wdXNoKFwiXFxuYGBgXFxuXCIgKyBwYXJ0LmNvZGVFeGVjdXRpb25SZXN1bHQub3V0cHV0ICsgXCJcXG5gYGBcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRleHRTdHJpbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRleHRTdHJpbmdzLmpvaW4oXCJcIik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG59XG4vKipcbiAqIFJldHVybnMgZnVuY3Rpb25DYWxsIG9mIGZpcnN0IGNhbmRpZGF0ZS5cbiAqL1xuZnVuY3Rpb24gZ2V0RnVuY3Rpb25DYWxscyhyZXNwb25zZSkge1xuICAgIHZhciBfYSwgX2IsIF9jLCBfZDtcbiAgICBjb25zdCBmdW5jdGlvbkNhbGxzID0gW107XG4gICAgaWYgKChfYiA9IChfYSA9IHJlc3BvbnNlLmNhbmRpZGF0ZXMpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYVswXS5jb250ZW50KSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IucGFydHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIChfZCA9IChfYyA9IHJlc3BvbnNlLmNhbmRpZGF0ZXMpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfY1swXS5jb250ZW50KSA9PT0gbnVsbCB8fCBfZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2QucGFydHMpIHtcbiAgICAgICAgICAgIGlmIChwYXJ0LmZ1bmN0aW9uQ2FsbCkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uQ2FsbHMucHVzaChwYXJ0LmZ1bmN0aW9uQ2FsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGZ1bmN0aW9uQ2FsbHMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb25DYWxscztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxufVxuY29uc3QgYmFkRmluaXNoUmVhc29ucyA9IFtcbiAgICBleHBvcnRzLkZpbmlzaFJlYXNvbi5SRUNJVEFUSU9OLFxuICAgIGV4cG9ydHMuRmluaXNoUmVhc29uLlNBRkVUWSxcbiAgICBleHBvcnRzLkZpbmlzaFJlYXNvbi5MQU5HVUFHRSxcbl07XG5mdW5jdGlvbiBoYWRCYWRGaW5pc2hSZWFzb24oY2FuZGlkYXRlKSB7XG4gICAgcmV0dXJuICghIWNhbmRpZGF0ZS5maW5pc2hSZWFzb24gJiZcbiAgICAgICAgYmFkRmluaXNoUmVhc29ucy5pbmNsdWRlcyhjYW5kaWRhdGUuZmluaXNoUmVhc29uKSk7XG59XG5mdW5jdGlvbiBmb3JtYXRCbG9ja0Vycm9yTWVzc2FnZShyZXNwb25zZSkge1xuICAgIHZhciBfYSwgX2IsIF9jO1xuICAgIGxldCBtZXNzYWdlID0gXCJcIjtcbiAgICBpZiAoKCFyZXNwb25zZS5jYW5kaWRhdGVzIHx8IHJlc3BvbnNlLmNhbmRpZGF0ZXMubGVuZ3RoID09PSAwKSAmJlxuICAgICAgICByZXNwb25zZS5wcm9tcHRGZWVkYmFjaykge1xuICAgICAgICBtZXNzYWdlICs9IFwiUmVzcG9uc2Ugd2FzIGJsb2NrZWRcIjtcbiAgICAgICAgaWYgKChfYSA9IHJlc3BvbnNlLnByb21wdEZlZWRiYWNrKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuYmxvY2tSZWFzb24pIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgKz0gYCBkdWUgdG8gJHtyZXNwb25zZS5wcm9tcHRGZWVkYmFjay5ibG9ja1JlYXNvbn1gO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoX2IgPSByZXNwb25zZS5wcm9tcHRGZWVkYmFjaykgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmJsb2NrUmVhc29uTWVzc2FnZSkge1xuICAgICAgICAgICAgbWVzc2FnZSArPSBgOiAke3Jlc3BvbnNlLnByb21wdEZlZWRiYWNrLmJsb2NrUmVhc29uTWVzc2FnZX1gO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKChfYyA9IHJlc3BvbnNlLmNhbmRpZGF0ZXMpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfY1swXSkge1xuICAgICAgICBjb25zdCBmaXJzdENhbmRpZGF0ZSA9IHJlc3BvbnNlLmNhbmRpZGF0ZXNbMF07XG4gICAgICAgIGlmIChoYWRCYWRGaW5pc2hSZWFzb24oZmlyc3RDYW5kaWRhdGUpKSB7XG4gICAgICAgICAgICBtZXNzYWdlICs9IGBDYW5kaWRhdGUgd2FzIGJsb2NrZWQgZHVlIHRvICR7Zmlyc3RDYW5kaWRhdGUuZmluaXNoUmVhc29ufWA7XG4gICAgICAgICAgICBpZiAoZmlyc3RDYW5kaWRhdGUuZmluaXNoTWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgKz0gYDogJHtmaXJzdENhbmRpZGF0ZS5maW5pc2hNZXNzYWdlfWA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1lc3NhZ2U7XG59XG5cbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSwgU3VwcHJlc3NlZEVycm9yLCBTeW1ib2wgKi9cclxuXHJcblxyXG5mdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG50eXBlb2YgU3VwcHJlc3NlZEVycm9yID09PSBcImZ1bmN0aW9uXCIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbiAoZXJyb3IsIHN1cHByZXNzZWQsIG1lc3NhZ2UpIHtcclxuICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG4gICAgcmV0dXJuIGUubmFtZSA9IFwiU3VwcHJlc3NlZEVycm9yXCIsIGUuZXJyb3IgPSBlcnJvciwgZS5zdXBwcmVzc2VkID0gc3VwcHJlc3NlZCwgZTtcclxufTtcblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmNvbnN0IHJlc3BvbnNlTGluZVJFID0gL15kYXRhXFw6ICguKikoPzpcXG5cXG58XFxyXFxyfFxcclxcblxcclxcbikvO1xuLyoqXG4gKiBQcm9jZXNzIGEgcmVzcG9uc2UuYm9keSBzdHJlYW0gZnJvbSB0aGUgYmFja2VuZCBhbmQgcmV0dXJuIGFuXG4gKiBpdGVyYXRvciB0aGF0IHByb3ZpZGVzIG9uZSBjb21wbGV0ZSBHZW5lcmF0ZUNvbnRlbnRSZXNwb25zZSBhdCBhIHRpbWVcbiAqIGFuZCBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIGEgc2luZ2xlIGFnZ3JlZ2F0ZWRcbiAqIEdlbmVyYXRlQ29udGVudFJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSByZXNwb25zZSAtIFJlc3BvbnNlIGZyb20gYSBmZXRjaCBjYWxsXG4gKi9cbmZ1bmN0aW9uIHByb2Nlc3NTdHJlYW0ocmVzcG9uc2UpIHtcbiAgICBjb25zdCBpbnB1dFN0cmVhbSA9IHJlc3BvbnNlLmJvZHkucGlwZVRocm91Z2gobmV3IFRleHREZWNvZGVyU3RyZWFtKFwidXRmOFwiLCB7IGZhdGFsOiB0cnVlIH0pKTtcbiAgICBjb25zdCByZXNwb25zZVN0cmVhbSA9IGdldFJlc3BvbnNlU3RyZWFtKGlucHV0U3RyZWFtKTtcbiAgICBjb25zdCBbc3RyZWFtMSwgc3RyZWFtMl0gPSByZXNwb25zZVN0cmVhbS50ZWUoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdHJlYW06IGdlbmVyYXRlUmVzcG9uc2VTZXF1ZW5jZShzdHJlYW0xKSxcbiAgICAgICAgcmVzcG9uc2U6IGdldFJlc3BvbnNlUHJvbWlzZShzdHJlYW0yKSxcbiAgICB9O1xufVxuYXN5bmMgZnVuY3Rpb24gZ2V0UmVzcG9uc2VQcm9taXNlKHN0cmVhbSkge1xuICAgIGNvbnN0IGFsbFJlc3BvbnNlcyA9IFtdO1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgcmV0dXJuIGFkZEhlbHBlcnMoYWdncmVnYXRlUmVzcG9uc2VzKGFsbFJlc3BvbnNlcykpO1xuICAgICAgICB9XG4gICAgICAgIGFsbFJlc3BvbnNlcy5wdXNoKHZhbHVlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZW5lcmF0ZVJlc3BvbnNlU2VxdWVuY2Uoc3RyZWFtKSB7XG4gICAgcmV0dXJuIF9fYXN5bmNHZW5lcmF0b3IodGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiogZ2VuZXJhdGVSZXNwb25zZVNlcXVlbmNlXzEoKSB7XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgdmFsdWUsIGRvbmUgfSA9IHlpZWxkIF9fYXdhaXQocmVhZGVyLnJlYWQoKSk7XG4gICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeWllbGQgeWllbGQgX19hd2FpdChhZGRIZWxwZXJzKHZhbHVlKSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbi8qKlxuICogUmVhZHMgYSByYXcgc3RyZWFtIGZyb20gdGhlIGZldGNoIHJlc3BvbnNlIGFuZCBqb2luIGluY29tcGxldGVcbiAqIGNodW5rcywgcmV0dXJuaW5nIGEgbmV3IHN0cmVhbSB0aGF0IHByb3ZpZGVzIGEgc2luZ2xlIGNvbXBsZXRlXG4gKiBHZW5lcmF0ZUNvbnRlbnRSZXNwb25zZSBpbiBlYWNoIGl0ZXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gZ2V0UmVzcG9uc2VTdHJlYW0oaW5wdXRTdHJlYW0pIHtcbiAgICBjb25zdCByZWFkZXIgPSBpbnB1dFN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICBjb25zdCBzdHJlYW0gPSBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgICAgICBzdGFydChjb250cm9sbGVyKSB7XG4gICAgICAgICAgICBsZXQgY3VycmVudFRleHQgPSBcIlwiO1xuICAgICAgICAgICAgcmV0dXJuIHB1bXAoKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHB1bXAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlYWRlclxuICAgICAgICAgICAgICAgICAgICAucmVhZCgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCh7IHZhbHVlLCBkb25lIH0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50VGV4dC50cmltKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVycm9yKG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihcIkZhaWxlZCB0byBwYXJzZSBzdHJlYW1cIikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50VGV4dCArPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1hdGNoID0gY3VycmVudFRleHQubWF0Y2gocmVzcG9uc2VMaW5lUkUpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgcGFyc2VkUmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZWRSZXNwb25zZSA9IEpTT04ucGFyc2UobWF0Y2hbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVycm9yKG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihgRXJyb3IgcGFyc2luZyBKU09OIHJlc3BvbnNlOiBcIiR7bWF0Y2hbMV19XCJgKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHBhcnNlZFJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUZXh0ID0gY3VycmVudFRleHQuc3Vic3RyaW5nKG1hdGNoWzBdLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGN1cnJlbnRUZXh0Lm1hdGNoKHJlc3BvbnNlTGluZVJFKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHVtcCgpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgZXJyID0gZTtcbiAgICAgICAgICAgICAgICAgICAgZXJyLnN0YWNrID0gZS5zdGFjaztcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVyci5uYW1lID09PSBcIkFib3J0RXJyb3JcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyID0gbmV3IEdvb2dsZUdlbmVyYXRpdmVBSUFib3J0RXJyb3IoXCJSZXF1ZXN0IGFib3J0ZWQgd2hlbiByZWFkaW5nIGZyb20gdGhlIHN0cmVhbVwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyciA9IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihcIkVycm9yIHJlYWRpbmcgZnJvbSB0aGUgc3RyZWFtXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gc3RyZWFtO1xufVxuLyoqXG4gKiBBZ2dyZWdhdGVzIGFuIGFycmF5IG9mIGBHZW5lcmF0ZUNvbnRlbnRSZXNwb25zZWBzIGludG8gYSBzaW5nbGVcbiAqIEdlbmVyYXRlQ29udGVudFJlc3BvbnNlLlxuICovXG5mdW5jdGlvbiBhZ2dyZWdhdGVSZXNwb25zZXMocmVzcG9uc2VzKSB7XG4gICAgY29uc3QgbGFzdFJlc3BvbnNlID0gcmVzcG9uc2VzW3Jlc3BvbnNlcy5sZW5ndGggLSAxXTtcbiAgICBjb25zdCBhZ2dyZWdhdGVkUmVzcG9uc2UgPSB7XG4gICAgICAgIHByb21wdEZlZWRiYWNrOiBsYXN0UmVzcG9uc2UgPT09IG51bGwgfHwgbGFzdFJlc3BvbnNlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsYXN0UmVzcG9uc2UucHJvbXB0RmVlZGJhY2ssXG4gICAgfTtcbiAgICBmb3IgKGNvbnN0IHJlc3BvbnNlIG9mIHJlc3BvbnNlcykge1xuICAgICAgICBpZiAocmVzcG9uc2UuY2FuZGlkYXRlcykge1xuICAgICAgICAgICAgbGV0IGNhbmRpZGF0ZUluZGV4ID0gMDtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIHJlc3BvbnNlLmNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWFnZ3JlZ2F0ZWRSZXNwb25zZS5jYW5kaWRhdGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZWRSZXNwb25zZS5jYW5kaWRhdGVzID0gW107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYWdncmVnYXRlZFJlc3BvbnNlLmNhbmRpZGF0ZXNbY2FuZGlkYXRlSW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZWRSZXNwb25zZS5jYW5kaWRhdGVzW2NhbmRpZGF0ZUluZGV4XSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiBjYW5kaWRhdGVJbmRleCxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gS2VlcCBvdmVyd3JpdGluZywgdGhlIGxhc3Qgb25lIHdpbGwgYmUgZmluYWxcbiAgICAgICAgICAgICAgICBhZ2dyZWdhdGVkUmVzcG9uc2UuY2FuZGlkYXRlc1tjYW5kaWRhdGVJbmRleF0uY2l0YXRpb25NZXRhZGF0YSA9XG4gICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZS5jaXRhdGlvbk1ldGFkYXRhO1xuICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZWRSZXNwb25zZS5jYW5kaWRhdGVzW2NhbmRpZGF0ZUluZGV4XS5ncm91bmRpbmdNZXRhZGF0YSA9XG4gICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZS5ncm91bmRpbmdNZXRhZGF0YTtcbiAgICAgICAgICAgICAgICBhZ2dyZWdhdGVkUmVzcG9uc2UuY2FuZGlkYXRlc1tjYW5kaWRhdGVJbmRleF0uZmluaXNoUmVhc29uID1cbiAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlLmZpbmlzaFJlYXNvbjtcbiAgICAgICAgICAgICAgICBhZ2dyZWdhdGVkUmVzcG9uc2UuY2FuZGlkYXRlc1tjYW5kaWRhdGVJbmRleF0uZmluaXNoTWVzc2FnZSA9XG4gICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZS5maW5pc2hNZXNzYWdlO1xuICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZWRSZXNwb25zZS5jYW5kaWRhdGVzW2NhbmRpZGF0ZUluZGV4XS5zYWZldHlSYXRpbmdzID1cbiAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlLnNhZmV0eVJhdGluZ3M7XG4gICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICogQ2FuZGlkYXRlcyBzaG91bGQgYWx3YXlzIGhhdmUgY29udGVudCBhbmQgcGFydHMsIGJ1dCB0aGlzIGhhbmRsZXNcbiAgICAgICAgICAgICAgICAgKiBwb3NzaWJsZSBtYWxmb3JtZWQgcmVzcG9uc2VzLlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGlmIChjYW5kaWRhdGUuY29udGVudCAmJiBjYW5kaWRhdGUuY29udGVudC5wYXJ0cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWFnZ3JlZ2F0ZWRSZXNwb25zZS5jYW5kaWRhdGVzW2NhbmRpZGF0ZUluZGV4XS5jb250ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZ2dyZWdhdGVkUmVzcG9uc2UuY2FuZGlkYXRlc1tjYW5kaWRhdGVJbmRleF0uY29udGVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2xlOiBjYW5kaWRhdGUuY29udGVudC5yb2xlIHx8IFwidXNlclwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3UGFydCA9IHt9O1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgY2FuZGlkYXRlLmNvbnRlbnQucGFydHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0LnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQYXJ0LnRleHQgPSBwYXJ0LnRleHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFydC5mdW5jdGlvbkNhbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQYXJ0LmZ1bmN0aW9uQ2FsbCA9IHBhcnQuZnVuY3Rpb25DYWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnQuZXhlY3V0YWJsZUNvZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQYXJ0LmV4ZWN1dGFibGVDb2RlID0gcGFydC5leGVjdXRhYmxlQ29kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0LmNvZGVFeGVjdXRpb25SZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQYXJ0LmNvZGVFeGVjdXRpb25SZXN1bHQgPSBwYXJ0LmNvZGVFeGVjdXRpb25SZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMobmV3UGFydCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UGFydC50ZXh0ID0gXCJcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZWRSZXNwb25zZS5jYW5kaWRhdGVzW2NhbmRpZGF0ZUluZGV4XS5jb250ZW50LnBhcnRzLnB1c2gobmV3UGFydCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYW5kaWRhdGVJbmRleCsrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXNwb25zZS51c2FnZU1ldGFkYXRhKSB7XG4gICAgICAgICAgICBhZ2dyZWdhdGVkUmVzcG9uc2UudXNhZ2VNZXRhZGF0YSA9IHJlc3BvbnNlLnVzYWdlTWV0YWRhdGE7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFnZ3JlZ2F0ZWRSZXNwb25zZTtcbn1cblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQ29udGVudFN0cmVhbShhcGlLZXksIG1vZGVsLCBwYXJhbXMsIHJlcXVlc3RPcHRpb25zKSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBtYWtlTW9kZWxSZXF1ZXN0KG1vZGVsLCBUYXNrLlNUUkVBTV9HRU5FUkFURV9DT05URU5ULCBhcGlLZXksIFxuICAgIC8qIHN0cmVhbSAqLyB0cnVlLCBKU09OLnN0cmluZ2lmeShwYXJhbXMpLCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgcmV0dXJuIHByb2Nlc3NTdHJlYW0ocmVzcG9uc2UpO1xufVxuYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVDb250ZW50KGFwaUtleSwgbW9kZWwsIHBhcmFtcywgcmVxdWVzdE9wdGlvbnMpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG1ha2VNb2RlbFJlcXVlc3QobW9kZWwsIFRhc2suR0VORVJBVEVfQ09OVEVOVCwgYXBpS2V5LCBcbiAgICAvKiBzdHJlYW0gKi8gZmFsc2UsIEpTT04uc3RyaW5naWZ5KHBhcmFtcyksIHJlcXVlc3RPcHRpb25zKTtcbiAgICBjb25zdCByZXNwb25zZUpzb24gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgY29uc3QgZW5oYW5jZWRSZXNwb25zZSA9IGFkZEhlbHBlcnMocmVzcG9uc2VKc29uKTtcbiAgICByZXR1cm4ge1xuICAgICAgICByZXNwb25zZTogZW5oYW5jZWRSZXNwb25zZSxcbiAgICB9O1xufVxuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0U3lzdGVtSW5zdHJ1Y3Rpb24oaW5wdXQpIHtcbiAgICAvLyBudWxsIG9yIHVuZGVmaW5lZFxuICAgIGlmIChpbnB1dCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBpbnB1dCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4geyByb2xlOiBcInN5c3RlbVwiLCBwYXJ0czogW3sgdGV4dDogaW5wdXQgfV0gfTtcbiAgICB9XG4gICAgZWxzZSBpZiAoaW5wdXQudGV4dCkge1xuICAgICAgICByZXR1cm4geyByb2xlOiBcInN5c3RlbVwiLCBwYXJ0czogW2lucHV0XSB9O1xuICAgIH1cbiAgICBlbHNlIGlmIChpbnB1dC5wYXJ0cykge1xuICAgICAgICBpZiAoIWlucHV0LnJvbGUpIHtcbiAgICAgICAgICAgIHJldHVybiB7IHJvbGU6IFwic3lzdGVtXCIsIHBhcnRzOiBpbnB1dC5wYXJ0cyB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gZm9ybWF0TmV3Q29udGVudChyZXF1ZXN0KSB7XG4gICAgbGV0IG5ld1BhcnRzID0gW107XG4gICAgaWYgKHR5cGVvZiByZXF1ZXN0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIG5ld1BhcnRzID0gW3sgdGV4dDogcmVxdWVzdCB9XTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGZvciAoY29uc3QgcGFydE9yU3RyaW5nIG9mIHJlcXVlc3QpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFydE9yU3RyaW5nID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgbmV3UGFydHMucHVzaCh7IHRleHQ6IHBhcnRPclN0cmluZyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG5ld1BhcnRzLnB1c2gocGFydE9yU3RyaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXNzaWduUm9sZVRvUGFydHNBbmRWYWxpZGF0ZVNlbmRNZXNzYWdlUmVxdWVzdChuZXdQYXJ0cyk7XG59XG4vKipcbiAqIFdoZW4gbXVsdGlwbGUgUGFydCB0eXBlcyAoaS5lLiBGdW5jdGlvblJlc3BvbnNlUGFydCBhbmQgVGV4dFBhcnQpIGFyZVxuICogcGFzc2VkIGluIGEgc2luZ2xlIFBhcnQgYXJyYXksIHdlIG1heSBuZWVkIHRvIGFzc2lnbiBkaWZmZXJlbnQgcm9sZXMgdG8gZWFjaFxuICogcGFydC4gQ3VycmVudGx5IG9ubHkgRnVuY3Rpb25SZXNwb25zZVBhcnQgcmVxdWlyZXMgYSByb2xlIG90aGVyIHRoYW4gJ3VzZXInLlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSBwYXJ0cyBBcnJheSBvZiBwYXJ0cyB0byBwYXNzIHRvIHRoZSBtb2RlbFxuICogQHJldHVybnMgQXJyYXkgb2YgY29udGVudCBpdGVtc1xuICovXG5mdW5jdGlvbiBhc3NpZ25Sb2xlVG9QYXJ0c0FuZFZhbGlkYXRlU2VuZE1lc3NhZ2VSZXF1ZXN0KHBhcnRzKSB7XG4gICAgY29uc3QgdXNlckNvbnRlbnQgPSB7IHJvbGU6IFwidXNlclwiLCBwYXJ0czogW10gfTtcbiAgICBjb25zdCBmdW5jdGlvbkNvbnRlbnQgPSB7IHJvbGU6IFwiZnVuY3Rpb25cIiwgcGFydHM6IFtdIH07XG4gICAgbGV0IGhhc1VzZXJDb250ZW50ID0gZmFsc2U7XG4gICAgbGV0IGhhc0Z1bmN0aW9uQ29udGVudCA9IGZhbHNlO1xuICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICBpZiAoXCJmdW5jdGlvblJlc3BvbnNlXCIgaW4gcGFydCkge1xuICAgICAgICAgICAgZnVuY3Rpb25Db250ZW50LnBhcnRzLnB1c2gocGFydCk7XG4gICAgICAgICAgICBoYXNGdW5jdGlvbkNvbnRlbnQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdXNlckNvbnRlbnQucGFydHMucHVzaChwYXJ0KTtcbiAgICAgICAgICAgIGhhc1VzZXJDb250ZW50ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaGFzVXNlckNvbnRlbnQgJiYgaGFzRnVuY3Rpb25Db250ZW50KSB7XG4gICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihcIldpdGhpbiBhIHNpbmdsZSBtZXNzYWdlLCBGdW5jdGlvblJlc3BvbnNlIGNhbm5vdCBiZSBtaXhlZCB3aXRoIG90aGVyIHR5cGUgb2YgcGFydCBpbiB0aGUgcmVxdWVzdCBmb3Igc2VuZGluZyBjaGF0IG1lc3NhZ2UuXCIpO1xuICAgIH1cbiAgICBpZiAoIWhhc1VzZXJDb250ZW50ICYmICFoYXNGdW5jdGlvbkNvbnRlbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEdvb2dsZUdlbmVyYXRpdmVBSUVycm9yKFwiTm8gY29udGVudCBpcyBwcm92aWRlZCBmb3Igc2VuZGluZyBjaGF0IG1lc3NhZ2UuXCIpO1xuICAgIH1cbiAgICBpZiAoaGFzVXNlckNvbnRlbnQpIHtcbiAgICAgICAgcmV0dXJuIHVzZXJDb250ZW50O1xuICAgIH1cbiAgICByZXR1cm4gZnVuY3Rpb25Db250ZW50O1xufVxuZnVuY3Rpb24gZm9ybWF0Q291bnRUb2tlbnNJbnB1dChwYXJhbXMsIG1vZGVsUGFyYW1zKSB7XG4gICAgdmFyIF9hO1xuICAgIGxldCBmb3JtYXR0ZWRHZW5lcmF0ZUNvbnRlbnRSZXF1ZXN0ID0ge1xuICAgICAgICBtb2RlbDogbW9kZWxQYXJhbXMgPT09IG51bGwgfHwgbW9kZWxQYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG1vZGVsUGFyYW1zLm1vZGVsLFxuICAgICAgICBnZW5lcmF0aW9uQ29uZmlnOiBtb2RlbFBhcmFtcyA9PT0gbnVsbCB8fCBtb2RlbFBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogbW9kZWxQYXJhbXMuZ2VuZXJhdGlvbkNvbmZpZyxcbiAgICAgICAgc2FmZXR5U2V0dGluZ3M6IG1vZGVsUGFyYW1zID09PSBudWxsIHx8IG1vZGVsUGFyYW1zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBtb2RlbFBhcmFtcy5zYWZldHlTZXR0aW5ncyxcbiAgICAgICAgdG9vbHM6IG1vZGVsUGFyYW1zID09PSBudWxsIHx8IG1vZGVsUGFyYW1zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBtb2RlbFBhcmFtcy50b29scyxcbiAgICAgICAgdG9vbENvbmZpZzogbW9kZWxQYXJhbXMgPT09IG51bGwgfHwgbW9kZWxQYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG1vZGVsUGFyYW1zLnRvb2xDb25maWcsXG4gICAgICAgIHN5c3RlbUluc3RydWN0aW9uOiBtb2RlbFBhcmFtcyA9PT0gbnVsbCB8fCBtb2RlbFBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogbW9kZWxQYXJhbXMuc3lzdGVtSW5zdHJ1Y3Rpb24sXG4gICAgICAgIGNhY2hlZENvbnRlbnQ6IChfYSA9IG1vZGVsUGFyYW1zID09PSBudWxsIHx8IG1vZGVsUGFyYW1zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBtb2RlbFBhcmFtcy5jYWNoZWRDb250ZW50KSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EubmFtZSxcbiAgICAgICAgY29udGVudHM6IFtdLFxuICAgIH07XG4gICAgY29uc3QgY29udGFpbnNHZW5lcmF0ZUNvbnRlbnRSZXF1ZXN0ID0gcGFyYW1zLmdlbmVyYXRlQ29udGVudFJlcXVlc3QgIT0gbnVsbDtcbiAgICBpZiAocGFyYW1zLmNvbnRlbnRzKSB7XG4gICAgICAgIGlmIChjb250YWluc0dlbmVyYXRlQ29udGVudFJlcXVlc3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlSZXF1ZXN0SW5wdXRFcnJvcihcIkNvdW50VG9rZW5zUmVxdWVzdCBtdXN0IGhhdmUgb25lIG9mIGNvbnRlbnRzIG9yIGdlbmVyYXRlQ29udGVudFJlcXVlc3QsIG5vdCBib3RoLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBmb3JtYXR0ZWRHZW5lcmF0ZUNvbnRlbnRSZXF1ZXN0LmNvbnRlbnRzID0gcGFyYW1zLmNvbnRlbnRzO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb250YWluc0dlbmVyYXRlQ29udGVudFJlcXVlc3QpIHtcbiAgICAgICAgZm9ybWF0dGVkR2VuZXJhdGVDb250ZW50UmVxdWVzdCA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgZm9ybWF0dGVkR2VuZXJhdGVDb250ZW50UmVxdWVzdCksIHBhcmFtcy5nZW5lcmF0ZUNvbnRlbnRSZXF1ZXN0KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIEFycmF5IG9yIHN0cmluZ1xuICAgICAgICBjb25zdCBjb250ZW50ID0gZm9ybWF0TmV3Q29udGVudChwYXJhbXMpO1xuICAgICAgICBmb3JtYXR0ZWRHZW5lcmF0ZUNvbnRlbnRSZXF1ZXN0LmNvbnRlbnRzID0gW2NvbnRlbnRdO1xuICAgIH1cbiAgICByZXR1cm4geyBnZW5lcmF0ZUNvbnRlbnRSZXF1ZXN0OiBmb3JtYXR0ZWRHZW5lcmF0ZUNvbnRlbnRSZXF1ZXN0IH07XG59XG5mdW5jdGlvbiBmb3JtYXRHZW5lcmF0ZUNvbnRlbnRJbnB1dChwYXJhbXMpIHtcbiAgICBsZXQgZm9ybWF0dGVkUmVxdWVzdDtcbiAgICBpZiAocGFyYW1zLmNvbnRlbnRzKSB7XG4gICAgICAgIGZvcm1hdHRlZFJlcXVlc3QgPSBwYXJhbXM7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICAvLyBBcnJheSBvciBzdHJpbmdcbiAgICAgICAgY29uc3QgY29udGVudCA9IGZvcm1hdE5ld0NvbnRlbnQocGFyYW1zKTtcbiAgICAgICAgZm9ybWF0dGVkUmVxdWVzdCA9IHsgY29udGVudHM6IFtjb250ZW50XSB9O1xuICAgIH1cbiAgICBpZiAocGFyYW1zLnN5c3RlbUluc3RydWN0aW9uKSB7XG4gICAgICAgIGZvcm1hdHRlZFJlcXVlc3Quc3lzdGVtSW5zdHJ1Y3Rpb24gPSBmb3JtYXRTeXN0ZW1JbnN0cnVjdGlvbihwYXJhbXMuc3lzdGVtSW5zdHJ1Y3Rpb24pO1xuICAgIH1cbiAgICByZXR1cm4gZm9ybWF0dGVkUmVxdWVzdDtcbn1cbmZ1bmN0aW9uIGZvcm1hdEVtYmVkQ29udGVudElucHV0KHBhcmFtcykge1xuICAgIGlmICh0eXBlb2YgcGFyYW1zID09PSBcInN0cmluZ1wiIHx8IEFycmF5LmlzQXJyYXkocGFyYW1zKSkge1xuICAgICAgICBjb25zdCBjb250ZW50ID0gZm9ybWF0TmV3Q29udGVudChwYXJhbXMpO1xuICAgICAgICByZXR1cm4geyBjb250ZW50IH07XG4gICAgfVxuICAgIHJldHVybiBwYXJhbXM7XG59XG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vLyBodHRwczovL2FpLmdvb2dsZS5kZXYvYXBpL3Jlc3QvdjFiZXRhL0NvbnRlbnQjcGFydFxuY29uc3QgVkFMSURfUEFSVF9GSUVMRFMgPSBbXG4gICAgXCJ0ZXh0XCIsXG4gICAgXCJpbmxpbmVEYXRhXCIsXG4gICAgXCJmdW5jdGlvbkNhbGxcIixcbiAgICBcImZ1bmN0aW9uUmVzcG9uc2VcIixcbiAgICBcImV4ZWN1dGFibGVDb2RlXCIsXG4gICAgXCJjb2RlRXhlY3V0aW9uUmVzdWx0XCIsXG5dO1xuY29uc3QgVkFMSURfUEFSVFNfUEVSX1JPTEUgPSB7XG4gICAgdXNlcjogW1widGV4dFwiLCBcImlubGluZURhdGFcIl0sXG4gICAgZnVuY3Rpb246IFtcImZ1bmN0aW9uUmVzcG9uc2VcIl0sXG4gICAgbW9kZWw6IFtcInRleHRcIiwgXCJmdW5jdGlvbkNhbGxcIiwgXCJleGVjdXRhYmxlQ29kZVwiLCBcImNvZGVFeGVjdXRpb25SZXN1bHRcIl0sXG4gICAgLy8gU3lzdGVtIGluc3RydWN0aW9ucyBzaG91bGRuJ3QgYmUgaW4gaGlzdG9yeSBhbnl3YXkuXG4gICAgc3lzdGVtOiBbXCJ0ZXh0XCJdLFxufTtcbmZ1bmN0aW9uIHZhbGlkYXRlQ2hhdEhpc3RvcnkoaGlzdG9yeSkge1xuICAgIGxldCBwcmV2Q29udGVudCA9IGZhbHNlO1xuICAgIGZvciAoY29uc3QgY3VyckNvbnRlbnQgb2YgaGlzdG9yeSkge1xuICAgICAgICBjb25zdCB7IHJvbGUsIHBhcnRzIH0gPSBjdXJyQ29udGVudDtcbiAgICAgICAgaWYgKCFwcmV2Q29udGVudCAmJiByb2xlICE9PSBcInVzZXJcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEdvb2dsZUdlbmVyYXRpdmVBSUVycm9yKGBGaXJzdCBjb250ZW50IHNob3VsZCBiZSB3aXRoIHJvbGUgJ3VzZXInLCBnb3QgJHtyb2xlfWApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghUE9TU0lCTEVfUk9MRVMuaW5jbHVkZXMocm9sZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihgRWFjaCBpdGVtIHNob3VsZCBpbmNsdWRlIHJvbGUgZmllbGQuIEdvdCAke3JvbGV9IGJ1dCB2YWxpZCByb2xlcyBhcmU6ICR7SlNPTi5zdHJpbmdpZnkoUE9TU0lCTEVfUk9MRVMpfWApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShwYXJ0cykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihcIkNvbnRlbnQgc2hvdWxkIGhhdmUgJ3BhcnRzJyBwcm9wZXJ0eSB3aXRoIGFuIGFycmF5IG9mIFBhcnRzXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihcIkVhY2ggQ29udGVudCBzaG91bGQgaGF2ZSBhdCBsZWFzdCBvbmUgcGFydFwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb3VudEZpZWxkcyA9IHtcbiAgICAgICAgICAgIHRleHQ6IDAsXG4gICAgICAgICAgICBpbmxpbmVEYXRhOiAwLFxuICAgICAgICAgICAgZnVuY3Rpb25DYWxsOiAwLFxuICAgICAgICAgICAgZnVuY3Rpb25SZXNwb25zZTogMCxcbiAgICAgICAgICAgIGZpbGVEYXRhOiAwLFxuICAgICAgICAgICAgZXhlY3V0YWJsZUNvZGU6IDAsXG4gICAgICAgICAgICBjb2RlRXhlY3V0aW9uUmVzdWx0OiAwLFxuICAgICAgICB9O1xuICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIFZBTElEX1BBUlRfRklFTERTKSB7XG4gICAgICAgICAgICAgICAgaWYgKGtleSBpbiBwYXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50RmllbGRzW2tleV0gKz0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmFsaWRQYXJ0cyA9IFZBTElEX1BBUlRTX1BFUl9ST0xFW3JvbGVdO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBWQUxJRF9QQVJUX0ZJRUxEUykge1xuICAgICAgICAgICAgaWYgKCF2YWxpZFBhcnRzLmluY2x1ZGVzKGtleSkgJiYgY291bnRGaWVsZHNba2V5XSA+IDApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJRXJyb3IoYENvbnRlbnQgd2l0aCByb2xlICcke3JvbGV9JyBjYW4ndCBjb250YWluICcke2tleX0nIHBhcnRgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBwcmV2Q29udGVudCA9IHRydWU7XG4gICAgfVxufVxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHJlc3BvbnNlIGlzIHZhbGlkIChjb3VsZCBiZSBhcHBlbmRlZCB0byB0aGUgaGlzdG9yeSksIGZsYXNlIG90aGVyd2lzZS5cbiAqL1xuZnVuY3Rpb24gaXNWYWxpZFJlc3BvbnNlKHJlc3BvbnNlKSB7XG4gICAgdmFyIF9hO1xuICAgIGlmIChyZXNwb25zZS5jYW5kaWRhdGVzID09PSB1bmRlZmluZWQgfHwgcmVzcG9uc2UuY2FuZGlkYXRlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBjb250ZW50ID0gKF9hID0gcmVzcG9uc2UuY2FuZGlkYXRlc1swXSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmNvbnRlbnQ7XG4gICAgaWYgKGNvbnRlbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChjb250ZW50LnBhcnRzID09PSB1bmRlZmluZWQgfHwgY29udGVudC5wYXJ0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgY29udGVudC5wYXJ0cykge1xuICAgICAgICBpZiAocGFydCA9PT0gdW5kZWZpbmVkIHx8IE9iamVjdC5rZXlzKHBhcnQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJ0LnRleHQgIT09IHVuZGVmaW5lZCAmJiBwYXJ0LnRleHQgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbi8qKlxuICogRG8gbm90IGxvZyBhIG1lc3NhZ2UgZm9yIHRoaXMgZXJyb3IuXG4gKi9cbmNvbnN0IFNJTEVOVF9FUlJPUiA9IFwiU0lMRU5UX0VSUk9SXCI7XG4vKipcbiAqIENoYXRTZXNzaW9uIGNsYXNzIHRoYXQgZW5hYmxlcyBzZW5kaW5nIGNoYXQgbWVzc2FnZXMgYW5kIHN0b3Jlc1xuICogaGlzdG9yeSBvZiBzZW50IGFuZCByZWNlaXZlZCBtZXNzYWdlcyBzbyBmYXIuXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBDaGF0U2Vzc2lvbiB7XG4gICAgY29uc3RydWN0b3IoYXBpS2V5LCBtb2RlbCwgcGFyYW1zLCBfcmVxdWVzdE9wdGlvbnMgPSB7fSkge1xuICAgICAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gICAgICAgIHRoaXMucGFyYW1zID0gcGFyYW1zO1xuICAgICAgICB0aGlzLl9yZXF1ZXN0T3B0aW9ucyA9IF9yZXF1ZXN0T3B0aW9ucztcbiAgICAgICAgdGhpcy5faGlzdG9yeSA9IFtdO1xuICAgICAgICB0aGlzLl9zZW5kUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB0aGlzLl9hcGlLZXkgPSBhcGlLZXk7XG4gICAgICAgIGlmIChwYXJhbXMgPT09IG51bGwgfHwgcGFyYW1zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBwYXJhbXMuaGlzdG9yeSkge1xuICAgICAgICAgICAgdmFsaWRhdGVDaGF0SGlzdG9yeShwYXJhbXMuaGlzdG9yeSk7XG4gICAgICAgICAgICB0aGlzLl9oaXN0b3J5ID0gcGFyYW1zLmhpc3Rvcnk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgY2hhdCBoaXN0b3J5IHNvIGZhci4gQmxvY2tlZCBwcm9tcHRzIGFyZSBub3QgYWRkZWQgdG8gaGlzdG9yeS5cbiAgICAgKiBCbG9ja2VkIGNhbmRpZGF0ZXMgYXJlIG5vdCBhZGRlZCB0byBoaXN0b3J5LCBub3IgYXJlIHRoZSBwcm9tcHRzIHRoYXRcbiAgICAgKiBnZW5lcmF0ZWQgdGhlbS5cbiAgICAgKi9cbiAgICBhc3luYyBnZXRIaXN0b3J5KCkge1xuICAgICAgICBhd2FpdCB0aGlzLl9zZW5kUHJvbWlzZTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hpc3Rvcnk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlbmRzIGEgY2hhdCBtZXNzYWdlIGFuZCByZWNlaXZlcyBhIG5vbi1zdHJlYW1pbmdcbiAgICAgKiB7QGxpbmsgR2VuZXJhdGVDb250ZW50UmVzdWx0fS5cbiAgICAgKlxuICAgICAqIEZpZWxkcyBzZXQgaW4gdGhlIG9wdGlvbmFsIHtAbGluayBTaW5nbGVSZXF1ZXN0T3B0aW9uc30gcGFyYW1ldGVyIHdpbGxcbiAgICAgKiB0YWtlIHByZWNlZGVuY2Ugb3ZlciB0aGUge0BsaW5rIFJlcXVlc3RPcHRpb25zfSB2YWx1ZXMgcHJvdmlkZWQgdG9cbiAgICAgKiB7QGxpbmsgR29vZ2xlR2VuZXJhdGl2ZUFJLmdldEdlbmVyYXRpdmVNb2RlbCB9LlxuICAgICAqL1xuICAgIGFzeW5jIHNlbmRNZXNzYWdlKHJlcXVlc3QsIHJlcXVlc3RPcHRpb25zID0ge30pIHtcbiAgICAgICAgdmFyIF9hLCBfYiwgX2MsIF9kLCBfZSwgX2Y7XG4gICAgICAgIGF3YWl0IHRoaXMuX3NlbmRQcm9taXNlO1xuICAgICAgICBjb25zdCBuZXdDb250ZW50ID0gZm9ybWF0TmV3Q29udGVudChyZXF1ZXN0KTtcbiAgICAgICAgY29uc3QgZ2VuZXJhdGVDb250ZW50UmVxdWVzdCA9IHtcbiAgICAgICAgICAgIHNhZmV0eVNldHRpbmdzOiAoX2EgPSB0aGlzLnBhcmFtcykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLnNhZmV0eVNldHRpbmdzLFxuICAgICAgICAgICAgZ2VuZXJhdGlvbkNvbmZpZzogKF9iID0gdGhpcy5wYXJhbXMpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5nZW5lcmF0aW9uQ29uZmlnLFxuICAgICAgICAgICAgdG9vbHM6IChfYyA9IHRoaXMucGFyYW1zKSA9PT0gbnVsbCB8fCBfYyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2MudG9vbHMsXG4gICAgICAgICAgICB0b29sQ29uZmlnOiAoX2QgPSB0aGlzLnBhcmFtcykgPT09IG51bGwgfHwgX2QgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9kLnRvb2xDb25maWcsXG4gICAgICAgICAgICBzeXN0ZW1JbnN0cnVjdGlvbjogKF9lID0gdGhpcy5wYXJhbXMpID09PSBudWxsIHx8IF9lID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZS5zeXN0ZW1JbnN0cnVjdGlvbixcbiAgICAgICAgICAgIGNhY2hlZENvbnRlbnQ6IChfZiA9IHRoaXMucGFyYW1zKSA9PT0gbnVsbCB8fCBfZiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2YuY2FjaGVkQ29udGVudCxcbiAgICAgICAgICAgIGNvbnRlbnRzOiBbLi4udGhpcy5faGlzdG9yeSwgbmV3Q29udGVudF0sXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNoYXRTZXNzaW9uUmVxdWVzdE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHRoaXMuX3JlcXVlc3RPcHRpb25zKSwgcmVxdWVzdE9wdGlvbnMpO1xuICAgICAgICBsZXQgZmluYWxSZXN1bHQ7XG4gICAgICAgIC8vIEFkZCBvbnRvIHRoZSBjaGFpbi5cbiAgICAgICAgdGhpcy5fc2VuZFByb21pc2UgPSB0aGlzLl9zZW5kUHJvbWlzZVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gZ2VuZXJhdGVDb250ZW50KHRoaXMuX2FwaUtleSwgdGhpcy5tb2RlbCwgZ2VuZXJhdGVDb250ZW50UmVxdWVzdCwgY2hhdFNlc3Npb25SZXF1ZXN0T3B0aW9ucykpXG4gICAgICAgICAgICAudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICBpZiAoaXNWYWxpZFJlc3BvbnNlKHJlc3VsdC5yZXNwb25zZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9oaXN0b3J5LnB1c2gobmV3Q29udGVudCk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2VDb250ZW50ID0gT2JqZWN0LmFzc2lnbih7IHBhcnRzOiBbXSwgXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc3BvbnNlIHNlZW1zIHRvIGNvbWUgYmFjayB3aXRob3V0IGEgcm9sZSBzZXQuXG4gICAgICAgICAgICAgICAgICAgIHJvbGU6IFwibW9kZWxcIiB9LCAoX2EgPSByZXN1bHQucmVzcG9uc2UuY2FuZGlkYXRlcykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hWzBdLmNvbnRlbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2hpc3RvcnkucHVzaChyZXNwb25zZUNvbnRlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYmxvY2tFcnJvck1lc3NhZ2UgPSBmb3JtYXRCbG9ja0Vycm9yTWVzc2FnZShyZXN1bHQucmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGlmIChibG9ja0Vycm9yTWVzc2FnZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYHNlbmRNZXNzYWdlKCkgd2FzIHVuc3VjY2Vzc2Z1bC4gJHtibG9ja0Vycm9yTWVzc2FnZX0uIEluc3BlY3QgcmVzcG9uc2Ugb2JqZWN0IGZvciBkZXRhaWxzLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsUmVzdWx0ID0gcmVzdWx0O1xuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5fc2VuZFByb21pc2U7XG4gICAgICAgIHJldHVybiBmaW5hbFJlc3VsdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VuZHMgYSBjaGF0IG1lc3NhZ2UgYW5kIHJlY2VpdmVzIHRoZSByZXNwb25zZSBhcyBhXG4gICAgICoge0BsaW5rIEdlbmVyYXRlQ29udGVudFN0cmVhbVJlc3VsdH0gY29udGFpbmluZyBhbiBpdGVyYWJsZSBzdHJlYW1cbiAgICAgKiBhbmQgYSByZXNwb25zZSBwcm9taXNlLlxuICAgICAqXG4gICAgICogRmllbGRzIHNldCBpbiB0aGUgb3B0aW9uYWwge0BsaW5rIFNpbmdsZVJlcXVlc3RPcHRpb25zfSBwYXJhbWV0ZXIgd2lsbFxuICAgICAqIHRha2UgcHJlY2VkZW5jZSBvdmVyIHRoZSB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IHZhbHVlcyBwcm92aWRlZCB0b1xuICAgICAqIHtAbGluayBHb29nbGVHZW5lcmF0aXZlQUkuZ2V0R2VuZXJhdGl2ZU1vZGVsIH0uXG4gICAgICovXG4gICAgYXN5bmMgc2VuZE1lc3NhZ2VTdHJlYW0ocmVxdWVzdCwgcmVxdWVzdE9wdGlvbnMgPSB7fSkge1xuICAgICAgICB2YXIgX2EsIF9iLCBfYywgX2QsIF9lLCBfZjtcbiAgICAgICAgYXdhaXQgdGhpcy5fc2VuZFByb21pc2U7XG4gICAgICAgIGNvbnN0IG5ld0NvbnRlbnQgPSBmb3JtYXROZXdDb250ZW50KHJlcXVlc3QpO1xuICAgICAgICBjb25zdCBnZW5lcmF0ZUNvbnRlbnRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgc2FmZXR5U2V0dGluZ3M6IChfYSA9IHRoaXMucGFyYW1zKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Euc2FmZXR5U2V0dGluZ3MsXG4gICAgICAgICAgICBnZW5lcmF0aW9uQ29uZmlnOiAoX2IgPSB0aGlzLnBhcmFtcykgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmdlbmVyYXRpb25Db25maWcsXG4gICAgICAgICAgICB0b29sczogKF9jID0gdGhpcy5wYXJhbXMpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYy50b29scyxcbiAgICAgICAgICAgIHRvb2xDb25maWc6IChfZCA9IHRoaXMucGFyYW1zKSA9PT0gbnVsbCB8fCBfZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2QudG9vbENvbmZpZyxcbiAgICAgICAgICAgIHN5c3RlbUluc3RydWN0aW9uOiAoX2UgPSB0aGlzLnBhcmFtcykgPT09IG51bGwgfHwgX2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9lLnN5c3RlbUluc3RydWN0aW9uLFxuICAgICAgICAgICAgY2FjaGVkQ29udGVudDogKF9mID0gdGhpcy5wYXJhbXMpID09PSBudWxsIHx8IF9mID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZi5jYWNoZWRDb250ZW50LFxuICAgICAgICAgICAgY29udGVudHM6IFsuLi50aGlzLl9oaXN0b3J5LCBuZXdDb250ZW50XSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY2hhdFNlc3Npb25SZXF1ZXN0T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fcmVxdWVzdE9wdGlvbnMpLCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IHN0cmVhbVByb21pc2UgPSBnZW5lcmF0ZUNvbnRlbnRTdHJlYW0odGhpcy5fYXBpS2V5LCB0aGlzLm1vZGVsLCBnZW5lcmF0ZUNvbnRlbnRSZXF1ZXN0LCBjaGF0U2Vzc2lvblJlcXVlc3RPcHRpb25zKTtcbiAgICAgICAgLy8gQWRkIG9udG8gdGhlIGNoYWluLlxuICAgICAgICB0aGlzLl9zZW5kUHJvbWlzZSA9IHRoaXMuX3NlbmRQcm9taXNlXG4gICAgICAgICAgICAudGhlbigoKSA9PiBzdHJlYW1Qcm9taXNlKVxuICAgICAgICAgICAgLy8gVGhpcyBtdXN0IGJlIGhhbmRsZWQgdG8gYXZvaWQgdW5oYW5kbGVkIHJlamVjdGlvbiwgYnV0IGp1bXBcbiAgICAgICAgICAgIC8vIHRvIHRoZSBmaW5hbCBjYXRjaCBibG9jayB3aXRoIGEgbGFiZWwgdG8gbm90IGxvZyB0aGlzIGVycm9yLlxuICAgICAgICAgICAgLmNhdGNoKChfaWdub3JlZCkgPT4ge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFNJTEVOVF9FUlJPUik7XG4gICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoc3RyZWFtUmVzdWx0KSA9PiBzdHJlYW1SZXN1bHQucmVzcG9uc2UpXG4gICAgICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChpc1ZhbGlkUmVzcG9uc2UocmVzcG9uc2UpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5faGlzdG9yeS5wdXNoKG5ld0NvbnRlbnQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlQ29udGVudCA9IE9iamVjdC5hc3NpZ24oe30sIHJlc3BvbnNlLmNhbmRpZGF0ZXNbMF0uY29udGVudCk7XG4gICAgICAgICAgICAgICAgLy8gUmVzcG9uc2Ugc2VlbXMgdG8gY29tZSBiYWNrIHdpdGhvdXQgYSByb2xlIHNldC5cbiAgICAgICAgICAgICAgICBpZiAoIXJlc3BvbnNlQ29udGVudC5yb2xlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlQ29udGVudC5yb2xlID0gXCJtb2RlbFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9oaXN0b3J5LnB1c2gocmVzcG9uc2VDb250ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJsb2NrRXJyb3JNZXNzYWdlID0gZm9ybWF0QmxvY2tFcnJvck1lc3NhZ2UocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGlmIChibG9ja0Vycm9yTWVzc2FnZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYHNlbmRNZXNzYWdlU3RyZWFtKCkgd2FzIHVuc3VjY2Vzc2Z1bC4gJHtibG9ja0Vycm9yTWVzc2FnZX0uIEluc3BlY3QgcmVzcG9uc2Ugb2JqZWN0IGZvciBkZXRhaWxzLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gRXJyb3JzIGluIHN0cmVhbVByb21pc2UgYXJlIGFscmVhZHkgY2F0Y2hhYmxlIGJ5IHRoZSB1c2VyIGFzXG4gICAgICAgICAgICAvLyBzdHJlYW1Qcm9taXNlIGlzIHJldHVybmVkLlxuICAgICAgICAgICAgLy8gQXZvaWQgZHVwbGljYXRpbmcgdGhlIGVycm9yIG1lc3NhZ2UgaW4gbG9ncy5cbiAgICAgICAgICAgIGlmIChlLm1lc3NhZ2UgIT09IFNJTEVOVF9FUlJPUikge1xuICAgICAgICAgICAgICAgIC8vIFVzZXJzIGRvIG5vdCBoYXZlIGFjY2VzcyB0byBfc2VuZFByb21pc2UgdG8gY2F0Y2ggZXJyb3JzXG4gICAgICAgICAgICAgICAgLy8gZG93bnN0cmVhbSBmcm9tIHN0cmVhbVByb21pc2UsIHNvIHRoZXkgc2hvdWxkIG5vdCB0aHJvdy5cbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHN0cmVhbVByb21pc2U7XG4gICAgfVxufVxuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gY291bnRUb2tlbnMoYXBpS2V5LCBtb2RlbCwgcGFyYW1zLCBzaW5nbGVSZXF1ZXN0T3B0aW9ucykge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgbWFrZU1vZGVsUmVxdWVzdChtb2RlbCwgVGFzay5DT1VOVF9UT0tFTlMsIGFwaUtleSwgZmFsc2UsIEpTT04uc3RyaW5naWZ5KHBhcmFtcyksIHNpbmdsZVJlcXVlc3RPcHRpb25zKTtcbiAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xufVxuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZW1iZWRDb250ZW50KGFwaUtleSwgbW9kZWwsIHBhcmFtcywgcmVxdWVzdE9wdGlvbnMpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG1ha2VNb2RlbFJlcXVlc3QobW9kZWwsIFRhc2suRU1CRURfQ09OVEVOVCwgYXBpS2V5LCBmYWxzZSwgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSwgcmVxdWVzdE9wdGlvbnMpO1xuICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG59XG5hc3luYyBmdW5jdGlvbiBiYXRjaEVtYmVkQ29udGVudHMoYXBpS2V5LCBtb2RlbCwgcGFyYW1zLCByZXF1ZXN0T3B0aW9ucykge1xuICAgIGNvbnN0IHJlcXVlc3RzV2l0aE1vZGVsID0gcGFyYW1zLnJlcXVlc3RzLm1hcCgocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCByZXF1ZXN0KSwgeyBtb2RlbCB9KTtcbiAgICB9KTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG1ha2VNb2RlbFJlcXVlc3QobW9kZWwsIFRhc2suQkFUQ0hfRU1CRURfQ09OVEVOVFMsIGFwaUtleSwgZmFsc2UsIEpTT04uc3RyaW5naWZ5KHsgcmVxdWVzdHM6IHJlcXVlc3RzV2l0aE1vZGVsIH0pLCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbn1cblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbi8qKlxuICogQ2xhc3MgZm9yIGdlbmVyYXRpdmUgbW9kZWwgQVBJcy5cbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgR2VuZXJhdGl2ZU1vZGVsIHtcbiAgICBjb25zdHJ1Y3RvcihhcGlLZXksIG1vZGVsUGFyYW1zLCBfcmVxdWVzdE9wdGlvbnMgPSB7fSkge1xuICAgICAgICB0aGlzLmFwaUtleSA9IGFwaUtleTtcbiAgICAgICAgdGhpcy5fcmVxdWVzdE9wdGlvbnMgPSBfcmVxdWVzdE9wdGlvbnM7XG4gICAgICAgIGlmIChtb2RlbFBhcmFtcy5tb2RlbC5pbmNsdWRlcyhcIi9cIikpIHtcbiAgICAgICAgICAgIC8vIE1vZGVscyBtYXkgYmUgbmFtZWQgXCJtb2RlbHMvbW9kZWwtbmFtZVwiIG9yIFwidHVuZWRNb2RlbHMvbW9kZWwtbmFtZVwiXG4gICAgICAgICAgICB0aGlzLm1vZGVsID0gbW9kZWxQYXJhbXMubW9kZWw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBJZiBwYXRoIGlzIG5vdCBpbmNsdWRlZCwgYXNzdW1lIGl0J3MgYSBub24tdHVuZWQgbW9kZWwuXG4gICAgICAgICAgICB0aGlzLm1vZGVsID0gYG1vZGVscy8ke21vZGVsUGFyYW1zLm1vZGVsfWA7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5nZW5lcmF0aW9uQ29uZmlnID0gbW9kZWxQYXJhbXMuZ2VuZXJhdGlvbkNvbmZpZyB8fCB7fTtcbiAgICAgICAgdGhpcy5zYWZldHlTZXR0aW5ncyA9IG1vZGVsUGFyYW1zLnNhZmV0eVNldHRpbmdzIHx8IFtdO1xuICAgICAgICB0aGlzLnRvb2xzID0gbW9kZWxQYXJhbXMudG9vbHM7XG4gICAgICAgIHRoaXMudG9vbENvbmZpZyA9IG1vZGVsUGFyYW1zLnRvb2xDb25maWc7XG4gICAgICAgIHRoaXMuc3lzdGVtSW5zdHJ1Y3Rpb24gPSBmb3JtYXRTeXN0ZW1JbnN0cnVjdGlvbihtb2RlbFBhcmFtcy5zeXN0ZW1JbnN0cnVjdGlvbik7XG4gICAgICAgIHRoaXMuY2FjaGVkQ29udGVudCA9IG1vZGVsUGFyYW1zLmNhY2hlZENvbnRlbnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1ha2VzIGEgc2luZ2xlIG5vbi1zdHJlYW1pbmcgY2FsbCB0byB0aGUgbW9kZWxcbiAgICAgKiBhbmQgcmV0dXJucyBhbiBvYmplY3QgY29udGFpbmluZyBhIHNpbmdsZSB7QGxpbmsgR2VuZXJhdGVDb250ZW50UmVzcG9uc2V9LlxuICAgICAqXG4gICAgICogRmllbGRzIHNldCBpbiB0aGUgb3B0aW9uYWwge0BsaW5rIFNpbmdsZVJlcXVlc3RPcHRpb25zfSBwYXJhbWV0ZXIgd2lsbFxuICAgICAqIHRha2UgcHJlY2VkZW5jZSBvdmVyIHRoZSB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IHZhbHVlcyBwcm92aWRlZCB0b1xuICAgICAqIHtAbGluayBHb29nbGVHZW5lcmF0aXZlQUkuZ2V0R2VuZXJhdGl2ZU1vZGVsIH0uXG4gICAgICovXG4gICAgYXN5bmMgZ2VuZXJhdGVDb250ZW50KHJlcXVlc3QsIHJlcXVlc3RPcHRpb25zID0ge30pIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICBjb25zdCBmb3JtYXR0ZWRQYXJhbXMgPSBmb3JtYXRHZW5lcmF0ZUNvbnRlbnRJbnB1dChyZXF1ZXN0KTtcbiAgICAgICAgY29uc3QgZ2VuZXJhdGl2ZU1vZGVsUmVxdWVzdE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHRoaXMuX3JlcXVlc3RPcHRpb25zKSwgcmVxdWVzdE9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gZ2VuZXJhdGVDb250ZW50KHRoaXMuYXBpS2V5LCB0aGlzLm1vZGVsLCBPYmplY3QuYXNzaWduKHsgZ2VuZXJhdGlvbkNvbmZpZzogdGhpcy5nZW5lcmF0aW9uQ29uZmlnLCBzYWZldHlTZXR0aW5nczogdGhpcy5zYWZldHlTZXR0aW5ncywgdG9vbHM6IHRoaXMudG9vbHMsIHRvb2xDb25maWc6IHRoaXMudG9vbENvbmZpZywgc3lzdGVtSW5zdHJ1Y3Rpb246IHRoaXMuc3lzdGVtSW5zdHJ1Y3Rpb24sIGNhY2hlZENvbnRlbnQ6IChfYSA9IHRoaXMuY2FjaGVkQ29udGVudCkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLm5hbWUgfSwgZm9ybWF0dGVkUGFyYW1zKSwgZ2VuZXJhdGl2ZU1vZGVsUmVxdWVzdE9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhIHNpbmdsZSBzdHJlYW1pbmcgY2FsbCB0byB0aGUgbW9kZWwgYW5kIHJldHVybnMgYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyBhbiBpdGVyYWJsZSBzdHJlYW0gdGhhdCBpdGVyYXRlcyBvdmVyIGFsbCBjaHVua3MgaW4gdGhlXG4gICAgICogc3RyZWFtaW5nIHJlc3BvbnNlIGFzIHdlbGwgYXMgYSBwcm9taXNlIHRoYXQgcmV0dXJucyB0aGUgZmluYWxcbiAgICAgKiBhZ2dyZWdhdGVkIHJlc3BvbnNlLlxuICAgICAqXG4gICAgICogRmllbGRzIHNldCBpbiB0aGUgb3B0aW9uYWwge0BsaW5rIFNpbmdsZVJlcXVlc3RPcHRpb25zfSBwYXJhbWV0ZXIgd2lsbFxuICAgICAqIHRha2UgcHJlY2VkZW5jZSBvdmVyIHRoZSB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IHZhbHVlcyBwcm92aWRlZCB0b1xuICAgICAqIHtAbGluayBHb29nbGVHZW5lcmF0aXZlQUkuZ2V0R2VuZXJhdGl2ZU1vZGVsIH0uXG4gICAgICovXG4gICAgYXN5bmMgZ2VuZXJhdGVDb250ZW50U3RyZWFtKHJlcXVlc3QsIHJlcXVlc3RPcHRpb25zID0ge30pIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICBjb25zdCBmb3JtYXR0ZWRQYXJhbXMgPSBmb3JtYXRHZW5lcmF0ZUNvbnRlbnRJbnB1dChyZXF1ZXN0KTtcbiAgICAgICAgY29uc3QgZ2VuZXJhdGl2ZU1vZGVsUmVxdWVzdE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHRoaXMuX3JlcXVlc3RPcHRpb25zKSwgcmVxdWVzdE9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gZ2VuZXJhdGVDb250ZW50U3RyZWFtKHRoaXMuYXBpS2V5LCB0aGlzLm1vZGVsLCBPYmplY3QuYXNzaWduKHsgZ2VuZXJhdGlvbkNvbmZpZzogdGhpcy5nZW5lcmF0aW9uQ29uZmlnLCBzYWZldHlTZXR0aW5nczogdGhpcy5zYWZldHlTZXR0aW5ncywgdG9vbHM6IHRoaXMudG9vbHMsIHRvb2xDb25maWc6IHRoaXMudG9vbENvbmZpZywgc3lzdGVtSW5zdHJ1Y3Rpb246IHRoaXMuc3lzdGVtSW5zdHJ1Y3Rpb24sIGNhY2hlZENvbnRlbnQ6IChfYSA9IHRoaXMuY2FjaGVkQ29udGVudCkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLm5hbWUgfSwgZm9ybWF0dGVkUGFyYW1zKSwgZ2VuZXJhdGl2ZU1vZGVsUmVxdWVzdE9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXRzIGEgbmV3IHtAbGluayBDaGF0U2Vzc2lvbn0gaW5zdGFuY2Ugd2hpY2ggY2FuIGJlIHVzZWQgZm9yXG4gICAgICogbXVsdGktdHVybiBjaGF0cy5cbiAgICAgKi9cbiAgICBzdGFydENoYXQoc3RhcnRDaGF0UGFyYW1zKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgcmV0dXJuIG5ldyBDaGF0U2Vzc2lvbih0aGlzLmFwaUtleSwgdGhpcy5tb2RlbCwgT2JqZWN0LmFzc2lnbih7IGdlbmVyYXRpb25Db25maWc6IHRoaXMuZ2VuZXJhdGlvbkNvbmZpZywgc2FmZXR5U2V0dGluZ3M6IHRoaXMuc2FmZXR5U2V0dGluZ3MsIHRvb2xzOiB0aGlzLnRvb2xzLCB0b29sQ29uZmlnOiB0aGlzLnRvb2xDb25maWcsIHN5c3RlbUluc3RydWN0aW9uOiB0aGlzLnN5c3RlbUluc3RydWN0aW9uLCBjYWNoZWRDb250ZW50OiAoX2EgPSB0aGlzLmNhY2hlZENvbnRlbnQpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5uYW1lIH0sIHN0YXJ0Q2hhdFBhcmFtcyksIHRoaXMuX3JlcXVlc3RPcHRpb25zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ291bnRzIHRoZSB0b2tlbnMgaW4gdGhlIHByb3ZpZGVkIHJlcXVlc3QuXG4gICAgICpcbiAgICAgKiBGaWVsZHMgc2V0IGluIHRoZSBvcHRpb25hbCB7QGxpbmsgU2luZ2xlUmVxdWVzdE9wdGlvbnN9IHBhcmFtZXRlciB3aWxsXG4gICAgICogdGFrZSBwcmVjZWRlbmNlIG92ZXIgdGhlIHtAbGluayBSZXF1ZXN0T3B0aW9uc30gdmFsdWVzIHByb3ZpZGVkIHRvXG4gICAgICoge0BsaW5rIEdvb2dsZUdlbmVyYXRpdmVBSS5nZXRHZW5lcmF0aXZlTW9kZWwgfS5cbiAgICAgKi9cbiAgICBhc3luYyBjb3VudFRva2VucyhyZXF1ZXN0LCByZXF1ZXN0T3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZFBhcmFtcyA9IGZvcm1hdENvdW50VG9rZW5zSW5wdXQocmVxdWVzdCwge1xuICAgICAgICAgICAgbW9kZWw6IHRoaXMubW9kZWwsXG4gICAgICAgICAgICBnZW5lcmF0aW9uQ29uZmlnOiB0aGlzLmdlbmVyYXRpb25Db25maWcsXG4gICAgICAgICAgICBzYWZldHlTZXR0aW5nczogdGhpcy5zYWZldHlTZXR0aW5ncyxcbiAgICAgICAgICAgIHRvb2xzOiB0aGlzLnRvb2xzLFxuICAgICAgICAgICAgdG9vbENvbmZpZzogdGhpcy50b29sQ29uZmlnLFxuICAgICAgICAgICAgc3lzdGVtSW5zdHJ1Y3Rpb246IHRoaXMuc3lzdGVtSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgICBjYWNoZWRDb250ZW50OiB0aGlzLmNhY2hlZENvbnRlbnQsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBnZW5lcmF0aXZlTW9kZWxSZXF1ZXN0T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fcmVxdWVzdE9wdGlvbnMpLCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBjb3VudFRva2Vucyh0aGlzLmFwaUtleSwgdGhpcy5tb2RlbCwgZm9ybWF0dGVkUGFyYW1zLCBnZW5lcmF0aXZlTW9kZWxSZXF1ZXN0T3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVtYmVkcyB0aGUgcHJvdmlkZWQgY29udGVudC5cbiAgICAgKlxuICAgICAqIEZpZWxkcyBzZXQgaW4gdGhlIG9wdGlvbmFsIHtAbGluayBTaW5nbGVSZXF1ZXN0T3B0aW9uc30gcGFyYW1ldGVyIHdpbGxcbiAgICAgKiB0YWtlIHByZWNlZGVuY2Ugb3ZlciB0aGUge0BsaW5rIFJlcXVlc3RPcHRpb25zfSB2YWx1ZXMgcHJvdmlkZWQgdG9cbiAgICAgKiB7QGxpbmsgR29vZ2xlR2VuZXJhdGl2ZUFJLmdldEdlbmVyYXRpdmVNb2RlbCB9LlxuICAgICAqL1xuICAgIGFzeW5jIGVtYmVkQ29udGVudChyZXF1ZXN0LCByZXF1ZXN0T3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZFBhcmFtcyA9IGZvcm1hdEVtYmVkQ29udGVudElucHV0KHJlcXVlc3QpO1xuICAgICAgICBjb25zdCBnZW5lcmF0aXZlTW9kZWxSZXF1ZXN0T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fcmVxdWVzdE9wdGlvbnMpLCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBlbWJlZENvbnRlbnQodGhpcy5hcGlLZXksIHRoaXMubW9kZWwsIGZvcm1hdHRlZFBhcmFtcywgZ2VuZXJhdGl2ZU1vZGVsUmVxdWVzdE9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFbWJlZHMgYW4gYXJyYXkgb2Yge0BsaW5rIEVtYmVkQ29udGVudFJlcXVlc3R9cy5cbiAgICAgKlxuICAgICAqIEZpZWxkcyBzZXQgaW4gdGhlIG9wdGlvbmFsIHtAbGluayBTaW5nbGVSZXF1ZXN0T3B0aW9uc30gcGFyYW1ldGVyIHdpbGxcbiAgICAgKiB0YWtlIHByZWNlZGVuY2Ugb3ZlciB0aGUge0BsaW5rIFJlcXVlc3RPcHRpb25zfSB2YWx1ZXMgcHJvdmlkZWQgdG9cbiAgICAgKiB7QGxpbmsgR29vZ2xlR2VuZXJhdGl2ZUFJLmdldEdlbmVyYXRpdmVNb2RlbCB9LlxuICAgICAqL1xuICAgIGFzeW5jIGJhdGNoRW1iZWRDb250ZW50cyhiYXRjaEVtYmVkQ29udGVudFJlcXVlc3QsIHJlcXVlc3RPcHRpb25zID0ge30pIHtcbiAgICAgICAgY29uc3QgZ2VuZXJhdGl2ZU1vZGVsUmVxdWVzdE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHRoaXMuX3JlcXVlc3RPcHRpb25zKSwgcmVxdWVzdE9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gYmF0Y2hFbWJlZENvbnRlbnRzKHRoaXMuYXBpS2V5LCB0aGlzLm1vZGVsLCBiYXRjaEVtYmVkQ29udGVudFJlcXVlc3QsIGdlbmVyYXRpdmVNb2RlbFJlcXVlc3RPcHRpb25zKTtcbiAgICB9XG59XG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIFRvcC1sZXZlbCBjbGFzcyBmb3IgdGhpcyBTREtcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgR29vZ2xlR2VuZXJhdGl2ZUFJIHtcbiAgICBjb25zdHJ1Y3RvcihhcGlLZXkpIHtcbiAgICAgICAgdGhpcy5hcGlLZXkgPSBhcGlLZXk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldHMgYSB7QGxpbmsgR2VuZXJhdGl2ZU1vZGVsfSBpbnN0YW5jZSBmb3IgdGhlIHByb3ZpZGVkIG1vZGVsIG5hbWUuXG4gICAgICovXG4gICAgZ2V0R2VuZXJhdGl2ZU1vZGVsKG1vZGVsUGFyYW1zLCByZXF1ZXN0T3B0aW9ucykge1xuICAgICAgICBpZiAoIW1vZGVsUGFyYW1zLm1vZGVsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJRXJyb3IoYE11c3QgcHJvdmlkZSBhIG1vZGVsIG5hbWUuIGAgK1xuICAgICAgICAgICAgICAgIGBFeGFtcGxlOiBnZW5haS5nZXRHZW5lcmF0aXZlTW9kZWwoeyBtb2RlbDogJ215LW1vZGVsLW5hbWUnIH0pYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmF0aXZlTW9kZWwodGhpcy5hcGlLZXksIG1vZGVsUGFyYW1zLCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB7QGxpbmsgR2VuZXJhdGl2ZU1vZGVsfSBpbnN0YW5jZSBmcm9tIHByb3ZpZGVkIGNvbnRlbnQgY2FjaGUuXG4gICAgICovXG4gICAgZ2V0R2VuZXJhdGl2ZU1vZGVsRnJvbUNhY2hlZENvbnRlbnQoY2FjaGVkQ29udGVudCwgbW9kZWxQYXJhbXMsIHJlcXVlc3RPcHRpb25zKSB7XG4gICAgICAgIGlmICghY2FjaGVkQ29udGVudC5uYW1lKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3IoXCJDYWNoZWQgY29udGVudCBtdXN0IGNvbnRhaW4gYSBgbmFtZWAgZmllbGQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY2FjaGVkQ29udGVudC5tb2RlbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEdvb2dsZUdlbmVyYXRpdmVBSVJlcXVlc3RJbnB1dEVycm9yKFwiQ2FjaGVkIGNvbnRlbnQgbXVzdCBjb250YWluIGEgYG1vZGVsYCBmaWVsZC5cIik7XG4gICAgICAgIH1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE5vdCBjaGVja2luZyB0b29scyBhbmQgdG9vbENvbmZpZyBmb3Igbm93IGFzIGl0IHdvdWxkIHJlcXVpcmUgYSBkZWVwXG4gICAgICAgICAqIGVxdWFsaXR5IGNvbXBhcmlzb24gYW5kIGlzbid0IGxpa2VseSB0byBiZSBhIGNvbW1vbiBjYXNlLlxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgZGlzYWxsb3dlZER1cGxpY2F0ZXMgPSBbXCJtb2RlbFwiLCBcInN5c3RlbUluc3RydWN0aW9uXCJdO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBkaXNhbGxvd2VkRHVwbGljYXRlcykge1xuICAgICAgICAgICAgaWYgKChtb2RlbFBhcmFtcyA9PT0gbnVsbCB8fCBtb2RlbFBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogbW9kZWxQYXJhbXNba2V5XSkgJiZcbiAgICAgICAgICAgICAgICBjYWNoZWRDb250ZW50W2tleV0gJiZcbiAgICAgICAgICAgICAgICAobW9kZWxQYXJhbXMgPT09IG51bGwgfHwgbW9kZWxQYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG1vZGVsUGFyYW1zW2tleV0pICE9PSBjYWNoZWRDb250ZW50W2tleV0pIHtcbiAgICAgICAgICAgICAgICBpZiAoa2V5ID09PSBcIm1vZGVsXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbW9kZWxQYXJhbXNDb21wID0gbW9kZWxQYXJhbXMubW9kZWwuc3RhcnRzV2l0aChcIm1vZGVscy9cIilcbiAgICAgICAgICAgICAgICAgICAgICAgID8gbW9kZWxQYXJhbXMubW9kZWwucmVwbGFjZShcIm1vZGVscy9cIiwgXCJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbW9kZWxQYXJhbXMubW9kZWw7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhY2hlZENvbnRlbnRDb21wID0gY2FjaGVkQ29udGVudC5tb2RlbC5zdGFydHNXaXRoKFwibW9kZWxzL1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBjYWNoZWRDb250ZW50Lm1vZGVsLnJlcGxhY2UoXCJtb2RlbHMvXCIsIFwiXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGNhY2hlZENvbnRlbnQubW9kZWw7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtb2RlbFBhcmFtc0NvbXAgPT09IGNhY2hlZENvbnRlbnRDb21wKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3IoYERpZmZlcmVudCB2YWx1ZSBmb3IgXCIke2tleX1cIiBzcGVjaWZpZWQgaW4gbW9kZWxQYXJhbXNgICtcbiAgICAgICAgICAgICAgICAgICAgYCAoJHttb2RlbFBhcmFtc1trZXldfSkgYW5kIGNhY2hlZENvbnRlbnQgKCR7Y2FjaGVkQ29udGVudFtrZXldfSlgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtb2RlbFBhcmFtc0Zyb21DYWNoZSA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgbW9kZWxQYXJhbXMpLCB7IG1vZGVsOiBjYWNoZWRDb250ZW50Lm1vZGVsLCB0b29sczogY2FjaGVkQ29udGVudC50b29scywgdG9vbENvbmZpZzogY2FjaGVkQ29udGVudC50b29sQ29uZmlnLCBzeXN0ZW1JbnN0cnVjdGlvbjogY2FjaGVkQ29udGVudC5zeXN0ZW1JbnN0cnVjdGlvbiwgY2FjaGVkQ29udGVudCB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmF0aXZlTW9kZWwodGhpcy5hcGlLZXksIG1vZGVsUGFyYW1zRnJvbUNhY2hlLCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgfVxufVxuXG5leHBvcnRzLkNoYXRTZXNzaW9uID0gQ2hhdFNlc3Npb247XG5leHBvcnRzLkdlbmVyYXRpdmVNb2RlbCA9IEdlbmVyYXRpdmVNb2RlbDtcbmV4cG9ydHMuR29vZ2xlR2VuZXJhdGl2ZUFJID0gR29vZ2xlR2VuZXJhdGl2ZUFJO1xuZXhwb3J0cy5Hb29nbGVHZW5lcmF0aXZlQUlBYm9ydEVycm9yID0gR29vZ2xlR2VuZXJhdGl2ZUFJQWJvcnRFcnJvcjtcbmV4cG9ydHMuR29vZ2xlR2VuZXJhdGl2ZUFJRXJyb3IgPSBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcjtcbmV4cG9ydHMuR29vZ2xlR2VuZXJhdGl2ZUFJRmV0Y2hFcnJvciA9IEdvb2dsZUdlbmVyYXRpdmVBSUZldGNoRXJyb3I7XG5leHBvcnRzLkdvb2dsZUdlbmVyYXRpdmVBSVJlcXVlc3RJbnB1dEVycm9yID0gR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3I7XG5leHBvcnRzLkdvb2dsZUdlbmVyYXRpdmVBSVJlc3BvbnNlRXJyb3IgPSBHb29nbGVHZW5lcmF0aXZlQUlSZXNwb25zZUVycm9yO1xuZXhwb3J0cy5QT1NTSUJMRV9ST0xFUyA9IFBPU1NJQkxFX1JPTEVTO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwXG4iXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbMF0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(action-browser)/./node_modules/@google/generative-ai/dist/index.js\n"); + +/***/ }), + +/***/ "(action-browser)/./node_modules/@google/generative-ai/dist/server/index.js": +/*!*****************************************************************!*\ + !*** ./node_modules/@google/generative-ai/dist/server/index.js ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +eval("\n\nvar fs = __webpack_require__(/*! fs */ \"fs\");\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Basic error type for this SDK.\n * @public\n */\nclass GoogleGenerativeAIError extends Error {\n constructor(message) {\n super(`[GoogleGenerativeAI Error]: ${message}`);\n }\n}\n/**\n * Error class covering HTTP errors when calling the server. Includes HTTP\n * status, statusText, and optional details, if provided in the server response.\n * @public\n */\nclass GoogleGenerativeAIFetchError extends GoogleGenerativeAIError {\n constructor(message, status, statusText, errorDetails) {\n super(message);\n this.status = status;\n this.statusText = statusText;\n this.errorDetails = errorDetails;\n }\n}\n/**\n * Errors in the contents of a request originating from user input.\n * @public\n */\nclass GoogleGenerativeAIRequestInputError extends GoogleGenerativeAIError {\n}\n/**\n * Error thrown when a request is aborted, either due to a timeout or\n * intentional cancellation by the user.\n * @public\n */\nclass GoogleGenerativeAIAbortError extends GoogleGenerativeAIError {\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst DEFAULT_BASE_URL = \"https://generativelanguage.googleapis.com\";\nconst DEFAULT_API_VERSION = \"v1beta\";\n/**\n * We can't `require` package.json if this runs on web. We will use rollup to\n * swap in the version number here at build time.\n */\nconst PACKAGE_VERSION = \"0.24.0\";\nconst PACKAGE_LOG_HEADER = \"genai-js\";\nvar Task;\n(function (Task) {\n Task[\"GENERATE_CONTENT\"] = \"generateContent\";\n Task[\"STREAM_GENERATE_CONTENT\"] = \"streamGenerateContent\";\n Task[\"COUNT_TOKENS\"] = \"countTokens\";\n Task[\"EMBED_CONTENT\"] = \"embedContent\";\n Task[\"BATCH_EMBED_CONTENTS\"] = \"batchEmbedContents\";\n})(Task || (Task = {}));\n/**\n * Simple, but may become more complex if we add more versions to log.\n */\nfunction getClientHeaders(requestOptions) {\n const clientHeaders = [];\n if (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.apiClient) {\n clientHeaders.push(requestOptions.apiClient);\n }\n clientHeaders.push(`${PACKAGE_LOG_HEADER}/${PACKAGE_VERSION}`);\n return clientHeaders.join(\" \");\n}\nasync function makeRequest(url, fetchOptions, fetchFn = fetch) {\n let response;\n try {\n response = await fetchFn(url, fetchOptions);\n }\n catch (e) {\n handleResponseError(e, url);\n }\n if (!response.ok) {\n await handleResponseNotOk(response, url);\n }\n return response;\n}\nfunction handleResponseError(e, url) {\n let err = e;\n if (err.name === \"AbortError\") {\n err = new GoogleGenerativeAIAbortError(`Request aborted when fetching ${url.toString()}: ${e.message}`);\n err.stack = e.stack;\n }\n else if (!(e instanceof GoogleGenerativeAIFetchError ||\n e instanceof GoogleGenerativeAIRequestInputError)) {\n err = new GoogleGenerativeAIError(`Error fetching from ${url.toString()}: ${e.message}`);\n err.stack = e.stack;\n }\n throw err;\n}\nasync function handleResponseNotOk(response, url) {\n let message = \"\";\n let errorDetails;\n try {\n const json = await response.json();\n message = json.error.message;\n if (json.error.details) {\n message += ` ${JSON.stringify(json.error.details)}`;\n errorDetails = json.error.details;\n }\n }\n catch (e) {\n // ignored\n }\n throw new GoogleGenerativeAIFetchError(`Error fetching from ${url.toString()}: [${response.status} ${response.statusText}] ${message}`, response.status, response.statusText, errorDetails);\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar RpcTask;\n(function (RpcTask) {\n RpcTask[\"UPLOAD\"] = \"upload\";\n RpcTask[\"LIST\"] = \"list\";\n RpcTask[\"GET\"] = \"get\";\n RpcTask[\"DELETE\"] = \"delete\";\n RpcTask[\"UPDATE\"] = \"update\";\n RpcTask[\"CREATE\"] = \"create\";\n})(RpcTask || (RpcTask = {}));\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst taskToMethod = {\n [RpcTask.UPLOAD]: \"POST\",\n [RpcTask.LIST]: \"GET\",\n [RpcTask.GET]: \"GET\",\n [RpcTask.DELETE]: \"DELETE\",\n [RpcTask.UPDATE]: \"PATCH\",\n [RpcTask.CREATE]: \"POST\",\n};\nclass ServerRequestUrl {\n constructor(task, apiKey, requestOptions) {\n this.task = task;\n this.apiKey = apiKey;\n this.requestOptions = requestOptions;\n }\n appendPath(path) {\n this._url.pathname = this._url.pathname + `/${path}`;\n }\n appendParam(key, value) {\n this._url.searchParams.append(key, value);\n }\n toString() {\n return this._url.toString();\n }\n}\nclass CachedContentUrl extends ServerRequestUrl {\n constructor(task, apiKey, requestOptions) {\n var _a, _b;\n super(task, apiKey, requestOptions);\n this.task = task;\n this.apiKey = apiKey;\n this.requestOptions = requestOptions;\n const apiVersion = ((_a = this.requestOptions) === null || _a === void 0 ? void 0 : _a.apiVersion) || DEFAULT_API_VERSION;\n const baseUrl = ((_b = this.requestOptions) === null || _b === void 0 ? void 0 : _b.baseUrl) || DEFAULT_BASE_URL;\n let initialUrl = baseUrl;\n initialUrl += `/${apiVersion}/cachedContents`;\n this._url = new URL(initialUrl);\n }\n}\nclass FilesRequestUrl extends ServerRequestUrl {\n constructor(task, apiKey, requestOptions) {\n var _a, _b;\n super(task, apiKey, requestOptions);\n this.task = task;\n this.apiKey = apiKey;\n this.requestOptions = requestOptions;\n const apiVersion = ((_a = this.requestOptions) === null || _a === void 0 ? void 0 : _a.apiVersion) || DEFAULT_API_VERSION;\n const baseUrl = ((_b = this.requestOptions) === null || _b === void 0 ? void 0 : _b.baseUrl) || DEFAULT_BASE_URL;\n let initialUrl = baseUrl;\n if (this.task === RpcTask.UPLOAD) {\n initialUrl += `/upload`;\n }\n initialUrl += `/${apiVersion}/files`;\n this._url = new URL(initialUrl);\n }\n}\nfunction getHeaders(url) {\n var _a;\n const headers = new Headers();\n headers.append(\"x-goog-api-client\", getClientHeaders(url.requestOptions));\n headers.append(\"x-goog-api-key\", url.apiKey);\n let customHeaders = (_a = url.requestOptions) === null || _a === void 0 ? void 0 : _a.customHeaders;\n if (customHeaders) {\n if (!(customHeaders instanceof Headers)) {\n try {\n customHeaders = new Headers(customHeaders);\n }\n catch (e) {\n throw new GoogleGenerativeAIRequestInputError(`unable to convert customHeaders value ${JSON.stringify(customHeaders)} to Headers: ${e.message}`);\n }\n }\n for (const [headerName, headerValue] of customHeaders.entries()) {\n if (headerName === \"x-goog-api-key\") {\n throw new GoogleGenerativeAIRequestInputError(`Cannot set reserved header name ${headerName}`);\n }\n else if (headerName === \"x-goog-api-client\") {\n throw new GoogleGenerativeAIRequestInputError(`Header name ${headerName} can only be set using the apiClient field`);\n }\n headers.append(headerName, headerValue);\n }\n }\n return headers;\n}\nasync function makeServerRequest(url, headers, body, fetchFn = fetch) {\n const requestInit = {\n method: taskToMethod[url.task],\n headers,\n };\n if (body) {\n requestInit.body = body;\n }\n const signal = getSignal(url.requestOptions);\n if (signal) {\n requestInit.signal = signal;\n }\n return makeRequest(url.toString(), requestInit, fetchFn);\n}\n/**\n * Create an AbortSignal based on the timeout and signal in the\n * RequestOptions.\n */\nfunction getSignal(requestOptions) {\n if ((requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.signal) !== undefined || (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.timeout) >= 0) {\n const controller = new AbortController();\n if ((requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.timeout) >= 0) {\n setTimeout(() => controller.abort(), requestOptions.timeout);\n }\n if (requestOptions.signal) {\n requestOptions.signal.addEventListener(\"abort\", () => {\n controller.abort();\n });\n }\n return controller.signal;\n }\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class for managing GoogleAI file uploads.\n * @public\n */\nclass GoogleAIFileManager {\n constructor(apiKey, _requestOptions = {}) {\n this.apiKey = apiKey;\n this._requestOptions = _requestOptions;\n }\n /**\n * Upload a file.\n */\n async uploadFile(fileData, fileMetadata) {\n const file = fileData instanceof Buffer ? fileData : fs.readFileSync(fileData);\n const url = new FilesRequestUrl(RpcTask.UPLOAD, this.apiKey, this._requestOptions);\n const uploadHeaders = getHeaders(url);\n const boundary = generateBoundary();\n uploadHeaders.append(\"X-Goog-Upload-Protocol\", \"multipart\");\n uploadHeaders.append(\"Content-Type\", `multipart/related; boundary=${boundary}`);\n const uploadMetadata = getUploadMetadata(fileMetadata);\n // Multipart formatting code taken from @firebase/storage\n const metadataString = JSON.stringify({ file: uploadMetadata });\n const preBlobPart = \"--\" +\n boundary +\n \"\\r\\n\" +\n \"Content-Type: application/json; charset=utf-8\\r\\n\\r\\n\" +\n metadataString +\n \"\\r\\n--\" +\n boundary +\n \"\\r\\n\" +\n \"Content-Type: \" +\n fileMetadata.mimeType +\n \"\\r\\n\\r\\n\";\n const postBlobPart = \"\\r\\n--\" + boundary + \"--\";\n const blob = new Blob([preBlobPart, file, postBlobPart]);\n const response = await makeServerRequest(url, uploadHeaders, blob);\n return response.json();\n }\n /**\n * List all uploaded files.\n *\n * Any fields set in the optional {@link SingleRequestOptions} parameter will take\n * precedence over the {@link RequestOptions} values provided at the time of the\n * {@link GoogleAIFileManager} initialization.\n */\n async listFiles(listParams, requestOptions = {}) {\n const filesRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);\n const url = new FilesRequestUrl(RpcTask.LIST, this.apiKey, filesRequestOptions);\n if (listParams === null || listParams === void 0 ? void 0 : listParams.pageSize) {\n url.appendParam(\"pageSize\", listParams.pageSize.toString());\n }\n if (listParams === null || listParams === void 0 ? void 0 : listParams.pageToken) {\n url.appendParam(\"pageToken\", listParams.pageToken);\n }\n const uploadHeaders = getHeaders(url);\n const response = await makeServerRequest(url, uploadHeaders);\n return response.json();\n }\n /**\n * Get metadata for file with given ID.\n *\n * Any fields set in the optional {@link SingleRequestOptions} parameter will take\n * precedence over the {@link RequestOptions} values provided at the time of the\n * {@link GoogleAIFileManager} initialization.\n */\n async getFile(fileId, requestOptions = {}) {\n const filesRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);\n const url = new FilesRequestUrl(RpcTask.GET, this.apiKey, filesRequestOptions);\n url.appendPath(parseFileId(fileId));\n const uploadHeaders = getHeaders(url);\n const response = await makeServerRequest(url, uploadHeaders);\n return response.json();\n }\n /**\n * Delete file with given ID.\n */\n async deleteFile(fileId) {\n const url = new FilesRequestUrl(RpcTask.DELETE, this.apiKey, this._requestOptions);\n url.appendPath(parseFileId(fileId));\n const uploadHeaders = getHeaders(url);\n await makeServerRequest(url, uploadHeaders);\n }\n}\n/**\n * If fileId is prepended with \"files/\", remove prefix\n */\nfunction parseFileId(fileId) {\n if (fileId.startsWith(\"files/\")) {\n return fileId.split(\"files/\")[1];\n }\n if (!fileId) {\n throw new GoogleGenerativeAIError(`Invalid fileId ${fileId}. ` +\n `Must be in the format \"files/filename\" or \"filename\"`);\n }\n return fileId;\n}\nfunction generateBoundary() {\n let str = \"\";\n for (let i = 0; i < 2; i++) {\n str = str + Math.random().toString().slice(2);\n }\n return str;\n}\nfunction getUploadMetadata(inputMetadata) {\n if (!inputMetadata.mimeType) {\n throw new GoogleGenerativeAIRequestInputError(\"Must provide a mimeType.\");\n }\n const uploadMetadata = {\n mimeType: inputMetadata.mimeType,\n displayName: inputMetadata.displayName,\n };\n if (inputMetadata.name) {\n uploadMetadata.name = inputMetadata.name.includes(\"/\")\n ? inputMetadata.name\n : `files/${inputMetadata.name}`;\n }\n return uploadMetadata;\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nfunction formatSystemInstruction(input) {\n // null or undefined\n if (input == null) {\n return undefined;\n }\n else if (typeof input === \"string\") {\n return { role: \"system\", parts: [{ text: input }] };\n }\n else if (input.text) {\n return { role: \"system\", parts: [input] };\n }\n else if (input.parts) {\n if (!input.role) {\n return { role: \"system\", parts: input.parts };\n }\n else {\n return input;\n }\n }\n}\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Class for managing GoogleAI content caches.\n * @public\n */\nclass GoogleAICacheManager {\n constructor(apiKey, _requestOptions) {\n this.apiKey = apiKey;\n this._requestOptions = _requestOptions;\n }\n /**\n * Upload a new content cache\n */\n async create(createOptions) {\n const newCachedContent = Object.assign({}, createOptions);\n if (createOptions.ttlSeconds) {\n if (createOptions.expireTime) {\n throw new GoogleGenerativeAIRequestInputError(\"You cannot specify both `ttlSeconds` and `expireTime` when creating\" +\n \" a content cache. You must choose one.\");\n }\n newCachedContent.ttl = createOptions.ttlSeconds.toString() + \"s\";\n delete newCachedContent.ttlSeconds;\n }\n if (createOptions.systemInstruction) {\n newCachedContent.systemInstruction = formatSystemInstruction(createOptions.systemInstruction);\n }\n if (!newCachedContent.model) {\n throw new GoogleGenerativeAIRequestInputError(\"Cached content must contain a `model` field.\");\n }\n if (!newCachedContent.model.includes(\"/\")) {\n // If path is not included, assume it's a non-tuned model.\n newCachedContent.model = `models/${newCachedContent.model}`;\n }\n const url = new CachedContentUrl(RpcTask.CREATE, this.apiKey, this._requestOptions);\n const headers = getHeaders(url);\n const response = await makeServerRequest(url, headers, JSON.stringify(newCachedContent));\n return response.json();\n }\n /**\n * List all uploaded content caches\n */\n async list(listParams) {\n const url = new CachedContentUrl(RpcTask.LIST, this.apiKey, this._requestOptions);\n if (listParams === null || listParams === void 0 ? void 0 : listParams.pageSize) {\n url.appendParam(\"pageSize\", listParams.pageSize.toString());\n }\n if (listParams === null || listParams === void 0 ? void 0 : listParams.pageToken) {\n url.appendParam(\"pageToken\", listParams.pageToken);\n }\n const headers = getHeaders(url);\n const response = await makeServerRequest(url, headers);\n return response.json();\n }\n /**\n * Get a content cache\n */\n async get(name) {\n const url = new CachedContentUrl(RpcTask.GET, this.apiKey, this._requestOptions);\n url.appendPath(parseCacheName(name));\n const headers = getHeaders(url);\n const response = await makeServerRequest(url, headers);\n return response.json();\n }\n /**\n * Update an existing content cache\n */\n async update(name, updateParams) {\n const url = new CachedContentUrl(RpcTask.UPDATE, this.apiKey, this._requestOptions);\n url.appendPath(parseCacheName(name));\n const headers = getHeaders(url);\n const formattedCachedContent = Object.assign({}, updateParams.cachedContent);\n if (updateParams.cachedContent.ttlSeconds) {\n formattedCachedContent.ttl =\n updateParams.cachedContent.ttlSeconds.toString() + \"s\";\n delete formattedCachedContent.ttlSeconds;\n }\n if (updateParams.updateMask) {\n url.appendParam(\"update_mask\", updateParams.updateMask.map((prop) => camelToSnake(prop)).join(\",\"));\n }\n const response = await makeServerRequest(url, headers, JSON.stringify(formattedCachedContent));\n return response.json();\n }\n /**\n * Delete content cache with given name\n */\n async delete(name) {\n const url = new CachedContentUrl(RpcTask.DELETE, this.apiKey, this._requestOptions);\n url.appendPath(parseCacheName(name));\n const headers = getHeaders(url);\n await makeServerRequest(url, headers);\n }\n}\n/**\n * If cache name is prepended with \"cachedContents/\", remove prefix\n */\nfunction parseCacheName(name) {\n if (name.startsWith(\"cachedContents/\")) {\n return name.split(\"cachedContents/\")[1];\n }\n if (!name) {\n throw new GoogleGenerativeAIError(`Invalid name ${name}. ` +\n `Must be in the format \"cachedContents/name\" or \"name\"`);\n }\n return name;\n}\nfunction camelToSnake(str) {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Processing state of the `File`.\n * @public\n */\nexports.FileState = void 0;\n(function (FileState) {\n // The default value. This value is used if the state is omitted.\n FileState[\"STATE_UNSPECIFIED\"] = \"STATE_UNSPECIFIED\";\n // File is being processed and cannot be used for inference yet.\n FileState[\"PROCESSING\"] = \"PROCESSING\";\n // File is processed and available for inference.\n FileState[\"ACTIVE\"] = \"ACTIVE\";\n // File failed processing.\n FileState[\"FAILED\"] = \"FAILED\";\n})(exports.FileState || (exports.FileState = {}));\n\n/**\n * Contains the list of OpenAPI data types\n * as defined by https://swagger.io/docs/specification/data-models/data-types/\n * @public\n */\nexports.SchemaType = void 0;\n(function (SchemaType) {\n /** String type. */\n SchemaType[\"STRING\"] = \"string\";\n /** Number type. */\n SchemaType[\"NUMBER\"] = \"number\";\n /** Integer type. */\n SchemaType[\"INTEGER\"] = \"integer\";\n /** Boolean type. */\n SchemaType[\"BOOLEAN\"] = \"boolean\";\n /** Array type. */\n SchemaType[\"ARRAY\"] = \"array\";\n /** Object type. */\n SchemaType[\"OBJECT\"] = \"object\";\n})(exports.SchemaType || (exports.SchemaType = {}));\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @public\n */\nexports.ExecutableCodeLanguage = void 0;\n(function (ExecutableCodeLanguage) {\n ExecutableCodeLanguage[\"LANGUAGE_UNSPECIFIED\"] = \"language_unspecified\";\n ExecutableCodeLanguage[\"PYTHON\"] = \"python\";\n})(exports.ExecutableCodeLanguage || (exports.ExecutableCodeLanguage = {}));\n/**\n * Possible outcomes of code execution.\n * @public\n */\nexports.Outcome = void 0;\n(function (Outcome) {\n /**\n * Unspecified status. This value should not be used.\n */\n Outcome[\"OUTCOME_UNSPECIFIED\"] = \"outcome_unspecified\";\n /**\n * Code execution completed successfully.\n */\n Outcome[\"OUTCOME_OK\"] = \"outcome_ok\";\n /**\n * Code execution finished but with a failure. `stderr` should contain the\n * reason.\n */\n Outcome[\"OUTCOME_FAILED\"] = \"outcome_failed\";\n /**\n * Code execution ran for too long, and was cancelled. There may or may not\n * be a partial output present.\n */\n Outcome[\"OUTCOME_DEADLINE_EXCEEDED\"] = \"outcome_deadline_exceeded\";\n})(exports.Outcome || (exports.Outcome = {}));\n\n/**\n * @license\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Possible roles.\n * @public\n */\n/**\n * Harm categories that would cause prompts or candidates to be blocked.\n * @public\n */\nvar HarmCategory;\n(function (HarmCategory) {\n HarmCategory[\"HARM_CATEGORY_UNSPECIFIED\"] = \"HARM_CATEGORY_UNSPECIFIED\";\n HarmCategory[\"HARM_CATEGORY_HATE_SPEECH\"] = \"HARM_CATEGORY_HATE_SPEECH\";\n HarmCategory[\"HARM_CATEGORY_SEXUALLY_EXPLICIT\"] = \"HARM_CATEGORY_SEXUALLY_EXPLICIT\";\n HarmCategory[\"HARM_CATEGORY_HARASSMENT\"] = \"HARM_CATEGORY_HARASSMENT\";\n HarmCategory[\"HARM_CATEGORY_DANGEROUS_CONTENT\"] = \"HARM_CATEGORY_DANGEROUS_CONTENT\";\n HarmCategory[\"HARM_CATEGORY_CIVIC_INTEGRITY\"] = \"HARM_CATEGORY_CIVIC_INTEGRITY\";\n})(HarmCategory || (HarmCategory = {}));\n/**\n * Threshold above which a prompt or candidate will be blocked.\n * @public\n */\nvar HarmBlockThreshold;\n(function (HarmBlockThreshold) {\n /** Threshold is unspecified. */\n HarmBlockThreshold[\"HARM_BLOCK_THRESHOLD_UNSPECIFIED\"] = \"HARM_BLOCK_THRESHOLD_UNSPECIFIED\";\n /** Content with NEGLIGIBLE will be allowed. */\n HarmBlockThreshold[\"BLOCK_LOW_AND_ABOVE\"] = \"BLOCK_LOW_AND_ABOVE\";\n /** Content with NEGLIGIBLE and LOW will be allowed. */\n HarmBlockThreshold[\"BLOCK_MEDIUM_AND_ABOVE\"] = \"BLOCK_MEDIUM_AND_ABOVE\";\n /** Content with NEGLIGIBLE, LOW, and MEDIUM will be allowed. */\n HarmBlockThreshold[\"BLOCK_ONLY_HIGH\"] = \"BLOCK_ONLY_HIGH\";\n /** All content will be allowed. */\n HarmBlockThreshold[\"BLOCK_NONE\"] = \"BLOCK_NONE\";\n})(HarmBlockThreshold || (HarmBlockThreshold = {}));\n/**\n * Probability that a prompt or candidate matches a harm category.\n * @public\n */\nvar HarmProbability;\n(function (HarmProbability) {\n /** Probability is unspecified. */\n HarmProbability[\"HARM_PROBABILITY_UNSPECIFIED\"] = \"HARM_PROBABILITY_UNSPECIFIED\";\n /** Content has a negligible chance of being unsafe. */\n HarmProbability[\"NEGLIGIBLE\"] = \"NEGLIGIBLE\";\n /** Content has a low chance of being unsafe. */\n HarmProbability[\"LOW\"] = \"LOW\";\n /** Content has a medium chance of being unsafe. */\n HarmProbability[\"MEDIUM\"] = \"MEDIUM\";\n /** Content has a high chance of being unsafe. */\n HarmProbability[\"HIGH\"] = \"HIGH\";\n})(HarmProbability || (HarmProbability = {}));\n/**\n * Reason that a prompt was blocked.\n * @public\n */\nvar BlockReason;\n(function (BlockReason) {\n // A blocked reason was not specified.\n BlockReason[\"BLOCKED_REASON_UNSPECIFIED\"] = \"BLOCKED_REASON_UNSPECIFIED\";\n // Content was blocked by safety settings.\n BlockReason[\"SAFETY\"] = \"SAFETY\";\n // Content was blocked, but the reason is uncategorized.\n BlockReason[\"OTHER\"] = \"OTHER\";\n})(BlockReason || (BlockReason = {}));\n/**\n * Reason that a candidate finished.\n * @public\n */\nvar FinishReason;\n(function (FinishReason) {\n // Default value. This value is unused.\n FinishReason[\"FINISH_REASON_UNSPECIFIED\"] = \"FINISH_REASON_UNSPECIFIED\";\n // Natural stop point of the model or provided stop sequence.\n FinishReason[\"STOP\"] = \"STOP\";\n // The maximum number of tokens as specified in the request was reached.\n FinishReason[\"MAX_TOKENS\"] = \"MAX_TOKENS\";\n // The candidate content was flagged for safety reasons.\n FinishReason[\"SAFETY\"] = \"SAFETY\";\n // The candidate content was flagged for recitation reasons.\n FinishReason[\"RECITATION\"] = \"RECITATION\";\n // The candidate content was flagged for using an unsupported language.\n FinishReason[\"LANGUAGE\"] = \"LANGUAGE\";\n // Token generation stopped because the content contains forbidden terms.\n FinishReason[\"BLOCKLIST\"] = \"BLOCKLIST\";\n // Token generation stopped for potentially containing prohibited content.\n FinishReason[\"PROHIBITED_CONTENT\"] = \"PROHIBITED_CONTENT\";\n // Token generation stopped because the content potentially contains Sensitive Personally Identifiable Information (SPII).\n FinishReason[\"SPII\"] = \"SPII\";\n // The function call generated by the model is invalid.\n FinishReason[\"MALFORMED_FUNCTION_CALL\"] = \"MALFORMED_FUNCTION_CALL\";\n // Unknown reason.\n FinishReason[\"OTHER\"] = \"OTHER\";\n})(FinishReason || (FinishReason = {}));\n/**\n * Task type for embedding content.\n * @public\n */\nvar TaskType;\n(function (TaskType) {\n TaskType[\"TASK_TYPE_UNSPECIFIED\"] = \"TASK_TYPE_UNSPECIFIED\";\n TaskType[\"RETRIEVAL_QUERY\"] = \"RETRIEVAL_QUERY\";\n TaskType[\"RETRIEVAL_DOCUMENT\"] = \"RETRIEVAL_DOCUMENT\";\n TaskType[\"SEMANTIC_SIMILARITY\"] = \"SEMANTIC_SIMILARITY\";\n TaskType[\"CLASSIFICATION\"] = \"CLASSIFICATION\";\n TaskType[\"CLUSTERING\"] = \"CLUSTERING\";\n})(TaskType || (TaskType = {}));\n/**\n * @public\n */\nexports.FunctionCallingMode = void 0;\n(function (FunctionCallingMode) {\n // Unspecified function calling mode. This value should not be used.\n FunctionCallingMode[\"MODE_UNSPECIFIED\"] = \"MODE_UNSPECIFIED\";\n // Default model behavior, model decides to predict either a function call\n // or a natural language repspose.\n FunctionCallingMode[\"AUTO\"] = \"AUTO\";\n // Model is constrained to always predicting a function call only.\n // If \"allowed_function_names\" are set, the predicted function call will be\n // limited to any one of \"allowed_function_names\", else the predicted\n // function call will be any one of the provided \"function_declarations\".\n FunctionCallingMode[\"ANY\"] = \"ANY\";\n // Model will not predict any function call. Model behavior is same as when\n // not passing any function declarations.\n FunctionCallingMode[\"NONE\"] = \"NONE\";\n})(exports.FunctionCallingMode || (exports.FunctionCallingMode = {}));\n/**\n * The mode of the predictor to be used in dynamic retrieval.\n * @public\n */\nvar DynamicRetrievalMode;\n(function (DynamicRetrievalMode) {\n // Unspecified function calling mode. This value should not be used.\n DynamicRetrievalMode[\"MODE_UNSPECIFIED\"] = \"MODE_UNSPECIFIED\";\n // Run retrieval only when system decides it is necessary.\n DynamicRetrievalMode[\"MODE_DYNAMIC\"] = \"MODE_DYNAMIC\";\n})(DynamicRetrievalMode || (DynamicRetrievalMode = {}));\n\nexports.GoogleAICacheManager = GoogleAICacheManager;\nexports.GoogleAIFileManager = GoogleAIFileManager;\n//# sourceMappingURL=index.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFjdGlvbi1icm93c2VyKS8uL25vZGVfbW9kdWxlcy9AZ29vZ2xlL2dlbmVyYXRpdmUtYWkvZGlzdC9zZXJ2ZXIvaW5kZXguanMiLCJtYXBwaW5ncyI6IkFBQWE7O0FBRWIsU0FBUyxtQkFBTyxDQUFDLGNBQUk7O0FBRXJCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLFFBQVE7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLG9CQUFvQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLG1CQUFtQixHQUFHLGdCQUFnQjtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRkFBZ0YsZUFBZSxJQUFJLFVBQVU7QUFDN0c7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUUsZUFBZSxJQUFJLFVBQVU7QUFDOUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixtQ0FBbUM7QUFD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLDBDQUEwQztBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLGtDQUFrQztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsb0NBQW9DO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsNEJBQTRCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxrQ0FBa0MsMkJBQTJCLEtBQUs7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLG9EQUFvRDs7QUFFckQsNEJBQTRCO0FBQzVCLDJCQUEyQjtBQUMzQiIsInNvdXJjZXMiOlsiL2hvbWUvdXNlci9zdHVkaW8vbm9kZV9tb2R1bGVzL0Bnb29nbGUvZ2VuZXJhdGl2ZS1haS9kaXN0L3NlcnZlci9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEJhc2ljIGVycm9yIHR5cGUgZm9yIHRoaXMgU0RLLlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlKSB7XG4gICAgICAgIHN1cGVyKGBbR29vZ2xlR2VuZXJhdGl2ZUFJIEVycm9yXTogJHttZXNzYWdlfWApO1xuICAgIH1cbn1cbi8qKlxuICogRXJyb3IgY2xhc3MgY292ZXJpbmcgSFRUUCBlcnJvcnMgd2hlbiBjYWxsaW5nIHRoZSBzZXJ2ZXIuIEluY2x1ZGVzIEhUVFBcbiAqIHN0YXR1cywgc3RhdHVzVGV4dCwgYW5kIG9wdGlvbmFsIGRldGFpbHMsIGlmIHByb3ZpZGVkIGluIHRoZSBzZXJ2ZXIgcmVzcG9uc2UuXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIEdvb2dsZUdlbmVyYXRpdmVBSUZldGNoRXJyb3IgZXh0ZW5kcyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvciB7XG4gICAgY29uc3RydWN0b3IobWVzc2FnZSwgc3RhdHVzLCBzdGF0dXNUZXh0LCBlcnJvckRldGFpbHMpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSBzdGF0dXNUZXh0O1xuICAgICAgICB0aGlzLmVycm9yRGV0YWlscyA9IGVycm9yRGV0YWlscztcbiAgICB9XG59XG4vKipcbiAqIEVycm9ycyBpbiB0aGUgY29udGVudHMgb2YgYSByZXF1ZXN0IG9yaWdpbmF0aW5nIGZyb20gdXNlciBpbnB1dC5cbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3IgZXh0ZW5kcyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvciB7XG59XG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGEgcmVxdWVzdCBpcyBhYm9ydGVkLCBlaXRoZXIgZHVlIHRvIGEgdGltZW91dCBvclxuICogaW50ZW50aW9uYWwgY2FuY2VsbGF0aW9uIGJ5IHRoZSB1c2VyLlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBHb29nbGVHZW5lcmF0aXZlQUlBYm9ydEVycm9yIGV4dGVuZHMgR29vZ2xlR2VuZXJhdGl2ZUFJRXJyb3Ige1xufVxuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuY29uc3QgREVGQVVMVF9CQVNFX1VSTCA9IFwiaHR0cHM6Ly9nZW5lcmF0aXZlbGFuZ3VhZ2UuZ29vZ2xlYXBpcy5jb21cIjtcbmNvbnN0IERFRkFVTFRfQVBJX1ZFUlNJT04gPSBcInYxYmV0YVwiO1xuLyoqXG4gKiBXZSBjYW4ndCBgcmVxdWlyZWAgcGFja2FnZS5qc29uIGlmIHRoaXMgcnVucyBvbiB3ZWIuIFdlIHdpbGwgdXNlIHJvbGx1cCB0b1xuICogc3dhcCBpbiB0aGUgdmVyc2lvbiBudW1iZXIgaGVyZSBhdCBidWlsZCB0aW1lLlxuICovXG5jb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuMjQuMFwiO1xuY29uc3QgUEFDS0FHRV9MT0dfSEVBREVSID0gXCJnZW5haS1qc1wiO1xudmFyIFRhc2s7XG4oZnVuY3Rpb24gKFRhc2spIHtcbiAgICBUYXNrW1wiR0VORVJBVEVfQ09OVEVOVFwiXSA9IFwiZ2VuZXJhdGVDb250ZW50XCI7XG4gICAgVGFza1tcIlNUUkVBTV9HRU5FUkFURV9DT05URU5UXCJdID0gXCJzdHJlYW1HZW5lcmF0ZUNvbnRlbnRcIjtcbiAgICBUYXNrW1wiQ09VTlRfVE9LRU5TXCJdID0gXCJjb3VudFRva2Vuc1wiO1xuICAgIFRhc2tbXCJFTUJFRF9DT05URU5UXCJdID0gXCJlbWJlZENvbnRlbnRcIjtcbiAgICBUYXNrW1wiQkFUQ0hfRU1CRURfQ09OVEVOVFNcIl0gPSBcImJhdGNoRW1iZWRDb250ZW50c1wiO1xufSkoVGFzayB8fCAoVGFzayA9IHt9KSk7XG4vKipcbiAqIFNpbXBsZSwgYnV0IG1heSBiZWNvbWUgbW9yZSBjb21wbGV4IGlmIHdlIGFkZCBtb3JlIHZlcnNpb25zIHRvIGxvZy5cbiAqL1xuZnVuY3Rpb24gZ2V0Q2xpZW50SGVhZGVycyhyZXF1ZXN0T3B0aW9ucykge1xuICAgIGNvbnN0IGNsaWVudEhlYWRlcnMgPSBbXTtcbiAgICBpZiAocmVxdWVzdE9wdGlvbnMgPT09IG51bGwgfHwgcmVxdWVzdE9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHJlcXVlc3RPcHRpb25zLmFwaUNsaWVudCkge1xuICAgICAgICBjbGllbnRIZWFkZXJzLnB1c2gocmVxdWVzdE9wdGlvbnMuYXBpQ2xpZW50KTtcbiAgICB9XG4gICAgY2xpZW50SGVhZGVycy5wdXNoKGAke1BBQ0tBR0VfTE9HX0hFQURFUn0vJHtQQUNLQUdFX1ZFUlNJT059YCk7XG4gICAgcmV0dXJuIGNsaWVudEhlYWRlcnMuam9pbihcIiBcIik7XG59XG5hc3luYyBmdW5jdGlvbiBtYWtlUmVxdWVzdCh1cmwsIGZldGNoT3B0aW9ucywgZmV0Y2hGbiA9IGZldGNoKSB7XG4gICAgbGV0IHJlc3BvbnNlO1xuICAgIHRyeSB7XG4gICAgICAgIHJlc3BvbnNlID0gYXdhaXQgZmV0Y2hGbih1cmwsIGZldGNoT3B0aW9ucyk7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIGhhbmRsZVJlc3BvbnNlRXJyb3IoZSwgdXJsKTtcbiAgICB9XG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICBhd2FpdCBoYW5kbGVSZXNwb25zZU5vdE9rKHJlc3BvbnNlLCB1cmwpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2U7XG59XG5mdW5jdGlvbiBoYW5kbGVSZXNwb25zZUVycm9yKGUsIHVybCkge1xuICAgIGxldCBlcnIgPSBlO1xuICAgIGlmIChlcnIubmFtZSA9PT0gXCJBYm9ydEVycm9yXCIpIHtcbiAgICAgICAgZXJyID0gbmV3IEdvb2dsZUdlbmVyYXRpdmVBSUFib3J0RXJyb3IoYFJlcXVlc3QgYWJvcnRlZCB3aGVuIGZldGNoaW5nICR7dXJsLnRvU3RyaW5nKCl9OiAke2UubWVzc2FnZX1gKTtcbiAgICAgICAgZXJyLnN0YWNrID0gZS5zdGFjaztcbiAgICB9XG4gICAgZWxzZSBpZiAoIShlIGluc3RhbmNlb2YgR29vZ2xlR2VuZXJhdGl2ZUFJRmV0Y2hFcnJvciB8fFxuICAgICAgICBlIGluc3RhbmNlb2YgR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3IpKSB7XG4gICAgICAgIGVyciA9IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihgRXJyb3IgZmV0Y2hpbmcgZnJvbSAke3VybC50b1N0cmluZygpfTogJHtlLm1lc3NhZ2V9YCk7XG4gICAgICAgIGVyci5zdGFjayA9IGUuc3RhY2s7XG4gICAgfVxuICAgIHRocm93IGVycjtcbn1cbmFzeW5jIGZ1bmN0aW9uIGhhbmRsZVJlc3BvbnNlTm90T2socmVzcG9uc2UsIHVybCkge1xuICAgIGxldCBtZXNzYWdlID0gXCJcIjtcbiAgICBsZXQgZXJyb3JEZXRhaWxzO1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGpzb24gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIG1lc3NhZ2UgPSBqc29uLmVycm9yLm1lc3NhZ2U7XG4gICAgICAgIGlmIChqc29uLmVycm9yLmRldGFpbHMpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgKz0gYCAke0pTT04uc3RyaW5naWZ5KGpzb24uZXJyb3IuZGV0YWlscyl9YDtcbiAgICAgICAgICAgIGVycm9yRGV0YWlscyA9IGpzb24uZXJyb3IuZGV0YWlscztcbiAgICAgICAgfVxuICAgIH1cbiAgICBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpZ25vcmVkXG4gICAgfVxuICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlGZXRjaEVycm9yKGBFcnJvciBmZXRjaGluZyBmcm9tICR7dXJsLnRvU3RyaW5nKCl9OiBbJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1dICR7bWVzc2FnZX1gLCByZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlLnN0YXR1c1RleHQsIGVycm9yRGV0YWlscyk7XG59XG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG52YXIgUnBjVGFzaztcbihmdW5jdGlvbiAoUnBjVGFzaykge1xuICAgIFJwY1Rhc2tbXCJVUExPQURcIl0gPSBcInVwbG9hZFwiO1xuICAgIFJwY1Rhc2tbXCJMSVNUXCJdID0gXCJsaXN0XCI7XG4gICAgUnBjVGFza1tcIkdFVFwiXSA9IFwiZ2V0XCI7XG4gICAgUnBjVGFza1tcIkRFTEVURVwiXSA9IFwiZGVsZXRlXCI7XG4gICAgUnBjVGFza1tcIlVQREFURVwiXSA9IFwidXBkYXRlXCI7XG4gICAgUnBjVGFza1tcIkNSRUFURVwiXSA9IFwiY3JlYXRlXCI7XG59KShScGNUYXNrIHx8IChScGNUYXNrID0ge30pKTtcblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmNvbnN0IHRhc2tUb01ldGhvZCA9IHtcbiAgICBbUnBjVGFzay5VUExPQURdOiBcIlBPU1RcIixcbiAgICBbUnBjVGFzay5MSVNUXTogXCJHRVRcIixcbiAgICBbUnBjVGFzay5HRVRdOiBcIkdFVFwiLFxuICAgIFtScGNUYXNrLkRFTEVURV06IFwiREVMRVRFXCIsXG4gICAgW1JwY1Rhc2suVVBEQVRFXTogXCJQQVRDSFwiLFxuICAgIFtScGNUYXNrLkNSRUFURV06IFwiUE9TVFwiLFxufTtcbmNsYXNzIFNlcnZlclJlcXVlc3RVcmwge1xuICAgIGNvbnN0cnVjdG9yKHRhc2ssIGFwaUtleSwgcmVxdWVzdE9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy50YXNrID0gdGFzaztcbiAgICAgICAgdGhpcy5hcGlLZXkgPSBhcGlLZXk7XG4gICAgICAgIHRoaXMucmVxdWVzdE9wdGlvbnMgPSByZXF1ZXN0T3B0aW9ucztcbiAgICB9XG4gICAgYXBwZW5kUGF0aChwYXRoKSB7XG4gICAgICAgIHRoaXMuX3VybC5wYXRobmFtZSA9IHRoaXMuX3VybC5wYXRobmFtZSArIGAvJHtwYXRofWA7XG4gICAgfVxuICAgIGFwcGVuZFBhcmFtKGtleSwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5fdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdXJsLnRvU3RyaW5nKCk7XG4gICAgfVxufVxuY2xhc3MgQ2FjaGVkQ29udGVudFVybCBleHRlbmRzIFNlcnZlclJlcXVlc3RVcmwge1xuICAgIGNvbnN0cnVjdG9yKHRhc2ssIGFwaUtleSwgcmVxdWVzdE9wdGlvbnMpIHtcbiAgICAgICAgdmFyIF9hLCBfYjtcbiAgICAgICAgc3VwZXIodGFzaywgYXBpS2V5LCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIHRoaXMudGFzayA9IHRhc2s7XG4gICAgICAgIHRoaXMuYXBpS2V5ID0gYXBpS2V5O1xuICAgICAgICB0aGlzLnJlcXVlc3RPcHRpb25zID0gcmVxdWVzdE9wdGlvbnM7XG4gICAgICAgIGNvbnN0IGFwaVZlcnNpb24gPSAoKF9hID0gdGhpcy5yZXF1ZXN0T3B0aW9ucykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmFwaVZlcnNpb24pIHx8IERFRkFVTFRfQVBJX1ZFUlNJT047XG4gICAgICAgIGNvbnN0IGJhc2VVcmwgPSAoKF9iID0gdGhpcy5yZXF1ZXN0T3B0aW9ucykgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmJhc2VVcmwpIHx8IERFRkFVTFRfQkFTRV9VUkw7XG4gICAgICAgIGxldCBpbml0aWFsVXJsID0gYmFzZVVybDtcbiAgICAgICAgaW5pdGlhbFVybCArPSBgLyR7YXBpVmVyc2lvbn0vY2FjaGVkQ29udGVudHNgO1xuICAgICAgICB0aGlzLl91cmwgPSBuZXcgVVJMKGluaXRpYWxVcmwpO1xuICAgIH1cbn1cbmNsYXNzIEZpbGVzUmVxdWVzdFVybCBleHRlbmRzIFNlcnZlclJlcXVlc3RVcmwge1xuICAgIGNvbnN0cnVjdG9yKHRhc2ssIGFwaUtleSwgcmVxdWVzdE9wdGlvbnMpIHtcbiAgICAgICAgdmFyIF9hLCBfYjtcbiAgICAgICAgc3VwZXIodGFzaywgYXBpS2V5LCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIHRoaXMudGFzayA9IHRhc2s7XG4gICAgICAgIHRoaXMuYXBpS2V5ID0gYXBpS2V5O1xuICAgICAgICB0aGlzLnJlcXVlc3RPcHRpb25zID0gcmVxdWVzdE9wdGlvbnM7XG4gICAgICAgIGNvbnN0IGFwaVZlcnNpb24gPSAoKF9hID0gdGhpcy5yZXF1ZXN0T3B0aW9ucykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmFwaVZlcnNpb24pIHx8IERFRkFVTFRfQVBJX1ZFUlNJT047XG4gICAgICAgIGNvbnN0IGJhc2VVcmwgPSAoKF9iID0gdGhpcy5yZXF1ZXN0T3B0aW9ucykgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmJhc2VVcmwpIHx8IERFRkFVTFRfQkFTRV9VUkw7XG4gICAgICAgIGxldCBpbml0aWFsVXJsID0gYmFzZVVybDtcbiAgICAgICAgaWYgKHRoaXMudGFzayA9PT0gUnBjVGFzay5VUExPQUQpIHtcbiAgICAgICAgICAgIGluaXRpYWxVcmwgKz0gYC91cGxvYWRgO1xuICAgICAgICB9XG4gICAgICAgIGluaXRpYWxVcmwgKz0gYC8ke2FwaVZlcnNpb259L2ZpbGVzYDtcbiAgICAgICAgdGhpcy5fdXJsID0gbmV3IFVSTChpbml0aWFsVXJsKTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRIZWFkZXJzKHVybCkge1xuICAgIHZhciBfYTtcbiAgICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICBoZWFkZXJzLmFwcGVuZChcIngtZ29vZy1hcGktY2xpZW50XCIsIGdldENsaWVudEhlYWRlcnModXJsLnJlcXVlc3RPcHRpb25zKSk7XG4gICAgaGVhZGVycy5hcHBlbmQoXCJ4LWdvb2ctYXBpLWtleVwiLCB1cmwuYXBpS2V5KTtcbiAgICBsZXQgY3VzdG9tSGVhZGVycyA9IChfYSA9IHVybC5yZXF1ZXN0T3B0aW9ucykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmN1c3RvbUhlYWRlcnM7XG4gICAgaWYgKGN1c3RvbUhlYWRlcnMpIHtcbiAgICAgICAgaWYgKCEoY3VzdG9tSGVhZGVycyBpbnN0YW5jZW9mIEhlYWRlcnMpKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGN1c3RvbUhlYWRlcnMgPSBuZXcgSGVhZGVycyhjdXN0b21IZWFkZXJzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEdvb2dsZUdlbmVyYXRpdmVBSVJlcXVlc3RJbnB1dEVycm9yKGB1bmFibGUgdG8gY29udmVydCBjdXN0b21IZWFkZXJzIHZhbHVlICR7SlNPTi5zdHJpbmdpZnkoY3VzdG9tSGVhZGVycyl9IHRvIEhlYWRlcnM6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgW2hlYWRlck5hbWUsIGhlYWRlclZhbHVlXSBvZiBjdXN0b21IZWFkZXJzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgaWYgKGhlYWRlck5hbWUgPT09IFwieC1nb29nLWFwaS1rZXlcIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlSZXF1ZXN0SW5wdXRFcnJvcihgQ2Fubm90IHNldCByZXNlcnZlZCBoZWFkZXIgbmFtZSAke2hlYWRlck5hbWV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChoZWFkZXJOYW1lID09PSBcIngtZ29vZy1hcGktY2xpZW50XCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3IoYEhlYWRlciBuYW1lICR7aGVhZGVyTmFtZX0gY2FuIG9ubHkgYmUgc2V0IHVzaW5nIHRoZSBhcGlDbGllbnQgZmllbGRgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhlYWRlcnMuYXBwZW5kKGhlYWRlck5hbWUsIGhlYWRlclZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaGVhZGVycztcbn1cbmFzeW5jIGZ1bmN0aW9uIG1ha2VTZXJ2ZXJSZXF1ZXN0KHVybCwgaGVhZGVycywgYm9keSwgZmV0Y2hGbiA9IGZldGNoKSB7XG4gICAgY29uc3QgcmVxdWVzdEluaXQgPSB7XG4gICAgICAgIG1ldGhvZDogdGFza1RvTWV0aG9kW3VybC50YXNrXSxcbiAgICAgICAgaGVhZGVycyxcbiAgICB9O1xuICAgIGlmIChib2R5KSB7XG4gICAgICAgIHJlcXVlc3RJbml0LmJvZHkgPSBib2R5O1xuICAgIH1cbiAgICBjb25zdCBzaWduYWwgPSBnZXRTaWduYWwodXJsLnJlcXVlc3RPcHRpb25zKTtcbiAgICBpZiAoc2lnbmFsKSB7XG4gICAgICAgIHJlcXVlc3RJbml0LnNpZ25hbCA9IHNpZ25hbDtcbiAgICB9XG4gICAgcmV0dXJuIG1ha2VSZXF1ZXN0KHVybC50b1N0cmluZygpLCByZXF1ZXN0SW5pdCwgZmV0Y2hGbik7XG59XG4vKipcbiAqIENyZWF0ZSBhbiBBYm9ydFNpZ25hbCBiYXNlZCBvbiB0aGUgdGltZW91dCBhbmQgc2lnbmFsIGluIHRoZVxuICogUmVxdWVzdE9wdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIGdldFNpZ25hbChyZXF1ZXN0T3B0aW9ucykge1xuICAgIGlmICgocmVxdWVzdE9wdGlvbnMgPT09IG51bGwgfHwgcmVxdWVzdE9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHJlcXVlc3RPcHRpb25zLnNpZ25hbCkgIT09IHVuZGVmaW5lZCB8fCAocmVxdWVzdE9wdGlvbnMgPT09IG51bGwgfHwgcmVxdWVzdE9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHJlcXVlc3RPcHRpb25zLnRpbWVvdXQpID49IDApIHtcbiAgICAgICAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICAgICAgaWYgKChyZXF1ZXN0T3B0aW9ucyA9PT0gbnVsbCB8fCByZXF1ZXN0T3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcmVxdWVzdE9wdGlvbnMudGltZW91dCkgPj0gMCkge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiBjb250cm9sbGVyLmFib3J0KCksIHJlcXVlc3RPcHRpb25zLnRpbWVvdXQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5zaWduYWwpIHtcbiAgICAgICAgICAgIHJlcXVlc3RPcHRpb25zLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb250cm9sbGVyLnNpZ25hbDtcbiAgICB9XG59XG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIENsYXNzIGZvciBtYW5hZ2luZyBHb29nbGVBSSBmaWxlIHVwbG9hZHMuXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIEdvb2dsZUFJRmlsZU1hbmFnZXIge1xuICAgIGNvbnN0cnVjdG9yKGFwaUtleSwgX3JlcXVlc3RPcHRpb25zID0ge30pIHtcbiAgICAgICAgdGhpcy5hcGlLZXkgPSBhcGlLZXk7XG4gICAgICAgIHRoaXMuX3JlcXVlc3RPcHRpb25zID0gX3JlcXVlc3RPcHRpb25zO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGxvYWQgYSBmaWxlLlxuICAgICAqL1xuICAgIGFzeW5jIHVwbG9hZEZpbGUoZmlsZURhdGEsIGZpbGVNZXRhZGF0YSkge1xuICAgICAgICBjb25zdCBmaWxlID0gZmlsZURhdGEgaW5zdGFuY2VvZiBCdWZmZXIgPyBmaWxlRGF0YSA6IGZzLnJlYWRGaWxlU3luYyhmaWxlRGF0YSk7XG4gICAgICAgIGNvbnN0IHVybCA9IG5ldyBGaWxlc1JlcXVlc3RVcmwoUnBjVGFzay5VUExPQUQsIHRoaXMuYXBpS2V5LCB0aGlzLl9yZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IHVwbG9hZEhlYWRlcnMgPSBnZXRIZWFkZXJzKHVybCk7XG4gICAgICAgIGNvbnN0IGJvdW5kYXJ5ID0gZ2VuZXJhdGVCb3VuZGFyeSgpO1xuICAgICAgICB1cGxvYWRIZWFkZXJzLmFwcGVuZChcIlgtR29vZy1VcGxvYWQtUHJvdG9jb2xcIiwgXCJtdWx0aXBhcnRcIik7XG4gICAgICAgIHVwbG9hZEhlYWRlcnMuYXBwZW5kKFwiQ29udGVudC1UeXBlXCIsIGBtdWx0aXBhcnQvcmVsYXRlZDsgYm91bmRhcnk9JHtib3VuZGFyeX1gKTtcbiAgICAgICAgY29uc3QgdXBsb2FkTWV0YWRhdGEgPSBnZXRVcGxvYWRNZXRhZGF0YShmaWxlTWV0YWRhdGEpO1xuICAgICAgICAvLyBNdWx0aXBhcnQgZm9ybWF0dGluZyBjb2RlIHRha2VuIGZyb20gQGZpcmViYXNlL3N0b3JhZ2VcbiAgICAgICAgY29uc3QgbWV0YWRhdGFTdHJpbmcgPSBKU09OLnN0cmluZ2lmeSh7IGZpbGU6IHVwbG9hZE1ldGFkYXRhIH0pO1xuICAgICAgICBjb25zdCBwcmVCbG9iUGFydCA9IFwiLS1cIiArXG4gICAgICAgICAgICBib3VuZGFyeSArXG4gICAgICAgICAgICBcIlxcclxcblwiICtcbiAgICAgICAgICAgIFwiQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XFxyXFxuXFxyXFxuXCIgK1xuICAgICAgICAgICAgbWV0YWRhdGFTdHJpbmcgK1xuICAgICAgICAgICAgXCJcXHJcXG4tLVwiICtcbiAgICAgICAgICAgIGJvdW5kYXJ5ICtcbiAgICAgICAgICAgIFwiXFxyXFxuXCIgK1xuICAgICAgICAgICAgXCJDb250ZW50LVR5cGU6IFwiICtcbiAgICAgICAgICAgIGZpbGVNZXRhZGF0YS5taW1lVHlwZSArXG4gICAgICAgICAgICBcIlxcclxcblxcclxcblwiO1xuICAgICAgICBjb25zdCBwb3N0QmxvYlBhcnQgPSBcIlxcclxcbi0tXCIgKyBib3VuZGFyeSArIFwiLS1cIjtcbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtwcmVCbG9iUGFydCwgZmlsZSwgcG9zdEJsb2JQYXJ0XSk7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgbWFrZVNlcnZlclJlcXVlc3QodXJsLCB1cGxvYWRIZWFkZXJzLCBibG9iKTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGlzdCBhbGwgdXBsb2FkZWQgZmlsZXMuXG4gICAgICpcbiAgICAgKiBBbnkgZmllbGRzIHNldCBpbiB0aGUgb3B0aW9uYWwge0BsaW5rIFNpbmdsZVJlcXVlc3RPcHRpb25zfSBwYXJhbWV0ZXIgd2lsbCB0YWtlXG4gICAgICogcHJlY2VkZW5jZSBvdmVyIHRoZSB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IHZhbHVlcyBwcm92aWRlZCBhdCB0aGUgdGltZSBvZiB0aGVcbiAgICAgKiB7QGxpbmsgR29vZ2xlQUlGaWxlTWFuYWdlcn0gaW5pdGlhbGl6YXRpb24uXG4gICAgICovXG4gICAgYXN5bmMgbGlzdEZpbGVzKGxpc3RQYXJhbXMsIHJlcXVlc3RPcHRpb25zID0ge30pIHtcbiAgICAgICAgY29uc3QgZmlsZXNSZXF1ZXN0T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fcmVxdWVzdE9wdGlvbnMpLCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IHVybCA9IG5ldyBGaWxlc1JlcXVlc3RVcmwoUnBjVGFzay5MSVNULCB0aGlzLmFwaUtleSwgZmlsZXNSZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIGlmIChsaXN0UGFyYW1zID09PSBudWxsIHx8IGxpc3RQYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGxpc3RQYXJhbXMucGFnZVNpemUpIHtcbiAgICAgICAgICAgIHVybC5hcHBlbmRQYXJhbShcInBhZ2VTaXplXCIsIGxpc3RQYXJhbXMucGFnZVNpemUudG9TdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxpc3RQYXJhbXMgPT09IG51bGwgfHwgbGlzdFBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogbGlzdFBhcmFtcy5wYWdlVG9rZW4pIHtcbiAgICAgICAgICAgIHVybC5hcHBlbmRQYXJhbShcInBhZ2VUb2tlblwiLCBsaXN0UGFyYW1zLnBhZ2VUb2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXBsb2FkSGVhZGVycyA9IGdldEhlYWRlcnModXJsKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBtYWtlU2VydmVyUmVxdWVzdCh1cmwsIHVwbG9hZEhlYWRlcnMpO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgbWV0YWRhdGEgZm9yIGZpbGUgd2l0aCBnaXZlbiBJRC5cbiAgICAgKlxuICAgICAqIEFueSBmaWVsZHMgc2V0IGluIHRoZSBvcHRpb25hbCB7QGxpbmsgU2luZ2xlUmVxdWVzdE9wdGlvbnN9IHBhcmFtZXRlciB3aWxsIHRha2VcbiAgICAgKiBwcmVjZWRlbmNlIG92ZXIgdGhlIHtAbGluayBSZXF1ZXN0T3B0aW9uc30gdmFsdWVzIHByb3ZpZGVkIGF0IHRoZSB0aW1lIG9mIHRoZVxuICAgICAqIHtAbGluayBHb29nbGVBSUZpbGVNYW5hZ2VyfSBpbml0aWFsaXphdGlvbi5cbiAgICAgKi9cbiAgICBhc3luYyBnZXRGaWxlKGZpbGVJZCwgcmVxdWVzdE9wdGlvbnMgPSB7fSkge1xuICAgICAgICBjb25zdCBmaWxlc1JlcXVlc3RPcHRpb25zID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9yZXF1ZXN0T3B0aW9ucyksIHJlcXVlc3RPcHRpb25zKTtcbiAgICAgICAgY29uc3QgdXJsID0gbmV3IEZpbGVzUmVxdWVzdFVybChScGNUYXNrLkdFVCwgdGhpcy5hcGlLZXksIGZpbGVzUmVxdWVzdE9wdGlvbnMpO1xuICAgICAgICB1cmwuYXBwZW5kUGF0aChwYXJzZUZpbGVJZChmaWxlSWQpKTtcbiAgICAgICAgY29uc3QgdXBsb2FkSGVhZGVycyA9IGdldEhlYWRlcnModXJsKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBtYWtlU2VydmVyUmVxdWVzdCh1cmwsIHVwbG9hZEhlYWRlcnMpO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZWxldGUgZmlsZSB3aXRoIGdpdmVuIElELlxuICAgICAqL1xuICAgIGFzeW5jIGRlbGV0ZUZpbGUoZmlsZUlkKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IG5ldyBGaWxlc1JlcXVlc3RVcmwoUnBjVGFzay5ERUxFVEUsIHRoaXMuYXBpS2V5LCB0aGlzLl9yZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIHVybC5hcHBlbmRQYXRoKHBhcnNlRmlsZUlkKGZpbGVJZCkpO1xuICAgICAgICBjb25zdCB1cGxvYWRIZWFkZXJzID0gZ2V0SGVhZGVycyh1cmwpO1xuICAgICAgICBhd2FpdCBtYWtlU2VydmVyUmVxdWVzdCh1cmwsIHVwbG9hZEhlYWRlcnMpO1xuICAgIH1cbn1cbi8qKlxuICogSWYgZmlsZUlkIGlzIHByZXBlbmRlZCB3aXRoIFwiZmlsZXMvXCIsIHJlbW92ZSBwcmVmaXhcbiAqL1xuZnVuY3Rpb24gcGFyc2VGaWxlSWQoZmlsZUlkKSB7XG4gICAgaWYgKGZpbGVJZC5zdGFydHNXaXRoKFwiZmlsZXMvXCIpKSB7XG4gICAgICAgIHJldHVybiBmaWxlSWQuc3BsaXQoXCJmaWxlcy9cIilbMV07XG4gICAgfVxuICAgIGlmICghZmlsZUlkKSB7XG4gICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihgSW52YWxpZCBmaWxlSWQgJHtmaWxlSWR9LiBgICtcbiAgICAgICAgICAgIGBNdXN0IGJlIGluIHRoZSBmb3JtYXQgXCJmaWxlcy9maWxlbmFtZVwiIG9yIFwiZmlsZW5hbWVcImApO1xuICAgIH1cbiAgICByZXR1cm4gZmlsZUlkO1xufVxuZnVuY3Rpb24gZ2VuZXJhdGVCb3VuZGFyeSgpIHtcbiAgICBsZXQgc3RyID0gXCJcIjtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDI7IGkrKykge1xuICAgICAgICBzdHIgPSBzdHIgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKCkuc2xpY2UoMik7XG4gICAgfVxuICAgIHJldHVybiBzdHI7XG59XG5mdW5jdGlvbiBnZXRVcGxvYWRNZXRhZGF0YShpbnB1dE1ldGFkYXRhKSB7XG4gICAgaWYgKCFpbnB1dE1ldGFkYXRhLm1pbWVUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlSZXF1ZXN0SW5wdXRFcnJvcihcIk11c3QgcHJvdmlkZSBhIG1pbWVUeXBlLlwiKTtcbiAgICB9XG4gICAgY29uc3QgdXBsb2FkTWV0YWRhdGEgPSB7XG4gICAgICAgIG1pbWVUeXBlOiBpbnB1dE1ldGFkYXRhLm1pbWVUeXBlLFxuICAgICAgICBkaXNwbGF5TmFtZTogaW5wdXRNZXRhZGF0YS5kaXNwbGF5TmFtZSxcbiAgICB9O1xuICAgIGlmIChpbnB1dE1ldGFkYXRhLm5hbWUpIHtcbiAgICAgICAgdXBsb2FkTWV0YWRhdGEubmFtZSA9IGlucHV0TWV0YWRhdGEubmFtZS5pbmNsdWRlcyhcIi9cIilcbiAgICAgICAgICAgID8gaW5wdXRNZXRhZGF0YS5uYW1lXG4gICAgICAgICAgICA6IGBmaWxlcy8ke2lucHV0TWV0YWRhdGEubmFtZX1gO1xuICAgIH1cbiAgICByZXR1cm4gdXBsb2FkTWV0YWRhdGE7XG59XG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5mdW5jdGlvbiBmb3JtYXRTeXN0ZW1JbnN0cnVjdGlvbihpbnB1dCkge1xuICAgIC8vIG51bGwgb3IgdW5kZWZpbmVkXG4gICAgaWYgKGlucHV0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIGlucHV0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHJldHVybiB7IHJvbGU6IFwic3lzdGVtXCIsIHBhcnRzOiBbeyB0ZXh0OiBpbnB1dCB9XSB9O1xuICAgIH1cbiAgICBlbHNlIGlmIChpbnB1dC50ZXh0KSB7XG4gICAgICAgIHJldHVybiB7IHJvbGU6IFwic3lzdGVtXCIsIHBhcnRzOiBbaW5wdXRdIH07XG4gICAgfVxuICAgIGVsc2UgaWYgKGlucHV0LnBhcnRzKSB7XG4gICAgICAgIGlmICghaW5wdXQucm9sZSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgcm9sZTogXCJzeXN0ZW1cIiwgcGFydHM6IGlucHV0LnBhcnRzIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIENsYXNzIGZvciBtYW5hZ2luZyBHb29nbGVBSSBjb250ZW50IGNhY2hlcy5cbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgR29vZ2xlQUlDYWNoZU1hbmFnZXIge1xuICAgIGNvbnN0cnVjdG9yKGFwaUtleSwgX3JlcXVlc3RPcHRpb25zKSB7XG4gICAgICAgIHRoaXMuYXBpS2V5ID0gYXBpS2V5O1xuICAgICAgICB0aGlzLl9yZXF1ZXN0T3B0aW9ucyA9IF9yZXF1ZXN0T3B0aW9ucztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBsb2FkIGEgbmV3IGNvbnRlbnQgY2FjaGVcbiAgICAgKi9cbiAgICBhc3luYyBjcmVhdGUoY3JlYXRlT3B0aW9ucykge1xuICAgICAgICBjb25zdCBuZXdDYWNoZWRDb250ZW50ID0gT2JqZWN0LmFzc2lnbih7fSwgY3JlYXRlT3B0aW9ucyk7XG4gICAgICAgIGlmIChjcmVhdGVPcHRpb25zLnR0bFNlY29uZHMpIHtcbiAgICAgICAgICAgIGlmIChjcmVhdGVPcHRpb25zLmV4cGlyZVRpbWUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgR29vZ2xlR2VuZXJhdGl2ZUFJUmVxdWVzdElucHV0RXJyb3IoXCJZb3UgY2Fubm90IHNwZWNpZnkgYm90aCBgdHRsU2Vjb25kc2AgYW5kIGBleHBpcmVUaW1lYCB3aGVuIGNyZWF0aW5nXCIgK1xuICAgICAgICAgICAgICAgICAgICBcIiBhIGNvbnRlbnQgY2FjaGUuIFlvdSBtdXN0IGNob29zZSBvbmUuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV3Q2FjaGVkQ29udGVudC50dGwgPSBjcmVhdGVPcHRpb25zLnR0bFNlY29uZHMudG9TdHJpbmcoKSArIFwic1wiO1xuICAgICAgICAgICAgZGVsZXRlIG5ld0NhY2hlZENvbnRlbnQudHRsU2Vjb25kcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3JlYXRlT3B0aW9ucy5zeXN0ZW1JbnN0cnVjdGlvbikge1xuICAgICAgICAgICAgbmV3Q2FjaGVkQ29udGVudC5zeXN0ZW1JbnN0cnVjdGlvbiA9IGZvcm1hdFN5c3RlbUluc3RydWN0aW9uKGNyZWF0ZU9wdGlvbnMuc3lzdGVtSW5zdHJ1Y3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghbmV3Q2FjaGVkQ29udGVudC5tb2RlbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEdvb2dsZUdlbmVyYXRpdmVBSVJlcXVlc3RJbnB1dEVycm9yKFwiQ2FjaGVkIGNvbnRlbnQgbXVzdCBjb250YWluIGEgYG1vZGVsYCBmaWVsZC5cIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFuZXdDYWNoZWRDb250ZW50Lm1vZGVsLmluY2x1ZGVzKFwiL1wiKSkge1xuICAgICAgICAgICAgLy8gSWYgcGF0aCBpcyBub3QgaW5jbHVkZWQsIGFzc3VtZSBpdCdzIGEgbm9uLXR1bmVkIG1vZGVsLlxuICAgICAgICAgICAgbmV3Q2FjaGVkQ29udGVudC5tb2RlbCA9IGBtb2RlbHMvJHtuZXdDYWNoZWRDb250ZW50Lm1vZGVsfWA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJsID0gbmV3IENhY2hlZENvbnRlbnRVcmwoUnBjVGFzay5DUkVBVEUsIHRoaXMuYXBpS2V5LCB0aGlzLl9yZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSBnZXRIZWFkZXJzKHVybCk7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgbWFrZVNlcnZlclJlcXVlc3QodXJsLCBoZWFkZXJzLCBKU09OLnN0cmluZ2lmeShuZXdDYWNoZWRDb250ZW50KSk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpc3QgYWxsIHVwbG9hZGVkIGNvbnRlbnQgY2FjaGVzXG4gICAgICovXG4gICAgYXN5bmMgbGlzdChsaXN0UGFyYW1zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IG5ldyBDYWNoZWRDb250ZW50VXJsKFJwY1Rhc2suTElTVCwgdGhpcy5hcGlLZXksIHRoaXMuX3JlcXVlc3RPcHRpb25zKTtcbiAgICAgICAgaWYgKGxpc3RQYXJhbXMgPT09IG51bGwgfHwgbGlzdFBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogbGlzdFBhcmFtcy5wYWdlU2l6ZSkge1xuICAgICAgICAgICAgdXJsLmFwcGVuZFBhcmFtKFwicGFnZVNpemVcIiwgbGlzdFBhcmFtcy5wYWdlU2l6ZS50b1N0cmluZygpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGlzdFBhcmFtcyA9PT0gbnVsbCB8fCBsaXN0UGFyYW1zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsaXN0UGFyYW1zLnBhZ2VUb2tlbikge1xuICAgICAgICAgICAgdXJsLmFwcGVuZFBhcmFtKFwicGFnZVRva2VuXCIsIGxpc3RQYXJhbXMucGFnZVRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoZWFkZXJzID0gZ2V0SGVhZGVycyh1cmwpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG1ha2VTZXJ2ZXJSZXF1ZXN0KHVybCwgaGVhZGVycyk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIGNvbnRlbnQgY2FjaGVcbiAgICAgKi9cbiAgICBhc3luYyBnZXQobmFtZSkge1xuICAgICAgICBjb25zdCB1cmwgPSBuZXcgQ2FjaGVkQ29udGVudFVybChScGNUYXNrLkdFVCwgdGhpcy5hcGlLZXksIHRoaXMuX3JlcXVlc3RPcHRpb25zKTtcbiAgICAgICAgdXJsLmFwcGVuZFBhdGgocGFyc2VDYWNoZU5hbWUobmFtZSkpO1xuICAgICAgICBjb25zdCBoZWFkZXJzID0gZ2V0SGVhZGVycyh1cmwpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG1ha2VTZXJ2ZXJSZXF1ZXN0KHVybCwgaGVhZGVycyk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBhbiBleGlzdGluZyBjb250ZW50IGNhY2hlXG4gICAgICovXG4gICAgYXN5bmMgdXBkYXRlKG5hbWUsIHVwZGF0ZVBhcmFtcykge1xuICAgICAgICBjb25zdCB1cmwgPSBuZXcgQ2FjaGVkQ29udGVudFVybChScGNUYXNrLlVQREFURSwgdGhpcy5hcGlLZXksIHRoaXMuX3JlcXVlc3RPcHRpb25zKTtcbiAgICAgICAgdXJsLmFwcGVuZFBhdGgocGFyc2VDYWNoZU5hbWUobmFtZSkpO1xuICAgICAgICBjb25zdCBoZWFkZXJzID0gZ2V0SGVhZGVycyh1cmwpO1xuICAgICAgICBjb25zdCBmb3JtYXR0ZWRDYWNoZWRDb250ZW50ID0gT2JqZWN0LmFzc2lnbih7fSwgdXBkYXRlUGFyYW1zLmNhY2hlZENvbnRlbnQpO1xuICAgICAgICBpZiAodXBkYXRlUGFyYW1zLmNhY2hlZENvbnRlbnQudHRsU2Vjb25kcykge1xuICAgICAgICAgICAgZm9ybWF0dGVkQ2FjaGVkQ29udGVudC50dGwgPVxuICAgICAgICAgICAgICAgIHVwZGF0ZVBhcmFtcy5jYWNoZWRDb250ZW50LnR0bFNlY29uZHMudG9TdHJpbmcoKSArIFwic1wiO1xuICAgICAgICAgICAgZGVsZXRlIGZvcm1hdHRlZENhY2hlZENvbnRlbnQudHRsU2Vjb25kcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodXBkYXRlUGFyYW1zLnVwZGF0ZU1hc2spIHtcbiAgICAgICAgICAgIHVybC5hcHBlbmRQYXJhbShcInVwZGF0ZV9tYXNrXCIsIHVwZGF0ZVBhcmFtcy51cGRhdGVNYXNrLm1hcCgocHJvcCkgPT4gY2FtZWxUb1NuYWtlKHByb3ApKS5qb2luKFwiLFwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBtYWtlU2VydmVyUmVxdWVzdCh1cmwsIGhlYWRlcnMsIEpTT04uc3RyaW5naWZ5KGZvcm1hdHRlZENhY2hlZENvbnRlbnQpKTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVsZXRlIGNvbnRlbnQgY2FjaGUgd2l0aCBnaXZlbiBuYW1lXG4gICAgICovXG4gICAgYXN5bmMgZGVsZXRlKG5hbWUpIHtcbiAgICAgICAgY29uc3QgdXJsID0gbmV3IENhY2hlZENvbnRlbnRVcmwoUnBjVGFzay5ERUxFVEUsIHRoaXMuYXBpS2V5LCB0aGlzLl9yZXF1ZXN0T3B0aW9ucyk7XG4gICAgICAgIHVybC5hcHBlbmRQYXRoKHBhcnNlQ2FjaGVOYW1lKG5hbWUpKTtcbiAgICAgICAgY29uc3QgaGVhZGVycyA9IGdldEhlYWRlcnModXJsKTtcbiAgICAgICAgYXdhaXQgbWFrZVNlcnZlclJlcXVlc3QodXJsLCBoZWFkZXJzKTtcbiAgICB9XG59XG4vKipcbiAqIElmIGNhY2hlIG5hbWUgaXMgcHJlcGVuZGVkIHdpdGggXCJjYWNoZWRDb250ZW50cy9cIiwgcmVtb3ZlIHByZWZpeFxuICovXG5mdW5jdGlvbiBwYXJzZUNhY2hlTmFtZShuYW1lKSB7XG4gICAgaWYgKG5hbWUuc3RhcnRzV2l0aChcImNhY2hlZENvbnRlbnRzL1wiKSkge1xuICAgICAgICByZXR1cm4gbmFtZS5zcGxpdChcImNhY2hlZENvbnRlbnRzL1wiKVsxXTtcbiAgICB9XG4gICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBHb29nbGVHZW5lcmF0aXZlQUlFcnJvcihgSW52YWxpZCBuYW1lICR7bmFtZX0uIGAgK1xuICAgICAgICAgICAgYE11c3QgYmUgaW4gdGhlIGZvcm1hdCBcImNhY2hlZENvbnRlbnRzL25hbWVcIiBvciBcIm5hbWVcImApO1xuICAgIH1cbiAgICByZXR1cm4gbmFtZTtcbn1cbmZ1bmN0aW9uIGNhbWVsVG9TbmFrZShzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoL1tBLVpdL2csIChsZXR0ZXIpID0+IGBfJHtsZXR0ZXIudG9Mb3dlckNhc2UoKX1gKTtcbn1cblxuLyoqXG4gKiBQcm9jZXNzaW5nIHN0YXRlIG9mIHRoZSBgRmlsZWAuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydHMuRmlsZVN0YXRlID0gdm9pZCAwO1xuKGZ1bmN0aW9uIChGaWxlU3RhdGUpIHtcbiAgICAvLyBUaGUgZGVmYXVsdCB2YWx1ZS4gVGhpcyB2YWx1ZSBpcyB1c2VkIGlmIHRoZSBzdGF0ZSBpcyBvbWl0dGVkLlxuICAgIEZpbGVTdGF0ZVtcIlNUQVRFX1VOU1BFQ0lGSUVEXCJdID0gXCJTVEFURV9VTlNQRUNJRklFRFwiO1xuICAgIC8vIEZpbGUgaXMgYmVpbmcgcHJvY2Vzc2VkIGFuZCBjYW5ub3QgYmUgdXNlZCBmb3IgaW5mZXJlbmNlIHlldC5cbiAgICBGaWxlU3RhdGVbXCJQUk9DRVNTSU5HXCJdID0gXCJQUk9DRVNTSU5HXCI7XG4gICAgLy8gRmlsZSBpcyBwcm9jZXNzZWQgYW5kIGF2YWlsYWJsZSBmb3IgaW5mZXJlbmNlLlxuICAgIEZpbGVTdGF0ZVtcIkFDVElWRVwiXSA9IFwiQUNUSVZFXCI7XG4gICAgLy8gRmlsZSBmYWlsZWQgcHJvY2Vzc2luZy5cbiAgICBGaWxlU3RhdGVbXCJGQUlMRURcIl0gPSBcIkZBSUxFRFwiO1xufSkoZXhwb3J0cy5GaWxlU3RhdGUgfHwgKGV4cG9ydHMuRmlsZVN0YXRlID0ge30pKTtcblxuLyoqXG4gKiBDb250YWlucyB0aGUgbGlzdCBvZiBPcGVuQVBJIGRhdGEgdHlwZXNcbiAqIGFzIGRlZmluZWQgYnkgaHR0cHM6Ly9zd2FnZ2VyLmlvL2RvY3Mvc3BlY2lmaWNhdGlvbi9kYXRhLW1vZGVscy9kYXRhLXR5cGVzL1xuICogQHB1YmxpY1xuICovXG5leHBvcnRzLlNjaGVtYVR5cGUgPSB2b2lkIDA7XG4oZnVuY3Rpb24gKFNjaGVtYVR5cGUpIHtcbiAgICAvKiogU3RyaW5nIHR5cGUuICovXG4gICAgU2NoZW1hVHlwZVtcIlNUUklOR1wiXSA9IFwic3RyaW5nXCI7XG4gICAgLyoqIE51bWJlciB0eXBlLiAqL1xuICAgIFNjaGVtYVR5cGVbXCJOVU1CRVJcIl0gPSBcIm51bWJlclwiO1xuICAgIC8qKiBJbnRlZ2VyIHR5cGUuICovXG4gICAgU2NoZW1hVHlwZVtcIklOVEVHRVJcIl0gPSBcImludGVnZXJcIjtcbiAgICAvKiogQm9vbGVhbiB0eXBlLiAqL1xuICAgIFNjaGVtYVR5cGVbXCJCT09MRUFOXCJdID0gXCJib29sZWFuXCI7XG4gICAgLyoqIEFycmF5IHR5cGUuICovXG4gICAgU2NoZW1hVHlwZVtcIkFSUkFZXCJdID0gXCJhcnJheVwiO1xuICAgIC8qKiBPYmplY3QgdHlwZS4gKi9cbiAgICBTY2hlbWFUeXBlW1wiT0JKRUNUXCJdID0gXCJvYmplY3RcIjtcbn0pKGV4cG9ydHMuU2NoZW1hVHlwZSB8fCAoZXhwb3J0cy5TY2hlbWFUeXBlID0ge30pKTtcblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnRzLkV4ZWN1dGFibGVDb2RlTGFuZ3VhZ2UgPSB2b2lkIDA7XG4oZnVuY3Rpb24gKEV4ZWN1dGFibGVDb2RlTGFuZ3VhZ2UpIHtcbiAgICBFeGVjdXRhYmxlQ29kZUxhbmd1YWdlW1wiTEFOR1VBR0VfVU5TUEVDSUZJRURcIl0gPSBcImxhbmd1YWdlX3Vuc3BlY2lmaWVkXCI7XG4gICAgRXhlY3V0YWJsZUNvZGVMYW5ndWFnZVtcIlBZVEhPTlwiXSA9IFwicHl0aG9uXCI7XG59KShleHBvcnRzLkV4ZWN1dGFibGVDb2RlTGFuZ3VhZ2UgfHwgKGV4cG9ydHMuRXhlY3V0YWJsZUNvZGVMYW5ndWFnZSA9IHt9KSk7XG4vKipcbiAqIFBvc3NpYmxlIG91dGNvbWVzIG9mIGNvZGUgZXhlY3V0aW9uLlxuICogQHB1YmxpY1xuICovXG5leHBvcnRzLk91dGNvbWUgPSB2b2lkIDA7XG4oZnVuY3Rpb24gKE91dGNvbWUpIHtcbiAgICAvKipcbiAgICAgKiBVbnNwZWNpZmllZCBzdGF0dXMuIFRoaXMgdmFsdWUgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICAgICAqL1xuICAgIE91dGNvbWVbXCJPVVRDT01FX1VOU1BFQ0lGSUVEXCJdID0gXCJvdXRjb21lX3Vuc3BlY2lmaWVkXCI7XG4gICAgLyoqXG4gICAgICogQ29kZSBleGVjdXRpb24gY29tcGxldGVkIHN1Y2Nlc3NmdWxseS5cbiAgICAgKi9cbiAgICBPdXRjb21lW1wiT1VUQ09NRV9PS1wiXSA9IFwib3V0Y29tZV9va1wiO1xuICAgIC8qKlxuICAgICAqIENvZGUgZXhlY3V0aW9uIGZpbmlzaGVkIGJ1dCB3aXRoIGEgZmFpbHVyZS4gYHN0ZGVycmAgc2hvdWxkIGNvbnRhaW4gdGhlXG4gICAgICogcmVhc29uLlxuICAgICAqL1xuICAgIE91dGNvbWVbXCJPVVRDT01FX0ZBSUxFRFwiXSA9IFwib3V0Y29tZV9mYWlsZWRcIjtcbiAgICAvKipcbiAgICAgKiBDb2RlIGV4ZWN1dGlvbiByYW4gZm9yIHRvbyBsb25nLCBhbmQgd2FzIGNhbmNlbGxlZC4gVGhlcmUgbWF5IG9yIG1heSBub3RcbiAgICAgKiBiZSBhIHBhcnRpYWwgb3V0cHV0IHByZXNlbnQuXG4gICAgICovXG4gICAgT3V0Y29tZVtcIk9VVENPTUVfREVBRExJTkVfRVhDRUVERURcIl0gPSBcIm91dGNvbWVfZGVhZGxpbmVfZXhjZWVkZWRcIjtcbn0pKGV4cG9ydHMuT3V0Y29tZSB8fCAoZXhwb3J0cy5PdXRjb21lID0ge30pKTtcblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbi8qKlxuICogUG9zc2libGUgcm9sZXMuXG4gKiBAcHVibGljXG4gKi9cbi8qKlxuICogSGFybSBjYXRlZ29yaWVzIHRoYXQgd291bGQgY2F1c2UgcHJvbXB0cyBvciBjYW5kaWRhdGVzIHRvIGJlIGJsb2NrZWQuXG4gKiBAcHVibGljXG4gKi9cbnZhciBIYXJtQ2F0ZWdvcnk7XG4oZnVuY3Rpb24gKEhhcm1DYXRlZ29yeSkge1xuICAgIEhhcm1DYXRlZ29yeVtcIkhBUk1fQ0FURUdPUllfVU5TUEVDSUZJRURcIl0gPSBcIkhBUk1fQ0FURUdPUllfVU5TUEVDSUZJRURcIjtcbiAgICBIYXJtQ2F0ZWdvcnlbXCJIQVJNX0NBVEVHT1JZX0hBVEVfU1BFRUNIXCJdID0gXCJIQVJNX0NBVEVHT1JZX0hBVEVfU1BFRUNIXCI7XG4gICAgSGFybUNhdGVnb3J5W1wiSEFSTV9DQVRFR09SWV9TRVhVQUxMWV9FWFBMSUNJVFwiXSA9IFwiSEFSTV9DQVRFR09SWV9TRVhVQUxMWV9FWFBMSUNJVFwiO1xuICAgIEhhcm1DYXRlZ29yeVtcIkhBUk1fQ0FURUdPUllfSEFSQVNTTUVOVFwiXSA9IFwiSEFSTV9DQVRFR09SWV9IQVJBU1NNRU5UXCI7XG4gICAgSGFybUNhdGVnb3J5W1wiSEFSTV9DQVRFR09SWV9EQU5HRVJPVVNfQ09OVEVOVFwiXSA9IFwiSEFSTV9DQVRFR09SWV9EQU5HRVJPVVNfQ09OVEVOVFwiO1xuICAgIEhhcm1DYXRlZ29yeVtcIkhBUk1fQ0FURUdPUllfQ0lWSUNfSU5URUdSSVRZXCJdID0gXCJIQVJNX0NBVEVHT1JZX0NJVklDX0lOVEVHUklUWVwiO1xufSkoSGFybUNhdGVnb3J5IHx8IChIYXJtQ2F0ZWdvcnkgPSB7fSkpO1xuLyoqXG4gKiBUaHJlc2hvbGQgYWJvdmUgd2hpY2ggYSBwcm9tcHQgb3IgY2FuZGlkYXRlIHdpbGwgYmUgYmxvY2tlZC5cbiAqIEBwdWJsaWNcbiAqL1xudmFyIEhhcm1CbG9ja1RocmVzaG9sZDtcbihmdW5jdGlvbiAoSGFybUJsb2NrVGhyZXNob2xkKSB7XG4gICAgLyoqIFRocmVzaG9sZCBpcyB1bnNwZWNpZmllZC4gKi9cbiAgICBIYXJtQmxvY2tUaHJlc2hvbGRbXCJIQVJNX0JMT0NLX1RIUkVTSE9MRF9VTlNQRUNJRklFRFwiXSA9IFwiSEFSTV9CTE9DS19USFJFU0hPTERfVU5TUEVDSUZJRURcIjtcbiAgICAvKiogQ29udGVudCB3aXRoIE5FR0xJR0lCTEUgd2lsbCBiZSBhbGxvd2VkLiAqL1xuICAgIEhhcm1CbG9ja1RocmVzaG9sZFtcIkJMT0NLX0xPV19BTkRfQUJPVkVcIl0gPSBcIkJMT0NLX0xPV19BTkRfQUJPVkVcIjtcbiAgICAvKiogQ29udGVudCB3aXRoIE5FR0xJR0lCTEUgYW5kIExPVyB3aWxsIGJlIGFsbG93ZWQuICovXG4gICAgSGFybUJsb2NrVGhyZXNob2xkW1wiQkxPQ0tfTUVESVVNX0FORF9BQk9WRVwiXSA9IFwiQkxPQ0tfTUVESVVNX0FORF9BQk9WRVwiO1xuICAgIC8qKiBDb250ZW50IHdpdGggTkVHTElHSUJMRSwgTE9XLCBhbmQgTUVESVVNIHdpbGwgYmUgYWxsb3dlZC4gKi9cbiAgICBIYXJtQmxvY2tUaHJlc2hvbGRbXCJCTE9DS19PTkxZX0hJR0hcIl0gPSBcIkJMT0NLX09OTFlfSElHSFwiO1xuICAgIC8qKiBBbGwgY29udGVudCB3aWxsIGJlIGFsbG93ZWQuICovXG4gICAgSGFybUJsb2NrVGhyZXNob2xkW1wiQkxPQ0tfTk9ORVwiXSA9IFwiQkxPQ0tfTk9ORVwiO1xufSkoSGFybUJsb2NrVGhyZXNob2xkIHx8IChIYXJtQmxvY2tUaHJlc2hvbGQgPSB7fSkpO1xuLyoqXG4gKiBQcm9iYWJpbGl0eSB0aGF0IGEgcHJvbXB0IG9yIGNhbmRpZGF0ZSBtYXRjaGVzIGEgaGFybSBjYXRlZ29yeS5cbiAqIEBwdWJsaWNcbiAqL1xudmFyIEhhcm1Qcm9iYWJpbGl0eTtcbihmdW5jdGlvbiAoSGFybVByb2JhYmlsaXR5KSB7XG4gICAgLyoqIFByb2JhYmlsaXR5IGlzIHVuc3BlY2lmaWVkLiAqL1xuICAgIEhhcm1Qcm9iYWJpbGl0eVtcIkhBUk1fUFJPQkFCSUxJVFlfVU5TUEVDSUZJRURcIl0gPSBcIkhBUk1fUFJPQkFCSUxJVFlfVU5TUEVDSUZJRURcIjtcbiAgICAvKiogQ29udGVudCBoYXMgYSBuZWdsaWdpYmxlIGNoYW5jZSBvZiBiZWluZyB1bnNhZmUuICovXG4gICAgSGFybVByb2JhYmlsaXR5W1wiTkVHTElHSUJMRVwiXSA9IFwiTkVHTElHSUJMRVwiO1xuICAgIC8qKiBDb250ZW50IGhhcyBhIGxvdyBjaGFuY2Ugb2YgYmVpbmcgdW5zYWZlLiAqL1xuICAgIEhhcm1Qcm9iYWJpbGl0eVtcIkxPV1wiXSA9IFwiTE9XXCI7XG4gICAgLyoqIENvbnRlbnQgaGFzIGEgbWVkaXVtIGNoYW5jZSBvZiBiZWluZyB1bnNhZmUuICovXG4gICAgSGFybVByb2JhYmlsaXR5W1wiTUVESVVNXCJdID0gXCJNRURJVU1cIjtcbiAgICAvKiogQ29udGVudCBoYXMgYSBoaWdoIGNoYW5jZSBvZiBiZWluZyB1bnNhZmUuICovXG4gICAgSGFybVByb2JhYmlsaXR5W1wiSElHSFwiXSA9IFwiSElHSFwiO1xufSkoSGFybVByb2JhYmlsaXR5IHx8IChIYXJtUHJvYmFiaWxpdHkgPSB7fSkpO1xuLyoqXG4gKiBSZWFzb24gdGhhdCBhIHByb21wdCB3YXMgYmxvY2tlZC5cbiAqIEBwdWJsaWNcbiAqL1xudmFyIEJsb2NrUmVhc29uO1xuKGZ1bmN0aW9uIChCbG9ja1JlYXNvbikge1xuICAgIC8vIEEgYmxvY2tlZCByZWFzb24gd2FzIG5vdCBzcGVjaWZpZWQuXG4gICAgQmxvY2tSZWFzb25bXCJCTE9DS0VEX1JFQVNPTl9VTlNQRUNJRklFRFwiXSA9IFwiQkxPQ0tFRF9SRUFTT05fVU5TUEVDSUZJRURcIjtcbiAgICAvLyBDb250ZW50IHdhcyBibG9ja2VkIGJ5IHNhZmV0eSBzZXR0aW5ncy5cbiAgICBCbG9ja1JlYXNvbltcIlNBRkVUWVwiXSA9IFwiU0FGRVRZXCI7XG4gICAgLy8gQ29udGVudCB3YXMgYmxvY2tlZCwgYnV0IHRoZSByZWFzb24gaXMgdW5jYXRlZ29yaXplZC5cbiAgICBCbG9ja1JlYXNvbltcIk9USEVSXCJdID0gXCJPVEhFUlwiO1xufSkoQmxvY2tSZWFzb24gfHwgKEJsb2NrUmVhc29uID0ge30pKTtcbi8qKlxuICogUmVhc29uIHRoYXQgYSBjYW5kaWRhdGUgZmluaXNoZWQuXG4gKiBAcHVibGljXG4gKi9cbnZhciBGaW5pc2hSZWFzb247XG4oZnVuY3Rpb24gKEZpbmlzaFJlYXNvbikge1xuICAgIC8vIERlZmF1bHQgdmFsdWUuIFRoaXMgdmFsdWUgaXMgdW51c2VkLlxuICAgIEZpbmlzaFJlYXNvbltcIkZJTklTSF9SRUFTT05fVU5TUEVDSUZJRURcIl0gPSBcIkZJTklTSF9SRUFTT05fVU5TUEVDSUZJRURcIjtcbiAgICAvLyBOYXR1cmFsIHN0b3AgcG9pbnQgb2YgdGhlIG1vZGVsIG9yIHByb3ZpZGVkIHN0b3Agc2VxdWVuY2UuXG4gICAgRmluaXNoUmVhc29uW1wiU1RPUFwiXSA9IFwiU1RPUFwiO1xuICAgIC8vIFRoZSBtYXhpbXVtIG51bWJlciBvZiB0b2tlbnMgYXMgc3BlY2lmaWVkIGluIHRoZSByZXF1ZXN0IHdhcyByZWFjaGVkLlxuICAgIEZpbmlzaFJlYXNvbltcIk1BWF9UT0tFTlNcIl0gPSBcIk1BWF9UT0tFTlNcIjtcbiAgICAvLyBUaGUgY2FuZGlkYXRlIGNvbnRlbnQgd2FzIGZsYWdnZWQgZm9yIHNhZmV0eSByZWFzb25zLlxuICAgIEZpbmlzaFJlYXNvbltcIlNBRkVUWVwiXSA9IFwiU0FGRVRZXCI7XG4gICAgLy8gVGhlIGNhbmRpZGF0ZSBjb250ZW50IHdhcyBmbGFnZ2VkIGZvciByZWNpdGF0aW9uIHJlYXNvbnMuXG4gICAgRmluaXNoUmVhc29uW1wiUkVDSVRBVElPTlwiXSA9IFwiUkVDSVRBVElPTlwiO1xuICAgIC8vIFRoZSBjYW5kaWRhdGUgY29udGVudCB3YXMgZmxhZ2dlZCBmb3IgdXNpbmcgYW4gdW5zdXBwb3J0ZWQgbGFuZ3VhZ2UuXG4gICAgRmluaXNoUmVhc29uW1wiTEFOR1VBR0VcIl0gPSBcIkxBTkdVQUdFXCI7XG4gICAgLy8gVG9rZW4gZ2VuZXJhdGlvbiBzdG9wcGVkIGJlY2F1c2UgdGhlIGNvbnRlbnQgY29udGFpbnMgZm9yYmlkZGVuIHRlcm1zLlxuICAgIEZpbmlzaFJlYXNvbltcIkJMT0NLTElTVFwiXSA9IFwiQkxPQ0tMSVNUXCI7XG4gICAgLy8gVG9rZW4gZ2VuZXJhdGlvbiBzdG9wcGVkIGZvciBwb3RlbnRpYWxseSBjb250YWluaW5nIHByb2hpYml0ZWQgY29udGVudC5cbiAgICBGaW5pc2hSZWFzb25bXCJQUk9ISUJJVEVEX0NPTlRFTlRcIl0gPSBcIlBST0hJQklURURfQ09OVEVOVFwiO1xuICAgIC8vIFRva2VuIGdlbmVyYXRpb24gc3RvcHBlZCBiZWNhdXNlIHRoZSBjb250ZW50IHBvdGVudGlhbGx5IGNvbnRhaW5zIFNlbnNpdGl2ZSBQZXJzb25hbGx5IElkZW50aWZpYWJsZSBJbmZvcm1hdGlvbiAoU1BJSSkuXG4gICAgRmluaXNoUmVhc29uW1wiU1BJSVwiXSA9IFwiU1BJSVwiO1xuICAgIC8vIFRoZSBmdW5jdGlvbiBjYWxsIGdlbmVyYXRlZCBieSB0aGUgbW9kZWwgaXMgaW52YWxpZC5cbiAgICBGaW5pc2hSZWFzb25bXCJNQUxGT1JNRURfRlVOQ1RJT05fQ0FMTFwiXSA9IFwiTUFMRk9STUVEX0ZVTkNUSU9OX0NBTExcIjtcbiAgICAvLyBVbmtub3duIHJlYXNvbi5cbiAgICBGaW5pc2hSZWFzb25bXCJPVEhFUlwiXSA9IFwiT1RIRVJcIjtcbn0pKEZpbmlzaFJlYXNvbiB8fCAoRmluaXNoUmVhc29uID0ge30pKTtcbi8qKlxuICogVGFzayB0eXBlIGZvciBlbWJlZGRpbmcgY29udGVudC5cbiAqIEBwdWJsaWNcbiAqL1xudmFyIFRhc2tUeXBlO1xuKGZ1bmN0aW9uIChUYXNrVHlwZSkge1xuICAgIFRhc2tUeXBlW1wiVEFTS19UWVBFX1VOU1BFQ0lGSUVEXCJdID0gXCJUQVNLX1RZUEVfVU5TUEVDSUZJRURcIjtcbiAgICBUYXNrVHlwZVtcIlJFVFJJRVZBTF9RVUVSWVwiXSA9IFwiUkVUUklFVkFMX1FVRVJZXCI7XG4gICAgVGFza1R5cGVbXCJSRVRSSUVWQUxfRE9DVU1FTlRcIl0gPSBcIlJFVFJJRVZBTF9ET0NVTUVOVFwiO1xuICAgIFRhc2tUeXBlW1wiU0VNQU5USUNfU0lNSUxBUklUWVwiXSA9IFwiU0VNQU5USUNfU0lNSUxBUklUWVwiO1xuICAgIFRhc2tUeXBlW1wiQ0xBU1NJRklDQVRJT05cIl0gPSBcIkNMQVNTSUZJQ0FUSU9OXCI7XG4gICAgVGFza1R5cGVbXCJDTFVTVEVSSU5HXCJdID0gXCJDTFVTVEVSSU5HXCI7XG59KShUYXNrVHlwZSB8fCAoVGFza1R5cGUgPSB7fSkpO1xuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydHMuRnVuY3Rpb25DYWxsaW5nTW9kZSA9IHZvaWQgMDtcbihmdW5jdGlvbiAoRnVuY3Rpb25DYWxsaW5nTW9kZSkge1xuICAgIC8vIFVuc3BlY2lmaWVkIGZ1bmN0aW9uIGNhbGxpbmcgbW9kZS4gVGhpcyB2YWx1ZSBzaG91bGQgbm90IGJlIHVzZWQuXG4gICAgRnVuY3Rpb25DYWxsaW5nTW9kZVtcIk1PREVfVU5TUEVDSUZJRURcIl0gPSBcIk1PREVfVU5TUEVDSUZJRURcIjtcbiAgICAvLyBEZWZhdWx0IG1vZGVsIGJlaGF2aW9yLCBtb2RlbCBkZWNpZGVzIHRvIHByZWRpY3QgZWl0aGVyIGEgZnVuY3Rpb24gY2FsbFxuICAgIC8vIG9yIGEgbmF0dXJhbCBsYW5ndWFnZSByZXBzcG9zZS5cbiAgICBGdW5jdGlvbkNhbGxpbmdNb2RlW1wiQVVUT1wiXSA9IFwiQVVUT1wiO1xuICAgIC8vIE1vZGVsIGlzIGNvbnN0cmFpbmVkIHRvIGFsd2F5cyBwcmVkaWN0aW5nIGEgZnVuY3Rpb24gY2FsbCBvbmx5LlxuICAgIC8vIElmIFwiYWxsb3dlZF9mdW5jdGlvbl9uYW1lc1wiIGFyZSBzZXQsIHRoZSBwcmVkaWN0ZWQgZnVuY3Rpb24gY2FsbCB3aWxsIGJlXG4gICAgLy8gbGltaXRlZCB0byBhbnkgb25lIG9mIFwiYWxsb3dlZF9mdW5jdGlvbl9uYW1lc1wiLCBlbHNlIHRoZSBwcmVkaWN0ZWRcbiAgICAvLyBmdW5jdGlvbiBjYWxsIHdpbGwgYmUgYW55IG9uZSBvZiB0aGUgcHJvdmlkZWQgXCJmdW5jdGlvbl9kZWNsYXJhdGlvbnNcIi5cbiAgICBGdW5jdGlvbkNhbGxpbmdNb2RlW1wiQU5ZXCJdID0gXCJBTllcIjtcbiAgICAvLyBNb2RlbCB3aWxsIG5vdCBwcmVkaWN0IGFueSBmdW5jdGlvbiBjYWxsLiBNb2RlbCBiZWhhdmlvciBpcyBzYW1lIGFzIHdoZW5cbiAgICAvLyBub3QgcGFzc2luZyBhbnkgZnVuY3Rpb24gZGVjbGFyYXRpb25zLlxuICAgIEZ1bmN0aW9uQ2FsbGluZ01vZGVbXCJOT05FXCJdID0gXCJOT05FXCI7XG59KShleHBvcnRzLkZ1bmN0aW9uQ2FsbGluZ01vZGUgfHwgKGV4cG9ydHMuRnVuY3Rpb25DYWxsaW5nTW9kZSA9IHt9KSk7XG4vKipcbiAqIFRoZSBtb2RlIG9mIHRoZSBwcmVkaWN0b3IgdG8gYmUgdXNlZCBpbiBkeW5hbWljIHJldHJpZXZhbC5cbiAqIEBwdWJsaWNcbiAqL1xudmFyIER5bmFtaWNSZXRyaWV2YWxNb2RlO1xuKGZ1bmN0aW9uIChEeW5hbWljUmV0cmlldmFsTW9kZSkge1xuICAgIC8vIFVuc3BlY2lmaWVkIGZ1bmN0aW9uIGNhbGxpbmcgbW9kZS4gVGhpcyB2YWx1ZSBzaG91bGQgbm90IGJlIHVzZWQuXG4gICAgRHluYW1pY1JldHJpZXZhbE1vZGVbXCJNT0RFX1VOU1BFQ0lGSUVEXCJdID0gXCJNT0RFX1VOU1BFQ0lGSUVEXCI7XG4gICAgLy8gUnVuIHJldHJpZXZhbCBvbmx5IHdoZW4gc3lzdGVtIGRlY2lkZXMgaXQgaXMgbmVjZXNzYXJ5LlxuICAgIER5bmFtaWNSZXRyaWV2YWxNb2RlW1wiTU9ERV9EWU5BTUlDXCJdID0gXCJNT0RFX0RZTkFNSUNcIjtcbn0pKER5bmFtaWNSZXRyaWV2YWxNb2RlIHx8IChEeW5hbWljUmV0cmlldmFsTW9kZSA9IHt9KSk7XG5cbmV4cG9ydHMuR29vZ2xlQUlDYWNoZU1hbmFnZXIgPSBHb29nbGVBSUNhY2hlTWFuYWdlcjtcbmV4cG9ydHMuR29vZ2xlQUlGaWxlTWFuYWdlciA9IEdvb2dsZUFJRmlsZU1hbmFnZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXBcbiJdLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOlswXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(action-browser)/./node_modules/@google/generative-ai/dist/server/index.js\n"); + +/***/ }) + +}; +; \ No newline at end of file