@expcluster/permission-groups 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/controller.ts +434 -0
- package/dist/browser/messages.d.ts +527 -0
- package/dist/browser/messages.d.ts.map +1 -0
- package/dist/browser/messages.js +561 -0
- package/dist/browser/messages.js.map +1 -0
- package/dist/browser/package.json +49 -0
- package/dist/browser/tsconfig.browser.tsbuildinfo +1 -0
- package/dist/browser/web/components/AssignmentForm.d.ts +7 -0
- package/dist/browser/web/components/AssignmentForm.d.ts.map +1 -0
- package/dist/browser/web/components/AssignmentForm.js +29 -0
- package/dist/browser/web/components/AssignmentForm.js.map +1 -0
- package/dist/browser/web/components/AssignmentsTable.d.ts +2 -0
- package/dist/browser/web/components/AssignmentsTable.d.ts.map +1 -0
- package/dist/browser/web/components/AssignmentsTable.js +61 -0
- package/dist/browser/web/components/AssignmentsTable.js.map +1 -0
- package/dist/browser/web/components/DeleteConfirm.d.ts +6 -0
- package/dist/browser/web/components/DeleteConfirm.d.ts.map +1 -0
- package/dist/browser/web/components/DeleteConfirm.js +7 -0
- package/dist/browser/web/components/DeleteConfirm.js.map +1 -0
- package/dist/browser/web/components/GroupForm.d.ts +5 -0
- package/dist/browser/web/components/GroupForm.d.ts.map +1 -0
- package/dist/browser/web/components/GroupForm.js +22 -0
- package/dist/browser/web/components/GroupForm.js.map +1 -0
- package/dist/browser/web/components/GroupViewPage.d.ts +2 -0
- package/dist/browser/web/components/GroupViewPage.d.ts.map +1 -0
- package/dist/browser/web/components/GroupViewPage.js +161 -0
- package/dist/browser/web/components/GroupViewPage.js.map +1 -0
- package/dist/browser/web/components/GroupsTable.d.ts +2 -0
- package/dist/browser/web/components/GroupsTable.d.ts.map +1 -0
- package/dist/browser/web/components/GroupsTable.js +29 -0
- package/dist/browser/web/components/GroupsTable.js.map +1 -0
- package/dist/browser/web/components/RoleMappingForm.d.ts +7 -0
- package/dist/browser/web/components/RoleMappingForm.d.ts.map +1 -0
- package/dist/browser/web/components/RoleMappingForm.js +32 -0
- package/dist/browser/web/components/RoleMappingForm.js.map +1 -0
- package/dist/browser/web/components/RoleMappingsTable.d.ts +2 -0
- package/dist/browser/web/components/RoleMappingsTable.d.ts.map +1 -0
- package/dist/browser/web/components/RoleMappingsTable.js +64 -0
- package/dist/browser/web/components/RoleMappingsTable.js.map +1 -0
- package/dist/browser/web/index.d.ts +13 -0
- package/dist/browser/web/index.d.ts.map +1 -0
- package/dist/browser/web/index.js +60 -0
- package/dist/browser/web/index.js.map +1 -0
- package/dist/node/controller.d.ts +37 -0
- package/dist/node/controller.d.ts.map +1 -0
- package/dist/node/controller.js +372 -0
- package/dist/node/controller.js.map +1 -0
- package/dist/node/index.d.ts +10 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +196 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/instance.d.ts +40 -0
- package/dist/node/instance.d.ts.map +1 -0
- package/dist/node/instance.js +155 -0
- package/dist/node/instance.js.map +1 -0
- package/dist/node/messages.d.ts +527 -0
- package/dist/node/messages.d.ts.map +1 -0
- package/dist/node/messages.js +620 -0
- package/dist/node/messages.js.map +1 -0
- package/dist/node/tsconfig.node.tsbuildinfo +1 -0
- package/dist/web/manifest.json +10 -0
- package/dist/web/static/exp_groups.afefd90b210f7c8e0df2.js +543 -0
- package/dist/web/static/index_ts.f7d30aa0c13ff0be393a.js +22 -0
- package/dist/web/static/main.c2178975889c1c720e80.js +653 -0
- package/dist/web/static/messages_ts.65a81c17fb37953c5d68.js +22 -0
- package/dist/web/static/package_json.aab0d3f37da0567c250c.js +22 -0
- package/dist/web/static/vendors-node_modules_pnpm_ant-design_icons_6_2_3_rea_94b50600dfe79448cabf92d130d83059_node_mo-c79f54.cf768c64b40c811ce6c9.js +273 -0
- package/dist/web/static/vendors-node_modules_pnpm_sinclair_typebox_0_30_4_node_modules_sinclair_typebox_typebox_js.7fa46fac84f2e9324e54.js +22 -0
- package/dist/web/static/web_index_tsx-webpack_sharing_consume_default_react.b4766180f4d467b7b24f.js +102 -0
- package/index.ts +183 -0
- package/instance.ts +171 -0
- package/messages.ts +692 -0
- package/module/control.lua +438 -0
- package/module/globals.lua +11 -0
- package/module/module.json +12 -0
- package/module/module_exports.lua +3 -0
- package/package.json +47 -0
- package/tsconfig.browser.json +4 -0
- package/tsconfig.json +7 -0
- package/tsconfig.node.json +5 -0
- package/web/components/AssignmentForm.tsx +74 -0
- package/web/components/AssignmentsTable.tsx +111 -0
- package/web/components/DeleteConfirm.tsx +16 -0
- package/web/components/GroupForm.tsx +45 -0
- package/web/components/GroupViewPage.tsx +287 -0
- package/web/components/GroupsTable.tsx +49 -0
- package/web/components/RoleMappingForm.tsx +106 -0
- package/web/components/RoleMappingsTable.tsx +107 -0
- package/web/index.tsx +108 -0
- package/webpack.config.js +34 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* ATTENTION: An "eval-source-map" devtool has been used.
|
|
4
|
+
* This devtool is neither made for production nor for readable output files.
|
|
5
|
+
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
|
6
|
+
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
|
7
|
+
* or disable the default devtool with "devtool: false".
|
|
8
|
+
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
|
9
|
+
*/
|
|
10
|
+
(self["webpackChunk_expcluster_permission_groups"] = self["webpackChunk_expcluster_permission_groups"] || []).push([["vendors-node_modules_pnpm_sinclair_typebox_0_30_4_node_modules_sinclair_typebox_typebox_js"],{
|
|
11
|
+
|
|
12
|
+
/***/ 213
|
|
13
|
+
/*!******************************************************************************************************!*\
|
|
14
|
+
!*** ../../../node_modules/.pnpm/@sinclair+typebox@0.30.4/node_modules/@sinclair/typebox/typebox.js ***!
|
|
15
|
+
\******************************************************************************************************/
|
|
16
|
+
(__unused_webpack_module, exports) {
|
|
17
|
+
|
|
18
|
+
eval("{\n/*--------------------------------------------------------------------------\n\n@sinclair/typebox\n\nThe MIT License (MIT)\n\nCopyright (c) 2017-2023 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n---------------------------------------------------------------------------*/\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Type = exports.StandardType = exports.ExtendedTypeBuilder = exports.StandardTypeBuilder = exports.TypeBuilder = exports.TemplateLiteralDslParser = exports.TemplateLiteralGenerator = exports.TemplateLiteralFinite = exports.TemplateLiteralParser = exports.TemplateLiteralParserError = exports.TemplateLiteralResolver = exports.TemplateLiteralPattern = exports.UnionResolver = exports.KeyArrayResolver = exports.KeyResolver = exports.ObjectMap = exports.Intrinsic = exports.IndexedAccessor = exports.TypeClone = exports.TypeExtends = exports.TypeExtendsResult = exports.ExtendsUndefined = exports.TypeGuard = exports.TypeGuardUnknownTypeError = exports.ValueGuard = exports.FormatRegistry = exports.TypeRegistry = exports.PatternStringExact = exports.PatternNumberExact = exports.PatternBooleanExact = exports.PatternString = exports.PatternNumber = exports.PatternBoolean = exports.Kind = exports.Hint = exports.Optional = exports.Readonly = void 0;\n// --------------------------------------------------------------------------\n// Symbols\n// --------------------------------------------------------------------------\nexports.Readonly = Symbol.for('TypeBox.Readonly');\nexports.Optional = Symbol.for('TypeBox.Optional');\nexports.Hint = Symbol.for('TypeBox.Hint');\nexports.Kind = Symbol.for('TypeBox.Kind');\n// --------------------------------------------------------------------------\n// Patterns\n// --------------------------------------------------------------------------\nexports.PatternBoolean = '(true|false)';\nexports.PatternNumber = '(0|[1-9][0-9]*)';\nexports.PatternString = '(.*)';\nexports.PatternBooleanExact = `^${exports.PatternBoolean}$`;\nexports.PatternNumberExact = `^${exports.PatternNumber}$`;\nexports.PatternStringExact = `^${exports.PatternString}$`;\n/** A registry for user defined types */\nvar TypeRegistry;\n(function (TypeRegistry) {\n const map = new Map();\n /** Returns the entries in this registry */\n function Entries() {\n return new Map(map);\n }\n TypeRegistry.Entries = Entries;\n /** Clears all user defined types */\n function Clear() {\n return map.clear();\n }\n TypeRegistry.Clear = Clear;\n /** Deletes a registered type */\n function Delete(kind) {\n return map.delete(kind);\n }\n TypeRegistry.Delete = Delete;\n /** Returns true if this registry contains this kind */\n function Has(kind) {\n return map.has(kind);\n }\n TypeRegistry.Has = Has;\n /** Sets a validation function for a user defined type */\n function Set(kind, func) {\n map.set(kind, func);\n }\n TypeRegistry.Set = Set;\n /** Gets a custom validation function for a user defined type */\n function Get(kind) {\n return map.get(kind);\n }\n TypeRegistry.Get = Get;\n})(TypeRegistry || (exports.TypeRegistry = TypeRegistry = {}));\n/** A registry for user defined string formats */\nvar FormatRegistry;\n(function (FormatRegistry) {\n const map = new Map();\n /** Returns the entries in this registry */\n function Entries() {\n return new Map(map);\n }\n FormatRegistry.Entries = Entries;\n /** Clears all user defined string formats */\n function Clear() {\n return map.clear();\n }\n FormatRegistry.Clear = Clear;\n /** Deletes a registered format */\n function Delete(format) {\n return map.delete(format);\n }\n FormatRegistry.Delete = Delete;\n /** Returns true if the user defined string format exists */\n function Has(format) {\n return map.has(format);\n }\n FormatRegistry.Has = Has;\n /** Sets a validation function for a user defined string format */\n function Set(format, func) {\n map.set(format, func);\n }\n FormatRegistry.Set = Set;\n /** Gets a validation function for a user defined string format */\n function Get(format) {\n return map.get(format);\n }\n FormatRegistry.Get = Get;\n})(FormatRegistry || (exports.FormatRegistry = FormatRegistry = {}));\n// --------------------------------------------------------------------------\n// ValueGuard\n// --------------------------------------------------------------------------\nvar ValueGuard;\n(function (ValueGuard) {\n function IsObject(value) {\n return typeof value === 'object' && value !== null;\n }\n ValueGuard.IsObject = IsObject;\n function IsArray(value) {\n return Array.isArray(value);\n }\n ValueGuard.IsArray = IsArray;\n function IsBoolean(value) {\n return typeof value === 'boolean';\n }\n ValueGuard.IsBoolean = IsBoolean;\n function IsNull(value) {\n return value === null;\n }\n ValueGuard.IsNull = IsNull;\n function IsUndefined(value) {\n return value === undefined;\n }\n ValueGuard.IsUndefined = IsUndefined;\n function IsBigInt(value) {\n return typeof value === 'bigint';\n }\n ValueGuard.IsBigInt = IsBigInt;\n function IsNumber(value) {\n return typeof value === 'number';\n }\n ValueGuard.IsNumber = IsNumber;\n function IsString(value) {\n return typeof value === 'string';\n }\n ValueGuard.IsString = IsString;\n})(ValueGuard || (exports.ValueGuard = ValueGuard = {}));\n// --------------------------------------------------------------------------\n// TypeGuard\n// --------------------------------------------------------------------------\nclass TypeGuardUnknownTypeError extends Error {\n constructor(schema) {\n super('TypeGuard: Unknown type');\n this.schema = schema;\n }\n}\nexports.TypeGuardUnknownTypeError = TypeGuardUnknownTypeError;\n/** Provides functions to test if JavaScript values are TypeBox types */\nvar TypeGuard;\n(function (TypeGuard) {\n function IsPattern(value) {\n try {\n new RegExp(value);\n return true;\n }\n catch {\n return false;\n }\n }\n function IsControlCharacterFree(value) {\n if (!ValueGuard.IsString(value))\n return false;\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if ((code >= 7 && code <= 13) || code === 27 || code === 127) {\n return false;\n }\n }\n return true;\n }\n function IsAdditionalProperties(value) {\n return IsOptionalBoolean(value) || TSchema(value);\n }\n function IsOptionalBigInt(value) {\n return ValueGuard.IsUndefined(value) || ValueGuard.IsBigInt(value);\n }\n function IsOptionalNumber(value) {\n return ValueGuard.IsUndefined(value) || ValueGuard.IsNumber(value);\n }\n function IsOptionalBoolean(value) {\n return ValueGuard.IsUndefined(value) || ValueGuard.IsBoolean(value);\n }\n function IsOptionalString(value) {\n return ValueGuard.IsUndefined(value) || ValueGuard.IsString(value);\n }\n function IsOptionalPattern(value) {\n return ValueGuard.IsUndefined(value) || (ValueGuard.IsString(value) && IsControlCharacterFree(value) && IsPattern(value));\n }\n function IsOptionalFormat(value) {\n return ValueGuard.IsUndefined(value) || (ValueGuard.IsString(value) && IsControlCharacterFree(value));\n }\n function IsOptionalSchema(value) {\n return ValueGuard.IsUndefined(value) || TSchema(value);\n }\n /** Returns true if the given schema is TAny */\n function TAny(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Any') &&\n IsOptionalString(schema.$id));\n }\n TypeGuard.TAny = TAny;\n /** Returns true if the given schema is TArray */\n function TArray(schema) {\n return (TKindOf(schema, 'Array') &&\n schema.type === 'array' &&\n IsOptionalString(schema.$id) &&\n TSchema(schema.items) &&\n IsOptionalNumber(schema.minItems) &&\n IsOptionalNumber(schema.maxItems) &&\n IsOptionalBoolean(schema.uniqueItems) &&\n IsOptionalSchema(schema.contains) &&\n IsOptionalNumber(schema.minContains) &&\n IsOptionalNumber(schema.maxContains));\n }\n TypeGuard.TArray = TArray;\n /** Returns true if the given schema is TAsyncIterator */\n function TAsyncIterator(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'AsyncIterator') &&\n schema.type === 'AsyncIterator' &&\n IsOptionalString(schema.$id) &&\n TSchema(schema.items));\n }\n TypeGuard.TAsyncIterator = TAsyncIterator;\n /** Returns true if the given schema is TBigInt */\n function TBigInt(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'BigInt') &&\n schema.type === 'bigint' &&\n IsOptionalString(schema.$id) &&\n IsOptionalBigInt(schema.multipleOf) &&\n IsOptionalBigInt(schema.minimum) &&\n IsOptionalBigInt(schema.maximum) &&\n IsOptionalBigInt(schema.exclusiveMinimum) &&\n IsOptionalBigInt(schema.exclusiveMaximum));\n }\n TypeGuard.TBigInt = TBigInt;\n /** Returns true if the given schema is TBoolean */\n function TBoolean(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Boolean') &&\n schema.type === 'boolean' &&\n IsOptionalString(schema.$id));\n }\n TypeGuard.TBoolean = TBoolean;\n /** Returns true if the given schema is TConstructor */\n function TConstructor(schema) {\n // prettier-ignore\n if (!(TKindOf(schema, 'Constructor') &&\n schema.type === 'constructor' &&\n IsOptionalString(schema.$id) &&\n ValueGuard.IsArray(schema.parameters) &&\n TSchema(schema.returns))) {\n return false;\n }\n for (const parameter of schema.parameters) {\n if (!TSchema(parameter))\n return false;\n }\n return true;\n }\n TypeGuard.TConstructor = TConstructor;\n /** Returns true if the given schema is TDate */\n function TDate(schema) {\n return (TKindOf(schema, 'Date') &&\n schema.type === 'Date' &&\n IsOptionalString(schema.$id) &&\n IsOptionalNumber(schema.minimumTimestamp) &&\n IsOptionalNumber(schema.maximumTimestamp) &&\n IsOptionalNumber(schema.exclusiveMinimumTimestamp) &&\n IsOptionalNumber(schema.exclusiveMaximumTimestamp));\n }\n TypeGuard.TDate = TDate;\n /** Returns true if the given schema is TFunction */\n function TFunction(schema) {\n // prettier-ignore\n if (!(TKindOf(schema, 'Function') &&\n schema.type === 'function' &&\n IsOptionalString(schema.$id) &&\n ValueGuard.IsArray(schema.parameters) &&\n TSchema(schema.returns))) {\n return false;\n }\n for (const parameter of schema.parameters) {\n if (!TSchema(parameter))\n return false;\n }\n return true;\n }\n TypeGuard.TFunction = TFunction;\n /** Returns true if the given schema is TInteger */\n function TInteger(schema) {\n return (TKindOf(schema, 'Integer') &&\n schema.type === 'integer' &&\n IsOptionalString(schema.$id) &&\n IsOptionalNumber(schema.multipleOf) &&\n IsOptionalNumber(schema.minimum) &&\n IsOptionalNumber(schema.maximum) &&\n IsOptionalNumber(schema.exclusiveMinimum) &&\n IsOptionalNumber(schema.exclusiveMaximum));\n }\n TypeGuard.TInteger = TInteger;\n /** Returns true if the given schema is TIntersect */\n function TIntersect(schema) {\n // prettier-ignore\n if (!(TKindOf(schema, 'Intersect') &&\n ValueGuard.IsArray(schema.allOf) &&\n IsOptionalString(schema.type) &&\n (IsOptionalBoolean(schema.unevaluatedProperties) || IsOptionalSchema(schema.unevaluatedProperties)) &&\n IsOptionalString(schema.$id))) {\n return false;\n }\n if ('type' in schema && schema.type !== 'object') {\n return false;\n }\n for (const inner of schema.allOf) {\n if (!TSchema(inner))\n return false;\n }\n return true;\n }\n TypeGuard.TIntersect = TIntersect;\n /** Returns true if the given schema is TIterator */\n function TIterator(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Iterator') &&\n schema.type === 'Iterator' &&\n IsOptionalString(schema.$id) &&\n TSchema(schema.items));\n }\n TypeGuard.TIterator = TIterator;\n /** Returns true if the given schema is a TKind with the given name. */\n function TKindOf(schema, kind) {\n return TKind(schema) && schema[exports.Kind] === kind;\n }\n TypeGuard.TKindOf = TKindOf;\n /** Returns true if the given schema is TKind */\n function TKind(schema) {\n return ValueGuard.IsObject(schema) && exports.Kind in schema && ValueGuard.IsString(schema[exports.Kind]);\n }\n TypeGuard.TKind = TKind;\n /** Returns true if the given schema is TLiteral<string> */\n function TLiteralString(schema) {\n return TLiteral(schema) && ValueGuard.IsString(schema.const);\n }\n TypeGuard.TLiteralString = TLiteralString;\n /** Returns true if the given schema is TLiteral<number> */\n function TLiteralNumber(schema) {\n return TLiteral(schema) && ValueGuard.IsNumber(schema.const);\n }\n TypeGuard.TLiteralNumber = TLiteralNumber;\n /** Returns true if the given schema is TLiteral<boolean> */\n function TLiteralBoolean(schema) {\n return TLiteral(schema) && ValueGuard.IsBoolean(schema.const);\n }\n TypeGuard.TLiteralBoolean = TLiteralBoolean;\n /** Returns true if the given schema is TLiteral */\n function TLiteral(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Literal') &&\n IsOptionalString(schema.$id) && (ValueGuard.IsBoolean(schema.const) ||\n ValueGuard.IsNumber(schema.const) ||\n ValueGuard.IsString(schema.const)));\n }\n TypeGuard.TLiteral = TLiteral;\n /** Returns true if the given schema is TNever */\n function TNever(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Never') &&\n ValueGuard.IsObject(schema.not) &&\n Object.getOwnPropertyNames(schema.not).length === 0);\n }\n TypeGuard.TNever = TNever;\n /** Returns true if the given schema is TNot */\n function TNot(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Not') &&\n TSchema(schema.not));\n }\n TypeGuard.TNot = TNot;\n /** Returns true if the given schema is TNull */\n function TNull(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Null') &&\n schema.type === 'null' &&\n IsOptionalString(schema.$id));\n }\n TypeGuard.TNull = TNull;\n /** Returns true if the given schema is TNumber */\n function TNumber(schema) {\n return (TKindOf(schema, 'Number') &&\n schema.type === 'number' &&\n IsOptionalString(schema.$id) &&\n IsOptionalNumber(schema.multipleOf) &&\n IsOptionalNumber(schema.minimum) &&\n IsOptionalNumber(schema.maximum) &&\n IsOptionalNumber(schema.exclusiveMinimum) &&\n IsOptionalNumber(schema.exclusiveMaximum));\n }\n TypeGuard.TNumber = TNumber;\n /** Returns true if the given schema is TObject */\n function TObject(schema) {\n if (!(TKindOf(schema, 'Object') &&\n schema.type === 'object' &&\n IsOptionalString(schema.$id) &&\n ValueGuard.IsObject(schema.properties) &&\n IsAdditionalProperties(schema.additionalProperties) &&\n IsOptionalNumber(schema.minProperties) &&\n IsOptionalNumber(schema.maxProperties))) {\n return false;\n }\n for (const [key, value] of Object.entries(schema.properties)) {\n if (!IsControlCharacterFree(key))\n return false;\n if (!TSchema(value))\n return false;\n }\n return true;\n }\n TypeGuard.TObject = TObject;\n /** Returns true if the given schema is TPromise */\n function TPromise(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Promise') &&\n schema.type === 'Promise' &&\n IsOptionalString(schema.$id) &&\n TSchema(schema.item));\n }\n TypeGuard.TPromise = TPromise;\n /** Returns true if the given schema is TRecord */\n function TRecord(schema) {\n // prettier-ignore\n if (!(TKindOf(schema, 'Record') &&\n schema.type === 'object' &&\n IsOptionalString(schema.$id) &&\n IsAdditionalProperties(schema.additionalProperties) &&\n ValueGuard.IsObject(schema.patternProperties))) {\n return false;\n }\n const keys = Object.getOwnPropertyNames(schema.patternProperties);\n if (keys.length !== 1) {\n return false;\n }\n if (!IsPattern(keys[0])) {\n return false;\n }\n if (!TSchema(schema.patternProperties[keys[0]])) {\n return false;\n }\n return true;\n }\n TypeGuard.TRecord = TRecord;\n /** Returns true if the given schema is TRef */\n function TRef(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Ref') &&\n IsOptionalString(schema.$id) &&\n ValueGuard.IsString(schema.$ref));\n }\n TypeGuard.TRef = TRef;\n /** Returns true if the given schema is TString */\n function TString(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'String') &&\n schema.type === 'string' &&\n IsOptionalString(schema.$id) &&\n IsOptionalNumber(schema.minLength) &&\n IsOptionalNumber(schema.maxLength) &&\n IsOptionalPattern(schema.pattern) &&\n IsOptionalFormat(schema.format));\n }\n TypeGuard.TString = TString;\n /** Returns true if the given schema is TSymbol */\n function TSymbol(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Symbol') &&\n schema.type === 'symbol' &&\n IsOptionalString(schema.$id));\n }\n TypeGuard.TSymbol = TSymbol;\n /** Returns true if the given schema is TTemplateLiteral */\n function TTemplateLiteral(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'TemplateLiteral') &&\n schema.type === 'string' &&\n ValueGuard.IsString(schema.pattern) &&\n schema.pattern[0] === '^' &&\n schema.pattern[schema.pattern.length - 1] === '$');\n }\n TypeGuard.TTemplateLiteral = TTemplateLiteral;\n /** Returns true if the given schema is TThis */\n function TThis(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'This') &&\n IsOptionalString(schema.$id) &&\n ValueGuard.IsString(schema.$ref));\n }\n TypeGuard.TThis = TThis;\n /** Returns true if the given schema is TTuple */\n function TTuple(schema) {\n // prettier-ignore\n if (!(TKindOf(schema, 'Tuple') &&\n schema.type === 'array' &&\n IsOptionalString(schema.$id) &&\n ValueGuard.IsNumber(schema.minItems) &&\n ValueGuard.IsNumber(schema.maxItems) &&\n schema.minItems === schema.maxItems)) {\n return false;\n }\n if (ValueGuard.IsUndefined(schema.items) && ValueGuard.IsUndefined(schema.additionalItems) && schema.minItems === 0) {\n return true;\n }\n if (!ValueGuard.IsArray(schema.items)) {\n return false;\n }\n for (const inner of schema.items) {\n if (!TSchema(inner))\n return false;\n }\n return true;\n }\n TypeGuard.TTuple = TTuple;\n /** Returns true if the given schema is TUndefined */\n function TUndefined(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Undefined') &&\n schema.type === 'undefined' &&\n IsOptionalString(schema.$id));\n }\n TypeGuard.TUndefined = TUndefined;\n /** Returns true if the given schema is TUnion<Literal<string | number>[]> */\n function TUnionLiteral(schema) {\n return TUnion(schema) && schema.anyOf.every((schema) => TLiteralString(schema) || TLiteralNumber(schema));\n }\n TypeGuard.TUnionLiteral = TUnionLiteral;\n /** Returns true if the given schema is TUnion */\n function TUnion(schema) {\n // prettier-ignore\n if (!(TKindOf(schema, 'Union') &&\n ValueGuard.IsArray(schema.anyOf) &&\n IsOptionalString(schema.$id))) {\n return false;\n }\n for (const inner of schema.anyOf) {\n if (!TSchema(inner))\n return false;\n }\n return true;\n }\n TypeGuard.TUnion = TUnion;\n /** Returns true if the given schema is TUint8Array */\n function TUint8Array(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Uint8Array') &&\n schema.type === 'Uint8Array' &&\n IsOptionalString(schema.$id) &&\n IsOptionalNumber(schema.minByteLength) &&\n IsOptionalNumber(schema.maxByteLength));\n }\n TypeGuard.TUint8Array = TUint8Array;\n /** Returns true if the given schema is TUnknown */\n function TUnknown(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Unknown') &&\n IsOptionalString(schema.$id));\n }\n TypeGuard.TUnknown = TUnknown;\n /** Returns true if the given schema is a raw TUnsafe */\n function TUnsafe(schema) {\n return TKindOf(schema, 'Unsafe');\n }\n TypeGuard.TUnsafe = TUnsafe;\n /** Returns true if the given schema is TVoid */\n function TVoid(schema) {\n // prettier-ignore\n return (TKindOf(schema, 'Void') &&\n schema.type === 'void' &&\n IsOptionalString(schema.$id));\n }\n TypeGuard.TVoid = TVoid;\n /** Returns true if this schema has the Readonly modifier */\n function TReadonly(schema) {\n return ValueGuard.IsObject(schema) && schema[exports.Readonly] === 'Readonly';\n }\n TypeGuard.TReadonly = TReadonly;\n /** Returns true if this schema has the Optional modifier */\n function TOptional(schema) {\n return ValueGuard.IsObject(schema) && schema[exports.Optional] === 'Optional';\n }\n TypeGuard.TOptional = TOptional;\n /** Returns true if the given schema is TSchema */\n function TSchema(schema) {\n return (ValueGuard.IsObject(schema) &&\n (TAny(schema) ||\n TArray(schema) ||\n TBoolean(schema) ||\n TBigInt(schema) ||\n TAsyncIterator(schema) ||\n TConstructor(schema) ||\n TDate(schema) ||\n TFunction(schema) ||\n TInteger(schema) ||\n TIntersect(schema) ||\n TIterator(schema) ||\n TLiteral(schema) ||\n TNever(schema) ||\n TNot(schema) ||\n TNull(schema) ||\n TNumber(schema) ||\n TObject(schema) ||\n TPromise(schema) ||\n TRecord(schema) ||\n TRef(schema) ||\n TString(schema) ||\n TSymbol(schema) ||\n TTemplateLiteral(schema) ||\n TThis(schema) ||\n TTuple(schema) ||\n TUndefined(schema) ||\n TUnion(schema) ||\n TUint8Array(schema) ||\n TUnknown(schema) ||\n TUnsafe(schema) ||\n TVoid(schema) ||\n (TKind(schema) && TypeRegistry.Has(schema[exports.Kind]))));\n }\n TypeGuard.TSchema = TSchema;\n})(TypeGuard || (exports.TypeGuard = TypeGuard = {}));\n// --------------------------------------------------------------------------\n// ExtendsUndefined\n// --------------------------------------------------------------------------\n/** Fast undefined check used for properties of type undefined */\nvar ExtendsUndefined;\n(function (ExtendsUndefined) {\n function Check(schema) {\n if (schema[exports.Kind] === 'Undefined')\n return true;\n if (schema[exports.Kind] === 'Not') {\n return !Check(schema.not);\n }\n if (schema[exports.Kind] === 'Intersect') {\n const intersect = schema;\n return intersect.allOf.every((schema) => Check(schema));\n }\n if (schema[exports.Kind] === 'Union') {\n const union = schema;\n return union.anyOf.some((schema) => Check(schema));\n }\n return false;\n }\n ExtendsUndefined.Check = Check;\n})(ExtendsUndefined || (exports.ExtendsUndefined = ExtendsUndefined = {}));\n// --------------------------------------------------------------------------\n// TypeExtends\n// --------------------------------------------------------------------------\nvar TypeExtendsResult;\n(function (TypeExtendsResult) {\n TypeExtendsResult[TypeExtendsResult[\"Union\"] = 0] = \"Union\";\n TypeExtendsResult[TypeExtendsResult[\"True\"] = 1] = \"True\";\n TypeExtendsResult[TypeExtendsResult[\"False\"] = 2] = \"False\";\n})(TypeExtendsResult || (exports.TypeExtendsResult = TypeExtendsResult = {}));\nvar TypeExtends;\n(function (TypeExtends) {\n // --------------------------------------------------------------------------\n // IntoBooleanResult\n // --------------------------------------------------------------------------\n function IntoBooleanResult(result) {\n return result === TypeExtendsResult.False ? TypeExtendsResult.False : TypeExtendsResult.True;\n }\n // --------------------------------------------------------------------------\n // StructuralRight\n // --------------------------------------------------------------------------\n function IsStructuralRight(right) {\n // prettier-ignore\n return (TypeGuard.TNever(right) ||\n TypeGuard.TIntersect(right) ||\n TypeGuard.TUnion(right) ||\n TypeGuard.TUnknown(right) ||\n TypeGuard.TAny(right));\n }\n function StructuralRight(left, right) {\n if (TypeGuard.TNever(right))\n return TNeverRight(left, right);\n if (TypeGuard.TIntersect(right))\n return TIntersectRight(left, right);\n if (TypeGuard.TUnion(right))\n return TUnionRight(left, right);\n if (TypeGuard.TUnknown(right))\n return TUnknownRight(left, right);\n if (TypeGuard.TAny(right))\n return TAnyRight(left, right);\n throw Error('TypeExtends: StructuralRight');\n }\n // --------------------------------------------------------------------------\n // Any\n // --------------------------------------------------------------------------\n function TAnyRight(left, right) {\n return TypeExtendsResult.True;\n }\n function TAny(left, right) {\n if (TypeGuard.TIntersect(right))\n return TIntersectRight(left, right);\n if (TypeGuard.TUnion(right) && right.anyOf.some((schema) => TypeGuard.TAny(schema) || TypeGuard.TUnknown(schema)))\n return TypeExtendsResult.True;\n if (TypeGuard.TUnion(right))\n return TypeExtendsResult.Union;\n if (TypeGuard.TUnknown(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TAny(right))\n return TypeExtendsResult.True;\n return TypeExtendsResult.Union;\n }\n // --------------------------------------------------------------------------\n // Array\n // --------------------------------------------------------------------------\n function TArrayRight(left, right) {\n if (TypeGuard.TUnknown(left))\n return TypeExtendsResult.False;\n if (TypeGuard.TAny(left))\n return TypeExtendsResult.Union;\n if (TypeGuard.TNever(left))\n return TypeExtendsResult.True;\n return TypeExtendsResult.False;\n }\n function TArray(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right) && IsObjectArrayLike(right))\n return TypeExtendsResult.True;\n if (!TypeGuard.TArray(right))\n return TypeExtendsResult.False;\n return IntoBooleanResult(Visit(left.items, right.items));\n }\n // --------------------------------------------------------------------------\n // AsyncIterator\n // --------------------------------------------------------------------------\n function TAsyncIterator(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (!TypeGuard.TAsyncIterator(right))\n return TypeExtendsResult.False;\n return IntoBooleanResult(Visit(left.items, right.items));\n }\n // --------------------------------------------------------------------------\n // BigInt\n // --------------------------------------------------------------------------\n function TBigInt(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n return TypeGuard.TBigInt(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Boolean\n // --------------------------------------------------------------------------\n function TBooleanRight(left, right) {\n if (TypeGuard.TLiteral(left) && ValueGuard.IsBoolean(left.const))\n return TypeExtendsResult.True;\n return TypeGuard.TBoolean(left) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n function TBoolean(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n return TypeGuard.TBoolean(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Constructor\n // --------------------------------------------------------------------------\n function TConstructor(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (!TypeGuard.TConstructor(right))\n return TypeExtendsResult.False;\n if (left.parameters.length > right.parameters.length)\n return TypeExtendsResult.False;\n if (!left.parameters.every((schema, index) => IntoBooleanResult(Visit(right.parameters[index], schema)) === TypeExtendsResult.True)) {\n return TypeExtendsResult.False;\n }\n return IntoBooleanResult(Visit(left.returns, right.returns));\n }\n // --------------------------------------------------------------------------\n // Date\n // --------------------------------------------------------------------------\n function TDate(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n return TypeGuard.TDate(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Function\n // --------------------------------------------------------------------------\n function TFunction(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (!TypeGuard.TFunction(right))\n return TypeExtendsResult.False;\n if (left.parameters.length > right.parameters.length)\n return TypeExtendsResult.False;\n if (!left.parameters.every((schema, index) => IntoBooleanResult(Visit(right.parameters[index], schema)) === TypeExtendsResult.True)) {\n return TypeExtendsResult.False;\n }\n return IntoBooleanResult(Visit(left.returns, right.returns));\n }\n // --------------------------------------------------------------------------\n // Integer\n // --------------------------------------------------------------------------\n function TIntegerRight(left, right) {\n if (TypeGuard.TLiteral(left) && ValueGuard.IsNumber(left.const))\n return TypeExtendsResult.True;\n return TypeGuard.TNumber(left) || TypeGuard.TInteger(left) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n function TInteger(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n return TypeGuard.TInteger(right) || TypeGuard.TNumber(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Intersect\n // --------------------------------------------------------------------------\n function TIntersectRight(left, right) {\n return right.allOf.every((schema) => Visit(left, schema) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n function TIntersect(left, right) {\n return left.allOf.some((schema) => Visit(schema, right) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Iterator\n // --------------------------------------------------------------------------\n function TIterator(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (!TypeGuard.TIterator(right))\n return TypeExtendsResult.False;\n return IntoBooleanResult(Visit(left.items, right.items));\n }\n // --------------------------------------------------------------------------\n // Literal\n // --------------------------------------------------------------------------\n function TLiteral(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n if (TypeGuard.TString(right))\n return TStringRight(left, right);\n if (TypeGuard.TNumber(right))\n return TNumberRight(left, right);\n if (TypeGuard.TInteger(right))\n return TIntegerRight(left, right);\n if (TypeGuard.TBoolean(right))\n return TBooleanRight(left, right);\n return TypeGuard.TLiteral(right) && right.const === left.const ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Never\n // --------------------------------------------------------------------------\n function TNeverRight(left, right) {\n return TypeExtendsResult.False;\n }\n function TNever(left, right) {\n return TypeExtendsResult.True;\n }\n // --------------------------------------------------------------------------\n // Not\n // --------------------------------------------------------------------------\n function UnwrapTNot(schema) {\n let [current, depth] = [schema, 0];\n while (true) {\n if (!TypeGuard.TNot(current))\n break;\n current = current.not;\n depth += 1;\n }\n return depth % 2 === 0 ? current : exports.Type.Unknown();\n }\n function TNot(left, right) {\n // TypeScript has no concept of negated types, and attempts to correctly check the negated\n // type at runtime would put TypeBox at odds with TypeScripts ability to statically infer\n // the type. Instead we unwrap to either unknown or T and continue evaluating.\n if (TypeGuard.TNot(left))\n return Visit(UnwrapTNot(left), right);\n if (TypeGuard.TNot(right))\n return Visit(left, UnwrapTNot(right));\n throw new Error(`TypeExtends: Invalid fallthrough for Not`);\n }\n // --------------------------------------------------------------------------\n // Null\n // --------------------------------------------------------------------------\n function TNull(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n return TypeGuard.TNull(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Number\n // --------------------------------------------------------------------------\n function TNumberRight(left, right) {\n if (TypeGuard.TLiteralNumber(left))\n return TypeExtendsResult.True;\n return TypeGuard.TNumber(left) || TypeGuard.TInteger(left) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n function TNumber(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n return TypeGuard.TInteger(right) || TypeGuard.TNumber(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Object\n // --------------------------------------------------------------------------\n function IsObjectPropertyCount(schema, count) {\n return Object.getOwnPropertyNames(schema.properties).length === count;\n }\n function IsObjectStringLike(schema) {\n return IsObjectArrayLike(schema);\n }\n function IsObjectSymbolLike(schema) {\n // prettier-ignore\n return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'description' in schema.properties && TypeGuard.TUnion(schema.properties.description) && schema.properties.description.anyOf.length === 2 && ((TypeGuard.TString(schema.properties.description.anyOf[0]) &&\n TypeGuard.TUndefined(schema.properties.description.anyOf[1])) || (TypeGuard.TString(schema.properties.description.anyOf[1]) &&\n TypeGuard.TUndefined(schema.properties.description.anyOf[0]))));\n }\n function IsObjectNumberLike(schema) {\n return IsObjectPropertyCount(schema, 0);\n }\n function IsObjectBooleanLike(schema) {\n return IsObjectPropertyCount(schema, 0);\n }\n function IsObjectBigIntLike(schema) {\n return IsObjectPropertyCount(schema, 0);\n }\n function IsObjectDateLike(schema) {\n return IsObjectPropertyCount(schema, 0);\n }\n function IsObjectUint8ArrayLike(schema) {\n return IsObjectArrayLike(schema);\n }\n function IsObjectFunctionLike(schema) {\n const length = exports.Type.Number();\n return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'length' in schema.properties && IntoBooleanResult(Visit(schema.properties['length'], length)) === TypeExtendsResult.True);\n }\n function IsObjectConstructorLike(schema) {\n return IsObjectPropertyCount(schema, 0);\n }\n function IsObjectArrayLike(schema) {\n const length = exports.Type.Number();\n return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'length' in schema.properties && IntoBooleanResult(Visit(schema.properties['length'], length)) === TypeExtendsResult.True);\n }\n function IsObjectPromiseLike(schema) {\n const then = exports.Type.Function([exports.Type.Any()], exports.Type.Any());\n return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'then' in schema.properties && IntoBooleanResult(Visit(schema.properties['then'], then)) === TypeExtendsResult.True);\n }\n // --------------------------------------------------------------------------\n // Property\n // --------------------------------------------------------------------------\n function Property(left, right) {\n if (Visit(left, right) === TypeExtendsResult.False)\n return TypeExtendsResult.False;\n if (TypeGuard.TOptional(left) && !TypeGuard.TOptional(right))\n return TypeExtendsResult.False;\n return TypeExtendsResult.True;\n }\n function TObjectRight(left, right) {\n if (TypeGuard.TUnknown(left))\n return TypeExtendsResult.False;\n if (TypeGuard.TAny(left))\n return TypeExtendsResult.Union;\n if (TypeGuard.TNever(left))\n return TypeExtendsResult.True;\n if (TypeGuard.TLiteralString(left) && IsObjectStringLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TLiteralNumber(left) && IsObjectNumberLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TLiteralBoolean(left) && IsObjectBooleanLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TSymbol(left) && IsObjectSymbolLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TBigInt(left) && IsObjectBigIntLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TString(left) && IsObjectStringLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TSymbol(left) && IsObjectSymbolLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TNumber(left) && IsObjectNumberLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TInteger(left) && IsObjectNumberLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TBoolean(left) && IsObjectBooleanLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TUint8Array(left) && IsObjectUint8ArrayLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TDate(left) && IsObjectDateLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TConstructor(left) && IsObjectConstructorLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TFunction(left) && IsObjectFunctionLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TRecord(left) && TypeGuard.TString(RecordKey(left))) {\n // When expressing a Record with literal key values, the Record is converted into a Object with\n // the Hint assigned as `Record`. This is used to invert the extends logic.\n return right[exports.Hint] === 'Record' ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n if (TypeGuard.TRecord(left) && TypeGuard.TNumber(RecordKey(left))) {\n return IsObjectPropertyCount(right, 0) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n return TypeExtendsResult.False;\n }\n function TObject(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n if (!TypeGuard.TObject(right))\n return TypeExtendsResult.False;\n for (const key of Object.getOwnPropertyNames(right.properties)) {\n if (!(key in left.properties))\n return TypeExtendsResult.False;\n if (Property(left.properties[key], right.properties[key]) === TypeExtendsResult.False) {\n return TypeExtendsResult.False;\n }\n }\n return TypeExtendsResult.True;\n }\n // --------------------------------------------------------------------------\n // Promise\n // --------------------------------------------------------------------------\n function TPromise(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right) && IsObjectPromiseLike(right))\n return TypeExtendsResult.True;\n if (!TypeGuard.TPromise(right))\n return TypeExtendsResult.False;\n return IntoBooleanResult(Visit(left.item, right.item));\n }\n // --------------------------------------------------------------------------\n // Record\n // --------------------------------------------------------------------------\n function RecordKey(schema) {\n if (exports.PatternNumberExact in schema.patternProperties)\n return exports.Type.Number();\n if (exports.PatternStringExact in schema.patternProperties)\n return exports.Type.String();\n throw Error('TypeExtends: Cannot get record key');\n }\n function RecordValue(schema) {\n if (exports.PatternNumberExact in schema.patternProperties)\n return schema.patternProperties[exports.PatternNumberExact];\n if (exports.PatternStringExact in schema.patternProperties)\n return schema.patternProperties[exports.PatternStringExact];\n throw Error('TypeExtends: Cannot get record value');\n }\n function TRecordRight(left, right) {\n const Key = RecordKey(right);\n const Value = RecordValue(right);\n if (TypeGuard.TLiteralString(left) && TypeGuard.TNumber(Key) && IntoBooleanResult(Visit(left, Value)) === TypeExtendsResult.True)\n return TypeExtendsResult.True;\n if (TypeGuard.TUint8Array(left) && TypeGuard.TNumber(Key))\n return Visit(left, Value);\n if (TypeGuard.TString(left) && TypeGuard.TNumber(Key))\n return Visit(left, Value);\n if (TypeGuard.TArray(left) && TypeGuard.TNumber(Key))\n return Visit(left, Value);\n if (TypeGuard.TObject(left)) {\n for (const key of Object.getOwnPropertyNames(left.properties)) {\n if (Property(Value, left.properties[key]) === TypeExtendsResult.False) {\n return TypeExtendsResult.False;\n }\n }\n return TypeExtendsResult.True;\n }\n return TypeExtendsResult.False;\n }\n function TRecord(left, right) {\n const Value = RecordValue(left);\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (!TypeGuard.TRecord(right))\n return TypeExtendsResult.False;\n return Visit(Value, RecordValue(right));\n }\n // --------------------------------------------------------------------------\n // String\n // --------------------------------------------------------------------------\n function TStringRight(left, right) {\n if (TypeGuard.TLiteral(left) && ValueGuard.IsString(left.const))\n return TypeExtendsResult.True;\n return TypeGuard.TString(left) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n function TString(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n return TypeGuard.TString(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Symbol\n // --------------------------------------------------------------------------\n function TSymbol(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n return TypeGuard.TSymbol(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // TemplateLiteral\n // --------------------------------------------------------------------------\n function TTemplateLiteral(left, right) {\n // TemplateLiteral types are resolved to either unions for finite expressions or string\n // for infinite expressions. Here we call to TemplateLiteralResolver to resolve for\n // either type and continue evaluating.\n if (TypeGuard.TTemplateLiteral(left))\n return Visit(TemplateLiteralResolver.Resolve(left), right);\n if (TypeGuard.TTemplateLiteral(right))\n return Visit(left, TemplateLiteralResolver.Resolve(right));\n throw new Error(`TypeExtends: Invalid fallthrough for TemplateLiteral`);\n }\n // --------------------------------------------------------------------------\n // Tuple\n // --------------------------------------------------------------------------\n function IsArrayOfTuple(left, right) {\n // prettier-ignore\n return (TypeGuard.TArray(right) &&\n left.items !== undefined &&\n left.items.every((schema) => Visit(schema, right.items) === TypeExtendsResult.True));\n }\n function TTupleRight(left, right) {\n if (TypeGuard.TNever(left))\n return TypeExtendsResult.True;\n if (TypeGuard.TUnknown(left))\n return TypeExtendsResult.False;\n if (TypeGuard.TAny(left))\n return TypeExtendsResult.Union;\n return TypeExtendsResult.False;\n }\n function TTuple(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right) && IsObjectArrayLike(right))\n return TypeExtendsResult.True;\n if (TypeGuard.TArray(right) && IsArrayOfTuple(left, right))\n return TypeExtendsResult.True;\n if (!TypeGuard.TTuple(right))\n return TypeExtendsResult.False;\n if ((ValueGuard.IsUndefined(left.items) && !ValueGuard.IsUndefined(right.items)) || (!ValueGuard.IsUndefined(left.items) && ValueGuard.IsUndefined(right.items)))\n return TypeExtendsResult.False;\n if (ValueGuard.IsUndefined(left.items) && !ValueGuard.IsUndefined(right.items))\n return TypeExtendsResult.True;\n return left.items.every((schema, index) => Visit(schema, right.items[index]) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Uint8Array\n // --------------------------------------------------------------------------\n function TUint8Array(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n return TypeGuard.TUint8Array(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Undefined\n // --------------------------------------------------------------------------\n function TUndefined(left, right) {\n if (IsStructuralRight(right))\n return StructuralRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n if (TypeGuard.TRecord(right))\n return TRecordRight(left, right);\n if (TypeGuard.TVoid(right))\n return VoidRight(left, right);\n return TypeGuard.TUndefined(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Union\n // --------------------------------------------------------------------------\n function TUnionRight(left, right) {\n return right.anyOf.some((schema) => Visit(left, schema) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n function TUnion(left, right) {\n return left.anyOf.every((schema) => Visit(schema, right) === TypeExtendsResult.True) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Unknown\n // --------------------------------------------------------------------------\n function TUnknownRight(left, right) {\n return TypeExtendsResult.True;\n }\n function TUnknown(left, right) {\n if (TypeGuard.TNever(right))\n return TNeverRight(left, right);\n if (TypeGuard.TIntersect(right))\n return TIntersectRight(left, right);\n if (TypeGuard.TUnion(right))\n return TUnionRight(left, right);\n if (TypeGuard.TAny(right))\n return TAnyRight(left, right);\n if (TypeGuard.TString(right))\n return TStringRight(left, right);\n if (TypeGuard.TNumber(right))\n return TNumberRight(left, right);\n if (TypeGuard.TInteger(right))\n return TIntegerRight(left, right);\n if (TypeGuard.TBoolean(right))\n return TBooleanRight(left, right);\n if (TypeGuard.TArray(right))\n return TArrayRight(left, right);\n if (TypeGuard.TTuple(right))\n return TTupleRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n return TypeGuard.TUnknown(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n // --------------------------------------------------------------------------\n // Void\n // --------------------------------------------------------------------------\n function VoidRight(left, right) {\n if (TypeGuard.TUndefined(left))\n return TypeExtendsResult.True;\n return TypeGuard.TUndefined(left) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n function TVoid(left, right) {\n if (TypeGuard.TIntersect(right))\n return TIntersectRight(left, right);\n if (TypeGuard.TUnion(right))\n return TUnionRight(left, right);\n if (TypeGuard.TUnknown(right))\n return TUnknownRight(left, right);\n if (TypeGuard.TAny(right))\n return TAnyRight(left, right);\n if (TypeGuard.TObject(right))\n return TObjectRight(left, right);\n return TypeGuard.TVoid(right) ? TypeExtendsResult.True : TypeExtendsResult.False;\n }\n function Visit(left, right) {\n // Resolvable Types\n if (TypeGuard.TTemplateLiteral(left) || TypeGuard.TTemplateLiteral(right))\n return TTemplateLiteral(left, right);\n if (TypeGuard.TNot(left) || TypeGuard.TNot(right))\n return TNot(left, right);\n // Standard Types\n if (TypeGuard.TAny(left))\n return TAny(left, right);\n if (TypeGuard.TArray(left))\n return TArray(left, right);\n if (TypeGuard.TBigInt(left))\n return TBigInt(left, right);\n if (TypeGuard.TBoolean(left))\n return TBoolean(left, right);\n if (TypeGuard.TAsyncIterator(left))\n return TAsyncIterator(left, right);\n if (TypeGuard.TConstructor(left))\n return TConstructor(left, right);\n if (TypeGuard.TDate(left))\n return TDate(left, right);\n if (TypeGuard.TFunction(left))\n return TFunction(left, right);\n if (TypeGuard.TInteger(left))\n return TInteger(left, right);\n if (TypeGuard.TIntersect(left))\n return TIntersect(left, right);\n if (TypeGuard.TIterator(left))\n return TIterator(left, right);\n if (TypeGuard.TLiteral(left))\n return TLiteral(left, right);\n if (TypeGuard.TNever(left))\n return TNever(left, right);\n if (TypeGuard.TNull(left))\n return TNull(left, right);\n if (TypeGuard.TNumber(left))\n return TNumber(left, right);\n if (TypeGuard.TObject(left))\n return TObject(left, right);\n if (TypeGuard.TRecord(left))\n return TRecord(left, right);\n if (TypeGuard.TString(left))\n return TString(left, right);\n if (TypeGuard.TSymbol(left))\n return TSymbol(left, right);\n if (TypeGuard.TTuple(left))\n return TTuple(left, right);\n if (TypeGuard.TPromise(left))\n return TPromise(left, right);\n if (TypeGuard.TUint8Array(left))\n return TUint8Array(left, right);\n if (TypeGuard.TUndefined(left))\n return TUndefined(left, right);\n if (TypeGuard.TUnion(left))\n return TUnion(left, right);\n if (TypeGuard.TUnknown(left))\n return TUnknown(left, right);\n if (TypeGuard.TVoid(left))\n return TVoid(left, right);\n throw Error(`TypeExtends: Unknown left type operand '${left[exports.Kind]}'`);\n }\n function Extends(left, right) {\n return Visit(left, right);\n }\n TypeExtends.Extends = Extends;\n})(TypeExtends || (exports.TypeExtends = TypeExtends = {}));\n// --------------------------------------------------------------------------\n// TypeClone\n// --------------------------------------------------------------------------\n/** Specialized Clone for Types */\nvar TypeClone;\n(function (TypeClone) {\n function ObjectType(value) {\n const clonedProperties = Object.getOwnPropertyNames(value).reduce((acc, key) => ({ ...acc, [key]: Visit(value[key]) }), {});\n const clonedSymbols = Object.getOwnPropertySymbols(value).reduce((acc, key) => ({ ...acc, [key]: Visit(value[key]) }), {});\n return { ...clonedProperties, ...clonedSymbols };\n }\n function ArrayType(value) {\n return value.map((value) => Visit(value));\n }\n function Visit(value) {\n if (ValueGuard.IsArray(value))\n return ArrayType(value);\n if (ValueGuard.IsObject(value))\n return ObjectType(value);\n return value;\n }\n /** Clones a type. */\n function Clone(schema, options = {}) {\n return { ...Visit(schema), ...options };\n }\n TypeClone.Clone = Clone;\n})(TypeClone || (exports.TypeClone = TypeClone = {}));\n// --------------------------------------------------------------------------\n// IndexedAccessor\n// --------------------------------------------------------------------------\nvar IndexedAccessor;\n(function (IndexedAccessor) {\n function OptionalUnwrap(schema) {\n return schema.map((schema) => {\n const { [exports.Optional]: _, ...clone } = TypeClone.Clone(schema);\n return clone;\n });\n }\n function IsIntersectOptional(schema) {\n return schema.every((schema) => TypeGuard.TOptional(schema));\n }\n function IsUnionOptional(schema) {\n return schema.some((schema) => TypeGuard.TOptional(schema));\n }\n function ResolveIntersect(schema) {\n const optional = IsIntersectOptional(schema.allOf);\n return optional ? exports.Type.Optional(exports.Type.Intersect(OptionalUnwrap(schema.allOf))) : schema;\n }\n function ResolveUnion(schema) {\n const optional = IsUnionOptional(schema.anyOf);\n return optional ? exports.Type.Optional(exports.Type.Union(OptionalUnwrap(schema.anyOf))) : schema;\n }\n function ResolveOptional(schema) {\n if (schema[exports.Kind] === 'Intersect')\n return ResolveIntersect(schema);\n if (schema[exports.Kind] === 'Union')\n return ResolveUnion(schema);\n return schema;\n }\n function TIntersect(schema, key) {\n const resolved = schema.allOf.reduce((acc, schema) => {\n const indexed = Visit(schema, key);\n return indexed[exports.Kind] === 'Never' ? acc : [...acc, indexed];\n }, []);\n return ResolveOptional(exports.Type.Intersect(resolved));\n }\n function TUnion(schema, key) {\n const resolved = schema.anyOf.map((schema) => Visit(schema, key));\n return ResolveOptional(exports.Type.Union(resolved));\n }\n function TObject(schema, key) {\n const property = schema.properties[key];\n return ValueGuard.IsUndefined(property) ? exports.Type.Never() : exports.Type.Union([property]);\n }\n function TTuple(schema, key) {\n const items = schema.items;\n if (ValueGuard.IsUndefined(items))\n return exports.Type.Never();\n const element = items[key]; //\n if (ValueGuard.IsUndefined(element))\n return exports.Type.Never();\n return element;\n }\n function Visit(schema, key) {\n if (schema[exports.Kind] === 'Intersect')\n return TIntersect(schema, key);\n if (schema[exports.Kind] === 'Union')\n return TUnion(schema, key);\n if (schema[exports.Kind] === 'Object')\n return TObject(schema, key);\n if (schema[exports.Kind] === 'Tuple')\n return TTuple(schema, key);\n return exports.Type.Never();\n }\n function Resolve(schema, keys, options = {}) {\n const resolved = keys.map((key) => Visit(schema, key.toString()));\n return ResolveOptional(exports.Type.Union(resolved, options));\n }\n IndexedAccessor.Resolve = Resolve;\n})(IndexedAccessor || (exports.IndexedAccessor = IndexedAccessor = {}));\n// --------------------------------------------------------------------------\n// Intrinsic\n// --------------------------------------------------------------------------\nvar Intrinsic;\n(function (Intrinsic) {\n function Uncapitalize(value) {\n const [first, rest] = [value.slice(0, 1), value.slice(1)];\n return `${first.toLowerCase()}${rest}`;\n }\n function Capitalize(value) {\n const [first, rest] = [value.slice(0, 1), value.slice(1)];\n return `${first.toUpperCase()}${rest}`;\n }\n function Uppercase(value) {\n return value.toUpperCase();\n }\n function Lowercase(value) {\n return value.toLowerCase();\n }\n function IntrinsicTemplateLiteral(schema, mode) {\n // note: template literals require special runtime handling as they are encoded in string patterns.\n // This diverges from the mapped type which would otherwise map on the template literal kind.\n const expression = TemplateLiteralParser.ParseExact(schema.pattern);\n const finite = TemplateLiteralFinite.Check(expression);\n if (!finite)\n return { ...schema, pattern: IntrinsicLiteral(schema.pattern, mode) };\n const strings = [...TemplateLiteralGenerator.Generate(expression)];\n const literals = strings.map((value) => exports.Type.Literal(value));\n const mapped = IntrinsicRest(literals, mode);\n const union = exports.Type.Union(mapped);\n return exports.Type.TemplateLiteral([union]);\n }\n function IntrinsicLiteral(value, mode) {\n // prettier-ignore\n return typeof value === 'string' ? (mode === 'Uncapitalize' ? Uncapitalize(value) :\n mode === 'Capitalize' ? Capitalize(value) :\n mode === 'Uppercase' ? Uppercase(value) :\n mode === 'Lowercase' ? Lowercase(value) :\n value) : value.toString();\n }\n function IntrinsicRest(schema, mode) {\n if (schema.length === 0)\n return [];\n const [L, ...R] = schema;\n return [Map(L, mode), ...IntrinsicRest(R, mode)];\n }\n function Visit(schema, mode) {\n if (TypeGuard.TTemplateLiteral(schema))\n return IntrinsicTemplateLiteral(schema, mode);\n if (TypeGuard.TUnion(schema))\n return exports.Type.Union(IntrinsicRest(schema.anyOf, mode));\n if (TypeGuard.TLiteral(schema))\n return exports.Type.Literal(IntrinsicLiteral(schema.const, mode));\n return schema;\n }\n /** Applies an intrinsic string manipulation to the given type. */\n function Map(schema, mode) {\n return Visit(schema, mode);\n }\n Intrinsic.Map = Map;\n})(Intrinsic || (exports.Intrinsic = Intrinsic = {}));\n// --------------------------------------------------------------------------\n// ObjectMap\n// --------------------------------------------------------------------------\nvar ObjectMap;\n(function (ObjectMap) {\n function TIntersect(schema, callback) {\n // prettier-ignore\n return exports.Type.Intersect(schema.allOf.map((inner) => Visit(inner, callback)), { ...schema });\n }\n function TUnion(schema, callback) {\n // prettier-ignore\n return exports.Type.Union(schema.anyOf.map((inner) => Visit(inner, callback)), { ...schema });\n }\n function TObject(schema, callback) {\n return callback(schema);\n }\n function Visit(schema, callback) {\n // There are cases where users need to map objects with unregistered kinds. Using a TypeGuard here would\n // prevent sub schema mapping as unregistered kinds will not pass TSchema checks. This is notable in the\n // case of TObject where unregistered property kinds cause the TObject check to fail. As mapping is only\n // used for composition, we use explicit checks instead.\n if (schema[exports.Kind] === 'Intersect')\n return TIntersect(schema, callback);\n if (schema[exports.Kind] === 'Union')\n return TUnion(schema, callback);\n if (schema[exports.Kind] === 'Object')\n return TObject(schema, callback);\n return schema;\n }\n function Map(schema, callback, options) {\n return { ...Visit(TypeClone.Clone(schema), callback), ...options };\n }\n ObjectMap.Map = Map;\n})(ObjectMap || (exports.ObjectMap = ObjectMap = {}));\nvar KeyResolver;\n(function (KeyResolver) {\n function UnwrapPattern(key) {\n return key[0] === '^' && key[key.length - 1] === '$' ? key.slice(1, key.length - 1) : key;\n }\n function TIntersect(schema, options) {\n return schema.allOf.reduce((acc, schema) => [...acc, ...Visit(schema, options)], []);\n }\n function TUnion(schema, options) {\n const sets = schema.anyOf.map((inner) => Visit(inner, options));\n return [...sets.reduce((set, outer) => outer.map((key) => (sets.every((inner) => inner.includes(key)) ? set.add(key) : set))[0], new Set())];\n }\n function TObject(schema, options) {\n return Object.getOwnPropertyNames(schema.properties);\n }\n function TRecord(schema, options) {\n return options.includePatterns ? Object.getOwnPropertyNames(schema.patternProperties) : [];\n }\n function Visit(schema, options) {\n if (TypeGuard.TIntersect(schema))\n return TIntersect(schema, options);\n if (TypeGuard.TUnion(schema))\n return TUnion(schema, options);\n if (TypeGuard.TObject(schema))\n return TObject(schema, options);\n if (TypeGuard.TRecord(schema))\n return TRecord(schema, options);\n return [];\n }\n /** Resolves an array of keys in this schema */\n function ResolveKeys(schema, options) {\n return [...new Set(Visit(schema, options))];\n }\n KeyResolver.ResolveKeys = ResolveKeys;\n /** Resolves a regular expression pattern matching all keys in this schema */\n function ResolvePattern(schema) {\n const keys = ResolveKeys(schema, { includePatterns: true });\n const pattern = keys.map((key) => `(${UnwrapPattern(key)})`);\n return `^(${pattern.join('|')})$`;\n }\n KeyResolver.ResolvePattern = ResolvePattern;\n})(KeyResolver || (exports.KeyResolver = KeyResolver = {}));\n// --------------------------------------------------------------------------\n// KeyArrayResolver\n// --------------------------------------------------------------------------\nvar KeyArrayResolver;\n(function (KeyArrayResolver) {\n /** Resolves an array of string[] keys from the given schema or array type. */\n function Resolve(schema) {\n if (Array.isArray(schema))\n return schema;\n if (TypeGuard.TUnionLiteral(schema))\n return schema.anyOf.map((schema) => schema.const.toString());\n if (TypeGuard.TLiteral(schema))\n return [schema.const];\n if (TypeGuard.TTemplateLiteral(schema)) {\n const expression = TemplateLiteralParser.ParseExact(schema.pattern);\n if (!TemplateLiteralFinite.Check(expression))\n throw Error('KeyArrayResolver: Cannot resolve keys from infinite template expression');\n return [...TemplateLiteralGenerator.Generate(expression)];\n }\n return [];\n }\n KeyArrayResolver.Resolve = Resolve;\n})(KeyArrayResolver || (exports.KeyArrayResolver = KeyArrayResolver = {}));\n// --------------------------------------------------------------------------\n// UnionResolver\n// --------------------------------------------------------------------------\nvar UnionResolver;\n(function (UnionResolver) {\n function* TUnion(union) {\n for (const schema of union.anyOf) {\n if (schema[exports.Kind] === 'Union') {\n yield* TUnion(schema);\n }\n else {\n yield schema;\n }\n }\n }\n /** Returns a resolved union with interior unions flattened */\n function Resolve(union) {\n return exports.Type.Union([...TUnion(union)], { ...union });\n }\n UnionResolver.Resolve = Resolve;\n})(UnionResolver || (exports.UnionResolver = UnionResolver = {}));\n// --------------------------------------------------------------------------\n// TemplateLiteralPattern\n// --------------------------------------------------------------------------\nvar TemplateLiteralPattern;\n(function (TemplateLiteralPattern) {\n function Escape(value) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n function Visit(schema, acc) {\n if (TypeGuard.TTemplateLiteral(schema)) {\n return schema.pattern.slice(1, schema.pattern.length - 1);\n }\n else if (TypeGuard.TUnion(schema)) {\n return `(${schema.anyOf.map((schema) => Visit(schema, acc)).join('|')})`;\n }\n else if (TypeGuard.TNumber(schema)) {\n return `${acc}${exports.PatternNumber}`;\n }\n else if (TypeGuard.TInteger(schema)) {\n return `${acc}${exports.PatternNumber}`;\n }\n else if (TypeGuard.TBigInt(schema)) {\n return `${acc}${exports.PatternNumber}`;\n }\n else if (TypeGuard.TString(schema)) {\n return `${acc}${exports.PatternString}`;\n }\n else if (TypeGuard.TLiteral(schema)) {\n return `${acc}${Escape(schema.const.toString())}`;\n }\n else if (TypeGuard.TBoolean(schema)) {\n return `${acc}${exports.PatternBoolean}`;\n }\n else if (TypeGuard.TNever(schema)) {\n throw Error('TemplateLiteralPattern: TemplateLiteral cannot operate on types of TNever');\n }\n else {\n throw Error(`TemplateLiteralPattern: Unexpected Kind '${schema[exports.Kind]}'`);\n }\n }\n function Create(kinds) {\n return `^${kinds.map((schema) => Visit(schema, '')).join('')}\\$`;\n }\n TemplateLiteralPattern.Create = Create;\n})(TemplateLiteralPattern || (exports.TemplateLiteralPattern = TemplateLiteralPattern = {}));\n// --------------------------------------------------------------------------------------\n// TemplateLiteralResolver\n// --------------------------------------------------------------------------------------\nvar TemplateLiteralResolver;\n(function (TemplateLiteralResolver) {\n /** Resolves a template literal as a TUnion */\n function Resolve(template) {\n const expression = TemplateLiteralParser.ParseExact(template.pattern);\n if (!TemplateLiteralFinite.Check(expression))\n return exports.Type.String();\n const literals = [...TemplateLiteralGenerator.Generate(expression)].map((value) => exports.Type.Literal(value));\n return exports.Type.Union(literals);\n }\n TemplateLiteralResolver.Resolve = Resolve;\n})(TemplateLiteralResolver || (exports.TemplateLiteralResolver = TemplateLiteralResolver = {}));\n// --------------------------------------------------------------------------------------\n// TemplateLiteralParser\n// --------------------------------------------------------------------------------------\nclass TemplateLiteralParserError extends Error {\n constructor(message) {\n super(message);\n }\n}\nexports.TemplateLiteralParserError = TemplateLiteralParserError;\nvar TemplateLiteralParser;\n(function (TemplateLiteralParser) {\n function IsNonEscaped(pattern, index, char) {\n return pattern[index] === char && pattern.charCodeAt(index - 1) !== 92;\n }\n function IsOpenParen(pattern, index) {\n return IsNonEscaped(pattern, index, '(');\n }\n function IsCloseParen(pattern, index) {\n return IsNonEscaped(pattern, index, ')');\n }\n function IsSeparator(pattern, index) {\n return IsNonEscaped(pattern, index, '|');\n }\n function IsGroup(pattern) {\n if (!(IsOpenParen(pattern, 0) && IsCloseParen(pattern, pattern.length - 1)))\n return false;\n let count = 0;\n for (let index = 0; index < pattern.length; index++) {\n if (IsOpenParen(pattern, index))\n count += 1;\n if (IsCloseParen(pattern, index))\n count -= 1;\n if (count === 0 && index !== pattern.length - 1)\n return false;\n }\n return true;\n }\n function InGroup(pattern) {\n return pattern.slice(1, pattern.length - 1);\n }\n function IsPrecedenceOr(pattern) {\n let count = 0;\n for (let index = 0; index < pattern.length; index++) {\n if (IsOpenParen(pattern, index))\n count += 1;\n if (IsCloseParen(pattern, index))\n count -= 1;\n if (IsSeparator(pattern, index) && count === 0)\n return true;\n }\n return false;\n }\n function IsPrecedenceAnd(pattern) {\n for (let index = 0; index < pattern.length; index++) {\n if (IsOpenParen(pattern, index))\n return true;\n }\n return false;\n }\n function Or(pattern) {\n let [count, start] = [0, 0];\n const expressions = [];\n for (let index = 0; index < pattern.length; index++) {\n if (IsOpenParen(pattern, index))\n count += 1;\n if (IsCloseParen(pattern, index))\n count -= 1;\n if (IsSeparator(pattern, index) && count === 0) {\n const range = pattern.slice(start, index);\n if (range.length > 0)\n expressions.push(Parse(range));\n start = index + 1;\n }\n }\n const range = pattern.slice(start);\n if (range.length > 0)\n expressions.push(Parse(range));\n if (expressions.length === 0)\n return { type: 'const', const: '' };\n if (expressions.length === 1)\n return expressions[0];\n return { type: 'or', expr: expressions };\n }\n function And(pattern) {\n function Group(value, index) {\n if (!IsOpenParen(value, index))\n throw new TemplateLiteralParserError(`TemplateLiteralParser: Index must point to open parens`);\n let count = 0;\n for (let scan = index; scan < value.length; scan++) {\n if (IsOpenParen(value, scan))\n count += 1;\n if (IsCloseParen(value, scan))\n count -= 1;\n if (count === 0)\n return [index, scan];\n }\n throw new TemplateLiteralParserError(`TemplateLiteralParser: Unclosed group parens in expression`);\n }\n function Range(pattern, index) {\n for (let scan = index; scan < pattern.length; scan++) {\n if (IsOpenParen(pattern, scan))\n return [index, scan];\n }\n return [index, pattern.length];\n }\n const expressions = [];\n for (let index = 0; index < pattern.length; index++) {\n if (IsOpenParen(pattern, index)) {\n const [start, end] = Group(pattern, index);\n const range = pattern.slice(start, end + 1);\n expressions.push(Parse(range));\n index = end;\n }\n else {\n const [start, end] = Range(pattern, index);\n const range = pattern.slice(start, end);\n if (range.length > 0)\n expressions.push(Parse(range));\n index = end - 1;\n }\n }\n if (expressions.length === 0)\n return { type: 'const', const: '' };\n if (expressions.length === 1)\n return expressions[0];\n return { type: 'and', expr: expressions };\n }\n /** Parses a pattern and returns an expression tree */\n function Parse(pattern) {\n if (IsGroup(pattern))\n return Parse(InGroup(pattern));\n if (IsPrecedenceOr(pattern))\n return Or(pattern);\n if (IsPrecedenceAnd(pattern))\n return And(pattern);\n return { type: 'const', const: pattern };\n }\n TemplateLiteralParser.Parse = Parse;\n /** Parses a pattern and strips forward and trailing ^ and $ */\n function ParseExact(pattern) {\n return Parse(pattern.slice(1, pattern.length - 1));\n }\n TemplateLiteralParser.ParseExact = ParseExact;\n})(TemplateLiteralParser || (exports.TemplateLiteralParser = TemplateLiteralParser = {}));\n// --------------------------------------------------------------------------------------\n// TemplateLiteralFinite\n// --------------------------------------------------------------------------------------\nvar TemplateLiteralFinite;\n(function (TemplateLiteralFinite) {\n function IsNumber(expression) {\n // prettier-ignore\n return (expression.type === 'or' &&\n expression.expr.length === 2 &&\n expression.expr[0].type === 'const' &&\n expression.expr[0].const === '0' &&\n expression.expr[1].type === 'const' &&\n expression.expr[1].const === '[1-9][0-9]*');\n }\n function IsBoolean(expression) {\n // prettier-ignore\n return (expression.type === 'or' &&\n expression.expr.length === 2 &&\n expression.expr[0].type === 'const' &&\n expression.expr[0].const === 'true' &&\n expression.expr[1].type === 'const' &&\n expression.expr[1].const === 'false');\n }\n function IsString(expression) {\n return expression.type === 'const' && expression.const === '.*';\n }\n function Check(expression) {\n if (IsBoolean(expression))\n return true;\n if (IsNumber(expression) || IsString(expression))\n return false;\n if (expression.type === 'and')\n return expression.expr.every((expr) => Check(expr));\n if (expression.type === 'or')\n return expression.expr.every((expr) => Check(expr));\n if (expression.type === 'const')\n return true;\n throw Error(`TemplateLiteralFinite: Unknown expression type`);\n }\n TemplateLiteralFinite.Check = Check;\n})(TemplateLiteralFinite || (exports.TemplateLiteralFinite = TemplateLiteralFinite = {}));\n// --------------------------------------------------------------------------------------\n// TemplateLiteralGenerator\n// --------------------------------------------------------------------------------------\nvar TemplateLiteralGenerator;\n(function (TemplateLiteralGenerator) {\n function* Reduce(buffer) {\n if (buffer.length === 1)\n return yield* buffer[0];\n for (const left of buffer[0]) {\n for (const right of Reduce(buffer.slice(1))) {\n yield `${left}${right}`;\n }\n }\n }\n function* And(expression) {\n return yield* Reduce(expression.expr.map((expr) => [...Generate(expr)]));\n }\n function* Or(expression) {\n for (const expr of expression.expr)\n yield* Generate(expr);\n }\n function* Const(expression) {\n return yield expression.const;\n }\n function* Generate(expression) {\n if (expression.type === 'and')\n return yield* And(expression);\n if (expression.type === 'or')\n return yield* Or(expression);\n if (expression.type === 'const')\n return yield* Const(expression);\n throw Error('TemplateLiteralGenerator: Unknown expression');\n }\n TemplateLiteralGenerator.Generate = Generate;\n})(TemplateLiteralGenerator || (exports.TemplateLiteralGenerator = TemplateLiteralGenerator = {}));\n// ---------------------------------------------------------------------\n// TemplateLiteralDslParser\n// ---------------------------------------------------------------------\nvar TemplateLiteralDslParser;\n(function (TemplateLiteralDslParser) {\n function* ParseUnion(template) {\n const trim = template.trim().replace(/\"|'/g, '');\n if (trim === 'boolean')\n return yield exports.Type.Boolean();\n if (trim === 'number')\n return yield exports.Type.Number();\n if (trim === 'bigint')\n return yield exports.Type.BigInt();\n if (trim === 'string')\n return yield exports.Type.String();\n const literals = trim.split('|').map((literal) => exports.Type.Literal(literal.trim()));\n return yield literals.length === 0 ? exports.Type.Never() : literals.length === 1 ? literals[0] : exports.Type.Union(literals);\n }\n function* ParseTerminal(template) {\n if (template[1] !== '{') {\n const L = exports.Type.Literal('$');\n const R = ParseLiteral(template.slice(1));\n return yield* [L, ...R];\n }\n for (let i = 2; i < template.length; i++) {\n if (template[i] === '}') {\n const L = ParseUnion(template.slice(2, i));\n const R = ParseLiteral(template.slice(i + 1));\n return yield* [...L, ...R];\n }\n }\n yield exports.Type.Literal(template);\n }\n function* ParseLiteral(template) {\n for (let i = 0; i < template.length; i++) {\n if (template[i] === '$') {\n const L = exports.Type.Literal(template.slice(0, i));\n const R = ParseTerminal(template.slice(i));\n return yield* [L, ...R];\n }\n }\n yield exports.Type.Literal(template);\n }\n function Parse(template_dsl) {\n return [...ParseLiteral(template_dsl)];\n }\n TemplateLiteralDslParser.Parse = Parse;\n})(TemplateLiteralDslParser || (exports.TemplateLiteralDslParser = TemplateLiteralDslParser = {}));\n// --------------------------------------------------------------------------\n// TypeOrdinal: Used for auto $id generation\n// --------------------------------------------------------------------------\nlet TypeOrdinal = 0;\n// --------------------------------------------------------------------------\n// TypeBuilder\n// --------------------------------------------------------------------------\nclass TypeBuilder {\n /** `[Utility]` Creates a schema without `static` and `params` types */\n Create(schema) {\n return schema;\n }\n /** `[Utility]` Discards a property key from the given schema */\n Discard(schema, key) {\n const { [key]: _, ...rest } = schema;\n return rest;\n }\n /** `[Standard]` Omits compositing symbols from this schema */\n Strict(schema) {\n return JSON.parse(JSON.stringify(schema));\n }\n}\nexports.TypeBuilder = TypeBuilder;\n// --------------------------------------------------------------------------\n// StandardTypeBuilder\n// --------------------------------------------------------------------------\nclass StandardTypeBuilder extends TypeBuilder {\n // ------------------------------------------------------------------------\n // Modifiers\n // ------------------------------------------------------------------------\n /** `[Standard]` Creates a Readonly and Optional property */\n ReadonlyOptional(schema) {\n return this.Readonly(this.Optional(schema));\n }\n /** `[Standard]` Creates a Readonly property */\n Readonly(schema) {\n return { ...TypeClone.Clone(schema), [exports.Readonly]: 'Readonly' };\n }\n /** `[Standard]` Creates an Optional property */\n Optional(schema) {\n return { ...TypeClone.Clone(schema), [exports.Optional]: 'Optional' };\n }\n // ------------------------------------------------------------------------\n // Types\n // ------------------------------------------------------------------------\n /** `[Standard]` Creates an Any type */\n Any(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Any' });\n }\n /** `[Standard]` Creates an Array type */\n Array(schema, options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Array', type: 'array', items: TypeClone.Clone(schema) });\n }\n /** `[Standard]` Creates a Boolean type */\n Boolean(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Boolean', type: 'boolean' });\n }\n /** `[Standard]` Intrinsic function to Capitalize LiteralString types */\n Capitalize(schema, options = {}) {\n return { ...Intrinsic.Map(TypeClone.Clone(schema), 'Capitalize'), ...options };\n }\n /** `[Standard]` Creates a Composite object type */\n Composite(objects, options) {\n const intersect = exports.Type.Intersect(objects, {});\n const keys = KeyResolver.ResolveKeys(intersect, { includePatterns: false });\n const properties = keys.reduce((acc, key) => ({ ...acc, [key]: exports.Type.Index(intersect, [key]) }), {});\n return exports.Type.Object(properties, options);\n }\n /** `[Standard]` Creates a Enum type */\n Enum(item, options = {}) {\n // prettier-ignore\n const values = Object.getOwnPropertyNames(item).filter((key) => isNaN(key)).map((key) => item[key]);\n const anyOf = values.map((value) => (ValueGuard.IsString(value) ? { [exports.Kind]: 'Literal', type: 'string', const: value } : { [exports.Kind]: 'Literal', type: 'number', const: value }));\n return this.Create({ ...options, [exports.Kind]: 'Union', anyOf });\n }\n /** `[Standard]` Creates a Conditional type */\n Extends(left, right, trueType, falseType, options = {}) {\n switch (TypeExtends.Extends(left, right)) {\n case TypeExtendsResult.Union:\n return this.Union([TypeClone.Clone(trueType, options), TypeClone.Clone(falseType, options)]);\n case TypeExtendsResult.True:\n return TypeClone.Clone(trueType, options);\n case TypeExtendsResult.False:\n return TypeClone.Clone(falseType, options);\n }\n }\n /** `[Standard]` Constructs a type by excluding from unionType all union members that are assignable to excludedMembers */\n Exclude(unionType, excludedMembers, options = {}) {\n if (TypeGuard.TTemplateLiteral(unionType))\n return this.Exclude(TemplateLiteralResolver.Resolve(unionType), excludedMembers, options);\n if (TypeGuard.TTemplateLiteral(excludedMembers))\n return this.Exclude(unionType, TemplateLiteralResolver.Resolve(excludedMembers), options);\n if (TypeGuard.TUnion(unionType)) {\n const narrowed = unionType.anyOf.filter((inner) => TypeExtends.Extends(inner, excludedMembers) === TypeExtendsResult.False);\n return (narrowed.length === 1 ? TypeClone.Clone(narrowed[0], options) : this.Union(narrowed, options));\n }\n else {\n return (TypeExtends.Extends(unionType, excludedMembers) !== TypeExtendsResult.False ? this.Never(options) : TypeClone.Clone(unionType, options));\n }\n }\n /** `[Standard]` Constructs a type by extracting from type all union members that are assignable to union */\n Extract(type, union, options = {}) {\n if (TypeGuard.TTemplateLiteral(type))\n return this.Extract(TemplateLiteralResolver.Resolve(type), union, options);\n if (TypeGuard.TTemplateLiteral(union))\n return this.Extract(type, TemplateLiteralResolver.Resolve(union), options);\n if (TypeGuard.TUnion(type)) {\n const narrowed = type.anyOf.filter((inner) => TypeExtends.Extends(inner, union) !== TypeExtendsResult.False);\n return (narrowed.length === 1 ? TypeClone.Clone(narrowed[0], options) : this.Union(narrowed, options));\n }\n else {\n return (TypeExtends.Extends(type, union) !== TypeExtendsResult.False ? TypeClone.Clone(type, options) : this.Never(options));\n }\n }\n /** `[Standard]` Returns an Indexed property type for the given keys */\n Index(schema, unresolved, options = {}) {\n if (TypeGuard.TArray(schema) && TypeGuard.TNumber(unresolved)) {\n return TypeClone.Clone(schema.items, options);\n }\n else if (TypeGuard.TTuple(schema) && TypeGuard.TNumber(unresolved)) {\n const items = ValueGuard.IsUndefined(schema.items) ? [] : schema.items;\n const cloned = items.map((schema) => TypeClone.Clone(schema));\n return this.Union(cloned, options);\n }\n else {\n const keys = KeyArrayResolver.Resolve(unresolved);\n const clone = TypeClone.Clone(schema);\n return IndexedAccessor.Resolve(clone, keys, options);\n }\n }\n /** `[Standard]` Creates an Integer type */\n Integer(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Integer', type: 'integer' });\n }\n /** `[Standard]` Creates an Intersect type */\n Intersect(allOf, options = {}) {\n if (allOf.length === 0)\n return exports.Type.Never();\n if (allOf.length === 1)\n return TypeClone.Clone(allOf[0], options);\n const objects = allOf.every((schema) => TypeGuard.TObject(schema));\n const cloned = allOf.map((schema) => TypeClone.Clone(schema));\n const clonedUnevaluatedProperties = TypeGuard.TSchema(options.unevaluatedProperties) ? { unevaluatedProperties: TypeClone.Clone(options.unevaluatedProperties) } : {};\n if (options.unevaluatedProperties === false || TypeGuard.TSchema(options.unevaluatedProperties) || objects) {\n return this.Create({ ...options, ...clonedUnevaluatedProperties, [exports.Kind]: 'Intersect', type: 'object', allOf: cloned });\n }\n else {\n return this.Create({ ...options, ...clonedUnevaluatedProperties, [exports.Kind]: 'Intersect', allOf: cloned });\n }\n }\n /** `[Standard]` Creates a KeyOf type */\n KeyOf(schema, options = {}) {\n if (TypeGuard.TRecord(schema)) {\n const pattern = Object.getOwnPropertyNames(schema.patternProperties)[0];\n if (pattern === exports.PatternNumberExact)\n return this.Number(options);\n if (pattern === exports.PatternStringExact)\n return this.String(options);\n throw Error('StandardTypeBuilder: Unable to resolve key type from Record key pattern');\n }\n else if (TypeGuard.TTuple(schema)) {\n const items = ValueGuard.IsUndefined(schema.items) ? [] : schema.items;\n const literals = items.map((_, index) => exports.Type.Literal(index));\n return this.Union(literals, options);\n }\n else if (TypeGuard.TArray(schema)) {\n return this.Number(options);\n }\n else {\n const keys = KeyResolver.ResolveKeys(schema, { includePatterns: false });\n if (keys.length === 0)\n return this.Never(options);\n const literals = keys.map((key) => this.Literal(key));\n return this.Union(literals, options);\n }\n }\n /** `[Standard]` Creates a Literal type */\n Literal(value, options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Literal', const: value, type: typeof value });\n }\n /** `[Standard]` Intrinsic function to Lowercase LiteralString types */\n Lowercase(schema, options = {}) {\n return { ...Intrinsic.Map(TypeClone.Clone(schema), 'Lowercase'), ...options };\n }\n /** `[Standard]` Creates a Never type */\n Never(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Never', not: {} });\n }\n /** `[Standard]` Creates a Not type */\n Not(schema, options) {\n return this.Create({ ...options, [exports.Kind]: 'Not', not: TypeClone.Clone(schema) });\n }\n /** `[Standard]` Creates a Null type */\n Null(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Null', type: 'null' });\n }\n /** `[Standard]` Creates a Number type */\n Number(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Number', type: 'number' });\n }\n /** `[Standard]` Creates an Object type */\n Object(properties, options = {}) {\n const propertyKeys = Object.getOwnPropertyNames(properties);\n const optionalKeys = propertyKeys.filter((key) => TypeGuard.TOptional(properties[key]));\n const requiredKeys = propertyKeys.filter((name) => !optionalKeys.includes(name));\n const clonedAdditionalProperties = TypeGuard.TSchema(options.additionalProperties) ? { additionalProperties: TypeClone.Clone(options.additionalProperties) } : {};\n const clonedProperties = propertyKeys.reduce((acc, key) => ({ ...acc, [key]: TypeClone.Clone(properties[key]) }), {});\n if (requiredKeys.length > 0) {\n return this.Create({ ...options, ...clonedAdditionalProperties, [exports.Kind]: 'Object', type: 'object', properties: clonedProperties, required: requiredKeys });\n }\n else {\n return this.Create({ ...options, ...clonedAdditionalProperties, [exports.Kind]: 'Object', type: 'object', properties: clonedProperties });\n }\n }\n /** `[Standard]` Constructs a type whose keys are omitted from the given type */\n Omit(schema, unresolved, options = {}) {\n const keys = KeyArrayResolver.Resolve(unresolved);\n // prettier-ignore\n return ObjectMap.Map(TypeClone.Clone(schema), (object) => {\n if (ValueGuard.IsArray(object.required)) {\n object.required = object.required.filter((key) => !keys.includes(key));\n if (object.required.length === 0)\n delete object.required;\n }\n for (const key of Object.getOwnPropertyNames(object.properties)) {\n if (keys.includes(key))\n delete object.properties[key];\n }\n return this.Create(object);\n }, options);\n }\n /** `[Standard]` Constructs a type where all properties are optional */\n Partial(schema, options = {}) {\n // prettier-ignore\n return ObjectMap.Map(schema, (object) => {\n const properties = Object.getOwnPropertyNames(object.properties).reduce((acc, key) => {\n return { ...acc, [key]: this.Optional(object.properties[key]) };\n }, {});\n return this.Object(properties, this.Discard(object, 'required') /* object used as options to retain other constraints */);\n }, options);\n }\n /** `[Standard]` Constructs a type whose keys are picked from the given type */\n Pick(schema, unresolved, options = {}) {\n const keys = KeyArrayResolver.Resolve(unresolved);\n // prettier-ignore\n return ObjectMap.Map(TypeClone.Clone(schema), (object) => {\n if (ValueGuard.IsArray(object.required)) {\n object.required = object.required.filter((key) => keys.includes(key));\n if (object.required.length === 0)\n delete object.required;\n }\n for (const key of Object.getOwnPropertyNames(object.properties)) {\n if (!keys.includes(key))\n delete object.properties[key];\n }\n return this.Create(object);\n }, options);\n }\n /** `[Standard]` Creates a Record type */\n Record(key, schema, options = {}) {\n if (TypeGuard.TTemplateLiteral(key)) {\n const expression = TemplateLiteralParser.ParseExact(key.pattern);\n // prettier-ignore\n return TemplateLiteralFinite.Check(expression)\n ? (this.Object([...TemplateLiteralGenerator.Generate(expression)].reduce((acc, key) => ({ ...acc, [key]: TypeClone.Clone(schema) }), {}), options))\n : this.Create({ ...options, [exports.Kind]: 'Record', type: 'object', patternProperties: { [key.pattern]: TypeClone.Clone(schema) } });\n }\n else if (TypeGuard.TUnion(key)) {\n const union = UnionResolver.Resolve(key);\n if (TypeGuard.TUnionLiteral(union)) {\n const properties = union.anyOf.reduce((acc, literal) => ({ ...acc, [literal.const]: TypeClone.Clone(schema) }), {});\n return this.Object(properties, { ...options, [exports.Hint]: 'Record' });\n }\n else\n throw Error('StandardTypeBuilder: Record key of type union contains non-literal types');\n }\n else if (TypeGuard.TLiteral(key)) {\n if (ValueGuard.IsString(key.const) || ValueGuard.IsNumber(key.const)) {\n return this.Object({ [key.const]: TypeClone.Clone(schema) }, options);\n }\n else\n throw Error('StandardTypeBuilder: Record key of type literal is not of type string or number');\n }\n else if (TypeGuard.TInteger(key) || TypeGuard.TNumber(key)) {\n return this.Create({ ...options, [exports.Kind]: 'Record', type: 'object', patternProperties: { [exports.PatternNumberExact]: TypeClone.Clone(schema) } });\n }\n else if (TypeGuard.TString(key)) {\n const pattern = ValueGuard.IsUndefined(key.pattern) ? exports.PatternStringExact : key.pattern;\n return this.Create({ ...options, [exports.Kind]: 'Record', type: 'object', patternProperties: { [pattern]: TypeClone.Clone(schema) } });\n }\n else {\n throw Error(`StandardTypeBuilder: Record key is an invalid type`);\n }\n }\n /** `[Standard]` Creates a Recursive type */\n Recursive(callback, options = {}) {\n if (ValueGuard.IsUndefined(options.$id))\n options.$id = `T${TypeOrdinal++}`;\n const thisType = callback({ [exports.Kind]: 'This', $ref: `${options.$id}` });\n thisType.$id = options.$id;\n return this.Create({ ...options, [exports.Hint]: 'Recursive', ...thisType });\n }\n /** `[Standard]` Creates a Ref type. */\n Ref(unresolved, options = {}) {\n if (ValueGuard.IsString(unresolved))\n return this.Create({ ...options, [exports.Kind]: 'Ref', $ref: unresolved });\n if (ValueGuard.IsUndefined(unresolved.$id))\n throw Error('StandardTypeBuilder.Ref: Target type must specify an $id');\n return this.Create({ ...options, [exports.Kind]: 'Ref', $ref: unresolved.$id });\n }\n /** `[Standard]` Constructs a type where all properties are required */\n Required(schema, options = {}) {\n // prettier-ignore\n return ObjectMap.Map(schema, (object) => {\n const properties = Object.getOwnPropertyNames(object.properties).reduce((acc, key) => {\n return { ...acc, [key]: this.Discard(object.properties[key], exports.Optional) };\n }, {});\n return this.Object(properties, object /* object used as options to retain other constraints */);\n }, options);\n }\n /** `[Standard]` Extracts the rest array from a Tuple */\n Rest(schema) {\n if (TypeGuard.TTuple(schema)) {\n if (ValueGuard.IsUndefined(schema.items))\n return [];\n return schema.items.map((schema) => TypeClone.Clone(schema));\n }\n else {\n return [TypeClone.Clone(schema)];\n }\n }\n /** `[Standard]` Creates a String type */\n String(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'String', type: 'string' });\n }\n /** `[Standard]` Creates a TemplateLiteral type */\n TemplateLiteral(unresolved, options = {}) {\n // prettier-ignore\n const pattern = (ValueGuard.IsString(unresolved))\n ? TemplateLiteralPattern.Create(TemplateLiteralDslParser.Parse(unresolved))\n : TemplateLiteralPattern.Create(unresolved);\n return this.Create({ ...options, [exports.Kind]: 'TemplateLiteral', type: 'string', pattern });\n }\n /** `[Standard]` Creates a Tuple type */\n Tuple(items, options = {}) {\n const [additionalItems, minItems, maxItems] = [false, items.length, items.length];\n const clonedItems = items.map((item) => TypeClone.Clone(item));\n // prettier-ignore\n const schema = (items.length > 0 ?\n { ...options, [exports.Kind]: 'Tuple', type: 'array', items: clonedItems, additionalItems, minItems, maxItems } :\n { ...options, [exports.Kind]: 'Tuple', type: 'array', minItems, maxItems });\n return this.Create(schema);\n }\n /** `[Standard]` Intrinsic function to Uncapitalize LiteralString types */\n Uncapitalize(schema, options = {}) {\n return { ...Intrinsic.Map(TypeClone.Clone(schema), 'Uncapitalize'), ...options };\n }\n /** `[Standard]` Creates a Union type */\n Union(union, options = {}) {\n if (TypeGuard.TTemplateLiteral(union)) {\n return TemplateLiteralResolver.Resolve(union);\n }\n else {\n const anyOf = union;\n if (anyOf.length === 0)\n return this.Never(options);\n if (anyOf.length === 1)\n return this.Create(TypeClone.Clone(anyOf[0], options));\n const clonedAnyOf = anyOf.map((schema) => TypeClone.Clone(schema));\n return this.Create({ ...options, [exports.Kind]: 'Union', anyOf: clonedAnyOf });\n }\n }\n /** `[Standard]` Creates an Unknown type */\n Unknown(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Unknown' });\n }\n /** `[Standard]` Creates a Unsafe type that will infers as the generic argument T */\n Unsafe(options = {}) {\n return this.Create({ ...options, [exports.Kind]: options[exports.Kind] || 'Unsafe' });\n }\n /** `[Standard]` Intrinsic function to Uppercase LiteralString types */\n Uppercase(schema, options = {}) {\n return { ...Intrinsic.Map(TypeClone.Clone(schema), 'Uppercase'), ...options };\n }\n}\nexports.StandardTypeBuilder = StandardTypeBuilder;\n// --------------------------------------------------------------------------\n// ExtendedTypeBuilder\n// --------------------------------------------------------------------------\nclass ExtendedTypeBuilder extends StandardTypeBuilder {\n /** `[Extended]` Creates a AsyncIterator type */\n AsyncIterator(items, options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'AsyncIterator', type: 'AsyncIterator', items: TypeClone.Clone(items) });\n }\n /** `[Extended]` Constructs a type by recursively unwrapping Promise types */\n Awaited(schema, options = {}) {\n const AwaitedRest = (rest) => {\n if (rest.length === 0)\n return rest;\n const [L, ...R] = rest;\n return [this.Awaited(L), ...AwaitedRest(R)];\n };\n // prettier-ignore\n return (TypeGuard.TIntersect(schema) ? exports.Type.Intersect(AwaitedRest(schema.allOf)) :\n TypeGuard.TUnion(schema) ? exports.Type.Union(AwaitedRest(schema.anyOf)) :\n TypeGuard.TPromise(schema) ? this.Awaited(schema.item) :\n TypeClone.Clone(schema, options));\n }\n /** `[Extended]` Creates a BigInt type */\n BigInt(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'BigInt', type: 'bigint' });\n }\n /** `[Extended]` Extracts the ConstructorParameters from the given Constructor type */\n ConstructorParameters(schema, options = {}) {\n return this.Tuple([...schema.parameters], { ...options });\n }\n /** `[Extended]` Creates a Constructor type */\n Constructor(parameters, returns, options) {\n const clonedReturns = TypeClone.Clone(returns);\n const clonedParameters = parameters.map((parameter) => TypeClone.Clone(parameter));\n return this.Create({ ...options, [exports.Kind]: 'Constructor', type: 'constructor', parameters: clonedParameters, returns: clonedReturns });\n }\n /** `[Extended]` Creates a Date type */\n Date(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Date', type: 'Date' });\n }\n /** `[Extended]` Creates a Function type */\n Function(parameters, returns, options) {\n const clonedReturns = TypeClone.Clone(returns, {});\n const clonedParameters = parameters.map((parameter) => TypeClone.Clone(parameter));\n return this.Create({ ...options, [exports.Kind]: 'Function', type: 'function', parameters: clonedParameters, returns: clonedReturns });\n }\n /** `[Extended]` Extracts the InstanceType from the given Constructor type */\n InstanceType(schema, options = {}) {\n return TypeClone.Clone(schema.returns, options);\n }\n /** `[Extended]` Creates an Iterator type */\n Iterator(items, options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Iterator', type: 'Iterator', items: TypeClone.Clone(items) });\n }\n /** `[Extended]` Extracts the Parameters from the given Function type */\n Parameters(schema, options = {}) {\n return this.Tuple(schema.parameters, { ...options });\n }\n /** `[Extended]` Creates a Promise type */\n Promise(item, options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Promise', type: 'Promise', item: TypeClone.Clone(item) });\n }\n /** `[Extended]` Creates a String type */\n RegExp(unresolved, options = {}) {\n const pattern = ValueGuard.IsString(unresolved) ? unresolved : unresolved.source;\n return this.Create({ ...options, [exports.Kind]: 'String', type: 'string', pattern });\n }\n /**\n * @deprecated Use `Type.RegExp`\n */\n RegEx(regex, options = {}) {\n return this.RegExp(regex, options);\n }\n /** `[Extended]` Extracts the ReturnType from the given Function type */\n ReturnType(schema, options = {}) {\n return TypeClone.Clone(schema.returns, options);\n }\n /** `[Extended]` Creates a Symbol type */\n Symbol(options) {\n return this.Create({ ...options, [exports.Kind]: 'Symbol', type: 'symbol' });\n }\n /** `[Extended]` Creates a Undefined type */\n Undefined(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Undefined', type: 'undefined' });\n }\n /** `[Extended]` Creates a Uint8Array type */\n Uint8Array(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Uint8Array', type: 'Uint8Array' });\n }\n /** `[Extended]` Creates a Void type */\n Void(options = {}) {\n return this.Create({ ...options, [exports.Kind]: 'Void', type: 'void' });\n }\n}\nexports.ExtendedTypeBuilder = ExtendedTypeBuilder;\n/** JSON Schema Type Builder with Static Resolution for TypeScript */\nexports.StandardType = new StandardTypeBuilder();\n/** JSON Schema Type Builder with Static Resolution for TypeScript */\nexports.Type = new ExtendedTypeBuilder();\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsZ0JBQWdCLGlCQUFpQixpQkFBaUI7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsdUJBQXVCLHdCQUF3Qix3QkFBd0I7QUFDeEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsd0JBQXdCLHlCQUF5Qix5QkFBeUI7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUFDQTtBQUNBLDZCQUE2QixzREFBc0Q7QUFDbkY7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQiw2QkFBNkIsNERBQTREO0FBQ3pGO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0IsNkJBQTZCLDhEQUE4RDtBQUMzRjtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLDZCQUE2QixrREFBa0Q7QUFDL0U7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBLFlBQVkiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9AZXhwY2x1c3Rlci9wZXJtaXNzaW9uLWdyb3Vwcy8uLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHNpbmNsYWlyK3R5cGVib3hAMC4zMC40L25vZGVfbW9kdWxlcy9Ac2luY2xhaXIvdHlwZWJveC90eXBlYm94LmpzPzhkZTIiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbkBzaW5jbGFpci90eXBlYm94XG5cblRoZSBNSVQgTGljZW5zZSAoTUlUKVxuXG5Db3B5cmlnaHQgKGMpIDIwMTctMjAyMyBIYXlkbiBQYXRlcnNvbiAoc2luY2xhaXIpIDxoYXlkbi5kZXZlbG9wZXJAZ21haWwuY29tPlxuXG5QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG5vZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG5pbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG50byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG5jb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbmZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG5hbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG5GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG5PVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG5USEUgU09GVFdBUkUuXG5cbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLlR5cGUgPSBleHBvcnRzLlN0YW5kYXJkVHlwZSA9IGV4cG9ydHMuRXh0ZW5kZWRUeXBlQnVpbGRlciA9IGV4cG9ydHMuU3RhbmRhcmRUeXBlQnVpbGRlciA9IGV4cG9ydHMuVHlwZUJ1aWxkZXIgPSBleHBvcnRzLlRlbXBsYXRlTGl0ZXJhbERzbFBhcnNlciA9IGV4cG9ydHMuVGVtcGxhdGVMaXRlcmFsR2VuZXJhdG9yID0gZXhwb3J0cy5UZW1wbGF0ZUxpdGVyYWxGaW5pdGUgPSBleHBvcnRzLlRlbXBsYXRlTGl0ZXJhbFBhcnNlciA9IGV4cG9ydHMuVGVtcGxhdGVMaXRlcmFsUGFyc2VyRXJyb3IgPSBleHBvcnRzLlRlbXBsYXRlTGl0ZXJhbFJlc29sdmVyID0gZXhwb3J0cy5UZW1wbGF0ZUxpdGVyYWxQYXR0ZXJuID0gZXhwb3J0cy5VbmlvblJlc29sdmVyID0gZXhwb3J0cy5LZXlBcnJheVJlc29sdmVyID0gZXhwb3J0cy5LZXlSZXNvbHZlciA9IGV4cG9ydHMuT2JqZWN0TWFwID0gZXhwb3J0cy5JbnRyaW5zaWMgPSBleHBvcnRzLkluZGV4ZWRBY2Nlc3NvciA9IGV4cG9ydHMuVHlwZUNsb25lID0gZXhwb3J0cy5UeXBlRXh0ZW5kcyA9IGV4cG9ydHMuVHlwZUV4dGVuZHNSZXN1bHQgPSBleHBvcnRzLkV4dGVuZHNVbmRlZmluZWQgPSBleHBvcnRzLlR5cGVHdWFyZCA9IGV4cG9ydHMuVHlwZUd1YXJkVW5rbm93blR5cGVFcnJvciA9IGV4cG9ydHMuVmFsdWVHdWFyZCA9IGV4cG9ydHMuRm9ybWF0UmVnaXN0cnkgPSBleHBvcnRzLlR5cGVSZWdpc3RyeSA9IGV4cG9ydHMuUGF0dGVyblN0cmluZ0V4YWN0ID0gZXhwb3J0cy5QYXR0ZXJuTnVtYmVyRXhhY3QgPSBleHBvcnRzLlBhdHRlcm5Cb29sZWFuRXhhY3QgPSBleHBvcnRzLlBhdHRlcm5TdHJpbmcgPSBleHBvcnRzLlBhdHRlcm5OdW1iZXIgPSBleHBvcnRzLlBhdHRlcm5Cb29sZWFuID0gZXhwb3J0cy5LaW5kID0gZXhwb3J0cy5IaW50ID0gZXhwb3J0cy5PcHRpb25hbCA9IGV4cG9ydHMuUmVhZG9ubHkgPSB2b2lkIDA7XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU3ltYm9sc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmV4cG9ydHMuUmVhZG9ubHkgPSBTeW1ib2wuZm9yKCdUeXBlQm94LlJlYWRvbmx5Jyk7XG5leHBvcnRzLk9wdGlvbmFsID0gU3ltYm9sLmZvcignVHlwZUJveC5PcHRpb25hbCcpO1xuZXhwb3J0cy5IaW50ID0gU3ltYm9sLmZvcignVHlwZUJveC5IaW50Jyk7XG5leHBvcnRzLktpbmQgPSBTeW1ib2wuZm9yKCdUeXBlQm94LktpbmQnKTtcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBQYXR0ZXJuc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmV4cG9ydHMuUGF0dGVybkJvb2xlYW4gPSAnKHRydWV8ZmFsc2UpJztcbmV4cG9ydHMuUGF0dGVybk51bWJlciA9ICcoMHxbMS05XVswLTldKiknO1xuZXhwb3J0cy5QYXR0ZXJuU3RyaW5nID0gJyguKiknO1xuZXhwb3J0cy5QYXR0ZXJuQm9vbGVhbkV4YWN0ID0gYF4ke2V4cG9ydHMuUGF0dGVybkJvb2xlYW59JGA7XG5leHBvcnRzLlBhdHRlcm5OdW1iZXJFeGFjdCA9IGBeJHtleHBvcnRzLlBhdHRlcm5OdW1iZXJ9JGA7XG5leHBvcnRzLlBhdHRlcm5TdHJpbmdFeGFjdCA9IGBeJHtleHBvcnRzLlBhdHRlcm5TdHJpbmd9JGA7XG4vKiogQSByZWdpc3RyeSBmb3IgdXNlciBkZWZpbmVkIHR5cGVzICovXG52YXIgVHlwZVJlZ2lzdHJ5O1xuKGZ1bmN0aW9uIChUeXBlUmVnaXN0cnkpIHtcbiAgICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XG4gICAgLyoqIFJldHVybnMgdGhlIGVudHJpZXMgaW4gdGhpcyByZWdpc3RyeSAqL1xuICAgIGZ1bmN0aW9uIEVudHJpZXMoKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWFwKG1hcCk7XG4gICAgfVxuICAgIFR5cGVSZWdpc3RyeS5FbnRyaWVzID0gRW50cmllcztcbiAgICAvKiogQ2xlYXJzIGFsbCB1c2VyIGRlZmluZWQgdHlwZXMgKi9cbiAgICBmdW5jdGlvbiBDbGVhcigpIHtcbiAgICAgICAgcmV0dXJuIG1hcC5jbGVhcigpO1xuICAgIH1cbiAgICBUeXBlUmVnaXN0cnkuQ2xlYXIgPSBDbGVhcjtcbiAgICAvKiogRGVsZXRlcyBhIHJlZ2lzdGVyZWQgdHlwZSAqL1xuICAgIGZ1bmN0aW9uIERlbGV0ZShraW5kKSB7XG4gICAgICAgIHJldHVybiBtYXAuZGVsZXRlKGtpbmQpO1xuICAgIH1cbiAgICBUeXBlUmVnaXN0cnkuRGVsZXRlID0gRGVsZXRlO1xuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhpcyByZWdpc3RyeSBjb250YWlucyB0aGlzIGtpbmQgKi9cbiAgICBmdW5jdGlvbiBIYXMoa2luZCkge1xuICAgICAgICByZXR1cm4gbWFwLmhhcyhraW5kKTtcbiAgICB9XG4gICAgVHlwZVJlZ2lzdHJ5LkhhcyA9IEhhcztcbiAgICAvKiogU2V0cyBhIHZhbGlkYXRpb24gZnVuY3Rpb24gZm9yIGEgdXNlciBkZWZpbmVkIHR5cGUgKi9cbiAgICBmdW5jdGlvbiBTZXQoa2luZCwgZnVuYykge1xuICAgICAgICBtYXAuc2V0KGtpbmQsIGZ1bmMpO1xuICAgIH1cbiAgICBUeXBlUmVnaXN0cnkuU2V0ID0gU2V0O1xuICAgIC8qKiBHZXRzIGEgY3VzdG9tIHZhbGlkYXRpb24gZnVuY3Rpb24gZm9yIGEgdXNlciBkZWZpbmVkIHR5cGUgKi9cbiAgICBmdW5jdGlvbiBHZXQoa2luZCkge1xuICAgICAgICByZXR1cm4gbWFwLmdldChraW5kKTtcbiAgICB9XG4gICAgVHlwZVJlZ2lzdHJ5LkdldCA9IEdldDtcbn0pKFR5cGVSZWdpc3RyeSB8fCAoZXhwb3J0cy5UeXBlUmVnaXN0cnkgPSBUeXBlUmVnaXN0cnkgPSB7fSkpO1xuLyoqIEEgcmVnaXN0cnkgZm9yIHVzZXIgZGVmaW5lZCBzdHJpbmcgZm9ybWF0cyAqL1xudmFyIEZvcm1hdFJlZ2lzdHJ5O1xuKGZ1bmN0aW9uIChGb3JtYXRSZWdpc3RyeSkge1xuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXAoKTtcbiAgICAvKiogUmV0dXJucyB0aGUgZW50cmllcyBpbiB0aGlzIHJlZ2lzdHJ5ICovXG4gICAgZnVuY3Rpb24gRW50cmllcygpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNYXAobWFwKTtcbiAgICB9XG4gICAgRm9ybWF0UmVnaXN0cnkuRW50cmllcyA9IEVudHJpZXM7XG4gICAgLyoqIENsZWFycyBhbGwgdXNlciBkZWZpbmVkIHN0cmluZyBmb3JtYXRzICovXG4gICAgZnVuY3Rpb24gQ2xlYXIoKSB7XG4gICAgICAgIHJldHVybiBtYXAuY2xlYXIoKTtcbiAgICB9XG4gICAgRm9ybWF0UmVnaXN0cnkuQ2xlYXIgPSBDbGVhcjtcbiAgICAvKiogRGVsZXRlcyBhIHJlZ2lzdGVyZWQgZm9ybWF0ICovXG4gICAgZnVuY3Rpb24gRGVsZXRlKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gbWFwLmRlbGV0ZShmb3JtYXQpO1xuICAgIH1cbiAgICBGb3JtYXRSZWdpc3RyeS5EZWxldGUgPSBEZWxldGU7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgdXNlciBkZWZpbmVkIHN0cmluZyBmb3JtYXQgZXhpc3RzICovXG4gICAgZnVuY3Rpb24gSGFzKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gbWFwLmhhcyhmb3JtYXQpO1xuICAgIH1cbiAgICBGb3JtYXRSZWdpc3RyeS5IYXMgPSBIYXM7XG4gICAgLyoqIFNldHMgYSB2YWxpZGF0aW9uIGZ1bmN0aW9uIGZvciBhIHVzZXIgZGVmaW5lZCBzdHJpbmcgZm9ybWF0ICovXG4gICAgZnVuY3Rpb24gU2V0KGZvcm1hdCwgZnVuYykge1xuICAgICAgICBtYXAuc2V0KGZvcm1hdCwgZnVuYyk7XG4gICAgfVxuICAgIEZvcm1hdFJlZ2lzdHJ5LlNldCA9IFNldDtcbiAgICAvKiogR2V0cyBhIHZhbGlkYXRpb24gZnVuY3Rpb24gZm9yIGEgdXNlciBkZWZpbmVkIHN0cmluZyBmb3JtYXQgKi9cbiAgICBmdW5jdGlvbiBHZXQoZm9ybWF0KSB7XG4gICAgICAgIHJldHVybiBtYXAuZ2V0KGZvcm1hdCk7XG4gICAgfVxuICAgIEZvcm1hdFJlZ2lzdHJ5LkdldCA9IEdldDtcbn0pKEZvcm1hdFJlZ2lzdHJ5IHx8IChleHBvcnRzLkZvcm1hdFJlZ2lzdHJ5ID0gRm9ybWF0UmVnaXN0cnkgPSB7fSkpO1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFZhbHVlR3VhcmRcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgVmFsdWVHdWFyZDtcbihmdW5jdGlvbiAoVmFsdWVHdWFyZCkge1xuICAgIGZ1bmN0aW9uIElzT2JqZWN0KHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsO1xuICAgIH1cbiAgICBWYWx1ZUd1YXJkLklzT2JqZWN0ID0gSXNPYmplY3Q7XG4gICAgZnVuY3Rpb24gSXNBcnJheSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG4gICAgfVxuICAgIFZhbHVlR3VhcmQuSXNBcnJheSA9IElzQXJyYXk7XG4gICAgZnVuY3Rpb24gSXNCb29sZWFuKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJztcbiAgICB9XG4gICAgVmFsdWVHdWFyZC5Jc0Jvb2xlYW4gPSBJc0Jvb2xlYW47XG4gICAgZnVuY3Rpb24gSXNOdWxsKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbDtcbiAgICB9XG4gICAgVmFsdWVHdWFyZC5Jc051bGwgPSBJc051bGw7XG4gICAgZnVuY3Rpb24gSXNVbmRlZmluZWQodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIFZhbHVlR3VhcmQuSXNVbmRlZmluZWQgPSBJc1VuZGVmaW5lZDtcbiAgICBmdW5jdGlvbiBJc0JpZ0ludCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnYmlnaW50JztcbiAgICB9XG4gICAgVmFsdWVHdWFyZC5Jc0JpZ0ludCA9IElzQmlnSW50O1xuICAgIGZ1bmN0aW9uIElzTnVtYmVyKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInO1xuICAgIH1cbiAgICBWYWx1ZUd1YXJkLklzTnVtYmVyID0gSXNOdW1iZXI7XG4gICAgZnVuY3Rpb24gSXNTdHJpbmcodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZyc7XG4gICAgfVxuICAgIFZhbHVlR3VhcmQuSXNTdHJpbmcgPSBJc1N0cmluZztcbn0pKFZhbHVlR3VhcmQgfHwgKGV4cG9ydHMuVmFsdWVHdWFyZCA9IFZhbHVlR3VhcmQgPSB7fSkpO1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFR5cGVHdWFyZFxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmNsYXNzIFR5cGVHdWFyZFVua25vd25UeXBlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3Ioc2NoZW1hKSB7XG4gICAgICAgIHN1cGVyKCdUeXBlR3VhcmQ6IFVua25vd24gdHlwZScpO1xuICAgICAgICB0aGlzLnNjaGVtYSA9IHNjaGVtYTtcbiAgICB9XG59XG5leHBvcnRzLlR5cGVHdWFyZFVua25vd25UeXBlRXJyb3IgPSBUeXBlR3VhcmRVbmtub3duVHlwZUVycm9yO1xuLyoqIFByb3ZpZGVzIGZ1bmN0aW9ucyB0byB0ZXN0IGlmIEphdmFTY3JpcHQgdmFsdWVzIGFyZSBUeXBlQm94IHR5cGVzICovXG52YXIgVHlwZUd1YXJkO1xuKGZ1bmN0aW9uIChUeXBlR3VhcmQpIHtcbiAgICBmdW5jdGlvbiBJc1BhdHRlcm4odmFsdWUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5ldyBSZWdFeHAodmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzQ29udHJvbENoYXJhY3RlckZyZWUodmFsdWUpIHtcbiAgICAgICAgaWYgKCFWYWx1ZUd1YXJkLklzU3RyaW5nKHZhbHVlKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgY29kZSA9IHZhbHVlLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgICAgICBpZiAoKGNvZGUgPj0gNyAmJiBjb2RlIDw9IDEzKSB8fCBjb2RlID09PSAyNyB8fCBjb2RlID09PSAxMjcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzQWRkaXRpb25hbFByb3BlcnRpZXModmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIElzT3B0aW9uYWxCb29sZWFuKHZhbHVlKSB8fCBUU2NoZW1hKHZhbHVlKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPcHRpb25hbEJpZ0ludCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZCh2YWx1ZSkgfHwgVmFsdWVHdWFyZC5Jc0JpZ0ludCh2YWx1ZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzT3B0aW9uYWxOdW1iZXIodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZhbHVlR3VhcmQuSXNVbmRlZmluZWQodmFsdWUpIHx8IFZhbHVlR3VhcmQuSXNOdW1iZXIodmFsdWUpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBJc09wdGlvbmFsQm9vbGVhbih2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZCh2YWx1ZSkgfHwgVmFsdWVHdWFyZC5Jc0Jvb2xlYW4odmFsdWUpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBJc09wdGlvbmFsU3RyaW5nKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBWYWx1ZUd1YXJkLklzVW5kZWZpbmVkKHZhbHVlKSB8fCBWYWx1ZUd1YXJkLklzU3RyaW5nKHZhbHVlKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPcHRpb25hbFBhdHRlcm4odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFZhbHVlR3VhcmQuSXNVbmRlZmluZWQodmFsdWUpIHx8IChWYWx1ZUd1YXJkLklzU3RyaW5nKHZhbHVlKSAmJiBJc0NvbnRyb2xDaGFyYWN0ZXJGcmVlKHZhbHVlKSAmJiBJc1BhdHRlcm4odmFsdWUpKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPcHRpb25hbEZvcm1hdCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZCh2YWx1ZSkgfHwgKFZhbHVlR3VhcmQuSXNTdHJpbmcodmFsdWUpICYmIElzQ29udHJvbENoYXJhY3RlckZyZWUodmFsdWUpKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPcHRpb25hbFNjaGVtYSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZCh2YWx1ZSkgfHwgVFNjaGVtYSh2YWx1ZSk7XG4gICAgfVxuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNjaGVtYSBpcyBUQW55ICovXG4gICAgZnVuY3Rpb24gVEFueShzY2hlbWEpIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiAoVEtpbmRPZihzY2hlbWEsICdBbnknKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSk7XG4gICAgfVxuICAgIFR5cGVHdWFyZC5UQW55ID0gVEFueTtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVEFycmF5ICovXG4gICAgZnVuY3Rpb24gVEFycmF5KHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gKFRLaW5kT2Yoc2NoZW1hLCAnQXJyYXknKSAmJlxuICAgICAgICAgICAgc2NoZW1hLnR5cGUgPT09ICdhcnJheScgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkgJiZcbiAgICAgICAgICAgIFRTY2hlbWEoc2NoZW1hLml0ZW1zKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEubWluSXRlbXMpICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsTnVtYmVyKHNjaGVtYS5tYXhJdGVtcykgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxCb29sZWFuKHNjaGVtYS51bmlxdWVJdGVtcykgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTY2hlbWEoc2NoZW1hLmNvbnRhaW5zKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEubWluQ29udGFpbnMpICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsTnVtYmVyKHNjaGVtYS5tYXhDb250YWlucykpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVEFycmF5ID0gVEFycmF5O1xuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNjaGVtYSBpcyBUQXN5bmNJdGVyYXRvciAqL1xuICAgIGZ1bmN0aW9uIFRBc3luY0l0ZXJhdG9yKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIChUS2luZE9mKHNjaGVtYSwgJ0FzeW5jSXRlcmF0b3InKSAmJlxuICAgICAgICAgICAgc2NoZW1hLnR5cGUgPT09ICdBc3luY0l0ZXJhdG9yJyAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgVFNjaGVtYShzY2hlbWEuaXRlbXMpKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRBc3luY0l0ZXJhdG9yID0gVEFzeW5jSXRlcmF0b3I7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRCaWdJbnQgKi9cbiAgICBmdW5jdGlvbiBUQmlnSW50KHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIChUS2luZE9mKHNjaGVtYSwgJ0JpZ0ludCcpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ2JpZ2ludCcgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxCaWdJbnQoc2NoZW1hLm11bHRpcGxlT2YpICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsQmlnSW50KHNjaGVtYS5taW5pbXVtKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbEJpZ0ludChzY2hlbWEubWF4aW11bSkgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxCaWdJbnQoc2NoZW1hLmV4Y2x1c2l2ZU1pbmltdW0pICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsQmlnSW50KHNjaGVtYS5leGNsdXNpdmVNYXhpbXVtKSk7XG4gICAgfVxuICAgIFR5cGVHdWFyZC5UQmlnSW50ID0gVEJpZ0ludDtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVEJvb2xlYW4gKi9cbiAgICBmdW5jdGlvbiBUQm9vbGVhbihzY2hlbWEpIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiAoVEtpbmRPZihzY2hlbWEsICdCb29sZWFuJykgJiZcbiAgICAgICAgICAgIHNjaGVtYS50eXBlID09PSAnYm9vbGVhbicgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVEJvb2xlYW4gPSBUQm9vbGVhbjtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVENvbnN0cnVjdG9yICovXG4gICAgZnVuY3Rpb24gVENvbnN0cnVjdG9yKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgaWYgKCEoVEtpbmRPZihzY2hlbWEsICdDb25zdHJ1Y3RvcicpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ2NvbnN0cnVjdG9yJyAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgVmFsdWVHdWFyZC5Jc0FycmF5KHNjaGVtYS5wYXJhbWV0ZXJzKSAmJlxuICAgICAgICAgICAgVFNjaGVtYShzY2hlbWEucmV0dXJucykpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2Ygc2NoZW1hLnBhcmFtZXRlcnMpIHtcbiAgICAgICAgICAgIGlmICghVFNjaGVtYShwYXJhbWV0ZXIpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRDb25zdHJ1Y3RvciA9IFRDb25zdHJ1Y3RvcjtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVERhdGUgKi9cbiAgICBmdW5jdGlvbiBURGF0ZShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIChUS2luZE9mKHNjaGVtYSwgJ0RhdGUnKSAmJlxuICAgICAgICAgICAgc2NoZW1hLnR5cGUgPT09ICdEYXRlJyAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEubWluaW11bVRpbWVzdGFtcCkgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxOdW1iZXIoc2NoZW1hLm1heGltdW1UaW1lc3RhbXApICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsTnVtYmVyKHNjaGVtYS5leGNsdXNpdmVNaW5pbXVtVGltZXN0YW1wKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEuZXhjbHVzaXZlTWF4aW11bVRpbWVzdGFtcCkpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVERhdGUgPSBURGF0ZTtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVEZ1bmN0aW9uICovXG4gICAgZnVuY3Rpb24gVEZ1bmN0aW9uKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgaWYgKCEoVEtpbmRPZihzY2hlbWEsICdGdW5jdGlvbicpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgVmFsdWVHdWFyZC5Jc0FycmF5KHNjaGVtYS5wYXJhbWV0ZXJzKSAmJlxuICAgICAgICAgICAgVFNjaGVtYShzY2hlbWEucmV0dXJucykpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2Ygc2NoZW1hLnBhcmFtZXRlcnMpIHtcbiAgICAgICAgICAgIGlmICghVFNjaGVtYShwYXJhbWV0ZXIpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRGdW5jdGlvbiA9IFRGdW5jdGlvbjtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVEludGVnZXIgKi9cbiAgICBmdW5jdGlvbiBUSW50ZWdlcihzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIChUS2luZE9mKHNjaGVtYSwgJ0ludGVnZXInKSAmJlxuICAgICAgICAgICAgc2NoZW1hLnR5cGUgPT09ICdpbnRlZ2VyJyAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEubXVsdGlwbGVPZikgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxOdW1iZXIoc2NoZW1hLm1pbmltdW0pICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsTnVtYmVyKHNjaGVtYS5tYXhpbXVtKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEuZXhjbHVzaXZlTWluaW11bSkgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxOdW1iZXIoc2NoZW1hLmV4Y2x1c2l2ZU1heGltdW0pKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRJbnRlZ2VyID0gVEludGVnZXI7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRJbnRlcnNlY3QgKi9cbiAgICBmdW5jdGlvbiBUSW50ZXJzZWN0KHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgaWYgKCEoVEtpbmRPZihzY2hlbWEsICdJbnRlcnNlY3QnKSAmJlxuICAgICAgICAgICAgVmFsdWVHdWFyZC5Jc0FycmF5KHNjaGVtYS5hbGxPZikgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLnR5cGUpICYmXG4gICAgICAgICAgICAoSXNPcHRpb25hbEJvb2xlYW4oc2NoZW1hLnVuZXZhbHVhdGVkUHJvcGVydGllcykgfHwgSXNPcHRpb25hbFNjaGVtYShzY2hlbWEudW5ldmFsdWF0ZWRQcm9wZXJ0aWVzKSkgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCd0eXBlJyBpbiBzY2hlbWEgJiYgc2NoZW1hLnR5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBpbm5lciBvZiBzY2hlbWEuYWxsT2YpIHtcbiAgICAgICAgICAgIGlmICghVFNjaGVtYShpbm5lcikpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVEludGVyc2VjdCA9IFRJbnRlcnNlY3Q7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRJdGVyYXRvciAqL1xuICAgIGZ1bmN0aW9uIFRJdGVyYXRvcihzY2hlbWEpIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiAoVEtpbmRPZihzY2hlbWEsICdJdGVyYXRvcicpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ0l0ZXJhdG9yJyAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgVFNjaGVtYShzY2hlbWEuaXRlbXMpKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRJdGVyYXRvciA9IFRJdGVyYXRvcjtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgYSBUS2luZCB3aXRoIHRoZSBnaXZlbiBuYW1lLiAqL1xuICAgIGZ1bmN0aW9uIFRLaW5kT2Yoc2NoZW1hLCBraW5kKSB7XG4gICAgICAgIHJldHVybiBUS2luZChzY2hlbWEpICYmIHNjaGVtYVtleHBvcnRzLktpbmRdID09PSBraW5kO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVEtpbmRPZiA9IFRLaW5kT2Y7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRLaW5kICovXG4gICAgZnVuY3Rpb24gVEtpbmQoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBWYWx1ZUd1YXJkLklzT2JqZWN0KHNjaGVtYSkgJiYgZXhwb3J0cy5LaW5kIGluIHNjaGVtYSAmJiBWYWx1ZUd1YXJkLklzU3RyaW5nKHNjaGVtYVtleHBvcnRzLktpbmRdKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRLaW5kID0gVEtpbmQ7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRMaXRlcmFsPHN0cmluZz4gKi9cbiAgICBmdW5jdGlvbiBUTGl0ZXJhbFN0cmluZyhzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIFRMaXRlcmFsKHNjaGVtYSkgJiYgVmFsdWVHdWFyZC5Jc1N0cmluZyhzY2hlbWEuY29uc3QpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVExpdGVyYWxTdHJpbmcgPSBUTGl0ZXJhbFN0cmluZztcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVExpdGVyYWw8bnVtYmVyPiAqL1xuICAgIGZ1bmN0aW9uIFRMaXRlcmFsTnVtYmVyKHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gVExpdGVyYWwoc2NoZW1hKSAmJiBWYWx1ZUd1YXJkLklzTnVtYmVyKHNjaGVtYS5jb25zdCk7XG4gICAgfVxuICAgIFR5cGVHdWFyZC5UTGl0ZXJhbE51bWJlciA9IFRMaXRlcmFsTnVtYmVyO1xuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNjaGVtYSBpcyBUTGl0ZXJhbDxib29sZWFuPiAqL1xuICAgIGZ1bmN0aW9uIFRMaXRlcmFsQm9vbGVhbihzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIFRMaXRlcmFsKHNjaGVtYSkgJiYgVmFsdWVHdWFyZC5Jc0Jvb2xlYW4oc2NoZW1hLmNvbnN0KTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRMaXRlcmFsQm9vbGVhbiA9IFRMaXRlcmFsQm9vbGVhbjtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVExpdGVyYWwgKi9cbiAgICBmdW5jdGlvbiBUTGl0ZXJhbChzY2hlbWEpIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiAoVEtpbmRPZihzY2hlbWEsICdMaXRlcmFsJykgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkgJiYgKFZhbHVlR3VhcmQuSXNCb29sZWFuKHNjaGVtYS5jb25zdCkgfHxcbiAgICAgICAgICAgIFZhbHVlR3VhcmQuSXNOdW1iZXIoc2NoZW1hLmNvbnN0KSB8fFxuICAgICAgICAgICAgVmFsdWVHdWFyZC5Jc1N0cmluZyhzY2hlbWEuY29uc3QpKSk7XG4gICAgfVxuICAgIFR5cGVHdWFyZC5UTGl0ZXJhbCA9IFRMaXRlcmFsO1xuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNjaGVtYSBpcyBUTmV2ZXIgKi9cbiAgICBmdW5jdGlvbiBUTmV2ZXIoc2NoZW1hKSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gKFRLaW5kT2Yoc2NoZW1hLCAnTmV2ZXInKSAmJlxuICAgICAgICAgICAgVmFsdWVHdWFyZC5Jc09iamVjdChzY2hlbWEubm90KSAmJlxuICAgICAgICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoc2NoZW1hLm5vdCkubGVuZ3RoID09PSAwKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlROZXZlciA9IFROZXZlcjtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVE5vdCAqL1xuICAgIGZ1bmN0aW9uIFROb3Qoc2NoZW1hKSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gKFRLaW5kT2Yoc2NoZW1hLCAnTm90JykgJiZcbiAgICAgICAgICAgIFRTY2hlbWEoc2NoZW1hLm5vdCkpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVE5vdCA9IFROb3Q7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFROdWxsICovXG4gICAgZnVuY3Rpb24gVE51bGwoc2NoZW1hKSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gKFRLaW5kT2Yoc2NoZW1hLCAnTnVsbCcpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ251bGwnICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsU3RyaW5nKHNjaGVtYS4kaWQpKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlROdWxsID0gVE51bGw7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFROdW1iZXIgKi9cbiAgICBmdW5jdGlvbiBUTnVtYmVyKHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gKFRLaW5kT2Yoc2NoZW1hLCAnTnVtYmVyJykgJiZcbiAgICAgICAgICAgIHNjaGVtYS50eXBlID09PSAnbnVtYmVyJyAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEubXVsdGlwbGVPZikgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxOdW1iZXIoc2NoZW1hLm1pbmltdW0pICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsTnVtYmVyKHNjaGVtYS5tYXhpbXVtKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEuZXhjbHVzaXZlTWluaW11bSkgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxOdW1iZXIoc2NoZW1hLmV4Y2x1c2l2ZU1heGltdW0pKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlROdW1iZXIgPSBUTnVtYmVyO1xuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNjaGVtYSBpcyBUT2JqZWN0ICovXG4gICAgZnVuY3Rpb24gVE9iamVjdChzY2hlbWEpIHtcbiAgICAgICAgaWYgKCEoVEtpbmRPZihzY2hlbWEsICdPYmplY3QnKSAmJlxuICAgICAgICAgICAgc2NoZW1hLnR5cGUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsU3RyaW5nKHNjaGVtYS4kaWQpICYmXG4gICAgICAgICAgICBWYWx1ZUd1YXJkLklzT2JqZWN0KHNjaGVtYS5wcm9wZXJ0aWVzKSAmJlxuICAgICAgICAgICAgSXNBZGRpdGlvbmFsUHJvcGVydGllcyhzY2hlbWEuYWRkaXRpb25hbFByb3BlcnRpZXMpICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsTnVtYmVyKHNjaGVtYS5taW5Qcm9wZXJ0aWVzKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEubWF4UHJvcGVydGllcykpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoc2NoZW1hLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgICBpZiAoIUlzQ29udHJvbENoYXJhY3RlckZyZWUoa2V5KSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAoIVRTY2hlbWEodmFsdWUpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRPYmplY3QgPSBUT2JqZWN0O1xuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNjaGVtYSBpcyBUUHJvbWlzZSAqL1xuICAgIGZ1bmN0aW9uIFRQcm9taXNlKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIChUS2luZE9mKHNjaGVtYSwgJ1Byb21pc2UnKSAmJlxuICAgICAgICAgICAgc2NoZW1hLnR5cGUgPT09ICdQcm9taXNlJyAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgVFNjaGVtYShzY2hlbWEuaXRlbSkpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVFByb21pc2UgPSBUUHJvbWlzZTtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVFJlY29yZCAqL1xuICAgIGZ1bmN0aW9uIFRSZWNvcmQoc2NoZW1hKSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICBpZiAoIShUS2luZE9mKHNjaGVtYSwgJ1JlY29yZCcpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkgJiZcbiAgICAgICAgICAgIElzQWRkaXRpb25hbFByb3BlcnRpZXMoc2NoZW1hLmFkZGl0aW9uYWxQcm9wZXJ0aWVzKSAmJlxuICAgICAgICAgICAgVmFsdWVHdWFyZC5Jc09iamVjdChzY2hlbWEucGF0dGVyblByb3BlcnRpZXMpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhzY2hlbWEucGF0dGVyblByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoa2V5cy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIUlzUGF0dGVybihrZXlzWzBdKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghVFNjaGVtYShzY2hlbWEucGF0dGVyblByb3BlcnRpZXNba2V5c1swXV0pKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIFR5cGVHdWFyZC5UUmVjb3JkID0gVFJlY29yZDtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVFJlZiAqL1xuICAgIGZ1bmN0aW9uIFRSZWYoc2NoZW1hKSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gKFRLaW5kT2Yoc2NoZW1hLCAnUmVmJykgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkgJiZcbiAgICAgICAgICAgIFZhbHVlR3VhcmQuSXNTdHJpbmcoc2NoZW1hLiRyZWYpKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRSZWYgPSBUUmVmO1xuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNjaGVtYSBpcyBUU3RyaW5nICovXG4gICAgZnVuY3Rpb24gVFN0cmluZyhzY2hlbWEpIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiAoVEtpbmRPZihzY2hlbWEsICdTdHJpbmcnKSAmJlxuICAgICAgICAgICAgc2NoZW1hLnR5cGUgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsU3RyaW5nKHNjaGVtYS4kaWQpICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsTnVtYmVyKHNjaGVtYS5taW5MZW5ndGgpICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsTnVtYmVyKHNjaGVtYS5tYXhMZW5ndGgpICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsUGF0dGVybihzY2hlbWEucGF0dGVybikgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxGb3JtYXQoc2NoZW1hLmZvcm1hdCkpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVFN0cmluZyA9IFRTdHJpbmc7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRTeW1ib2wgKi9cbiAgICBmdW5jdGlvbiBUU3ltYm9sKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIChUS2luZE9mKHNjaGVtYSwgJ1N5bWJvbCcpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ3N5bWJvbCcgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVFN5bWJvbCA9IFRTeW1ib2w7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRUZW1wbGF0ZUxpdGVyYWwgKi9cbiAgICBmdW5jdGlvbiBUVGVtcGxhdGVMaXRlcmFsKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIChUS2luZE9mKHNjaGVtYSwgJ1RlbXBsYXRlTGl0ZXJhbCcpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgIFZhbHVlR3VhcmQuSXNTdHJpbmcoc2NoZW1hLnBhdHRlcm4pICYmXG4gICAgICAgICAgICBzY2hlbWEucGF0dGVyblswXSA9PT0gJ14nICYmXG4gICAgICAgICAgICBzY2hlbWEucGF0dGVybltzY2hlbWEucGF0dGVybi5sZW5ndGggLSAxXSA9PT0gJyQnKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRUZW1wbGF0ZUxpdGVyYWwgPSBUVGVtcGxhdGVMaXRlcmFsO1xuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNjaGVtYSBpcyBUVGhpcyAqL1xuICAgIGZ1bmN0aW9uIFRUaGlzKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIChUS2luZE9mKHNjaGVtYSwgJ1RoaXMnKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgVmFsdWVHdWFyZC5Jc1N0cmluZyhzY2hlbWEuJHJlZikpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVFRoaXMgPSBUVGhpcztcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVFR1cGxlICovXG4gICAgZnVuY3Rpb24gVFR1cGxlKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgaWYgKCEoVEtpbmRPZihzY2hlbWEsICdUdXBsZScpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ2FycmF5JyAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSAmJlxuICAgICAgICAgICAgVmFsdWVHdWFyZC5Jc051bWJlcihzY2hlbWEubWluSXRlbXMpICYmXG4gICAgICAgICAgICBWYWx1ZUd1YXJkLklzTnVtYmVyKHNjaGVtYS5tYXhJdGVtcykgJiZcbiAgICAgICAgICAgIHNjaGVtYS5taW5JdGVtcyA9PT0gc2NoZW1hLm1heEl0ZW1zKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChWYWx1ZUd1YXJkLklzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykgJiYgVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZChzY2hlbWEuYWRkaXRpb25hbEl0ZW1zKSAmJiBzY2hlbWEubWluSXRlbXMgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghVmFsdWVHdWFyZC5Jc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGlubmVyIG9mIHNjaGVtYS5pdGVtcykge1xuICAgICAgICAgICAgaWYgKCFUU2NoZW1hKGlubmVyKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIFR5cGVHdWFyZC5UVHVwbGUgPSBUVHVwbGU7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRVbmRlZmluZWQgKi9cbiAgICBmdW5jdGlvbiBUVW5kZWZpbmVkKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIChUS2luZE9mKHNjaGVtYSwgJ1VuZGVmaW5lZCcpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVFVuZGVmaW5lZCA9IFRVbmRlZmluZWQ7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRVbmlvbjxMaXRlcmFsPHN0cmluZyB8IG51bWJlcj5bXT4gKi9cbiAgICBmdW5jdGlvbiBUVW5pb25MaXRlcmFsKHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gVFVuaW9uKHNjaGVtYSkgJiYgc2NoZW1hLmFueU9mLmV2ZXJ5KChzY2hlbWEpID0+IFRMaXRlcmFsU3RyaW5nKHNjaGVtYSkgfHwgVExpdGVyYWxOdW1iZXIoc2NoZW1hKSk7XG4gICAgfVxuICAgIFR5cGVHdWFyZC5UVW5pb25MaXRlcmFsID0gVFVuaW9uTGl0ZXJhbDtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVFVuaW9uICovXG4gICAgZnVuY3Rpb24gVFVuaW9uKHNjaGVtYSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgaWYgKCEoVEtpbmRPZihzY2hlbWEsICdVbmlvbicpICYmXG4gICAgICAgICAgICBWYWx1ZUd1YXJkLklzQXJyYXkoc2NoZW1hLmFueU9mKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbFN0cmluZyhzY2hlbWEuJGlkKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGlubmVyIG9mIHNjaGVtYS5hbnlPZikge1xuICAgICAgICAgICAgaWYgKCFUU2NoZW1hKGlubmVyKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIFR5cGVHdWFyZC5UVW5pb24gPSBUVW5pb247XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRVaW50OEFycmF5ICovXG4gICAgZnVuY3Rpb24gVFVpbnQ4QXJyYXkoc2NoZW1hKSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gKFRLaW5kT2Yoc2NoZW1hLCAnVWludDhBcnJheScpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ1VpbnQ4QXJyYXknICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsU3RyaW5nKHNjaGVtYS4kaWQpICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsTnVtYmVyKHNjaGVtYS5taW5CeXRlTGVuZ3RoKSAmJlxuICAgICAgICAgICAgSXNPcHRpb25hbE51bWJlcihzY2hlbWEubWF4Qnl0ZUxlbmd0aCkpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVFVpbnQ4QXJyYXkgPSBUVWludDhBcnJheTtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgVFVua25vd24gKi9cbiAgICBmdW5jdGlvbiBUVW5rbm93bihzY2hlbWEpIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiAoVEtpbmRPZihzY2hlbWEsICdVbmtub3duJykgJiZcbiAgICAgICAgICAgIElzT3B0aW9uYWxTdHJpbmcoc2NoZW1hLiRpZCkpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVFVua25vd24gPSBUVW5rbm93bjtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzY2hlbWEgaXMgYSByYXcgVFVuc2FmZSAqL1xuICAgIGZ1bmN0aW9uIFRVbnNhZmUoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBUS2luZE9mKHNjaGVtYSwgJ1Vuc2FmZScpO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVFVuc2FmZSA9IFRVbnNhZmU7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2NoZW1hIGlzIFRWb2lkICovXG4gICAgZnVuY3Rpb24gVFZvaWQoc2NoZW1hKSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gKFRLaW5kT2Yoc2NoZW1hLCAnVm9pZCcpICYmXG4gICAgICAgICAgICBzY2hlbWEudHlwZSA9PT0gJ3ZvaWQnICYmXG4gICAgICAgICAgICBJc09wdGlvbmFsU3RyaW5nKHNjaGVtYS4kaWQpKTtcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRWb2lkID0gVFZvaWQ7XG4gICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHNjaGVtYSBoYXMgdGhlIFJlYWRvbmx5IG1vZGlmaWVyICovXG4gICAgZnVuY3Rpb24gVFJlYWRvbmx5KHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gVmFsdWVHdWFyZC5Jc09iamVjdChzY2hlbWEpICYmIHNjaGVtYVtleHBvcnRzLlJlYWRvbmx5XSA9PT0gJ1JlYWRvbmx5JztcbiAgICB9XG4gICAgVHlwZUd1YXJkLlRSZWFkb25seSA9IFRSZWFkb25seTtcbiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoaXMgc2NoZW1hIGhhcyB0aGUgT3B0aW9uYWwgbW9kaWZpZXIgKi9cbiAgICBmdW5jdGlvbiBUT3B0aW9uYWwoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBWYWx1ZUd1YXJkLklzT2JqZWN0KHNjaGVtYSkgJiYgc2NoZW1hW2V4cG9ydHMuT3B0aW9uYWxdID09PSAnT3B0aW9uYWwnO1xuICAgIH1cbiAgICBUeXBlR3VhcmQuVE9wdGlvbmFsID0gVE9wdGlvbmFsO1xuICAgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNjaGVtYSBpcyBUU2NoZW1hICovXG4gICAgZnVuY3Rpb24gVFNjaGVtYShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIChWYWx1ZUd1YXJkLklzT2JqZWN0KHNjaGVtYSkgJiZcbiAgICAgICAgICAgIChUQW55KHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUQXJyYXkoc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRCb29sZWFuKHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUQmlnSW50KHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUQXN5bmNJdGVyYXRvcihzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgVENvbnN0cnVjdG9yKHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBURGF0ZShzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgVEZ1bmN0aW9uKHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUSW50ZWdlcihzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgVEludGVyc2VjdChzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgVEl0ZXJhdG9yKHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUTGl0ZXJhbChzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgVE5ldmVyKHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUTm90KHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUTnVsbChzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgVE51bWJlcihzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgVE9iamVjdChzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgVFByb21pc2Uoc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRSZWNvcmQoc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRSZWYoc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRTdHJpbmcoc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRTeW1ib2woc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRUZW1wbGF0ZUxpdGVyYWwoc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRUaGlzKHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUVHVwbGUoc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRVbmRlZmluZWQoc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRVbmlvbihzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgVFVpbnQ4QXJyYXkoc2NoZW1hKSB8fFxuICAgICAgICAgICAgICAgIFRVbmtub3duKHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUVW5zYWZlKHNjaGVtYSkgfHxcbiAgICAgICAgICAgICAgICBUVm9pZChzY2hlbWEpIHx8XG4gICAgICAgICAgICAgICAgKFRLaW5kKHNjaGVtYSkgJiYgVHlwZVJlZ2lzdHJ5LkhhcyhzY2hlbWFbZXhwb3J0cy5LaW5kXSkpKSk7XG4gICAgfVxuICAgIFR5cGVHdWFyZC5UU2NoZW1hID0gVFNjaGVtYTtcbn0pKFR5cGVHdWFyZCB8fCAoZXhwb3J0cy5UeXBlR3VhcmQgPSBUeXBlR3VhcmQgPSB7fSkpO1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEV4dGVuZHNVbmRlZmluZWRcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vKiogRmFzdCB1bmRlZmluZWQgY2hlY2sgdXNlZCBmb3IgcHJvcGVydGllcyBvZiB0eXBlIHVuZGVmaW5lZCAqL1xudmFyIEV4dGVuZHNVbmRlZmluZWQ7XG4oZnVuY3Rpb24gKEV4dGVuZHNVbmRlZmluZWQpIHtcbiAgICBmdW5jdGlvbiBDaGVjayhzY2hlbWEpIHtcbiAgICAgICAgaWYgKHNjaGVtYVtleHBvcnRzLktpbmRdID09PSAnVW5kZWZpbmVkJylcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAoc2NoZW1hW2V4cG9ydHMuS2luZF0gPT09ICdOb3QnKSB7XG4gICAgICAgICAgICByZXR1cm4gIUNoZWNrKHNjaGVtYS5ub3QpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzY2hlbWFbZXhwb3J0cy5LaW5kXSA9PT0gJ0ludGVyc2VjdCcpIHtcbiAgICAgICAgICAgIGNvbnN0IGludGVyc2VjdCA9IHNjaGVtYTtcbiAgICAgICAgICAgIHJldHVybiBpbnRlcnNlY3QuYWxsT2YuZXZlcnkoKHNjaGVtYSkgPT4gQ2hlY2soc2NoZW1hKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjaGVtYVtleHBvcnRzLktpbmRdID09PSAnVW5pb24nKSB7XG4gICAgICAgICAgICBjb25zdCB1bmlvbiA9IHNjaGVtYTtcbiAgICAgICAgICAgIHJldHVybiB1bmlvbi5hbnlPZi5zb21lKChzY2hlbWEpID0+IENoZWNrKHNjaGVtYSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgRXh0ZW5kc1VuZGVmaW5lZC5DaGVjayA9IENoZWNrO1xufSkoRXh0ZW5kc1VuZGVmaW5lZCB8fCAoZXhwb3J0cy5FeHRlbmRzVW5kZWZpbmVkID0gRXh0ZW5kc1VuZGVmaW5lZCA9IHt9KSk7XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVHlwZUV4dGVuZHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgVHlwZUV4dGVuZHNSZXN1bHQ7XG4oZnVuY3Rpb24gKFR5cGVFeHRlbmRzUmVzdWx0KSB7XG4gICAgVHlwZUV4dGVuZHNSZXN1bHRbVHlwZUV4dGVuZHNSZXN1bHRbXCJVbmlvblwiXSA9IDBdID0gXCJVbmlvblwiO1xuICAgIFR5cGVFeHRlbmRzUmVzdWx0W1R5cGVFeHRlbmRzUmVzdWx0W1wiVHJ1ZVwiXSA9IDFdID0gXCJUcnVlXCI7XG4gICAgVHlwZUV4dGVuZHNSZXN1bHRbVHlwZUV4dGVuZHNSZXN1bHRbXCJGYWxzZVwiXSA9IDJdID0gXCJGYWxzZVwiO1xufSkoVHlwZUV4dGVuZHNSZXN1bHQgfHwgKGV4cG9ydHMuVHlwZUV4dGVuZHNSZXN1bHQgPSBUeXBlRXh0ZW5kc1Jlc3VsdCA9IHt9KSk7XG52YXIgVHlwZUV4dGVuZHM7XG4oZnVuY3Rpb24gKFR5cGVFeHRlbmRzKSB7XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBJbnRvQm9vbGVhblJlc3VsdFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gSW50b0Jvb2xlYW5SZXN1bHQocmVzdWx0KSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlID8gVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2UgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFN0cnVjdHVyYWxSaWdodFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gSXNTdHJ1Y3R1cmFsUmlnaHQocmlnaHQpIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiAoVHlwZUd1YXJkLlROZXZlcihyaWdodCkgfHxcbiAgICAgICAgICAgIFR5cGVHdWFyZC5USW50ZXJzZWN0KHJpZ2h0KSB8fFxuICAgICAgICAgICAgVHlwZUd1YXJkLlRVbmlvbihyaWdodCkgfHxcbiAgICAgICAgICAgIFR5cGVHdWFyZC5UVW5rbm93bihyaWdodCkgfHxcbiAgICAgICAgICAgIFR5cGVHdWFyZC5UQW55KHJpZ2h0KSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFN0cnVjdHVyYWxSaWdodChsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlROZXZlcihyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE5ldmVyUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRJbnRlcnNlY3QocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRJbnRlcnNlY3RSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFVuaW9uKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUVW5pb25SaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFVua25vd24ocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRVbmtub3duUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRBbnkocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRBbnlSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIHRocm93IEVycm9yKCdUeXBlRXh0ZW5kczogU3RydWN0dXJhbFJpZ2h0Jyk7XG4gICAgfVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQW55XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBUQW55UmlnaHQobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFRBbnkobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5USW50ZXJzZWN0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUSW50ZXJzZWN0UmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRVbmlvbihyaWdodCkgJiYgcmlnaHQuYW55T2Yuc29tZSgoc2NoZW1hKSA9PiBUeXBlR3VhcmQuVEFueShzY2hlbWEpIHx8IFR5cGVHdWFyZC5UVW5rbm93bihzY2hlbWEpKSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRVbmlvbihyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVW5pb247XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFVua25vd24ocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVEFueShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlVuaW9uO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEFycmF5XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBUQXJyYXlSaWdodChsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRVbmtub3duKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRBbnkobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVW5pb247XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE5ldmVyKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gVEFycmF5KGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGlmIChJc1N0cnVjdHVyYWxSaWdodChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gU3RydWN0dXJhbFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UT2JqZWN0KHJpZ2h0KSAmJiBJc09iamVjdEFycmF5TGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKCFUeXBlR3VhcmQuVEFycmF5KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgcmV0dXJuIEludG9Cb29sZWFuUmVzdWx0KFZpc2l0KGxlZnQuaXRlbXMsIHJpZ2h0Lml0ZW1zKSk7XG4gICAgfVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQXN5bmNJdGVyYXRvclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gVEFzeW5jSXRlcmF0b3IobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKElzU3RydWN0dXJhbFJpZ2h0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBTdHJ1Y3R1cmFsUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoIVR5cGVHdWFyZC5UQXN5bmNJdGVyYXRvcihyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U7XG4gICAgICAgIHJldHVybiBJbnRvQm9vbGVhblJlc3VsdChWaXNpdChsZWZ0Lml0ZW1zLCByaWdodC5pdGVtcykpO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEJpZ0ludFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gVEJpZ0ludChsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoSXNTdHJ1Y3R1cmFsUmlnaHQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFN0cnVjdHVyYWxSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9iamVjdChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE9iamVjdFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UUmVjb3JkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUUmVjb3JkUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlRCaWdJbnQocmlnaHQpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEJvb2xlYW5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGZ1bmN0aW9uIFRCb29sZWFuUmlnaHQobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UTGl0ZXJhbChsZWZ0KSAmJiBWYWx1ZUd1YXJkLklzQm9vbGVhbihsZWZ0LmNvbnN0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlRCb29sZWFuKGxlZnQpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUQm9vbGVhbihsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoSXNTdHJ1Y3R1cmFsUmlnaHQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFN0cnVjdHVyYWxSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9iamVjdChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE9iamVjdFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UUmVjb3JkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUUmVjb3JkUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlRCb29sZWFuKHJpZ2h0KSA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBDb25zdHJ1Y3RvclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gVENvbnN0cnVjdG9yKGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGlmIChJc1N0cnVjdHVyYWxSaWdodChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gU3RydWN0dXJhbFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UT2JqZWN0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUT2JqZWN0UmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoIVR5cGVHdWFyZC5UQ29uc3RydWN0b3IocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgICAgICBpZiAobGVmdC5wYXJhbWV0ZXJzLmxlbmd0aCA+IHJpZ2h0LnBhcmFtZXRlcnMubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgICAgICBpZiAoIWxlZnQucGFyYW1ldGVycy5ldmVyeSgoc2NoZW1hLCBpbmRleCkgPT4gSW50b0Jvb2xlYW5SZXN1bHQoVmlzaXQocmlnaHQucGFyYW1ldGVyc1tpbmRleF0sIHNjaGVtYSkpID09PSBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBJbnRvQm9vbGVhblJlc3VsdChWaXNpdChsZWZ0LnJldHVybnMsIHJpZ2h0LnJldHVybnMpKTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBEYXRlXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBURGF0ZShsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoSXNTdHJ1Y3R1cmFsUmlnaHQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFN0cnVjdHVyYWxSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9iamVjdChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE9iamVjdFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UUmVjb3JkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUUmVjb3JkUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlREYXRlKHJpZ2h0KSA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBGdW5jdGlvblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gVEZ1bmN0aW9uKGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGlmIChJc1N0cnVjdHVyYWxSaWdodChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gU3RydWN0dXJhbFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UT2JqZWN0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUT2JqZWN0UmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoIVR5cGVHdWFyZC5URnVuY3Rpb24ocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgICAgICBpZiAobGVmdC5wYXJhbWV0ZXJzLmxlbmd0aCA+IHJpZ2h0LnBhcmFtZXRlcnMubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgICAgICBpZiAoIWxlZnQucGFyYW1ldGVycy5ldmVyeSgoc2NoZW1hLCBpbmRleCkgPT4gSW50b0Jvb2xlYW5SZXN1bHQoVmlzaXQocmlnaHQucGFyYW1ldGVyc1tpbmRleF0sIHNjaGVtYSkpID09PSBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBJbnRvQm9vbGVhblJlc3VsdChWaXNpdChsZWZ0LnJldHVybnMsIHJpZ2h0LnJldHVybnMpKTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBJbnRlZ2VyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBUSW50ZWdlclJpZ2h0KGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVExpdGVyYWwobGVmdCkgJiYgVmFsdWVHdWFyZC5Jc051bWJlcihsZWZ0LmNvbnN0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlROdW1iZXIobGVmdCkgfHwgVHlwZUd1YXJkLlRJbnRlZ2VyKGxlZnQpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUSW50ZWdlcihsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoSXNTdHJ1Y3R1cmFsUmlnaHQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFN0cnVjdHVyYWxSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9iamVjdChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE9iamVjdFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UUmVjb3JkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUUmVjb3JkUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlRJbnRlZ2VyKHJpZ2h0KSB8fCBUeXBlR3VhcmQuVE51bWJlcihyaWdodCkgPyBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlIDogVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U7XG4gICAgfVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gSW50ZXJzZWN0XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBUSW50ZXJzZWN0UmlnaHQobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgcmV0dXJuIHJpZ2h0LmFsbE9mLmV2ZXJ5KChzY2hlbWEpID0+IFZpc2l0KGxlZnQsIHNjaGVtYSkgPT09IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUSW50ZXJzZWN0KGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIHJldHVybiBsZWZ0LmFsbE9mLnNvbWUoKHNjaGVtYSkgPT4gVmlzaXQoc2NoZW1hLCByaWdodCkgPT09IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEl0ZXJhdG9yXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBUSXRlcmF0b3IobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKElzU3RydWN0dXJhbFJpZ2h0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBTdHJ1Y3R1cmFsUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoIVR5cGVHdWFyZC5USXRlcmF0b3IocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgICAgICByZXR1cm4gSW50b0Jvb2xlYW5SZXN1bHQoVmlzaXQobGVmdC5pdGVtcywgcmlnaHQuaXRlbXMpKTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBMaXRlcmFsXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBUTGl0ZXJhbChsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoSXNTdHJ1Y3R1cmFsUmlnaHQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFN0cnVjdHVyYWxSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9iamVjdChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE9iamVjdFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UUmVjb3JkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUUmVjb3JkUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRTdHJpbmcocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRTdHJpbmdSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE51bWJlcihyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE51bWJlclJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5USW50ZWdlcihyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVEludGVnZXJSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVEJvb2xlYW4ocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRCb29sZWFuUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlRMaXRlcmFsKHJpZ2h0KSAmJiByaWdodC5jb25zdCA9PT0gbGVmdC5jb25zdCA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBOZXZlclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gVE5ldmVyUmlnaHQobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUTmV2ZXIobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgfVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gTm90XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBVbndyYXBUTm90KHNjaGVtYSkge1xuICAgICAgICBsZXQgW2N1cnJlbnQsIGRlcHRoXSA9IFtzY2hlbWEsIDBdO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgaWYgKCFUeXBlR3VhcmQuVE5vdChjdXJyZW50KSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm5vdDtcbiAgICAgICAgICAgIGRlcHRoICs9IDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlcHRoICUgMiA9PT0gMCA/IGN1cnJlbnQgOiBleHBvcnRzLlR5cGUuVW5rbm93bigpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUTm90KGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIC8vIFR5cGVTY3JpcHQgaGFzIG5vIGNvbmNlcHQgb2YgbmVnYXRlZCB0eXBlcywgYW5kIGF0dGVtcHRzIHRvIGNvcnJlY3RseSBjaGVjayB0aGUgbmVnYXRlZFxuICAgICAgICAvLyB0eXBlIGF0IHJ1bnRpbWUgd291bGQgcHV0IFR5cGVCb3ggYXQgb2RkcyB3aXRoIFR5cGVTY3JpcHRzIGFiaWxpdHkgdG8gc3RhdGljYWxseSBpbmZlclxuICAgICAgICAvLyB0aGUgdHlwZS4gSW5zdGVhZCB3ZSB1bndyYXAgdG8gZWl0aGVyIHVua25vd24gb3IgVCBhbmQgY29udGludWUgZXZhbHVhdGluZy5cbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UTm90KGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFZpc2l0KFVud3JhcFROb3QobGVmdCksIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UTm90KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBWaXNpdChsZWZ0LCBVbndyYXBUTm90KHJpZ2h0KSk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVHlwZUV4dGVuZHM6IEludmFsaWQgZmFsbHRocm91Z2ggZm9yIE5vdGApO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIE51bGxcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGZ1bmN0aW9uIFROdWxsKGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGlmIChJc1N0cnVjdHVyYWxSaWdodChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gU3RydWN0dXJhbFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UT2JqZWN0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUT2JqZWN0UmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRSZWNvcmQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRSZWNvcmRSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIHJldHVybiBUeXBlR3VhcmQuVE51bGwocmlnaHQpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIE51bWJlclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gVE51bWJlclJpZ2h0KGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVExpdGVyYWxOdW1iZXIobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgcmV0dXJuIFR5cGVHdWFyZC5UTnVtYmVyKGxlZnQpIHx8IFR5cGVHdWFyZC5USW50ZWdlcihsZWZ0KSA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gVE51bWJlcihsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoSXNTdHJ1Y3R1cmFsUmlnaHQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFN0cnVjdHVyYWxSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9iamVjdChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE9iamVjdFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UUmVjb3JkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUUmVjb3JkUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlRJbnRlZ2VyKHJpZ2h0KSB8fCBUeXBlR3VhcmQuVE51bWJlcihyaWdodCkgPyBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlIDogVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U7XG4gICAgfVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gT2JqZWN0XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBJc09iamVjdFByb3BlcnR5Q291bnQoc2NoZW1hLCBjb3VudCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoc2NoZW1hLnByb3BlcnRpZXMpLmxlbmd0aCA9PT0gY291bnQ7XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzT2JqZWN0U3RyaW5nTGlrZShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIElzT2JqZWN0QXJyYXlMaWtlKHNjaGVtYSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzT2JqZWN0U3ltYm9sTGlrZShzY2hlbWEpIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiBJc09iamVjdFByb3BlcnR5Q291bnQoc2NoZW1hLCAwKSB8fCAoSXNPYmplY3RQcm9wZXJ0eUNvdW50KHNjaGVtYSwgMSkgJiYgJ2Rlc2NyaXB0aW9uJyBpbiBzY2hlbWEucHJvcGVydGllcyAmJiBUeXBlR3VhcmQuVFVuaW9uKHNjaGVtYS5wcm9wZXJ0aWVzLmRlc2NyaXB0aW9uKSAmJiBzY2hlbWEucHJvcGVydGllcy5kZXNjcmlwdGlvbi5hbnlPZi5sZW5ndGggPT09IDIgJiYgKChUeXBlR3VhcmQuVFN0cmluZyhzY2hlbWEucHJvcGVydGllcy5kZXNjcmlwdGlvbi5hbnlPZlswXSkgJiZcbiAgICAgICAgICAgIFR5cGVHdWFyZC5UVW5kZWZpbmVkKHNjaGVtYS5wcm9wZXJ0aWVzLmRlc2NyaXB0aW9uLmFueU9mWzFdKSkgfHwgKFR5cGVHdWFyZC5UU3RyaW5nKHNjaGVtYS5wcm9wZXJ0aWVzLmRlc2NyaXB0aW9uLmFueU9mWzFdKSAmJlxuICAgICAgICAgICAgVHlwZUd1YXJkLlRVbmRlZmluZWQoc2NoZW1hLnByb3BlcnRpZXMuZGVzY3JpcHRpb24uYW55T2ZbMF0pKSkpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBJc09iamVjdE51bWJlckxpa2Uoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBJc09iamVjdFByb3BlcnR5Q291bnQoc2NoZW1hLCAwKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPYmplY3RCb29sZWFuTGlrZShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIElzT2JqZWN0UHJvcGVydHlDb3VudChzY2hlbWEsIDApO1xuICAgIH1cbiAgICBmdW5jdGlvbiBJc09iamVjdEJpZ0ludExpa2Uoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBJc09iamVjdFByb3BlcnR5Q291bnQoc2NoZW1hLCAwKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPYmplY3REYXRlTGlrZShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIElzT2JqZWN0UHJvcGVydHlDb3VudChzY2hlbWEsIDApO1xuICAgIH1cbiAgICBmdW5jdGlvbiBJc09iamVjdFVpbnQ4QXJyYXlMaWtlKHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gSXNPYmplY3RBcnJheUxpa2Uoc2NoZW1hKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPYmplY3RGdW5jdGlvbkxpa2Uoc2NoZW1hKSB7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IGV4cG9ydHMuVHlwZS5OdW1iZXIoKTtcbiAgICAgICAgcmV0dXJuIElzT2JqZWN0UHJvcGVydHlDb3VudChzY2hlbWEsIDApIHx8IChJc09iamVjdFByb3BlcnR5Q291bnQoc2NoZW1hLCAxKSAmJiAnbGVuZ3RoJyBpbiBzY2hlbWEucHJvcGVydGllcyAmJiBJbnRvQm9vbGVhblJlc3VsdChWaXNpdChzY2hlbWEucHJvcGVydGllc1snbGVuZ3RoJ10sIGxlbmd0aCkpID09PSBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPYmplY3RDb25zdHJ1Y3Rvckxpa2Uoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBJc09iamVjdFByb3BlcnR5Q291bnQoc2NoZW1hLCAwKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPYmplY3RBcnJheUxpa2Uoc2NoZW1hKSB7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IGV4cG9ydHMuVHlwZS5OdW1iZXIoKTtcbiAgICAgICAgcmV0dXJuIElzT2JqZWN0UHJvcGVydHlDb3VudChzY2hlbWEsIDApIHx8IChJc09iamVjdFByb3BlcnR5Q291bnQoc2NoZW1hLCAxKSAmJiAnbGVuZ3RoJyBpbiBzY2hlbWEucHJvcGVydGllcyAmJiBJbnRvQm9vbGVhblJlc3VsdChWaXNpdChzY2hlbWEucHJvcGVydGllc1snbGVuZ3RoJ10sIGxlbmd0aCkpID09PSBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPYmplY3RQcm9taXNlTGlrZShzY2hlbWEpIHtcbiAgICAgICAgY29uc3QgdGhlbiA9IGV4cG9ydHMuVHlwZS5GdW5jdGlvbihbZXhwb3J0cy5UeXBlLkFueSgpXSwgZXhwb3J0cy5UeXBlLkFueSgpKTtcbiAgICAgICAgcmV0dXJuIElzT2JqZWN0UHJvcGVydHlDb3VudChzY2hlbWEsIDApIHx8IChJc09iamVjdFByb3BlcnR5Q291bnQoc2NoZW1hLCAxKSAmJiAndGhlbicgaW4gc2NoZW1hLnByb3BlcnRpZXMgJiYgSW50b0Jvb2xlYW5SZXN1bHQoVmlzaXQoc2NoZW1hLnByb3BlcnRpZXNbJ3RoZW4nXSwgdGhlbikpID09PSBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlKTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBQcm9wZXJ0eVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gUHJvcGVydHkobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKFZpc2l0KGxlZnQsIHJpZ2h0KSA9PT0gVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2UpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9wdGlvbmFsKGxlZnQpICYmICFUeXBlR3VhcmQuVE9wdGlvbmFsKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFRPYmplY3RSaWdodChsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRVbmtub3duKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRBbnkobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVW5pb247XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE5ldmVyKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVExpdGVyYWxTdHJpbmcobGVmdCkgJiYgSXNPYmplY3RTdHJpbmdMaWtlKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRMaXRlcmFsTnVtYmVyKGxlZnQpICYmIElzT2JqZWN0TnVtYmVyTGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UTGl0ZXJhbEJvb2xlYW4obGVmdCkgJiYgSXNPYmplY3RCb29sZWFuTGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UU3ltYm9sKGxlZnQpICYmIElzT2JqZWN0U3ltYm9sTGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UQmlnSW50KGxlZnQpICYmIElzT2JqZWN0QmlnSW50TGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UU3RyaW5nKGxlZnQpICYmIElzT2JqZWN0U3RyaW5nTGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UU3ltYm9sKGxlZnQpICYmIElzT2JqZWN0U3ltYm9sTGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UTnVtYmVyKGxlZnQpICYmIElzT2JqZWN0TnVtYmVyTGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5USW50ZWdlcihsZWZ0KSAmJiBJc09iamVjdE51bWJlckxpa2UocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVEJvb2xlYW4obGVmdCkgJiYgSXNPYmplY3RCb29sZWFuTGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVWludDhBcnJheShsZWZ0KSAmJiBJc09iamVjdFVpbnQ4QXJyYXlMaWtlKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlREYXRlKGxlZnQpICYmIElzT2JqZWN0RGF0ZUxpa2UocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVENvbnN0cnVjdG9yKGxlZnQpICYmIElzT2JqZWN0Q29uc3RydWN0b3JMaWtlKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRGdW5jdGlvbihsZWZ0KSAmJiBJc09iamVjdEZ1bmN0aW9uTGlrZShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UUmVjb3JkKGxlZnQpICYmIFR5cGVHdWFyZC5UU3RyaW5nKFJlY29yZEtleShsZWZ0KSkpIHtcbiAgICAgICAgICAgIC8vIFdoZW4gZXhwcmVzc2luZyBhIFJlY29yZCB3aXRoIGxpdGVyYWwga2V5IHZhbHVlcywgdGhlIFJlY29yZCBpcyBjb252ZXJ0ZWQgaW50byBhIE9iamVjdCB3aXRoXG4gICAgICAgICAgICAvLyB0aGUgSGludCBhc3NpZ25lZCBhcyBgUmVjb3JkYC4gVGhpcyBpcyB1c2VkIHRvIGludmVydCB0aGUgZXh0ZW5kcyBsb2dpYy5cbiAgICAgICAgICAgIHJldHVybiByaWdodFtleHBvcnRzLkhpbnRdID09PSAnUmVjb3JkJyA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoVHlwZUd1YXJkLlRSZWNvcmQobGVmdCkgJiYgVHlwZUd1YXJkLlROdW1iZXIoUmVjb3JkS2V5KGxlZnQpKSkge1xuICAgICAgICAgICAgcmV0dXJuIElzT2JqZWN0UHJvcGVydHlDb3VudChyaWdodCwgMCkgPyBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlIDogVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUT2JqZWN0KGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGlmIChJc1N0cnVjdHVyYWxSaWdodChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gU3RydWN0dXJhbFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UUmVjb3JkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUUmVjb3JkUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoIVR5cGVHdWFyZC5UT2JqZWN0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocmlnaHQucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgIGlmICghKGtleSBpbiBsZWZ0LnByb3BlcnRpZXMpKVxuICAgICAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgICAgIGlmIChQcm9wZXJ0eShsZWZ0LnByb3BlcnRpZXNba2V5XSwgcmlnaHQucHJvcGVydGllc1trZXldKSA9PT0gVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgfVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gUHJvbWlzZVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gVFByb21pc2UobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKElzU3RydWN0dXJhbFJpZ2h0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBTdHJ1Y3R1cmFsUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRPYmplY3QocmlnaHQpICYmIElzT2JqZWN0UHJvbWlzZUxpa2UocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIGlmICghVHlwZUd1YXJkLlRQcm9taXNlKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgcmV0dXJuIEludG9Cb29sZWFuUmVzdWx0KFZpc2l0KGxlZnQuaXRlbSwgcmlnaHQuaXRlbSkpO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFJlY29yZFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gUmVjb3JkS2V5KHNjaGVtYSkge1xuICAgICAgICBpZiAoZXhwb3J0cy5QYXR0ZXJuTnVtYmVyRXhhY3QgaW4gc2NoZW1hLnBhdHRlcm5Qcm9wZXJ0aWVzKVxuICAgICAgICAgICAgcmV0dXJuIGV4cG9ydHMuVHlwZS5OdW1iZXIoKTtcbiAgICAgICAgaWYgKGV4cG9ydHMuUGF0dGVyblN0cmluZ0V4YWN0IGluIHNjaGVtYS5wYXR0ZXJuUHJvcGVydGllcylcbiAgICAgICAgICAgIHJldHVybiBleHBvcnRzLlR5cGUuU3RyaW5nKCk7XG4gICAgICAgIHRocm93IEVycm9yKCdUeXBlRXh0ZW5kczogQ2Fubm90IGdldCByZWNvcmQga2V5Jyk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFJlY29yZFZhbHVlKHNjaGVtYSkge1xuICAgICAgICBpZiAoZXhwb3J0cy5QYXR0ZXJuTnVtYmVyRXhhY3QgaW4gc2NoZW1hLnBhdHRlcm5Qcm9wZXJ0aWVzKVxuICAgICAgICAgICAgcmV0dXJuIHNjaGVtYS5wYXR0ZXJuUHJvcGVydGllc1tleHBvcnRzLlBhdHRlcm5OdW1iZXJFeGFjdF07XG4gICAgICAgIGlmIChleHBvcnRzLlBhdHRlcm5TdHJpbmdFeGFjdCBpbiBzY2hlbWEucGF0dGVyblByb3BlcnRpZXMpXG4gICAgICAgICAgICByZXR1cm4gc2NoZW1hLnBhdHRlcm5Qcm9wZXJ0aWVzW2V4cG9ydHMuUGF0dGVyblN0cmluZ0V4YWN0XTtcbiAgICAgICAgdGhyb3cgRXJyb3IoJ1R5cGVFeHRlbmRzOiBDYW5ub3QgZ2V0IHJlY29yZCB2YWx1ZScpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUUmVjb3JkUmlnaHQobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgY29uc3QgS2V5ID0gUmVjb3JkS2V5KHJpZ2h0KTtcbiAgICAgICAgY29uc3QgVmFsdWUgPSBSZWNvcmRWYWx1ZShyaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVExpdGVyYWxTdHJpbmcobGVmdCkgJiYgVHlwZUd1YXJkLlROdW1iZXIoS2V5KSAmJiBJbnRvQm9vbGVhblJlc3VsdChWaXNpdChsZWZ0LCBWYWx1ZSkpID09PSBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFVpbnQ4QXJyYXkobGVmdCkgJiYgVHlwZUd1YXJkLlROdW1iZXIoS2V5KSlcbiAgICAgICAgICAgIHJldHVybiBWaXNpdChsZWZ0LCBWYWx1ZSk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFN0cmluZyhsZWZ0KSAmJiBUeXBlR3VhcmQuVE51bWJlcihLZXkpKVxuICAgICAgICAgICAgcmV0dXJuIFZpc2l0KGxlZnQsIFZhbHVlKTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UQXJyYXkobGVmdCkgJiYgVHlwZUd1YXJkLlROdW1iZXIoS2V5KSlcbiAgICAgICAgICAgIHJldHVybiBWaXNpdChsZWZ0LCBWYWx1ZSk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9iamVjdChsZWZ0KSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMobGVmdC5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgICAgIGlmIChQcm9wZXJ0eShWYWx1ZSwgbGVmdC5wcm9wZXJ0aWVzW2tleV0pID09PSBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUUmVjb3JkKGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGNvbnN0IFZhbHVlID0gUmVjb3JkVmFsdWUobGVmdCk7XG4gICAgICAgIGlmIChJc1N0cnVjdHVyYWxSaWdodChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gU3RydWN0dXJhbFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UT2JqZWN0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUT2JqZWN0UmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoIVR5cGVHdWFyZC5UUmVjb3JkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgcmV0dXJuIFZpc2l0KFZhbHVlLCBSZWNvcmRWYWx1ZShyaWdodCkpO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFN0cmluZ1xuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gVFN0cmluZ1JpZ2h0KGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVExpdGVyYWwobGVmdCkgJiYgVmFsdWVHdWFyZC5Jc1N0cmluZyhsZWZ0LmNvbnN0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlRTdHJpbmcobGVmdCkgPyBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlIDogVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFRTdHJpbmcobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKElzU3RydWN0dXJhbFJpZ2h0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBTdHJ1Y3R1cmFsUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRPYmplY3QocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRPYmplY3RSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFJlY29yZChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVFJlY29yZFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgcmV0dXJuIFR5cGVHdWFyZC5UU3RyaW5nKHJpZ2h0KSA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBTeW1ib2xcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGZ1bmN0aW9uIFRTeW1ib2wobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKElzU3RydWN0dXJhbFJpZ2h0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBTdHJ1Y3R1cmFsUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRPYmplY3QocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRPYmplY3RSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFJlY29yZChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVFJlY29yZFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgcmV0dXJuIFR5cGVHdWFyZC5UU3ltYm9sKHJpZ2h0KSA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUZW1wbGF0ZUxpdGVyYWxcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGZ1bmN0aW9uIFRUZW1wbGF0ZUxpdGVyYWwobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgLy8gVGVtcGxhdGVMaXRlcmFsIHR5cGVzIGFyZSByZXNvbHZlZCB0byBlaXRoZXIgdW5pb25zIGZvciBmaW5pdGUgZXhwcmVzc2lvbnMgb3Igc3RyaW5nXG4gICAgICAgIC8vIGZvciBpbmZpbml0ZSBleHByZXNzaW9ucy4gSGVyZSB3ZSBjYWxsIHRvIFRlbXBsYXRlTGl0ZXJhbFJlc29sdmVyIHRvIHJlc29sdmUgZm9yXG4gICAgICAgIC8vIGVpdGhlciB0eXBlIGFuZCBjb250aW51ZSBldmFsdWF0aW5nLlxuICAgICAgICBpZiAoVHlwZUd1YXJkLlRUZW1wbGF0ZUxpdGVyYWwobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVmlzaXQoVGVtcGxhdGVMaXRlcmFsUmVzb2x2ZXIuUmVzb2x2ZShsZWZ0KSwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRUZW1wbGF0ZUxpdGVyYWwocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFZpc2l0KGxlZnQsIFRlbXBsYXRlTGl0ZXJhbFJlc29sdmVyLlJlc29sdmUocmlnaHQpKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUeXBlRXh0ZW5kczogSW52YWxpZCBmYWxsdGhyb3VnaCBmb3IgVGVtcGxhdGVMaXRlcmFsYCk7XG4gICAgfVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gVHVwbGVcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGZ1bmN0aW9uIElzQXJyYXlPZlR1cGxlKGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gKFR5cGVHdWFyZC5UQXJyYXkocmlnaHQpICYmXG4gICAgICAgICAgICBsZWZ0Lml0ZW1zICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgIGxlZnQuaXRlbXMuZXZlcnkoKHNjaGVtYSkgPT4gVmlzaXQoc2NoZW1hLCByaWdodC5pdGVtcykgPT09IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUpKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gVFR1cGxlUmlnaHQobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UTmV2ZXIobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVW5rbm93bihsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UQW55KGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlVuaW9uO1xuICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFRUdXBsZShsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoSXNTdHJ1Y3R1cmFsUmlnaHQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFN0cnVjdHVyYWxSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9iamVjdChyaWdodCkgJiYgSXNPYmplY3RBcnJheUxpa2UocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVEFycmF5KHJpZ2h0KSAmJiBJc0FycmF5T2ZUdXBsZShsZWZ0LCByaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTtcbiAgICAgICAgaWYgKCFUeXBlR3VhcmQuVFR1cGxlKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgaWYgKChWYWx1ZUd1YXJkLklzVW5kZWZpbmVkKGxlZnQuaXRlbXMpICYmICFWYWx1ZUd1YXJkLklzVW5kZWZpbmVkKHJpZ2h0Lml0ZW1zKSkgfHwgKCFWYWx1ZUd1YXJkLklzVW5kZWZpbmVkKGxlZnQuaXRlbXMpICYmIFZhbHVlR3VhcmQuSXNVbmRlZmluZWQocmlnaHQuaXRlbXMpKSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICAgICAgaWYgKFZhbHVlR3VhcmQuSXNVbmRlZmluZWQobGVmdC5pdGVtcykgJiYgIVZhbHVlR3VhcmQuSXNVbmRlZmluZWQocmlnaHQuaXRlbXMpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIHJldHVybiBsZWZ0Lml0ZW1zLmV2ZXJ5KChzY2hlbWEsIGluZGV4KSA9PiBWaXNpdChzY2hlbWEsIHJpZ2h0Lml0ZW1zW2luZGV4XSkgPT09IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFVpbnQ4QXJyYXlcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGZ1bmN0aW9uIFRVaW50OEFycmF5KGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIGlmIChJc1N0cnVjdHVyYWxSaWdodChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gU3RydWN0dXJhbFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UT2JqZWN0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUT2JqZWN0UmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRSZWNvcmQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRSZWNvcmRSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIHJldHVybiBUeXBlR3VhcmQuVFVpbnQ4QXJyYXkocmlnaHQpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFVuZGVmaW5lZFxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnVuY3Rpb24gVFVuZGVmaW5lZChsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoSXNTdHJ1Y3R1cmFsUmlnaHQocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFN0cnVjdHVyYWxSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE9iamVjdChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE9iamVjdFJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UUmVjb3JkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUUmVjb3JkUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRWb2lkKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBWb2lkUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlRVbmRlZmluZWQocmlnaHQpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFVuaW9uXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBUVW5pb25SaWdodChsZWZ0LCByaWdodCkge1xuICAgICAgICByZXR1cm4gcmlnaHQuYW55T2Yuc29tZSgoc2NoZW1hKSA9PiBWaXNpdChsZWZ0LCBzY2hlbWEpID09PSBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlKSA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gVFVuaW9uKGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIHJldHVybiBsZWZ0LmFueU9mLmV2ZXJ5KChzY2hlbWEpID0+IFZpc2l0KHNjaGVtYSwgcmlnaHQpID09PSBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlKSA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBVbmtub3duXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBUVW5rbm93blJpZ2h0KGxlZnQsIHJpZ2h0KSB7XG4gICAgICAgIHJldHVybiBUeXBlRXh0ZW5kc1Jlc3VsdC5UcnVlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUVW5rbm93bihsZWZ0LCByaWdodCkge1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlROZXZlcihyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE5ldmVyUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRJbnRlcnNlY3QocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRJbnRlcnNlY3RSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFVuaW9uKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUVW5pb25SaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVEFueShyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVEFueVJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UU3RyaW5nKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUU3RyaW5nUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlROdW1iZXIocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFROdW1iZXJSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVEludGVnZXIocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRJbnRlZ2VyUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRCb29sZWFuKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUQm9vbGVhblJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UQXJyYXkocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRBcnJheVJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVHVwbGUocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRUdXBsZVJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UT2JqZWN0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUT2JqZWN0UmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICByZXR1cm4gVHlwZUd1YXJkLlRVbmtub3duKHJpZ2h0KSA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBWb2lkXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmdW5jdGlvbiBWb2lkUmlnaHQobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVW5kZWZpbmVkKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFR5cGVFeHRlbmRzUmVzdWx0LlRydWU7XG4gICAgICAgIHJldHVybiBUeXBlR3VhcmQuVFVuZGVmaW5lZChsZWZ0KSA/IFR5cGVFeHRlbmRzUmVzdWx0LlRydWUgOiBUeXBlRXh0ZW5kc1Jlc3VsdC5GYWxzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gVFZvaWQobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5USW50ZXJzZWN0KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUSW50ZXJzZWN0UmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRVbmlvbihyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVFVuaW9uUmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRVbmtub3duKHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUVW5rbm93blJpZ2h0KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UQW55KHJpZ2h0KSlcbiAgICAgICAgICAgIHJldHVybiBUQW55UmlnaHQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRPYmplY3QocmlnaHQpKVxuICAgICAgICAgICAgcmV0dXJuIFRPYmplY3RSaWdodChsZWZ0LCByaWdodCk7XG4gICAgICAgIHJldHVybiBUeXBlR3VhcmQuVFZvaWQocmlnaHQpID8gVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZSA6IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBWaXNpdChsZWZ0LCByaWdodCkge1xuICAgICAgICAvLyBSZXNvbHZhYmxlIFR5cGVzXG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFRlbXBsYXRlTGl0ZXJhbChsZWZ0KSB8fCBUeXBlR3VhcmQuVFRlbXBsYXRlTGl0ZXJhbChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVFRlbXBsYXRlTGl0ZXJhbChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE5vdChsZWZ0KSB8fCBUeXBlR3VhcmQuVE5vdChyaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gVE5vdChsZWZ0LCByaWdodCk7XG4gICAgICAgIC8vIFN0YW5kYXJkIFR5cGVzXG4gICAgICAgIGlmIChUeXBlR3VhcmQuVEFueShsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUQW55KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UQXJyYXkobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVEFycmF5KGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UQmlnSW50KGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFRCaWdJbnQobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRCb29sZWFuKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFRCb29sZWFuKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UQXN5bmNJdGVyYXRvcihsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUQXN5bmNJdGVyYXRvcihsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVENvbnN0cnVjdG9yKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFRDb25zdHJ1Y3RvcihsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVERhdGUobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVERhdGUobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRGdW5jdGlvbihsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBURnVuY3Rpb24obGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRJbnRlZ2VyKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFRJbnRlZ2VyKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5USW50ZXJzZWN0KGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFRJbnRlcnNlY3QobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRJdGVyYXRvcihsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUSXRlcmF0b3IobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRMaXRlcmFsKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFRMaXRlcmFsKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UTmV2ZXIobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVE5ldmVyKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UTnVsbChsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUTnVsbChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVE51bWJlcihsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUTnVtYmVyKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UT2JqZWN0KGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFRPYmplY3QobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRSZWNvcmQobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVFJlY29yZChsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFN0cmluZyhsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUU3RyaW5nKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UU3ltYm9sKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFRTeW1ib2wobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRUdXBsZShsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUVHVwbGUobGVmdCwgcmlnaHQpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRQcm9taXNlKGxlZnQpKVxuICAgICAgICAgICAgcmV0dXJuIFRQcm9taXNlKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVWludDhBcnJheShsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUVWludDhBcnJheShsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFVuZGVmaW5lZChsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUVW5kZWZpbmVkKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVW5pb24obGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVFVuaW9uKGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVW5rbm93bihsZWZ0KSlcbiAgICAgICAgICAgIHJldHVybiBUVW5rbm93bihsZWZ0LCByaWdodCk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFZvaWQobGVmdCkpXG4gICAgICAgICAgICByZXR1cm4gVFZvaWQobGVmdCwgcmlnaHQpO1xuICAgICAgICB0aHJvdyBFcnJvcihgVHlwZUV4dGVuZHM6IFVua25vd24gbGVmdCB0eXBlIG9wZXJhbmQgJyR7bGVmdFtleHBvcnRzLktpbmRdfSdgKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gRXh0ZW5kcyhsZWZ0LCByaWdodCkge1xuICAgICAgICByZXR1cm4gVmlzaXQobGVmdCwgcmlnaHQpO1xuICAgIH1cbiAgICBUeXBlRXh0ZW5kcy5FeHRlbmRzID0gRXh0ZW5kcztcbn0pKFR5cGVFeHRlbmRzIHx8IChleHBvcnRzLlR5cGVFeHRlbmRzID0gVHlwZUV4dGVuZHMgPSB7fSkpO1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFR5cGVDbG9uZVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKiBTcGVjaWFsaXplZCBDbG9uZSBmb3IgVHlwZXMgKi9cbnZhciBUeXBlQ2xvbmU7XG4oZnVuY3Rpb24gKFR5cGVDbG9uZSkge1xuICAgIGZ1bmN0aW9uIE9iamVjdFR5cGUodmFsdWUpIHtcbiAgICAgICAgY29uc3QgY2xvbmVkUHJvcGVydGllcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHZhbHVlKS5yZWR1Y2UoKGFjYywga2V5KSA9PiAoeyAuLi5hY2MsIFtrZXldOiBWaXNpdCh2YWx1ZVtrZXldKSB9KSwge30pO1xuICAgICAgICBjb25zdCBjbG9uZWRTeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyh2YWx1ZSkucmVkdWNlKChhY2MsIGtleSkgPT4gKHsgLi4uYWNjLCBba2V5XTogVmlzaXQodmFsdWVba2V5XSkgfSksIHt9KTtcbiAgICAgICAgcmV0dXJuIHsgLi4uY2xvbmVkUHJvcGVydGllcywgLi4uY2xvbmVkU3ltYm9scyB9O1xuICAgIH1cbiAgICBmdW5jdGlvbiBBcnJheVR5cGUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlLm1hcCgodmFsdWUpID0+IFZpc2l0KHZhbHVlKSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFZpc2l0KHZhbHVlKSB7XG4gICAgICAgIGlmIChWYWx1ZUd1YXJkLklzQXJyYXkodmFsdWUpKVxuICAgICAgICAgICAgcmV0dXJuIEFycmF5VHlwZSh2YWx1ZSk7XG4gICAgICAgIGlmIChWYWx1ZUd1YXJkLklzT2JqZWN0KHZhbHVlKSlcbiAgICAgICAgICAgIHJldHVybiBPYmplY3RUeXBlKHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICAvKiogQ2xvbmVzIGEgdHlwZS4gKi9cbiAgICBmdW5jdGlvbiBDbG9uZShzY2hlbWEsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4geyAuLi5WaXNpdChzY2hlbWEpLCAuLi5vcHRpb25zIH07XG4gICAgfVxuICAgIFR5cGVDbG9uZS5DbG9uZSA9IENsb25lO1xufSkoVHlwZUNsb25lIHx8IChleHBvcnRzLlR5cGVDbG9uZSA9IFR5cGVDbG9uZSA9IHt9KSk7XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gSW5kZXhlZEFjY2Vzc29yXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxudmFyIEluZGV4ZWRBY2Nlc3NvcjtcbihmdW5jdGlvbiAoSW5kZXhlZEFjY2Vzc29yKSB7XG4gICAgZnVuY3Rpb24gT3B0aW9uYWxVbndyYXAoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBzY2hlbWEubWFwKChzY2hlbWEpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgW2V4cG9ydHMuT3B0aW9uYWxdOiBfLCAuLi5jbG9uZSB9ID0gVHlwZUNsb25lLkNsb25lKHNjaGVtYSk7XG4gICAgICAgICAgICByZXR1cm4gY2xvbmU7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBJc0ludGVyc2VjdE9wdGlvbmFsKHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gc2NoZW1hLmV2ZXJ5KChzY2hlbWEpID0+IFR5cGVHdWFyZC5UT3B0aW9uYWwoc2NoZW1hKSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzVW5pb25PcHRpb25hbChzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYS5zb21lKChzY2hlbWEpID0+IFR5cGVHdWFyZC5UT3B0aW9uYWwoc2NoZW1hKSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFJlc29sdmVJbnRlcnNlY3Qoc2NoZW1hKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbmFsID0gSXNJbnRlcnNlY3RPcHRpb25hbChzY2hlbWEuYWxsT2YpO1xuICAgICAgICByZXR1cm4gb3B0aW9uYWwgPyBleHBvcnRzLlR5cGUuT3B0aW9uYWwoZXhwb3J0cy5UeXBlLkludGVyc2VjdChPcHRpb25hbFVud3JhcChzY2hlbWEuYWxsT2YpKSkgOiBzY2hlbWE7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFJlc29sdmVVbmlvbihzY2hlbWEpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uYWwgPSBJc1VuaW9uT3B0aW9uYWwoc2NoZW1hLmFueU9mKTtcbiAgICAgICAgcmV0dXJuIG9wdGlvbmFsID8gZXhwb3J0cy5UeXBlLk9wdGlvbmFsKGV4cG9ydHMuVHlwZS5VbmlvbihPcHRpb25hbFVud3JhcChzY2hlbWEuYW55T2YpKSkgOiBzY2hlbWE7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFJlc29sdmVPcHRpb25hbChzY2hlbWEpIHtcbiAgICAgICAgaWYgKHNjaGVtYVtleHBvcnRzLktpbmRdID09PSAnSW50ZXJzZWN0JylcbiAgICAgICAgICAgIHJldHVybiBSZXNvbHZlSW50ZXJzZWN0KHNjaGVtYSk7XG4gICAgICAgIGlmIChzY2hlbWFbZXhwb3J0cy5LaW5kXSA9PT0gJ1VuaW9uJylcbiAgICAgICAgICAgIHJldHVybiBSZXNvbHZlVW5pb24oc2NoZW1hKTtcbiAgICAgICAgcmV0dXJuIHNjaGVtYTtcbiAgICB9XG4gICAgZnVuY3Rpb24gVEludGVyc2VjdChzY2hlbWEsIGtleSkge1xuICAgICAgICBjb25zdCByZXNvbHZlZCA9IHNjaGVtYS5hbGxPZi5yZWR1Y2UoKGFjYywgc2NoZW1hKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbmRleGVkID0gVmlzaXQoc2NoZW1hLCBrZXkpO1xuICAgICAgICAgICAgcmV0dXJuIGluZGV4ZWRbZXhwb3J0cy5LaW5kXSA9PT0gJ05ldmVyJyA/IGFjYyA6IFsuLi5hY2MsIGluZGV4ZWRdO1xuICAgICAgICB9LCBbXSk7XG4gICAgICAgIHJldHVybiBSZXNvbHZlT3B0aW9uYWwoZXhwb3J0cy5UeXBlLkludGVyc2VjdChyZXNvbHZlZCkpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUVW5pb24oc2NoZW1hLCBrZXkpIHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZWQgPSBzY2hlbWEuYW55T2YubWFwKChzY2hlbWEpID0+IFZpc2l0KHNjaGVtYSwga2V5KSk7XG4gICAgICAgIHJldHVybiBSZXNvbHZlT3B0aW9uYWwoZXhwb3J0cy5UeXBlLlVuaW9uKHJlc29sdmVkKSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFRPYmplY3Qoc2NoZW1hLCBrZXkpIHtcbiAgICAgICAgY29uc3QgcHJvcGVydHkgPSBzY2hlbWEucHJvcGVydGllc1trZXldO1xuICAgICAgICByZXR1cm4gVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZChwcm9wZXJ0eSkgPyBleHBvcnRzLlR5cGUuTmV2ZXIoKSA6IGV4cG9ydHMuVHlwZS5VbmlvbihbcHJvcGVydHldKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gVFR1cGxlKHNjaGVtYSwga2V5KSB7XG4gICAgICAgIGNvbnN0IGl0ZW1zID0gc2NoZW1hLml0ZW1zO1xuICAgICAgICBpZiAoVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZChpdGVtcykpXG4gICAgICAgICAgICByZXR1cm4gZXhwb3J0cy5UeXBlLk5ldmVyKCk7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBpdGVtc1trZXldOyAvL1xuICAgICAgICBpZiAoVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZChlbGVtZW50KSlcbiAgICAgICAgICAgIHJldHVybiBleHBvcnRzLlR5cGUuTmV2ZXIoKTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFZpc2l0KHNjaGVtYSwga2V5KSB7XG4gICAgICAgIGlmIChzY2hlbWFbZXhwb3J0cy5LaW5kXSA9PT0gJ0ludGVyc2VjdCcpXG4gICAgICAgICAgICByZXR1cm4gVEludGVyc2VjdChzY2hlbWEsIGtleSk7XG4gICAgICAgIGlmIChzY2hlbWFbZXhwb3J0cy5LaW5kXSA9PT0gJ1VuaW9uJylcbiAgICAgICAgICAgIHJldHVybiBUVW5pb24oc2NoZW1hLCBrZXkpO1xuICAgICAgICBpZiAoc2NoZW1hW2V4cG9ydHMuS2luZF0gPT09ICdPYmplY3QnKVxuICAgICAgICAgICAgcmV0dXJuIFRPYmplY3Qoc2NoZW1hLCBrZXkpO1xuICAgICAgICBpZiAoc2NoZW1hW2V4cG9ydHMuS2luZF0gPT09ICdUdXBsZScpXG4gICAgICAgICAgICByZXR1cm4gVFR1cGxlKHNjaGVtYSwga2V5KTtcbiAgICAgICAgcmV0dXJuIGV4cG9ydHMuVHlwZS5OZXZlcigpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBSZXNvbHZlKHNjaGVtYSwga2V5cywgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkID0ga2V5cy5tYXAoKGtleSkgPT4gVmlzaXQoc2NoZW1hLCBrZXkudG9TdHJpbmcoKSkpO1xuICAgICAgICByZXR1cm4gUmVzb2x2ZU9wdGlvbmFsKGV4cG9ydHMuVHlwZS5VbmlvbihyZXNvbHZlZCwgb3B0aW9ucykpO1xuICAgIH1cbiAgICBJbmRleGVkQWNjZXNzb3IuUmVzb2x2ZSA9IFJlc29sdmU7XG59KShJbmRleGVkQWNjZXNzb3IgfHwgKGV4cG9ydHMuSW5kZXhlZEFjY2Vzc29yID0gSW5kZXhlZEFjY2Vzc29yID0ge30pKTtcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBJbnRyaW5zaWNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgSW50cmluc2ljO1xuKGZ1bmN0aW9uIChJbnRyaW5zaWMpIHtcbiAgICBmdW5jdGlvbiBVbmNhcGl0YWxpemUodmFsdWUpIHtcbiAgICAgICAgY29uc3QgW2ZpcnN0LCByZXN0XSA9IFt2YWx1ZS5zbGljZSgwLCAxKSwgdmFsdWUuc2xpY2UoMSldO1xuICAgICAgICByZXR1cm4gYCR7Zmlyc3QudG9Mb3dlckNhc2UoKX0ke3Jlc3R9YDtcbiAgICB9XG4gICAgZnVuY3Rpb24gQ2FwaXRhbGl6ZSh2YWx1ZSkge1xuICAgICAgICBjb25zdCBbZmlyc3QsIHJlc3RdID0gW3ZhbHVlLnNsaWNlKDAsIDEpLCB2YWx1ZS5zbGljZSgxKV07XG4gICAgICAgIHJldHVybiBgJHtmaXJzdC50b1VwcGVyQ2FzZSgpfSR7cmVzdH1gO1xuICAgIH1cbiAgICBmdW5jdGlvbiBVcHBlcmNhc2UodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIExvd2VyY2FzZSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUudG9Mb3dlckNhc2UoKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSW50cmluc2ljVGVtcGxhdGVMaXRlcmFsKHNjaGVtYSwgbW9kZSkge1xuICAgICAgICAvLyBub3RlOiB0ZW1wbGF0ZSBsaXRlcmFscyByZXF1aXJlIHNwZWNpYWwgcnVudGltZSBoYW5kbGluZyBhcyB0aGV5IGFyZSBlbmNvZGVkIGluIHN0cmluZyBwYXR0ZXJucy5cbiAgICAgICAgLy8gVGhpcyBkaXZlcmdlcyBmcm9tIHRoZSBtYXBwZWQgdHlwZSB3aGljaCB3b3VsZCBvdGhlcndpc2UgbWFwIG9uIHRoZSB0ZW1wbGF0ZSBsaXRlcmFsIGtpbmQuXG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBUZW1wbGF0ZUxpdGVyYWxQYXJzZXIuUGFyc2VFeGFjdChzY2hlbWEucGF0dGVybik7XG4gICAgICAgIGNvbnN0IGZpbml0ZSA9IFRlbXBsYXRlTGl0ZXJhbEZpbml0ZS5DaGVjayhleHByZXNzaW9uKTtcbiAgICAgICAgaWYgKCFmaW5pdGUpXG4gICAgICAgICAgICByZXR1cm4geyAuLi5zY2hlbWEsIHBhdHRlcm46IEludHJpbnNpY0xpdGVyYWwoc2NoZW1hLnBhdHRlcm4sIG1vZGUpIH07XG4gICAgICAgIGNvbnN0IHN0cmluZ3MgPSBbLi4uVGVtcGxhdGVMaXRlcmFsR2VuZXJhdG9yLkdlbmVyYXRlKGV4cHJlc3Npb24pXTtcbiAgICAgICAgY29uc3QgbGl0ZXJhbHMgPSBzdHJpbmdzLm1hcCgodmFsdWUpID0+IGV4cG9ydHMuVHlwZS5MaXRlcmFsKHZhbHVlKSk7XG4gICAgICAgIGNvbnN0IG1hcHBlZCA9IEludHJpbnNpY1Jlc3QobGl0ZXJhbHMsIG1vZGUpO1xuICAgICAgICBjb25zdCB1bmlvbiA9IGV4cG9ydHMuVHlwZS5VbmlvbihtYXBwZWQpO1xuICAgICAgICByZXR1cm4gZXhwb3J0cy5UeXBlLlRlbXBsYXRlTGl0ZXJhbChbdW5pb25dKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSW50cmluc2ljTGl0ZXJhbCh2YWx1ZSwgbW9kZSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyAobW9kZSA9PT0gJ1VuY2FwaXRhbGl6ZScgPyBVbmNhcGl0YWxpemUodmFsdWUpIDpcbiAgICAgICAgICAgIG1vZGUgPT09ICdDYXBpdGFsaXplJyA/IENhcGl0YWxpemUodmFsdWUpIDpcbiAgICAgICAgICAgICAgICBtb2RlID09PSAnVXBwZXJjYXNlJyA/IFVwcGVyY2FzZSh2YWx1ZSkgOlxuICAgICAgICAgICAgICAgICAgICBtb2RlID09PSAnTG93ZXJjYXNlJyA/IExvd2VyY2FzZSh2YWx1ZSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUpIDogdmFsdWUudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSW50cmluc2ljUmVzdChzY2hlbWEsIG1vZGUpIHtcbiAgICAgICAgaWYgKHNjaGVtYS5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIGNvbnN0IFtMLCAuLi5SXSA9IHNjaGVtYTtcbiAgICAgICAgcmV0dXJuIFtNYXAoTCwgbW9kZSksIC4uLkludHJpbnNpY1Jlc3QoUiwgbW9kZSldO1xuICAgIH1cbiAgICBmdW5jdGlvbiBWaXNpdChzY2hlbWEsIG1vZGUpIHtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVGVtcGxhdGVMaXRlcmFsKHNjaGVtYSkpXG4gICAgICAgICAgICByZXR1cm4gSW50cmluc2ljVGVtcGxhdGVMaXRlcmFsKHNjaGVtYSwgbW9kZSk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFVuaW9uKHNjaGVtYSkpXG4gICAgICAgICAgICByZXR1cm4gZXhwb3J0cy5UeXBlLlVuaW9uKEludHJpbnNpY1Jlc3Qoc2NoZW1hLmFueU9mLCBtb2RlKSk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVExpdGVyYWwoc2NoZW1hKSlcbiAgICAgICAgICAgIHJldHVybiBleHBvcnRzLlR5cGUuTGl0ZXJhbChJbnRyaW5zaWNMaXRlcmFsKHNjaGVtYS5jb25zdCwgbW9kZSkpO1xuICAgICAgICByZXR1cm4gc2NoZW1hO1xuICAgIH1cbiAgICAvKiogQXBwbGllcyBhbiBpbnRyaW5zaWMgc3RyaW5nIG1hbmlwdWxhdGlvbiB0byB0aGUgZ2l2ZW4gdHlwZS4gKi9cbiAgICBmdW5jdGlvbiBNYXAoc2NoZW1hLCBtb2RlKSB7XG4gICAgICAgIHJldHVybiBWaXNpdChzY2hlbWEsIG1vZGUpO1xuICAgIH1cbiAgICBJbnRyaW5zaWMuTWFwID0gTWFwO1xufSkoSW50cmluc2ljIHx8IChleHBvcnRzLkludHJpbnNpYyA9IEludHJpbnNpYyA9IHt9KSk7XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gT2JqZWN0TWFwXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxudmFyIE9iamVjdE1hcDtcbihmdW5jdGlvbiAoT2JqZWN0TWFwKSB7XG4gICAgZnVuY3Rpb24gVEludGVyc2VjdChzY2hlbWEsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gZXhwb3J0cy5UeXBlLkludGVyc2VjdChzY2hlbWEuYWxsT2YubWFwKChpbm5lcikgPT4gVmlzaXQoaW5uZXIsIGNhbGxiYWNrKSksIHsgLi4uc2NoZW1hIH0pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUVW5pb24oc2NoZW1hLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIGV4cG9ydHMuVHlwZS5VbmlvbihzY2hlbWEuYW55T2YubWFwKChpbm5lcikgPT4gVmlzaXQoaW5uZXIsIGNhbGxiYWNrKSksIHsgLi4uc2NoZW1hIH0pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBUT2JqZWN0KHNjaGVtYSwgY2FsbGJhY2spIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHNjaGVtYSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFZpc2l0KHNjaGVtYSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gVGhlcmUgYXJlIGNhc2VzIHdoZXJlIHVzZXJzIG5lZWQgdG8gbWFwIG9iamVjdHMgd2l0aCB1bnJlZ2lzdGVyZWQga2luZHMuIFVzaW5nIGEgVHlwZUd1YXJkIGhlcmUgd291bGRcbiAgICAgICAgLy8gcHJldmVudCBzdWIgc2NoZW1hIG1hcHBpbmcgYXMgdW5yZWdpc3RlcmVkIGtpbmRzIHdpbGwgbm90IHBhc3MgVFNjaGVtYSBjaGVja3MuIFRoaXMgaXMgbm90YWJsZSBpbiB0aGVcbiAgICAgICAgLy8gY2FzZSBvZiBUT2JqZWN0IHdoZXJlIHVucmVnaXN0ZXJlZCBwcm9wZXJ0eSBraW5kcyBjYXVzZSB0aGUgVE9iamVjdCBjaGVjayB0byBmYWlsLiBBcyBtYXBwaW5nIGlzIG9ubHlcbiAgICAgICAgLy8gdXNlZCBmb3IgY29tcG9zaXRpb24sIHdlIHVzZSBleHBsaWNpdCBjaGVja3MgaW5zdGVhZC5cbiAgICAgICAgaWYgKHNjaGVtYVtleHBvcnRzLktpbmRdID09PSAnSW50ZXJzZWN0JylcbiAgICAgICAgICAgIHJldHVybiBUSW50ZXJzZWN0KHNjaGVtYSwgY2FsbGJhY2spO1xuICAgICAgICBpZiAoc2NoZW1hW2V4cG9ydHMuS2luZF0gPT09ICdVbmlvbicpXG4gICAgICAgICAgICByZXR1cm4gVFVuaW9uKHNjaGVtYSwgY2FsbGJhY2spO1xuICAgICAgICBpZiAoc2NoZW1hW2V4cG9ydHMuS2luZF0gPT09ICdPYmplY3QnKVxuICAgICAgICAgICAgcmV0dXJuIFRPYmplY3Qoc2NoZW1hLCBjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiBzY2hlbWE7XG4gICAgfVxuICAgIGZ1bmN0aW9uIE1hcChzY2hlbWEsIGNhbGxiYWNrLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB7IC4uLlZpc2l0KFR5cGVDbG9uZS5DbG9uZShzY2hlbWEpLCBjYWxsYmFjayksIC4uLm9wdGlvbnMgfTtcbiAgICB9XG4gICAgT2JqZWN0TWFwLk1hcCA9IE1hcDtcbn0pKE9iamVjdE1hcCB8fCAoZXhwb3J0cy5PYmplY3RNYXAgPSBPYmplY3RNYXAgPSB7fSkpO1xudmFyIEtleVJlc29sdmVyO1xuKGZ1bmN0aW9uIChLZXlSZXNvbHZlcikge1xuICAgIGZ1bmN0aW9uIFVud3JhcFBhdHRlcm4oa2V5KSB7XG4gICAgICAgIHJldHVybiBrZXlbMF0gPT09ICdeJyAmJiBrZXlba2V5Lmxlbmd0aCAtIDFdID09PSAnJCcgPyBrZXkuc2xpY2UoMSwga2V5Lmxlbmd0aCAtIDEpIDoga2V5O1xuICAgIH1cbiAgICBmdW5jdGlvbiBUSW50ZXJzZWN0KHNjaGVtYSwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gc2NoZW1hLmFsbE9mLnJlZHVjZSgoYWNjLCBzY2hlbWEpID0+IFsuLi5hY2MsIC4uLlZpc2l0KHNjaGVtYSwgb3B0aW9ucyldLCBbXSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFRVbmlvbihzY2hlbWEsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3Qgc2V0cyA9IHNjaGVtYS5hbnlPZi5tYXAoKGlubmVyKSA9PiBWaXNpdChpbm5lciwgb3B0aW9ucykpO1xuICAgICAgICByZXR1cm4gWy4uLnNldHMucmVkdWNlKChzZXQsIG91dGVyKSA9PiBvdXRlci5tYXAoKGtleSkgPT4gKHNldHMuZXZlcnkoKGlubmVyKSA9PiBpbm5lci5pbmNsdWRlcyhrZXkpKSA/IHNldC5hZGQoa2V5KSA6IHNldCkpWzBdLCBuZXcgU2V0KCkpXTtcbiAgICB9XG4gICAgZnVuY3Rpb24gVE9iamVjdChzY2hlbWEsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHNjaGVtYS5wcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gVFJlY29yZChzY2hlbWEsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuaW5jbHVkZVBhdHRlcm5zID8gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoc2NoZW1hLnBhdHRlcm5Qcm9wZXJ0aWVzKSA6IFtdO1xuICAgIH1cbiAgICBmdW5jdGlvbiBWaXNpdChzY2hlbWEsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5USW50ZXJzZWN0KHNjaGVtYSkpXG4gICAgICAgICAgICByZXR1cm4gVEludGVyc2VjdChzY2hlbWEsIG9wdGlvbnMpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRVbmlvbihzY2hlbWEpKVxuICAgICAgICAgICAgcmV0dXJuIFRVbmlvbihzY2hlbWEsIG9wdGlvbnMpO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRPYmplY3Qoc2NoZW1hKSlcbiAgICAgICAgICAgIHJldHVybiBUT2JqZWN0KHNjaGVtYSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFJlY29yZChzY2hlbWEpKVxuICAgICAgICAgICAgcmV0dXJuIFRSZWNvcmQoc2NoZW1hLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICAvKiogUmVzb2x2ZXMgYW4gYXJyYXkgb2Yga2V5cyBpbiB0aGlzIHNjaGVtYSAqL1xuICAgIGZ1bmN0aW9uIFJlc29sdmVLZXlzKHNjaGVtYSwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gWy4uLm5ldyBTZXQoVmlzaXQoc2NoZW1hLCBvcHRpb25zKSldO1xuICAgIH1cbiAgICBLZXlSZXNvbHZlci5SZXNvbHZlS2V5cyA9IFJlc29sdmVLZXlzO1xuICAgIC8qKiBSZXNvbHZlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuIG1hdGNoaW5nIGFsbCBrZXlzIGluIHRoaXMgc2NoZW1hICovXG4gICAgZnVuY3Rpb24gUmVzb2x2ZVBhdHRlcm4oc2NoZW1hKSB7XG4gICAgICAgIGNvbnN0IGtleXMgPSBSZXNvbHZlS2V5cyhzY2hlbWEsIHsgaW5jbHVkZVBhdHRlcm5zOiB0cnVlIH0pO1xuICAgICAgICBjb25zdCBwYXR0ZXJuID0ga2V5cy5tYXAoKGtleSkgPT4gYCgke1Vud3JhcFBhdHRlcm4oa2V5KX0pYCk7XG4gICAgICAgIHJldHVybiBgXigke3BhdHRlcm4uam9pbignfCcpfSkkYDtcbiAgICB9XG4gICAgS2V5UmVzb2x2ZXIuUmVzb2x2ZVBhdHRlcm4gPSBSZXNvbHZlUGF0dGVybjtcbn0pKEtleVJlc29sdmVyIHx8IChleHBvcnRzLktleVJlc29sdmVyID0gS2V5UmVzb2x2ZXIgPSB7fSkpO1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEtleUFycmF5UmVzb2x2ZXJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgS2V5QXJyYXlSZXNvbHZlcjtcbihmdW5jdGlvbiAoS2V5QXJyYXlSZXNvbHZlcikge1xuICAgIC8qKiBSZXNvbHZlcyBhbiBhcnJheSBvZiBzdHJpbmdbXSBrZXlzIGZyb20gdGhlIGdpdmVuIHNjaGVtYSBvciBhcnJheSB0eXBlLiAqL1xuICAgIGZ1bmN0aW9uIFJlc29sdmUoc2NoZW1hKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHNjaGVtYSkpXG4gICAgICAgICAgICByZXR1cm4gc2NoZW1hO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRVbmlvbkxpdGVyYWwoc2NoZW1hKSlcbiAgICAgICAgICAgIHJldHVybiBzY2hlbWEuYW55T2YubWFwKChzY2hlbWEpID0+IHNjaGVtYS5jb25zdC50b1N0cmluZygpKTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UTGl0ZXJhbChzY2hlbWEpKVxuICAgICAgICAgICAgcmV0dXJuIFtzY2hlbWEuY29uc3RdO1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRUZW1wbGF0ZUxpdGVyYWwoc2NoZW1hKSkge1xuICAgICAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IFRlbXBsYXRlTGl0ZXJhbFBhcnNlci5QYXJzZUV4YWN0KHNjaGVtYS5wYXR0ZXJuKTtcbiAgICAgICAgICAgIGlmICghVGVtcGxhdGVMaXRlcmFsRmluaXRlLkNoZWNrKGV4cHJlc3Npb24pKVxuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKCdLZXlBcnJheVJlc29sdmVyOiBDYW5ub3QgcmVzb2x2ZSBrZXlzIGZyb20gaW5maW5pdGUgdGVtcGxhdGUgZXhwcmVzc2lvbicpO1xuICAgICAgICAgICAgcmV0dXJuIFsuLi5UZW1wbGF0ZUxpdGVyYWxHZW5lcmF0b3IuR2VuZXJhdGUoZXhwcmVzc2lvbildO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgS2V5QXJyYXlSZXNvbHZlci5SZXNvbHZlID0gUmVzb2x2ZTtcbn0pKEtleUFycmF5UmVzb2x2ZXIgfHwgKGV4cG9ydHMuS2V5QXJyYXlSZXNvbHZlciA9IEtleUFycmF5UmVzb2x2ZXIgPSB7fSkpO1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFVuaW9uUmVzb2x2ZXJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgVW5pb25SZXNvbHZlcjtcbihmdW5jdGlvbiAoVW5pb25SZXNvbHZlcikge1xuICAgIGZ1bmN0aW9uKiBUVW5pb24odW5pb24pIHtcbiAgICAgICAgZm9yIChjb25zdCBzY2hlbWEgb2YgdW5pb24uYW55T2YpIHtcbiAgICAgICAgICAgIGlmIChzY2hlbWFbZXhwb3J0cy5LaW5kXSA9PT0gJ1VuaW9uJykge1xuICAgICAgICAgICAgICAgIHlpZWxkKiBUVW5pb24oc2NoZW1hKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHlpZWxkIHNjaGVtYTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKiogUmV0dXJucyBhIHJlc29sdmVkIHVuaW9uIHdpdGggaW50ZXJpb3IgdW5pb25zIGZsYXR0ZW5lZCAqL1xuICAgIGZ1bmN0aW9uIFJlc29sdmUodW5pb24pIHtcbiAgICAgICAgcmV0dXJuIGV4cG9ydHMuVHlwZS5VbmlvbihbLi4uVFVuaW9uKHVuaW9uKV0sIHsgLi4udW5pb24gfSk7XG4gICAgfVxuICAgIFVuaW9uUmVzb2x2ZXIuUmVzb2x2ZSA9IFJlc29sdmU7XG59KShVbmlvblJlc29sdmVyIHx8IChleHBvcnRzLlVuaW9uUmVzb2x2ZXIgPSBVbmlvblJlc29sdmVyID0ge30pKTtcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUZW1wbGF0ZUxpdGVyYWxQYXR0ZXJuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxudmFyIFRlbXBsYXRlTGl0ZXJhbFBhdHRlcm47XG4oZnVuY3Rpb24gKFRlbXBsYXRlTGl0ZXJhbFBhdHRlcm4pIHtcbiAgICBmdW5jdGlvbiBFc2NhcGUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCAnXFxcXCQmJyk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFZpc2l0KHNjaGVtYSwgYWNjKSB7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFRlbXBsYXRlTGl0ZXJhbChzY2hlbWEpKSB7XG4gICAgICAgICAgICByZXR1cm4gc2NoZW1hLnBhdHRlcm4uc2xpY2UoMSwgc2NoZW1hLnBhdHRlcm4ubGVuZ3RoIC0gMSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoVHlwZUd1YXJkLlRVbmlvbihzY2hlbWEpKSB7XG4gICAgICAgICAgICByZXR1cm4gYCgke3NjaGVtYS5hbnlPZi5tYXAoKHNjaGVtYSkgPT4gVmlzaXQoc2NoZW1hLCBhY2MpKS5qb2luKCd8Jyl9KWA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoVHlwZUd1YXJkLlROdW1iZXIoc2NoZW1hKSkge1xuICAgICAgICAgICAgcmV0dXJuIGAke2FjY30ke2V4cG9ydHMuUGF0dGVybk51bWJlcn1gO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKFR5cGVHdWFyZC5USW50ZWdlcihzY2hlbWEpKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7YWNjfSR7ZXhwb3J0cy5QYXR0ZXJuTnVtYmVyfWA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoVHlwZUd1YXJkLlRCaWdJbnQoc2NoZW1hKSkge1xuICAgICAgICAgICAgcmV0dXJuIGAke2FjY30ke2V4cG9ydHMuUGF0dGVybk51bWJlcn1gO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKFR5cGVHdWFyZC5UU3RyaW5nKHNjaGVtYSkpIHtcbiAgICAgICAgICAgIHJldHVybiBgJHthY2N9JHtleHBvcnRzLlBhdHRlcm5TdHJpbmd9YDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChUeXBlR3VhcmQuVExpdGVyYWwoc2NoZW1hKSkge1xuICAgICAgICAgICAgcmV0dXJuIGAke2FjY30ke0VzY2FwZShzY2hlbWEuY29uc3QudG9TdHJpbmcoKSl9YDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChUeXBlR3VhcmQuVEJvb2xlYW4oc2NoZW1hKSkge1xuICAgICAgICAgICAgcmV0dXJuIGAke2FjY30ke2V4cG9ydHMuUGF0dGVybkJvb2xlYW59YDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChUeXBlR3VhcmQuVE5ldmVyKHNjaGVtYSkpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdUZW1wbGF0ZUxpdGVyYWxQYXR0ZXJuOiBUZW1wbGF0ZUxpdGVyYWwgY2Fubm90IG9wZXJhdGUgb24gdHlwZXMgb2YgVE5ldmVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihgVGVtcGxhdGVMaXRlcmFsUGF0dGVybjogVW5leHBlY3RlZCBLaW5kICcke3NjaGVtYVtleHBvcnRzLktpbmRdfSdgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBDcmVhdGUoa2luZHMpIHtcbiAgICAgICAgcmV0dXJuIGBeJHtraW5kcy5tYXAoKHNjaGVtYSkgPT4gVmlzaXQoc2NoZW1hLCAnJykpLmpvaW4oJycpfVxcJGA7XG4gICAgfVxuICAgIFRlbXBsYXRlTGl0ZXJhbFBhdHRlcm4uQ3JlYXRlID0gQ3JlYXRlO1xufSkoVGVtcGxhdGVMaXRlcmFsUGF0dGVybiB8fCAoZXhwb3J0cy5UZW1wbGF0ZUxpdGVyYWxQYXR0ZXJuID0gVGVtcGxhdGVMaXRlcmFsUGF0dGVybiA9IHt9KSk7XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVGVtcGxhdGVMaXRlcmFsUmVzb2x2ZXJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgVGVtcGxhdGVMaXRlcmFsUmVzb2x2ZXI7XG4oZnVuY3Rpb24gKFRlbXBsYXRlTGl0ZXJhbFJlc29sdmVyKSB7XG4gICAgLyoqIFJlc29sdmVzIGEgdGVtcGxhdGUgbGl0ZXJhbCBhcyBhIFRVbmlvbiAqL1xuICAgIGZ1bmN0aW9uIFJlc29sdmUodGVtcGxhdGUpIHtcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IFRlbXBsYXRlTGl0ZXJhbFBhcnNlci5QYXJzZUV4YWN0KHRlbXBsYXRlLnBhdHRlcm4pO1xuICAgICAgICBpZiAoIVRlbXBsYXRlTGl0ZXJhbEZpbml0ZS5DaGVjayhleHByZXNzaW9uKSlcbiAgICAgICAgICAgIHJldHVybiBleHBvcnRzLlR5cGUuU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGxpdGVyYWxzID0gWy4uLlRlbXBsYXRlTGl0ZXJhbEdlbmVyYXRvci5HZW5lcmF0ZShleHByZXNzaW9uKV0ubWFwKCh2YWx1ZSkgPT4gZXhwb3J0cy5UeXBlLkxpdGVyYWwodmFsdWUpKTtcbiAgICAgICAgcmV0dXJuIGV4cG9ydHMuVHlwZS5VbmlvbihsaXRlcmFscyk7XG4gICAgfVxuICAgIFRlbXBsYXRlTGl0ZXJhbFJlc29sdmVyLlJlc29sdmUgPSBSZXNvbHZlO1xufSkoVGVtcGxhdGVMaXRlcmFsUmVzb2x2ZXIgfHwgKGV4cG9ydHMuVGVtcGxhdGVMaXRlcmFsUmVzb2x2ZXIgPSBUZW1wbGF0ZUxpdGVyYWxSZXNvbHZlciA9IHt9KSk7XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVGVtcGxhdGVMaXRlcmFsUGFyc2VyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuY2xhc3MgVGVtcGxhdGVMaXRlcmFsUGFyc2VyRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB9XG59XG5leHBvcnRzLlRlbXBsYXRlTGl0ZXJhbFBhcnNlckVycm9yID0gVGVtcGxhdGVMaXRlcmFsUGFyc2VyRXJyb3I7XG52YXIgVGVtcGxhdGVMaXRlcmFsUGFyc2VyO1xuKGZ1bmN0aW9uIChUZW1wbGF0ZUxpdGVyYWxQYXJzZXIpIHtcbiAgICBmdW5jdGlvbiBJc05vbkVzY2FwZWQocGF0dGVybiwgaW5kZXgsIGNoYXIpIHtcbiAgICAgICAgcmV0dXJuIHBhdHRlcm5baW5kZXhdID09PSBjaGFyICYmIHBhdHRlcm4uY2hhckNvZGVBdChpbmRleCAtIDEpICE9PSA5MjtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNPcGVuUGFyZW4ocGF0dGVybiwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIElzTm9uRXNjYXBlZChwYXR0ZXJuLCBpbmRleCwgJygnKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNDbG9zZVBhcmVuKHBhdHRlcm4sIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBJc05vbkVzY2FwZWQocGF0dGVybiwgaW5kZXgsICcpJyk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzU2VwYXJhdG9yKHBhdHRlcm4sIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBJc05vbkVzY2FwZWQocGF0dGVybiwgaW5kZXgsICd8Jyk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzR3JvdXAocGF0dGVybikge1xuICAgICAgICBpZiAoIShJc09wZW5QYXJlbihwYXR0ZXJuLCAwKSAmJiBJc0Nsb3NlUGFyZW4ocGF0dGVybiwgcGF0dGVybi5sZW5ndGggLSAxKSkpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCBjb3VudCA9IDA7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwYXR0ZXJuLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgaWYgKElzT3BlblBhcmVuKHBhdHRlcm4sIGluZGV4KSlcbiAgICAgICAgICAgICAgICBjb3VudCArPSAxO1xuICAgICAgICAgICAgaWYgKElzQ2xvc2VQYXJlbihwYXR0ZXJuLCBpbmRleCkpXG4gICAgICAgICAgICAgICAgY291bnQgLT0gMTtcbiAgICAgICAgICAgIGlmIChjb3VudCA9PT0gMCAmJiBpbmRleCAhPT0gcGF0dGVybi5sZW5ndGggLSAxKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSW5Hcm91cChwYXR0ZXJuKSB7XG4gICAgICAgIHJldHVybiBwYXR0ZXJuLnNsaWNlKDEsIHBhdHRlcm4ubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzUHJlY2VkZW5jZU9yKHBhdHRlcm4pIHtcbiAgICAgICAgbGV0IGNvdW50ID0gMDtcbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHBhdHRlcm4ubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICBpZiAoSXNPcGVuUGFyZW4ocGF0dGVybiwgaW5kZXgpKVxuICAgICAgICAgICAgICAgIGNvdW50ICs9IDE7XG4gICAgICAgICAgICBpZiAoSXNDbG9zZVBhcmVuKHBhdHRlcm4sIGluZGV4KSlcbiAgICAgICAgICAgICAgICBjb3VudCAtPSAxO1xuICAgICAgICAgICAgaWYgKElzU2VwYXJhdG9yKHBhdHRlcm4sIGluZGV4KSAmJiBjb3VudCA9PT0gMClcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIElzUHJlY2VkZW5jZUFuZChwYXR0ZXJuKSB7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwYXR0ZXJuLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgaWYgKElzT3BlblBhcmVuKHBhdHRlcm4sIGluZGV4KSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIE9yKHBhdHRlcm4pIHtcbiAgICAgICAgbGV0IFtjb3VudCwgc3RhcnRdID0gWzAsIDBdO1xuICAgICAgICBjb25zdCBleHByZXNzaW9ucyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcGF0dGVybi5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgIGlmIChJc09wZW5QYXJlbihwYXR0ZXJuLCBpbmRleCkpXG4gICAgICAgICAgICAgICAgY291bnQgKz0gMTtcbiAgICAgICAgICAgIGlmIChJc0Nsb3NlUGFyZW4ocGF0dGVybiwgaW5kZXgpKVxuICAgICAgICAgICAgICAgIGNvdW50IC09IDE7XG4gICAgICAgICAgICBpZiAoSXNTZXBhcmF0b3IocGF0dGVybiwgaW5kZXgpICYmIGNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBwYXR0ZXJuLnNsaWNlKHN0YXJ0LCBpbmRleCk7XG4gICAgICAgICAgICAgICAgaWYgKHJhbmdlLmxlbmd0aCA+IDApXG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb25zLnB1c2goUGFyc2UocmFuZ2UpKTtcbiAgICAgICAgICAgICAgICBzdGFydCA9IGluZGV4ICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCByYW5nZSA9IHBhdHRlcm4uc2xpY2Uoc3RhcnQpO1xuICAgICAgICBpZiAocmFuZ2UubGVuZ3RoID4gMClcbiAgICAgICAgICAgIGV4cHJlc3Npb25zLnB1c2goUGFyc2UocmFuZ2UpKTtcbiAgICAgICAgaWYgKGV4cHJlc3Npb25zLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybiB7IHR5cGU6ICdjb25zdCcsIGNvbnN0OiAnJyB9O1xuICAgICAgICBpZiAoZXhwcmVzc2lvbnMubGVuZ3RoID09PSAxKVxuICAgICAgICAgICAgcmV0dXJuIGV4cHJlc3Npb25zWzBdO1xuICAgICAgICByZXR1cm4geyB0eXBlOiAnb3InLCBleHByOiBleHByZXNzaW9ucyB9O1xuICAgIH1cbiAgICBmdW5jdGlvbiBBbmQocGF0dGVybikge1xuICAgICAgICBmdW5jdGlvbiBHcm91cCh2YWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgICAgIGlmICghSXNPcGVuUGFyZW4odmFsdWUsIGluZGV4KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVMaXRlcmFsUGFyc2VyRXJyb3IoYFRlbXBsYXRlTGl0ZXJhbFBhcnNlcjogSW5kZXggbXVzdCBwb2ludCB0byBvcGVuIHBhcmVuc2ApO1xuICAgICAgICAgICAgbGV0IGNvdW50ID0gMDtcbiAgICAgICAgICAgIGZvciAobGV0IHNjYW4gPSBpbmRleDsgc2NhbiA8IHZhbHVlLmxlbmd0aDsgc2NhbisrKSB7XG4gICAgICAgICAgICAgICAgaWYgKElzT3BlblBhcmVuKHZhbHVlLCBzY2FuKSlcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gMTtcbiAgICAgICAgICAgICAgICBpZiAoSXNDbG9zZVBhcmVuKHZhbHVlLCBzY2FuKSlcbiAgICAgICAgICAgICAgICAgICAgY291bnQgLT0gMTtcbiAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IDApXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbaW5kZXgsIHNjYW5dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFRlbXBsYXRlTGl0ZXJhbFBhcnNlckVycm9yKGBUZW1wbGF0ZUxpdGVyYWxQYXJzZXI6IFVuY2xvc2VkIGdyb3VwIHBhcmVucyBpbiBleHByZXNzaW9uYCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gUmFuZ2UocGF0dGVybiwgaW5kZXgpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHNjYW4gPSBpbmRleDsgc2NhbiA8IHBhdHRlcm4ubGVuZ3RoOyBzY2FuKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoSXNPcGVuUGFyZW4ocGF0dGVybiwgc2NhbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbaW5kZXgsIHNjYW5dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtpbmRleCwgcGF0dGVybi5sZW5ndGhdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb25zID0gW107XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwYXR0ZXJuLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgaWYgKElzT3BlblBhcmVuKHBhdHRlcm4sIGluZGV4KSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9IEdyb3VwKHBhdHRlcm4sIGluZGV4KTtcbiAgICAgICAgICAgICAgICBjb25zdCByYW5nZSA9IHBhdHRlcm4uc2xpY2Uoc3RhcnQsIGVuZCArIDEpO1xuICAgICAgICAgICAgICAgIGV4cHJlc3Npb25zLnB1c2goUGFyc2UocmFuZ2UpKTtcbiAgICAgICAgICAgICAgICBpbmRleCA9IGVuZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9IFJhbmdlKHBhdHRlcm4sIGluZGV4KTtcbiAgICAgICAgICAgICAgICBjb25zdCByYW5nZSA9IHBhdHRlcm4uc2xpY2Uoc3RhcnQsIGVuZCk7XG4gICAgICAgICAgICAgICAgaWYgKHJhbmdlLmxlbmd0aCA+IDApXG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb25zLnB1c2goUGFyc2UocmFuZ2UpKTtcbiAgICAgICAgICAgICAgICBpbmRleCA9IGVuZCAtIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4cHJlc3Npb25zLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybiB7IHR5cGU6ICdjb25zdCcsIGNvbnN0OiAnJyB9O1xuICAgICAgICBpZiAoZXhwcmVzc2lvbnMubGVuZ3RoID09PSAxKVxuICAgICAgICAgICAgcmV0dXJuIGV4cHJlc3Npb25zWzBdO1xuICAgICAgICByZXR1cm4geyB0eXBlOiAnYW5kJywgZXhwcjogZXhwcmVzc2lvbnMgfTtcbiAgICB9XG4gICAgLyoqIFBhcnNlcyBhIHBhdHRlcm4gYW5kIHJldHVybnMgYW4gZXhwcmVzc2lvbiB0cmVlICovXG4gICAgZnVuY3Rpb24gUGFyc2UocGF0dGVybikge1xuICAgICAgICBpZiAoSXNHcm91cChwYXR0ZXJuKSlcbiAgICAgICAgICAgIHJldHVybiBQYXJzZShJbkdyb3VwKHBhdHRlcm4pKTtcbiAgICAgICAgaWYgKElzUHJlY2VkZW5jZU9yKHBhdHRlcm4pKVxuICAgICAgICAgICAgcmV0dXJuIE9yKHBhdHRlcm4pO1xuICAgICAgICBpZiAoSXNQcmVjZWRlbmNlQW5kKHBhdHRlcm4pKVxuICAgICAgICAgICAgcmV0dXJuIEFuZChwYXR0ZXJuKTtcbiAgICAgICAgcmV0dXJuIHsgdHlwZTogJ2NvbnN0JywgY29uc3Q6IHBhdHRlcm4gfTtcbiAgICB9XG4gICAgVGVtcGxhdGVMaXRlcmFsUGFyc2VyLlBhcnNlID0gUGFyc2U7XG4gICAgLyoqIFBhcnNlcyBhIHBhdHRlcm4gYW5kIHN0cmlwcyBmb3J3YXJkIGFuZCB0cmFpbGluZyBeIGFuZCAkICovXG4gICAgZnVuY3Rpb24gUGFyc2VFeGFjdChwYXR0ZXJuKSB7XG4gICAgICAgIHJldHVybiBQYXJzZShwYXR0ZXJuLnNsaWNlKDEsIHBhdHRlcm4ubGVuZ3RoIC0gMSkpO1xuICAgIH1cbiAgICBUZW1wbGF0ZUxpdGVyYWxQYXJzZXIuUGFyc2VFeGFjdCA9IFBhcnNlRXhhY3Q7XG59KShUZW1wbGF0ZUxpdGVyYWxQYXJzZXIgfHwgKGV4cG9ydHMuVGVtcGxhdGVMaXRlcmFsUGFyc2VyID0gVGVtcGxhdGVMaXRlcmFsUGFyc2VyID0ge30pKTtcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUZW1wbGF0ZUxpdGVyYWxGaW5pdGVcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgVGVtcGxhdGVMaXRlcmFsRmluaXRlO1xuKGZ1bmN0aW9uIChUZW1wbGF0ZUxpdGVyYWxGaW5pdGUpIHtcbiAgICBmdW5jdGlvbiBJc051bWJlcihleHByZXNzaW9uKSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gKGV4cHJlc3Npb24udHlwZSA9PT0gJ29yJyAmJlxuICAgICAgICAgICAgZXhwcmVzc2lvbi5leHByLmxlbmd0aCA9PT0gMiAmJlxuICAgICAgICAgICAgZXhwcmVzc2lvbi5leHByWzBdLnR5cGUgPT09ICdjb25zdCcgJiZcbiAgICAgICAgICAgIGV4cHJlc3Npb24uZXhwclswXS5jb25zdCA9PT0gJzAnICYmXG4gICAgICAgICAgICBleHByZXNzaW9uLmV4cHJbMV0udHlwZSA9PT0gJ2NvbnN0JyAmJlxuICAgICAgICAgICAgZXhwcmVzc2lvbi5leHByWzFdLmNvbnN0ID09PSAnWzEtOV1bMC05XSonKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gSXNCb29sZWFuKGV4cHJlc3Npb24pIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiAoZXhwcmVzc2lvbi50eXBlID09PSAnb3InICYmXG4gICAgICAgICAgICBleHByZXNzaW9uLmV4cHIubGVuZ3RoID09PSAyICYmXG4gICAgICAgICAgICBleHByZXNzaW9uLmV4cHJbMF0udHlwZSA9PT0gJ2NvbnN0JyAmJlxuICAgICAgICAgICAgZXhwcmVzc2lvbi5leHByWzBdLmNvbnN0ID09PSAndHJ1ZScgJiZcbiAgICAgICAgICAgIGV4cHJlc3Npb24uZXhwclsxXS50eXBlID09PSAnY29uc3QnICYmXG4gICAgICAgICAgICBleHByZXNzaW9uLmV4cHJbMV0uY29uc3QgPT09ICdmYWxzZScpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBJc1N0cmluZyhleHByZXNzaW9uKSB7XG4gICAgICAgIHJldHVybiBleHByZXNzaW9uLnR5cGUgPT09ICdjb25zdCcgJiYgZXhwcmVzc2lvbi5jb25zdCA9PT0gJy4qJztcbiAgICB9XG4gICAgZnVuY3Rpb24gQ2hlY2soZXhwcmVzc2lvbikge1xuICAgICAgICBpZiAoSXNCb29sZWFuKGV4cHJlc3Npb24pKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGlmIChJc051bWJlcihleHByZXNzaW9uKSB8fCBJc1N0cmluZyhleHByZXNzaW9uKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGV4cHJlc3Npb24udHlwZSA9PT0gJ2FuZCcpXG4gICAgICAgICAgICByZXR1cm4gZXhwcmVzc2lvbi5leHByLmV2ZXJ5KChleHByKSA9PiBDaGVjayhleHByKSk7XG4gICAgICAgIGlmIChleHByZXNzaW9uLnR5cGUgPT09ICdvcicpXG4gICAgICAgICAgICByZXR1cm4gZXhwcmVzc2lvbi5leHByLmV2ZXJ5KChleHByKSA9PiBDaGVjayhleHByKSk7XG4gICAgICAgIGlmIChleHByZXNzaW9uLnR5cGUgPT09ICdjb25zdCcpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgdGhyb3cgRXJyb3IoYFRlbXBsYXRlTGl0ZXJhbEZpbml0ZTogVW5rbm93biBleHByZXNzaW9uIHR5cGVgKTtcbiAgICB9XG4gICAgVGVtcGxhdGVMaXRlcmFsRmluaXRlLkNoZWNrID0gQ2hlY2s7XG59KShUZW1wbGF0ZUxpdGVyYWxGaW5pdGUgfHwgKGV4cG9ydHMuVGVtcGxhdGVMaXRlcmFsRmluaXRlID0gVGVtcGxhdGVMaXRlcmFsRmluaXRlID0ge30pKTtcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUZW1wbGF0ZUxpdGVyYWxHZW5lcmF0b3Jcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgVGVtcGxhdGVMaXRlcmFsR2VuZXJhdG9yO1xuKGZ1bmN0aW9uIChUZW1wbGF0ZUxpdGVyYWxHZW5lcmF0b3IpIHtcbiAgICBmdW5jdGlvbiogUmVkdWNlKGJ1ZmZlcikge1xuICAgICAgICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCogYnVmZmVyWzBdO1xuICAgICAgICBmb3IgKGNvbnN0IGxlZnQgb2YgYnVmZmVyWzBdKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJpZ2h0IG9mIFJlZHVjZShidWZmZXIuc2xpY2UoMSkpKSB7XG4gICAgICAgICAgICAgICAgeWllbGQgYCR7bGVmdH0ke3JpZ2h0fWA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZnVuY3Rpb24qIEFuZChleHByZXNzaW9uKSB7XG4gICAgICAgIHJldHVybiB5aWVsZCogUmVkdWNlKGV4cHJlc3Npb24uZXhwci5tYXAoKGV4cHIpID0+IFsuLi5HZW5lcmF0ZShleHByKV0pKTtcbiAgICB9XG4gICAgZnVuY3Rpb24qIE9yKGV4cHJlc3Npb24pIHtcbiAgICAgICAgZm9yIChjb25zdCBleHByIG9mIGV4cHJlc3Npb24uZXhwcilcbiAgICAgICAgICAgIHlpZWxkKiBHZW5lcmF0ZShleHByKTtcbiAgICB9XG4gICAgZnVuY3Rpb24qIENvbnN0KGV4cHJlc3Npb24pIHtcbiAgICAgICAgcmV0dXJuIHlpZWxkIGV4cHJlc3Npb24uY29uc3Q7XG4gICAgfVxuICAgIGZ1bmN0aW9uKiBHZW5lcmF0ZShleHByZXNzaW9uKSB7XG4gICAgICAgIGlmIChleHByZXNzaW9uLnR5cGUgPT09ICdhbmQnKVxuICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBBbmQoZXhwcmVzc2lvbik7XG4gICAgICAgIGlmIChleHByZXNzaW9uLnR5cGUgPT09ICdvcicpXG4gICAgICAgICAgICByZXR1cm4geWllbGQqIE9yKGV4cHJlc3Npb24pO1xuICAgICAgICBpZiAoZXhwcmVzc2lvbi50eXBlID09PSAnY29uc3QnKVxuICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBDb25zdChleHByZXNzaW9uKTtcbiAgICAgICAgdGhyb3cgRXJyb3IoJ1RlbXBsYXRlTGl0ZXJhbEdlbmVyYXRvcjogVW5rbm93biBleHByZXNzaW9uJyk7XG4gICAgfVxuICAgIFRlbXBsYXRlTGl0ZXJhbEdlbmVyYXRvci5HZW5lcmF0ZSA9IEdlbmVyYXRlO1xufSkoVGVtcGxhdGVMaXRlcmFsR2VuZXJhdG9yIHx8IChleHBvcnRzLlRlbXBsYXRlTGl0ZXJhbEdlbmVyYXRvciA9IFRlbXBsYXRlTGl0ZXJhbEdlbmVyYXRvciA9IHt9KSk7XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRlbXBsYXRlTGl0ZXJhbERzbFBhcnNlclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgVGVtcGxhdGVMaXRlcmFsRHNsUGFyc2VyO1xuKGZ1bmN0aW9uIChUZW1wbGF0ZUxpdGVyYWxEc2xQYXJzZXIpIHtcbiAgICBmdW5jdGlvbiogUGFyc2VVbmlvbih0ZW1wbGF0ZSkge1xuICAgICAgICBjb25zdCB0cmltID0gdGVtcGxhdGUudHJpbSgpLnJlcGxhY2UoL1wifCcvZywgJycpO1xuICAgICAgICBpZiAodHJpbSA9PT0gJ2Jvb2xlYW4nKVxuICAgICAgICAgICAgcmV0dXJuIHlpZWxkIGV4cG9ydHMuVHlwZS5Cb29sZWFuKCk7XG4gICAgICAgIGlmICh0cmltID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCBleHBvcnRzLlR5cGUuTnVtYmVyKCk7XG4gICAgICAgIGlmICh0cmltID09PSAnYmlnaW50JylcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCBleHBvcnRzLlR5cGUuQmlnSW50KCk7XG4gICAgICAgIGlmICh0cmltID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCBleHBvcnRzLlR5cGUuU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGxpdGVyYWxzID0gdHJpbS5zcGxpdCgnfCcpLm1hcCgobGl0ZXJhbCkgPT4gZXhwb3J0cy5UeXBlLkxpdGVyYWwobGl0ZXJhbC50cmltKCkpKTtcbiAgICAgICAgcmV0dXJuIHlpZWxkIGxpdGVyYWxzLmxlbmd0aCA9PT0gMCA/IGV4cG9ydHMuVHlwZS5OZXZlcigpIDogbGl0ZXJhbHMubGVuZ3RoID09PSAxID8gbGl0ZXJhbHNbMF0gOiBleHBvcnRzLlR5cGUuVW5pb24obGl0ZXJhbHMpO1xuICAgIH1cbiAgICBmdW5jdGlvbiogUGFyc2VUZXJtaW5hbCh0ZW1wbGF0ZSkge1xuICAgICAgICBpZiAodGVtcGxhdGVbMV0gIT09ICd7Jykge1xuICAgICAgICAgICAgY29uc3QgTCA9IGV4cG9ydHMuVHlwZS5MaXRlcmFsKCckJyk7XG4gICAgICAgICAgICBjb25zdCBSID0gUGFyc2VMaXRlcmFsKHRlbXBsYXRlLnNsaWNlKDEpKTtcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCogW0wsIC4uLlJdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAyOyBpIDwgdGVtcGxhdGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0ZW1wbGF0ZVtpXSA9PT0gJ30nKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgTCA9IFBhcnNlVW5pb24odGVtcGxhdGUuc2xpY2UoMiwgaSkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IFIgPSBQYXJzZUxpdGVyYWwodGVtcGxhdGUuc2xpY2UoaSArIDEpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4geWllbGQqIFsuLi5MLCAuLi5SXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB5aWVsZCBleHBvcnRzLlR5cGUuTGl0ZXJhbCh0ZW1wbGF0ZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uKiBQYXJzZUxpdGVyYWwodGVtcGxhdGUpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZW1wbGF0ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRlbXBsYXRlW2ldID09PSAnJCcpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBMID0gZXhwb3J0cy5UeXBlLkxpdGVyYWwodGVtcGxhdGUuc2xpY2UoMCwgaSkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IFIgPSBQYXJzZVRlcm1pbmFsKHRlbXBsYXRlLnNsaWNlKGkpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4geWllbGQqIFtMLCAuLi5SXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB5aWVsZCBleHBvcnRzLlR5cGUuTGl0ZXJhbCh0ZW1wbGF0ZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIFBhcnNlKHRlbXBsYXRlX2RzbCkge1xuICAgICAgICByZXR1cm4gWy4uLlBhcnNlTGl0ZXJhbCh0ZW1wbGF0ZV9kc2wpXTtcbiAgICB9XG4gICAgVGVtcGxhdGVMaXRlcmFsRHNsUGFyc2VyLlBhcnNlID0gUGFyc2U7XG59KShUZW1wbGF0ZUxpdGVyYWxEc2xQYXJzZXIgfHwgKGV4cG9ydHMuVGVtcGxhdGVMaXRlcmFsRHNsUGFyc2VyID0gVGVtcGxhdGVMaXRlcmFsRHNsUGFyc2VyID0ge30pKTtcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUeXBlT3JkaW5hbDogVXNlZCBmb3IgYXV0byAkaWQgZ2VuZXJhdGlvblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmxldCBUeXBlT3JkaW5hbCA9IDA7XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVHlwZUJ1aWxkZXJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5jbGFzcyBUeXBlQnVpbGRlciB7XG4gICAgLyoqIGBbVXRpbGl0eV1gIENyZWF0ZXMgYSBzY2hlbWEgd2l0aG91dCBgc3RhdGljYCBhbmQgYHBhcmFtc2AgdHlwZXMgKi9cbiAgICBDcmVhdGUoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBzY2hlbWE7XG4gICAgfVxuICAgIC8qKiBgW1V0aWxpdHldYCBEaXNjYXJkcyBhIHByb3BlcnR5IGtleSBmcm9tIHRoZSBnaXZlbiBzY2hlbWEgKi9cbiAgICBEaXNjYXJkKHNjaGVtYSwga2V5KSB7XG4gICAgICAgIGNvbnN0IHsgW2tleV06IF8sIC4uLnJlc3QgfSA9IHNjaGVtYTtcbiAgICAgICAgcmV0dXJuIHJlc3Q7XG4gICAgfVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgT21pdHMgY29tcG9zaXRpbmcgc3ltYm9scyBmcm9tIHRoaXMgc2NoZW1hICovXG4gICAgU3RyaWN0KHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShzY2hlbWEpKTtcbiAgICB9XG59XG5leHBvcnRzLlR5cGVCdWlsZGVyID0gVHlwZUJ1aWxkZXI7XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU3RhbmRhcmRUeXBlQnVpbGRlclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmNsYXNzIFN0YW5kYXJkVHlwZUJ1aWxkZXIgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gTW9kaWZpZXJzXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgUmVhZG9ubHkgYW5kIE9wdGlvbmFsIHByb3BlcnR5ICovXG4gICAgUmVhZG9ubHlPcHRpb25hbChzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuUmVhZG9ubHkodGhpcy5PcHRpb25hbChzY2hlbWEpKTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgUmVhZG9ubHkgcHJvcGVydHkgKi9cbiAgICBSZWFkb25seShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHsgLi4uVHlwZUNsb25lLkNsb25lKHNjaGVtYSksIFtleHBvcnRzLlJlYWRvbmx5XTogJ1JlYWRvbmx5JyB9O1xuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIENyZWF0ZXMgYW4gT3B0aW9uYWwgcHJvcGVydHkgKi9cbiAgICBPcHRpb25hbChzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHsgLi4uVHlwZUNsb25lLkNsb25lKHNjaGVtYSksIFtleHBvcnRzLk9wdGlvbmFsXTogJ09wdGlvbmFsJyB9O1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUeXBlc1xuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgQ3JlYXRlcyBhbiBBbnkgdHlwZSAqL1xuICAgIEFueShvcHRpb25zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdBbnknIH0pO1xuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIENyZWF0ZXMgYW4gQXJyYXkgdHlwZSAqL1xuICAgIEFycmF5KHNjaGVtYSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnQXJyYXknLCB0eXBlOiAnYXJyYXknLCBpdGVtczogVHlwZUNsb25lLkNsb25lKHNjaGVtYSkgfSk7XG4gICAgfVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgQ3JlYXRlcyBhIEJvb2xlYW4gdHlwZSAqL1xuICAgIEJvb2xlYW4ob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnQm9vbGVhbicsIHR5cGU6ICdib29sZWFuJyB9KTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBJbnRyaW5zaWMgZnVuY3Rpb24gdG8gQ2FwaXRhbGl6ZSBMaXRlcmFsU3RyaW5nIHR5cGVzICovXG4gICAgQ2FwaXRhbGl6ZShzY2hlbWEsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4geyAuLi5JbnRyaW5zaWMuTWFwKFR5cGVDbG9uZS5DbG9uZShzY2hlbWEpLCAnQ2FwaXRhbGl6ZScpLCAuLi5vcHRpb25zIH07XG4gICAgfVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgQ3JlYXRlcyBhIENvbXBvc2l0ZSBvYmplY3QgdHlwZSAqL1xuICAgIENvbXBvc2l0ZShvYmplY3RzLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGludGVyc2VjdCA9IGV4cG9ydHMuVHlwZS5JbnRlcnNlY3Qob2JqZWN0cywge30pO1xuICAgICAgICBjb25zdCBrZXlzID0gS2V5UmVzb2x2ZXIuUmVzb2x2ZUtleXMoaW50ZXJzZWN0LCB7IGluY2x1ZGVQYXR0ZXJuczogZmFsc2UgfSk7XG4gICAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSBrZXlzLnJlZHVjZSgoYWNjLCBrZXkpID0+ICh7IC4uLmFjYywgW2tleV06IGV4cG9ydHMuVHlwZS5JbmRleChpbnRlcnNlY3QsIFtrZXldKSB9KSwge30pO1xuICAgICAgICByZXR1cm4gZXhwb3J0cy5UeXBlLk9iamVjdChwcm9wZXJ0aWVzLCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgRW51bSB0eXBlICovXG4gICAgRW51bShpdGVtLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGl0ZW0pLmZpbHRlcigoa2V5KSA9PiBpc05hTihrZXkpKS5tYXAoKGtleSkgPT4gaXRlbVtrZXldKTtcbiAgICAgICAgY29uc3QgYW55T2YgPSB2YWx1ZXMubWFwKCh2YWx1ZSkgPT4gKFZhbHVlR3VhcmQuSXNTdHJpbmcodmFsdWUpID8geyBbZXhwb3J0cy5LaW5kXTogJ0xpdGVyYWwnLCB0eXBlOiAnc3RyaW5nJywgY29uc3Q6IHZhbHVlIH0gOiB7IFtleHBvcnRzLktpbmRdOiAnTGl0ZXJhbCcsIHR5cGU6ICdudW1iZXInLCBjb25zdDogdmFsdWUgfSkpO1xuICAgICAgICByZXR1cm4gdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogJ1VuaW9uJywgYW55T2YgfSk7XG4gICAgfVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgQ3JlYXRlcyBhIENvbmRpdGlvbmFsIHR5cGUgKi9cbiAgICBFeHRlbmRzKGxlZnQsIHJpZ2h0LCB0cnVlVHlwZSwgZmFsc2VUeXBlLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgc3dpdGNoIChUeXBlRXh0ZW5kcy5FeHRlbmRzKGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgY2FzZSBUeXBlRXh0ZW5kc1Jlc3VsdC5VbmlvbjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5VbmlvbihbVHlwZUNsb25lLkNsb25lKHRydWVUeXBlLCBvcHRpb25zKSwgVHlwZUNsb25lLkNsb25lKGZhbHNlVHlwZSwgb3B0aW9ucyldKTtcbiAgICAgICAgICAgIGNhc2UgVHlwZUV4dGVuZHNSZXN1bHQuVHJ1ZTpcbiAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUNsb25lLkNsb25lKHRydWVUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGNhc2UgVHlwZUV4dGVuZHNSZXN1bHQuRmFsc2U6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVDbG9uZS5DbG9uZShmYWxzZVR5cGUsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgQ29uc3RydWN0cyBhIHR5cGUgYnkgZXhjbHVkaW5nIGZyb20gdW5pb25UeXBlIGFsbCB1bmlvbiBtZW1iZXJzIHRoYXQgYXJlIGFzc2lnbmFibGUgdG8gZXhjbHVkZWRNZW1iZXJzICovXG4gICAgRXhjbHVkZSh1bmlvblR5cGUsIGV4Y2x1ZGVkTWVtYmVycywgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFRlbXBsYXRlTGl0ZXJhbCh1bmlvblR5cGUpKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuRXhjbHVkZShUZW1wbGF0ZUxpdGVyYWxSZXNvbHZlci5SZXNvbHZlKHVuaW9uVHlwZSksIGV4Y2x1ZGVkTWVtYmVycywgb3B0aW9ucyk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFRlbXBsYXRlTGl0ZXJhbChleGNsdWRlZE1lbWJlcnMpKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuRXhjbHVkZSh1bmlvblR5cGUsIFRlbXBsYXRlTGl0ZXJhbFJlc29sdmVyLlJlc29sdmUoZXhjbHVkZWRNZW1iZXJzKSwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFVuaW9uKHVuaW9uVHlwZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hcnJvd2VkID0gdW5pb25UeXBlLmFueU9mLmZpbHRlcigoaW5uZXIpID0+IFR5cGVFeHRlbmRzLkV4dGVuZHMoaW5uZXIsIGV4Y2x1ZGVkTWVtYmVycykgPT09IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiAobmFycm93ZWQubGVuZ3RoID09PSAxID8gVHlwZUNsb25lLkNsb25lKG5hcnJvd2VkWzBdLCBvcHRpb25zKSA6IHRoaXMuVW5pb24obmFycm93ZWQsIG9wdGlvbnMpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAoVHlwZUV4dGVuZHMuRXh0ZW5kcyh1bmlvblR5cGUsIGV4Y2x1ZGVkTWVtYmVycykgIT09IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlID8gdGhpcy5OZXZlcihvcHRpb25zKSA6IFR5cGVDbG9uZS5DbG9uZSh1bmlvblR5cGUsIG9wdGlvbnMpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIENvbnN0cnVjdHMgYSB0eXBlIGJ5IGV4dHJhY3RpbmcgZnJvbSB0eXBlIGFsbCB1bmlvbiBtZW1iZXJzIHRoYXQgYXJlIGFzc2lnbmFibGUgdG8gdW5pb24gKi9cbiAgICBFeHRyYWN0KHR5cGUsIHVuaW9uLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVGVtcGxhdGVMaXRlcmFsKHR5cGUpKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuRXh0cmFjdChUZW1wbGF0ZUxpdGVyYWxSZXNvbHZlci5SZXNvbHZlKHR5cGUpLCB1bmlvbiwgb3B0aW9ucyk7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFRlbXBsYXRlTGl0ZXJhbCh1bmlvbikpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5FeHRyYWN0KHR5cGUsIFRlbXBsYXRlTGl0ZXJhbFJlc29sdmVyLlJlc29sdmUodW5pb24pLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKFR5cGVHdWFyZC5UVW5pb24odHlwZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hcnJvd2VkID0gdHlwZS5hbnlPZi5maWx0ZXIoKGlubmVyKSA9PiBUeXBlRXh0ZW5kcy5FeHRlbmRzKGlubmVyLCB1bmlvbikgIT09IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiAobmFycm93ZWQubGVuZ3RoID09PSAxID8gVHlwZUNsb25lLkNsb25lKG5hcnJvd2VkWzBdLCBvcHRpb25zKSA6IHRoaXMuVW5pb24obmFycm93ZWQsIG9wdGlvbnMpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAoVHlwZUV4dGVuZHMuRXh0ZW5kcyh0eXBlLCB1bmlvbikgIT09IFR5cGVFeHRlbmRzUmVzdWx0LkZhbHNlID8gVHlwZUNsb25lLkNsb25lKHR5cGUsIG9wdGlvbnMpIDogdGhpcy5OZXZlcihvcHRpb25zKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBSZXR1cm5zIGFuIEluZGV4ZWQgcHJvcGVydHkgdHlwZSBmb3IgdGhlIGdpdmVuIGtleXMgKi9cbiAgICBJbmRleChzY2hlbWEsIHVucmVzb2x2ZWQsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRBcnJheShzY2hlbWEpICYmIFR5cGVHdWFyZC5UTnVtYmVyKHVucmVzb2x2ZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gVHlwZUNsb25lLkNsb25lKHNjaGVtYS5pdGVtcywgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoVHlwZUd1YXJkLlRUdXBsZShzY2hlbWEpICYmIFR5cGVHdWFyZC5UTnVtYmVyKHVucmVzb2x2ZWQpKSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtcyA9IFZhbHVlR3VhcmQuSXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSA/IFtdIDogc2NoZW1hLml0ZW1zO1xuICAgICAgICAgICAgY29uc3QgY2xvbmVkID0gaXRlbXMubWFwKChzY2hlbWEpID0+IFR5cGVDbG9uZS5DbG9uZShzY2hlbWEpKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLlVuaW9uKGNsb25lZCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBrZXlzID0gS2V5QXJyYXlSZXNvbHZlci5SZXNvbHZlKHVucmVzb2x2ZWQpO1xuICAgICAgICAgICAgY29uc3QgY2xvbmUgPSBUeXBlQ2xvbmUuQ2xvbmUoc2NoZW1hKTtcbiAgICAgICAgICAgIHJldHVybiBJbmRleGVkQWNjZXNzb3IuUmVzb2x2ZShjbG9uZSwga2V5cywgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGFuIEludGVnZXIgdHlwZSAqL1xuICAgIEludGVnZXIob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnSW50ZWdlcicsIHR5cGU6ICdpbnRlZ2VyJyB9KTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGFuIEludGVyc2VjdCB0eXBlICovXG4gICAgSW50ZXJzZWN0KGFsbE9mLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgaWYgKGFsbE9mLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybiBleHBvcnRzLlR5cGUuTmV2ZXIoKTtcbiAgICAgICAgaWYgKGFsbE9mLmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICAgIHJldHVybiBUeXBlQ2xvbmUuQ2xvbmUoYWxsT2ZbMF0sIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBvYmplY3RzID0gYWxsT2YuZXZlcnkoKHNjaGVtYSkgPT4gVHlwZUd1YXJkLlRPYmplY3Qoc2NoZW1hKSk7XG4gICAgICAgIGNvbnN0IGNsb25lZCA9IGFsbE9mLm1hcCgoc2NoZW1hKSA9PiBUeXBlQ2xvbmUuQ2xvbmUoc2NoZW1hKSk7XG4gICAgICAgIGNvbnN0IGNsb25lZFVuZXZhbHVhdGVkUHJvcGVydGllcyA9IFR5cGVHdWFyZC5UU2NoZW1hKG9wdGlvbnMudW5ldmFsdWF0ZWRQcm9wZXJ0aWVzKSA/IHsgdW5ldmFsdWF0ZWRQcm9wZXJ0aWVzOiBUeXBlQ2xvbmUuQ2xvbmUob3B0aW9ucy51bmV2YWx1YXRlZFByb3BlcnRpZXMpIH0gOiB7fTtcbiAgICAgICAgaWYgKG9wdGlvbnMudW5ldmFsdWF0ZWRQcm9wZXJ0aWVzID09PSBmYWxzZSB8fCBUeXBlR3VhcmQuVFNjaGVtYShvcHRpb25zLnVuZXZhbHVhdGVkUHJvcGVydGllcykgfHwgb2JqZWN0cykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgLi4uY2xvbmVkVW5ldmFsdWF0ZWRQcm9wZXJ0aWVzLCBbZXhwb3J0cy5LaW5kXTogJ0ludGVyc2VjdCcsIHR5cGU6ICdvYmplY3QnLCBhbGxPZjogY2xvbmVkIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgLi4uY2xvbmVkVW5ldmFsdWF0ZWRQcm9wZXJ0aWVzLCBbZXhwb3J0cy5LaW5kXTogJ0ludGVyc2VjdCcsIGFsbE9mOiBjbG9uZWQgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgS2V5T2YgdHlwZSAqL1xuICAgIEtleU9mKHNjaGVtYSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFJlY29yZChzY2hlbWEpKSB7XG4gICAgICAgICAgICBjb25zdCBwYXR0ZXJuID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoc2NoZW1hLnBhdHRlcm5Qcm9wZXJ0aWVzKVswXTtcbiAgICAgICAgICAgIGlmIChwYXR0ZXJuID09PSBleHBvcnRzLlBhdHRlcm5OdW1iZXJFeGFjdClcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5OdW1iZXIob3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAocGF0dGVybiA9PT0gZXhwb3J0cy5QYXR0ZXJuU3RyaW5nRXhhY3QpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuU3RyaW5nKG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1N0YW5kYXJkVHlwZUJ1aWxkZXI6IFVuYWJsZSB0byByZXNvbHZlIGtleSB0eXBlIGZyb20gUmVjb3JkIGtleSBwYXR0ZXJuJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoVHlwZUd1YXJkLlRUdXBsZShzY2hlbWEpKSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtcyA9IFZhbHVlR3VhcmQuSXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSA/IFtdIDogc2NoZW1hLml0ZW1zO1xuICAgICAgICAgICAgY29uc3QgbGl0ZXJhbHMgPSBpdGVtcy5tYXAoKF8sIGluZGV4KSA9PiBleHBvcnRzLlR5cGUuTGl0ZXJhbChpbmRleCkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuVW5pb24obGl0ZXJhbHMsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKFR5cGVHdWFyZC5UQXJyYXkoc2NoZW1hKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuTnVtYmVyKG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qga2V5cyA9IEtleVJlc29sdmVyLlJlc29sdmVLZXlzKHNjaGVtYSwgeyBpbmNsdWRlUGF0dGVybnM6IGZhbHNlIH0pO1xuICAgICAgICAgICAgaWYgKGtleXMubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLk5ldmVyKG9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgbGl0ZXJhbHMgPSBrZXlzLm1hcCgoa2V5KSA9PiB0aGlzLkxpdGVyYWwoa2V5KSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5VbmlvbihsaXRlcmFscywgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgTGl0ZXJhbCB0eXBlICovXG4gICAgTGl0ZXJhbCh2YWx1ZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnTGl0ZXJhbCcsIGNvbnN0OiB2YWx1ZSwgdHlwZTogdHlwZW9mIHZhbHVlIH0pO1xuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIEludHJpbnNpYyBmdW5jdGlvbiB0byBMb3dlcmNhc2UgTGl0ZXJhbFN0cmluZyB0eXBlcyAqL1xuICAgIExvd2VyY2FzZShzY2hlbWEsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4geyAuLi5JbnRyaW5zaWMuTWFwKFR5cGVDbG9uZS5DbG9uZShzY2hlbWEpLCAnTG93ZXJjYXNlJyksIC4uLm9wdGlvbnMgfTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgTmV2ZXIgdHlwZSAqL1xuICAgIE5ldmVyKG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4gdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogJ05ldmVyJywgbm90OiB7fSB9KTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgTm90IHR5cGUgKi9cbiAgICBOb3Qoc2NoZW1hLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnTm90Jywgbm90OiBUeXBlQ2xvbmUuQ2xvbmUoc2NoZW1hKSB9KTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgTnVsbCB0eXBlICovXG4gICAgTnVsbChvcHRpb25zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdOdWxsJywgdHlwZTogJ251bGwnIH0pO1xuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIENyZWF0ZXMgYSBOdW1iZXIgdHlwZSAqL1xuICAgIE51bWJlcihvcHRpb25zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdOdW1iZXInLCB0eXBlOiAnbnVtYmVyJyB9KTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGFuIE9iamVjdCB0eXBlICovXG4gICAgT2JqZWN0KHByb3BlcnRpZXMsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBjb25zdCBwcm9wZXJ0eUtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhwcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9uYWxLZXlzID0gcHJvcGVydHlLZXlzLmZpbHRlcigoa2V5KSA9PiBUeXBlR3VhcmQuVE9wdGlvbmFsKHByb3BlcnRpZXNba2V5XSkpO1xuICAgICAgICBjb25zdCByZXF1aXJlZEtleXMgPSBwcm9wZXJ0eUtleXMuZmlsdGVyKChuYW1lKSA9PiAhb3B0aW9uYWxLZXlzLmluY2x1ZGVzKG5hbWUpKTtcbiAgICAgICAgY29uc3QgY2xvbmVkQWRkaXRpb25hbFByb3BlcnRpZXMgPSBUeXBlR3VhcmQuVFNjaGVtYShvcHRpb25zLmFkZGl0aW9uYWxQcm9wZXJ0aWVzKSA/IHsgYWRkaXRpb25hbFByb3BlcnRpZXM6IFR5cGVDbG9uZS5DbG9uZShvcHRpb25zLmFkZGl0aW9uYWxQcm9wZXJ0aWVzKSB9IDoge307XG4gICAgICAgIGNvbnN0IGNsb25lZFByb3BlcnRpZXMgPSBwcm9wZXJ0eUtleXMucmVkdWNlKChhY2MsIGtleSkgPT4gKHsgLi4uYWNjLCBba2V5XTogVHlwZUNsb25lLkNsb25lKHByb3BlcnRpZXNba2V5XSkgfSksIHt9KTtcbiAgICAgICAgaWYgKHJlcXVpcmVkS2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCAuLi5jbG9uZWRBZGRpdGlvbmFsUHJvcGVydGllcywgW2V4cG9ydHMuS2luZF06ICdPYmplY3QnLCB0eXBlOiAnb2JqZWN0JywgcHJvcGVydGllczogY2xvbmVkUHJvcGVydGllcywgcmVxdWlyZWQ6IHJlcXVpcmVkS2V5cyB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIC4uLmNsb25lZEFkZGl0aW9uYWxQcm9wZXJ0aWVzLCBbZXhwb3J0cy5LaW5kXTogJ09iamVjdCcsIHR5cGU6ICdvYmplY3QnLCBwcm9wZXJ0aWVzOiBjbG9uZWRQcm9wZXJ0aWVzIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgQ29uc3RydWN0cyBhIHR5cGUgd2hvc2Uga2V5cyBhcmUgb21pdHRlZCBmcm9tIHRoZSBnaXZlbiB0eXBlICovXG4gICAgT21pdChzY2hlbWEsIHVucmVzb2x2ZWQsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBjb25zdCBrZXlzID0gS2V5QXJyYXlSZXNvbHZlci5SZXNvbHZlKHVucmVzb2x2ZWQpO1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIE9iamVjdE1hcC5NYXAoVHlwZUNsb25lLkNsb25lKHNjaGVtYSksIChvYmplY3QpID0+IHtcbiAgICAgICAgICAgIGlmIChWYWx1ZUd1YXJkLklzQXJyYXkob2JqZWN0LnJlcXVpcmVkKSkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5yZXF1aXJlZCA9IG9iamVjdC5yZXF1aXJlZC5maWx0ZXIoKGtleSkgPT4gIWtleXMuaW5jbHVkZXMoa2V5KSk7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdC5yZXF1aXJlZC5sZW5ndGggPT09IDApXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBvYmplY3QucmVxdWlyZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmplY3QucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgICBpZiAoa2V5cy5pbmNsdWRlcyhrZXkpKVxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqZWN0LnByb3BlcnRpZXNba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZShvYmplY3QpO1xuICAgICAgICB9LCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDb25zdHJ1Y3RzIGEgdHlwZSB3aGVyZSBhbGwgcHJvcGVydGllcyBhcmUgb3B0aW9uYWwgKi9cbiAgICBQYXJ0aWFsKHNjaGVtYSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICByZXR1cm4gT2JqZWN0TWFwLk1hcChzY2hlbWEsIChvYmplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmplY3QucHJvcGVydGllcykucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLmFjYywgW2tleV06IHRoaXMuT3B0aW9uYWwob2JqZWN0LnByb3BlcnRpZXNba2V5XSkgfTtcbiAgICAgICAgICAgIH0sIHt9KTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLk9iamVjdChwcm9wZXJ0aWVzLCB0aGlzLkRpc2NhcmQob2JqZWN0LCAncmVxdWlyZWQnKSAvKiBvYmplY3QgdXNlZCBhcyBvcHRpb25zIHRvIHJldGFpbiBvdGhlciBjb25zdHJhaW50cyAqLyk7XG4gICAgICAgIH0sIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIENvbnN0cnVjdHMgYSB0eXBlIHdob3NlIGtleXMgYXJlIHBpY2tlZCBmcm9tIHRoZSBnaXZlbiB0eXBlICovXG4gICAgUGljayhzY2hlbWEsIHVucmVzb2x2ZWQsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBjb25zdCBrZXlzID0gS2V5QXJyYXlSZXNvbHZlci5SZXNvbHZlKHVucmVzb2x2ZWQpO1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgcmV0dXJuIE9iamVjdE1hcC5NYXAoVHlwZUNsb25lLkNsb25lKHNjaGVtYSksIChvYmplY3QpID0+IHtcbiAgICAgICAgICAgIGlmIChWYWx1ZUd1YXJkLklzQXJyYXkob2JqZWN0LnJlcXVpcmVkKSkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5yZXF1aXJlZCA9IG9iamVjdC5yZXF1aXJlZC5maWx0ZXIoKGtleSkgPT4ga2V5cy5pbmNsdWRlcyhrZXkpKTtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0LnJlcXVpcmVkLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIG9iamVjdC5yZXF1aXJlZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iamVjdC5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgICAgIGlmICgha2V5cy5pbmNsdWRlcyhrZXkpKVxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqZWN0LnByb3BlcnRpZXNba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZShvYmplY3QpO1xuICAgICAgICB9LCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgUmVjb3JkIHR5cGUgKi9cbiAgICBSZWNvcmQoa2V5LCBzY2hlbWEsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRUZW1wbGF0ZUxpdGVyYWwoa2V5KSkge1xuICAgICAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IFRlbXBsYXRlTGl0ZXJhbFBhcnNlci5QYXJzZUV4YWN0KGtleS5wYXR0ZXJuKTtcbiAgICAgICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICAgICAgcmV0dXJuIFRlbXBsYXRlTGl0ZXJhbEZpbml0ZS5DaGVjayhleHByZXNzaW9uKVxuICAgICAgICAgICAgICAgID8gKHRoaXMuT2JqZWN0KFsuLi5UZW1wbGF0ZUxpdGVyYWxHZW5lcmF0b3IuR2VuZXJhdGUoZXhwcmVzc2lvbildLnJlZHVjZSgoYWNjLCBrZXkpID0+ICh7IC4uLmFjYywgW2tleV06IFR5cGVDbG9uZS5DbG9uZShzY2hlbWEpIH0pLCB7fSksIG9wdGlvbnMpKVxuICAgICAgICAgICAgICAgIDogdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogJ1JlY29yZCcsIHR5cGU6ICdvYmplY3QnLCBwYXR0ZXJuUHJvcGVydGllczogeyBba2V5LnBhdHRlcm5dOiBUeXBlQ2xvbmUuQ2xvbmUoc2NoZW1hKSB9IH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKFR5cGVHdWFyZC5UVW5pb24oa2V5KSkge1xuICAgICAgICAgICAgY29uc3QgdW5pb24gPSBVbmlvblJlc29sdmVyLlJlc29sdmUoa2V5KTtcbiAgICAgICAgICAgIGlmIChUeXBlR3VhcmQuVFVuaW9uTGl0ZXJhbCh1bmlvbikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9wZXJ0aWVzID0gdW5pb24uYW55T2YucmVkdWNlKChhY2MsIGxpdGVyYWwpID0+ICh7IC4uLmFjYywgW2xpdGVyYWwuY29uc3RdOiBUeXBlQ2xvbmUuQ2xvbmUoc2NoZW1hKSB9KSwge30pO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLk9iamVjdChwcm9wZXJ0aWVzLCB7IC4uLm9wdGlvbnMsIFtleHBvcnRzLkhpbnRdOiAnUmVjb3JkJyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignU3RhbmRhcmRUeXBlQnVpbGRlcjogUmVjb3JkIGtleSBvZiB0eXBlIHVuaW9uIGNvbnRhaW5zIG5vbi1saXRlcmFsIHR5cGVzJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoVHlwZUd1YXJkLlRMaXRlcmFsKGtleSkpIHtcbiAgICAgICAgICAgIGlmIChWYWx1ZUd1YXJkLklzU3RyaW5nKGtleS5jb25zdCkgfHwgVmFsdWVHdWFyZC5Jc051bWJlcihrZXkuY29uc3QpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuT2JqZWN0KHsgW2tleS5jb25zdF06IFR5cGVDbG9uZS5DbG9uZShzY2hlbWEpIH0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKCdTdGFuZGFyZFR5cGVCdWlsZGVyOiBSZWNvcmQga2V5IG9mIHR5cGUgbGl0ZXJhbCBpcyBub3Qgb2YgdHlwZSBzdHJpbmcgb3IgbnVtYmVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoVHlwZUd1YXJkLlRJbnRlZ2VyKGtleSkgfHwgVHlwZUd1YXJkLlROdW1iZXIoa2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdSZWNvcmQnLCB0eXBlOiAnb2JqZWN0JywgcGF0dGVyblByb3BlcnRpZXM6IHsgW2V4cG9ydHMuUGF0dGVybk51bWJlckV4YWN0XTogVHlwZUNsb25lLkNsb25lKHNjaGVtYSkgfSB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChUeXBlR3VhcmQuVFN0cmluZyhrZXkpKSB7XG4gICAgICAgICAgICBjb25zdCBwYXR0ZXJuID0gVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZChrZXkucGF0dGVybikgPyBleHBvcnRzLlBhdHRlcm5TdHJpbmdFeGFjdCA6IGtleS5wYXR0ZXJuO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdSZWNvcmQnLCB0eXBlOiAnb2JqZWN0JywgcGF0dGVyblByb3BlcnRpZXM6IHsgW3BhdHRlcm5dOiBUeXBlQ2xvbmUuQ2xvbmUoc2NoZW1hKSB9IH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYFN0YW5kYXJkVHlwZUJ1aWxkZXI6IFJlY29yZCBrZXkgaXMgYW4gaW52YWxpZCB0eXBlYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgUmVjdXJzaXZlIHR5cGUgKi9cbiAgICBSZWN1cnNpdmUoY2FsbGJhY2ssIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAoVmFsdWVHdWFyZC5Jc1VuZGVmaW5lZChvcHRpb25zLiRpZCkpXG4gICAgICAgICAgICBvcHRpb25zLiRpZCA9IGBUJHtUeXBlT3JkaW5hbCsrfWA7XG4gICAgICAgIGNvbnN0IHRoaXNUeXBlID0gY2FsbGJhY2soeyBbZXhwb3J0cy5LaW5kXTogJ1RoaXMnLCAkcmVmOiBgJHtvcHRpb25zLiRpZH1gIH0pO1xuICAgICAgICB0aGlzVHlwZS4kaWQgPSBvcHRpb25zLiRpZDtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuSGludF06ICdSZWN1cnNpdmUnLCAuLi50aGlzVHlwZSB9KTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgUmVmIHR5cGUuICovXG4gICAgUmVmKHVucmVzb2x2ZWQsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAoVmFsdWVHdWFyZC5Jc1N0cmluZyh1bnJlc29sdmVkKSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnUmVmJywgJHJlZjogdW5yZXNvbHZlZCB9KTtcbiAgICAgICAgaWYgKFZhbHVlR3VhcmQuSXNVbmRlZmluZWQodW5yZXNvbHZlZC4kaWQpKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1N0YW5kYXJkVHlwZUJ1aWxkZXIuUmVmOiBUYXJnZXQgdHlwZSBtdXN0IHNwZWNpZnkgYW4gJGlkJyk7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnUmVmJywgJHJlZjogdW5yZXNvbHZlZC4kaWQgfSk7XG4gICAgfVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgQ29uc3RydWN0cyBhIHR5cGUgd2hlcmUgYWxsIHByb3BlcnRpZXMgYXJlIHJlcXVpcmVkICovXG4gICAgUmVxdWlyZWQoc2NoZW1hLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiBPYmplY3RNYXAuTWFwKHNjaGVtYSwgKG9iamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iamVjdC5wcm9wZXJ0aWVzKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgLi4uYWNjLCBba2V5XTogdGhpcy5EaXNjYXJkKG9iamVjdC5wcm9wZXJ0aWVzW2tleV0sIGV4cG9ydHMuT3B0aW9uYWwpIH07XG4gICAgICAgICAgICB9LCB7fSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5PYmplY3QocHJvcGVydGllcywgb2JqZWN0IC8qIG9iamVjdCB1c2VkIGFzIG9wdGlvbnMgdG8gcmV0YWluIG90aGVyIGNvbnN0cmFpbnRzICAqLyk7XG4gICAgICAgIH0sIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIEV4dHJhY3RzIHRoZSByZXN0IGFycmF5IGZyb20gYSBUdXBsZSAqL1xuICAgIFJlc3Qoc2NoZW1hKSB7XG4gICAgICAgIGlmIChUeXBlR3VhcmQuVFR1cGxlKHNjaGVtYSkpIHtcbiAgICAgICAgICAgIGlmIChWYWx1ZUd1YXJkLklzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgcmV0dXJuIHNjaGVtYS5pdGVtcy5tYXAoKHNjaGVtYSkgPT4gVHlwZUNsb25lLkNsb25lKHNjaGVtYSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFtUeXBlQ2xvbmUuQ2xvbmUoc2NoZW1hKV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgU3RyaW5nIHR5cGUgKi9cbiAgICBTdHJpbmcob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnU3RyaW5nJywgdHlwZTogJ3N0cmluZycgfSk7XG4gICAgfVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgQ3JlYXRlcyBhIFRlbXBsYXRlTGl0ZXJhbCB0eXBlICovXG4gICAgVGVtcGxhdGVMaXRlcmFsKHVucmVzb2x2ZWQsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgY29uc3QgcGF0dGVybiA9IChWYWx1ZUd1YXJkLklzU3RyaW5nKHVucmVzb2x2ZWQpKVxuICAgICAgICAgICAgPyBUZW1wbGF0ZUxpdGVyYWxQYXR0ZXJuLkNyZWF0ZShUZW1wbGF0ZUxpdGVyYWxEc2xQYXJzZXIuUGFyc2UodW5yZXNvbHZlZCkpXG4gICAgICAgICAgICA6IFRlbXBsYXRlTGl0ZXJhbFBhdHRlcm4uQ3JlYXRlKHVucmVzb2x2ZWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogJ1RlbXBsYXRlTGl0ZXJhbCcsIHR5cGU6ICdzdHJpbmcnLCBwYXR0ZXJuIH0pO1xuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIENyZWF0ZXMgYSBUdXBsZSB0eXBlICovXG4gICAgVHVwbGUoaXRlbXMsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBjb25zdCBbYWRkaXRpb25hbEl0ZW1zLCBtaW5JdGVtcywgbWF4SXRlbXNdID0gW2ZhbHNlLCBpdGVtcy5sZW5ndGgsIGl0ZW1zLmxlbmd0aF07XG4gICAgICAgIGNvbnN0IGNsb25lZEl0ZW1zID0gaXRlbXMubWFwKChpdGVtKSA9PiBUeXBlQ2xvbmUuQ2xvbmUoaXRlbSkpO1xuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgY29uc3Qgc2NoZW1hID0gKGl0ZW1zLmxlbmd0aCA+IDAgP1xuICAgICAgICAgICAgeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogJ1R1cGxlJywgdHlwZTogJ2FycmF5JywgaXRlbXM6IGNsb25lZEl0ZW1zLCBhZGRpdGlvbmFsSXRlbXMsIG1pbkl0ZW1zLCBtYXhJdGVtcyB9IDpcbiAgICAgICAgICAgIHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdUdXBsZScsIHR5cGU6ICdhcnJheScsIG1pbkl0ZW1zLCBtYXhJdGVtcyB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHNjaGVtYSk7XG4gICAgfVxuICAgIC8qKiBgW1N0YW5kYXJkXWAgSW50cmluc2ljIGZ1bmN0aW9uIHRvIFVuY2FwaXRhbGl6ZSBMaXRlcmFsU3RyaW5nIHR5cGVzICovXG4gICAgVW5jYXBpdGFsaXplKHNjaGVtYSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB7IC4uLkludHJpbnNpYy5NYXAoVHlwZUNsb25lLkNsb25lKHNjaGVtYSksICdVbmNhcGl0YWxpemUnKSwgLi4ub3B0aW9ucyB9O1xuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIENyZWF0ZXMgYSBVbmlvbiB0eXBlICovXG4gICAgVW5pb24odW5pb24sIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAoVHlwZUd1YXJkLlRUZW1wbGF0ZUxpdGVyYWwodW5pb24pKSB7XG4gICAgICAgICAgICByZXR1cm4gVGVtcGxhdGVMaXRlcmFsUmVzb2x2ZXIuUmVzb2x2ZSh1bmlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhbnlPZiA9IHVuaW9uO1xuICAgICAgICAgICAgaWYgKGFueU9mLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5OZXZlcihvcHRpb25zKTtcbiAgICAgICAgICAgIGlmIChhbnlPZi5sZW5ndGggPT09IDEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKFR5cGVDbG9uZS5DbG9uZShhbnlPZlswXSwgb3B0aW9ucykpO1xuICAgICAgICAgICAgY29uc3QgY2xvbmVkQW55T2YgPSBhbnlPZi5tYXAoKHNjaGVtYSkgPT4gVHlwZUNsb25lLkNsb25lKHNjaGVtYSkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdVbmlvbicsIGFueU9mOiBjbG9uZWRBbnlPZiB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIENyZWF0ZXMgYW4gVW5rbm93biB0eXBlICovXG4gICAgVW5rbm93bihvcHRpb25zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdVbmtub3duJyB9KTtcbiAgICB9XG4gICAgLyoqIGBbU3RhbmRhcmRdYCBDcmVhdGVzIGEgVW5zYWZlIHR5cGUgdGhhdCB3aWxsIGluZmVycyBhcyB0aGUgZ2VuZXJpYyBhcmd1bWVudCBUICovXG4gICAgVW5zYWZlKG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4gdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogb3B0aW9uc1tleHBvcnRzLktpbmRdIHx8ICdVbnNhZmUnIH0pO1xuICAgIH1cbiAgICAvKiogYFtTdGFuZGFyZF1gIEludHJpbnNpYyBmdW5jdGlvbiB0byBVcHBlcmNhc2UgTGl0ZXJhbFN0cmluZyB0eXBlcyAqL1xuICAgIFVwcGVyY2FzZShzY2hlbWEsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4geyAuLi5JbnRyaW5zaWMuTWFwKFR5cGVDbG9uZS5DbG9uZShzY2hlbWEpLCAnVXBwZXJjYXNlJyksIC4uLm9wdGlvbnMgfTtcbiAgICB9XG59XG5leHBvcnRzLlN0YW5kYXJkVHlwZUJ1aWxkZXIgPSBTdGFuZGFyZFR5cGVCdWlsZGVyO1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEV4dGVuZGVkVHlwZUJ1aWxkZXJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5jbGFzcyBFeHRlbmRlZFR5cGVCdWlsZGVyIGV4dGVuZHMgU3RhbmRhcmRUeXBlQnVpbGRlciB7XG4gICAgLyoqIGBbRXh0ZW5kZWRdYCBDcmVhdGVzIGEgQXN5bmNJdGVyYXRvciB0eXBlICovXG4gICAgQXN5bmNJdGVyYXRvcihpdGVtcywgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnQXN5bmNJdGVyYXRvcicsIHR5cGU6ICdBc3luY0l0ZXJhdG9yJywgaXRlbXM6IFR5cGVDbG9uZS5DbG9uZShpdGVtcykgfSk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgQ29uc3RydWN0cyBhIHR5cGUgYnkgcmVjdXJzaXZlbHkgdW53cmFwcGluZyBQcm9taXNlIHR5cGVzICovXG4gICAgQXdhaXRlZChzY2hlbWEsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBjb25zdCBBd2FpdGVkUmVzdCA9IChyZXN0KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzdC5sZW5ndGggPT09IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3Q7XG4gICAgICAgICAgICBjb25zdCBbTCwgLi4uUl0gPSByZXN0O1xuICAgICAgICAgICAgcmV0dXJuIFt0aGlzLkF3YWl0ZWQoTCksIC4uLkF3YWl0ZWRSZXN0KFIpXTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIHJldHVybiAoVHlwZUd1YXJkLlRJbnRlcnNlY3Qoc2NoZW1hKSA/IGV4cG9ydHMuVHlwZS5JbnRlcnNlY3QoQXdhaXRlZFJlc3Qoc2NoZW1hLmFsbE9mKSkgOlxuICAgICAgICAgICAgVHlwZUd1YXJkLlRVbmlvbihzY2hlbWEpID8gZXhwb3J0cy5UeXBlLlVuaW9uKEF3YWl0ZWRSZXN0KHNjaGVtYS5hbnlPZikpIDpcbiAgICAgICAgICAgICAgICBUeXBlR3VhcmQuVFByb21pc2Uoc2NoZW1hKSA/IHRoaXMuQXdhaXRlZChzY2hlbWEuaXRlbSkgOlxuICAgICAgICAgICAgICAgICAgICBUeXBlQ2xvbmUuQ2xvbmUoc2NoZW1hLCBvcHRpb25zKSk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgQ3JlYXRlcyBhIEJpZ0ludCB0eXBlICovXG4gICAgQmlnSW50KG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4gdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogJ0JpZ0ludCcsIHR5cGU6ICdiaWdpbnQnIH0pO1xuICAgIH1cbiAgICAvKiogYFtFeHRlbmRlZF1gIEV4dHJhY3RzIHRoZSBDb25zdHJ1Y3RvclBhcmFtZXRlcnMgZnJvbSB0aGUgZ2l2ZW4gQ29uc3RydWN0b3IgdHlwZSAqL1xuICAgIENvbnN0cnVjdG9yUGFyYW1ldGVycyhzY2hlbWEsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4gdGhpcy5UdXBsZShbLi4uc2NoZW1hLnBhcmFtZXRlcnNdLCB7IC4uLm9wdGlvbnMgfSk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgQ3JlYXRlcyBhIENvbnN0cnVjdG9yIHR5cGUgKi9cbiAgICBDb25zdHJ1Y3RvcihwYXJhbWV0ZXJzLCByZXR1cm5zLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGNsb25lZFJldHVybnMgPSBUeXBlQ2xvbmUuQ2xvbmUocmV0dXJucyk7XG4gICAgICAgIGNvbnN0IGNsb25lZFBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiBUeXBlQ2xvbmUuQ2xvbmUocGFyYW1ldGVyKSk7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnQ29uc3RydWN0b3InLCB0eXBlOiAnY29uc3RydWN0b3InLCBwYXJhbWV0ZXJzOiBjbG9uZWRQYXJhbWV0ZXJzLCByZXR1cm5zOiBjbG9uZWRSZXR1cm5zIH0pO1xuICAgIH1cbiAgICAvKiogYFtFeHRlbmRlZF1gIENyZWF0ZXMgYSBEYXRlIHR5cGUgKi9cbiAgICBEYXRlKG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4gdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogJ0RhdGUnLCB0eXBlOiAnRGF0ZScgfSk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgQ3JlYXRlcyBhIEZ1bmN0aW9uIHR5cGUgKi9cbiAgICBGdW5jdGlvbihwYXJhbWV0ZXJzLCByZXR1cm5zLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGNsb25lZFJldHVybnMgPSBUeXBlQ2xvbmUuQ2xvbmUocmV0dXJucywge30pO1xuICAgICAgICBjb25zdCBjbG9uZWRQYXJhbWV0ZXJzID0gcGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT4gVHlwZUNsb25lLkNsb25lKHBhcmFtZXRlcikpO1xuICAgICAgICByZXR1cm4gdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogJ0Z1bmN0aW9uJywgdHlwZTogJ2Z1bmN0aW9uJywgcGFyYW1ldGVyczogY2xvbmVkUGFyYW1ldGVycywgcmV0dXJuczogY2xvbmVkUmV0dXJucyB9KTtcbiAgICB9XG4gICAgLyoqIGBbRXh0ZW5kZWRdYCBFeHRyYWN0cyB0aGUgSW5zdGFuY2VUeXBlIGZyb20gdGhlIGdpdmVuIENvbnN0cnVjdG9yIHR5cGUgKi9cbiAgICBJbnN0YW5jZVR5cGUoc2NoZW1hLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIFR5cGVDbG9uZS5DbG9uZShzY2hlbWEucmV0dXJucywgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgQ3JlYXRlcyBhbiBJdGVyYXRvciB0eXBlICovXG4gICAgSXRlcmF0b3IoaXRlbXMsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4gdGhpcy5DcmVhdGUoeyAuLi5vcHRpb25zLCBbZXhwb3J0cy5LaW5kXTogJ0l0ZXJhdG9yJywgdHlwZTogJ0l0ZXJhdG9yJywgaXRlbXM6IFR5cGVDbG9uZS5DbG9uZShpdGVtcykgfSk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgRXh0cmFjdHMgdGhlIFBhcmFtZXRlcnMgZnJvbSB0aGUgZ2l2ZW4gRnVuY3Rpb24gdHlwZSAqL1xuICAgIFBhcmFtZXRlcnMoc2NoZW1hLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuVHVwbGUoc2NoZW1hLnBhcmFtZXRlcnMsIHsgLi4ub3B0aW9ucyB9KTtcbiAgICB9XG4gICAgLyoqIGBbRXh0ZW5kZWRdYCBDcmVhdGVzIGEgUHJvbWlzZSB0eXBlICovXG4gICAgUHJvbWlzZShpdGVtLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdQcm9taXNlJywgdHlwZTogJ1Byb21pc2UnLCBpdGVtOiBUeXBlQ2xvbmUuQ2xvbmUoaXRlbSkgfSk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgQ3JlYXRlcyBhIFN0cmluZyB0eXBlICovXG4gICAgUmVnRXhwKHVucmVzb2x2ZWQsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBjb25zdCBwYXR0ZXJuID0gVmFsdWVHdWFyZC5Jc1N0cmluZyh1bnJlc29sdmVkKSA/IHVucmVzb2x2ZWQgOiB1bnJlc29sdmVkLnNvdXJjZTtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdTdHJpbmcnLCB0eXBlOiAnc3RyaW5nJywgcGF0dGVybiB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWQgVXNlIGBUeXBlLlJlZ0V4cGBcbiAgICAgKi9cbiAgICBSZWdFeChyZWdleCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLlJlZ0V4cChyZWdleCwgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgRXh0cmFjdHMgdGhlIFJldHVyblR5cGUgZnJvbSB0aGUgZ2l2ZW4gRnVuY3Rpb24gdHlwZSAqL1xuICAgIFJldHVyblR5cGUoc2NoZW1hLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIFR5cGVDbG9uZS5DbG9uZShzY2hlbWEucmV0dXJucywgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgQ3JlYXRlcyBhIFN5bWJvbCB0eXBlICovXG4gICAgU3ltYm9sKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdTeW1ib2wnLCB0eXBlOiAnc3ltYm9sJyB9KTtcbiAgICB9XG4gICAgLyoqIGBbRXh0ZW5kZWRdYCBDcmVhdGVzIGEgVW5kZWZpbmVkIHR5cGUgKi9cbiAgICBVbmRlZmluZWQob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnVW5kZWZpbmVkJywgdHlwZTogJ3VuZGVmaW5lZCcgfSk7XG4gICAgfVxuICAgIC8qKiBgW0V4dGVuZGVkXWAgQ3JlYXRlcyBhIFVpbnQ4QXJyYXkgdHlwZSAqL1xuICAgIFVpbnQ4QXJyYXkob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiB0aGlzLkNyZWF0ZSh7IC4uLm9wdGlvbnMsIFtleHBvcnRzLktpbmRdOiAnVWludDhBcnJheScsIHR5cGU6ICdVaW50OEFycmF5JyB9KTtcbiAgICB9XG4gICAgLyoqIGBbRXh0ZW5kZWRdYCBDcmVhdGVzIGEgVm9pZCB0eXBlICovXG4gICAgVm9pZChvcHRpb25zID0ge30pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ3JlYXRlKHsgLi4ub3B0aW9ucywgW2V4cG9ydHMuS2luZF06ICdWb2lkJywgdHlwZTogJ3ZvaWQnIH0pO1xuICAgIH1cbn1cbmV4cG9ydHMuRXh0ZW5kZWRUeXBlQnVpbGRlciA9IEV4dGVuZGVkVHlwZUJ1aWxkZXI7XG4vKiogSlNPTiBTY2hlbWEgVHlwZSBCdWlsZGVyIHdpdGggU3RhdGljIFJlc29sdXRpb24gZm9yIFR5cGVTY3JpcHQgKi9cbmV4cG9ydHMuU3RhbmRhcmRUeXBlID0gbmV3IFN0YW5kYXJkVHlwZUJ1aWxkZXIoKTtcbi8qKiBKU09OIFNjaGVtYSBUeXBlIEJ1aWxkZXIgd2l0aCBTdGF0aWMgUmVzb2x1dGlvbiBmb3IgVHlwZVNjcmlwdCAqL1xuZXhwb3J0cy5UeXBlID0gbmV3IEV4dGVuZGVkVHlwZUJ1aWxkZXIoKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///213\n\n}");
|
|
19
|
+
|
|
20
|
+
/***/ }
|
|
21
|
+
|
|
22
|
+
}]);
|